JQuery-UI Draggable drag at mouse position - javascript

I have this code:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>jQuery UI Draggable - Default functionality</title>
<style>
#draggable {
width: 150px;
height: 150px;
padding: 0.5em;
border: 1px solid red;
}
.container {
height: 500px;
width: 500px;
border: 1px solid green;
transform: scale(1.6);
position: relative;
left: 300px;
top: 150px;
}
</style>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(function() {
$("#draggable").draggable();
});
</script>
</head>
<body>
<div class="container">
<div id="draggable" class="ui-widget-content">
<p>Drag me around</p>
</div>
</div>
</body>
</html>
It works perfect without transform: scale(1.6);. However, the #draggable moves faster than the mouse with the transform property. How can I make it draggable and scale the container to a value like 1.65? Is there any draggable option I'm supposed to use?

This can be solved by adjusting for the transform: scale(1.6). When the item is dragged, it uses it's position to adjust the top and left of the dragged item. With the scale(), these values are off and you will see the items movement move that same factor faster then the mouse.
x1 = x * 1.6;
y1 = y * 1.6;
To move with the mouse, we need to adjust this back to the same 1:1 (instead of 1:1.6) ratio. This can be done like so:
jQuery > Draggable > Drag Option
drag: function(e, ui) {
// Adjust for Scale
var myScale = parseFloat($('.container').css('transform').split(',')[3]);
var myTop = Math.round(ui.position.top / myScale);
var myLeft = Math.round(ui.position.left / myScale);
ui.position = {
top: myTop,
left: myLeft
};
}
FYI, $('.container').css('transform') will return: matrix(1.6, 0, 0, 1.6, 0, 0). See more: Get CSS transform property with jQuery
You could hard code 1.6 into your script, but I like to keep things portable. So if you change the CSS, you don't have to change this script. See more about setting position: http://api.jqueryui.com/draggable/#event-drag
Working Example: https://jsfiddle.net/Twisty/1gnehyum/

Related

Make an element falling down to the page using html ,css, js

I want to make the grid element to fall down to the page . I used setInterval to repeat the proces (the bottom will decrease so the grid will descend ) . I think I didn't create move() function correctly.I just want to know how can I set the function correctly .
!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel= "stylesheet" href ="style.css"></link>
</head>
<body>
<div class="grid"></div>
<script src="javascript.js" ></script>
</body>
</html>
.grid {
background-color:blue;
height: 20px;
width :100px;
left:600px;
top:150px;
position : absolute;
}
var grid =document.querySelector('.grid');
function move () {
grid.style.bottom-=4;
grid.style.bottom=grid.bottom +'px';
}
move();
setInterval(move,30);
If you would still like to implement your approach to realize this movement, here is some feedback.
Bottom value is String, not numerical (e.g. 300px vs 300)
If you want to manipulate the bottom value of an element, you have to parse the numerical value first, then change it, and then append a 'px' (or whatever unit you're using).
// grid.style.bottom-=4; // subtraction on strings is not allowed
// instead, use:
const currentBottom = parseInt(grid.style.bottom, 10)
grid.style.bottom = (currentBottom - 4) + 'px'
document.getElementById(...).style misses styles from <style> blocks and stylesheets
If you want to get all current styles of a DOM element, you should use window.getComputedStyle. As described in the docs:
getComputedStyle is read-only, and should be used to inspect the element's style — including those set by a element or an external stylesheet
In the snippet below, you can see and compare the values grid.style.bottom and window.getComputedStyle(grid). At first, the first version is empty, but the second has the expected value from the stylesheet.
Alternatively, you could directly apply the style in-line with the HTML element. Then you could use .style as well for accessing the correct value from the beginning.
<div class="grid" style="bottom: 100px"></div>
Check out the fixed version of the snippet below with a delay of 3 seconds for better understanding.
var grid = document.querySelector('.grid');
function move() {
const style = grid.style.bottom
const computedStyle = window.getComputedStyle(grid)
console.log('bottom', style)
console.log('bottom from computed style', computedStyle.bottom)
// grid.style.bottom -= 4;
// grid.style.bottom = grid.bottom + 'px';
const newBottom = parseInt(computedStyle.bottom, 10) - 4; // parseInt only reads the numeric value from the bottom string
grid.style.bottom = newBottom + 'px';
}
move();
setInterval(move, 3000);
.grid {
background-color: blue;
height: 20px;
width: 100px;
left: 100px;
bottom: 200px;
position: absolute;
}
<div class="grid"></div>
I would recommend you to use a CSS animation for that, you don't need JavaScript for that.
.grid {
background-color: blue;
height: 20px;
width: 100px;
left: 100px;
position: absolute;
animation: move 1.5s forwards;
}
#keyframes move {
from {
bottom: 200px;
}
to {
bottom: 0;
}
}
<body>
<div class="grid"></div>
</body>

vanilla javascript image zoom scroll effect

I'm trying to recreate this simple jquery image zoom scroll effect in vanilla javascript with no success:
I'm looking online and all tutorials seems to use jquery or skrollr library which is not being supported since 2014.
This is a tutorial of this effect on youtube:
https://www.youtube.com/watch?v=hjeS8HxH3k0
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Image Zoom Scroll Effect</title>
<style>
body {
margin: 0;
padding: 0;
}
div {
width: 100%;
height: 100vh;
overflow: hidden;
position: relative;
}
div img {
width: 100%;
position: absolute;
top: 0;
left: 50%;
transform: translate(-50%);
}
/* BLANK SPACE, JUST TO TRY OUT THE SCROLL EFFECT */
.whitespace {
width: 100%;
height: 100vh;
}
</style>
<!-- JQUERY CDN -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>
<div class="img-area">
<img
src="https://images.pexels.com/photos/775201/pexels-photo-775201.jpeg"
/>
</div>
<!-- BLANK SPACE, JUST TO TRY OUT THE SCROLL EFFECT -->
<div class="whitespace"></div>
<script>
// JQUERY
$(window).scroll(() => {
let scroll = $(window).scrollTop();
$('.img-area img').css({
width: 100 + scroll / 5 + '%',
});
});
// VANILLA JS
// window.addEventListener('scroll', () => {
// let scroll = window.scrollTop;
// document.querySelector('.img-area img').style.width =
// 100 + scroll / 5 + '%';
// });
</script>
</body>
</html>
I've commented out my vanilla javascript code.
There is no property scrollTop for the window object. Use document.documentElement:
window.addEventListener('scroll', () => {
let scrollTop = document.documentElement.scrollTop;
document.getElementById('test').style.width = 100 + scrollTop / 5 + '%';
});
See working fiddle: https://jsfiddle.net/z3hux1ra/5/

Setting marginBottom via Javascript does not work as expected

i try to set a margin bottom to the body element, but it wont work as expected...
document.addEventListener('DOMContentLoaded', (event) => {
if(window.outerWidth > 768) {
let footerHeight = document.querySelector('footer').offsetHeight;
document.querySelector('body').style.marginBottom = footerHeight + "px";
}
/* .... */
});
its just doing nothing.
the weird part i dont understand: it works as expected when i try to set it as a paddingBottom, but when i change it to margin...
my current solution for now is to wrap it in a setTimeout() like:
document.addEventListener('DOMContentLoaded', (event) => {
if(window.outerWidth > 768) {
setTimeout(function(){
let footerHeight = document.querySelector('footer').offsetHeight;
document.querySelector('body').style.marginBottom = footerHeight + "px";
}, 1);
}
/* .... */
});
let footerHeight gets the correct value in any cases.
no other scripts are loaded which i can think of could affect this...
The simplified CSS & HTML:
body {
margin: 0;
padding-top: 48px;
}
.content-wrapper {
background: #fff;
padding-bottom: 40px;
box-shadow: 0 2px 2px rgba(0, 0, 0, 0.08), 0 4px 4px rgba(0, 0, 0, 0.16);
}
footer {
position: fixed;
bottom: 0;
z-index: -1;
background-size: cover;
background-position: center;
display: flex;
width: 100%;
}
<!DOCTYPE html>
<head>
<meta charset="utf-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
</head>
<body class="start">
...
<div class="content-wrapper">
...
</div>
<footer style="background-image: url('/images/polygon.jpg');">
<div class="container">
<div class="row">
...
</div>
</div>
</footer>
<script src="/js/script.js"></script>
</body>
</html>
creates this type of footer reveal effect: https://codepen.io/hkdc/pen/BLJAVL
but to make sure that the whole footer is always visible i add a margin-bottom of the footers height to the body element.
Anyone has an idea what is happening here or am i getting wrong and can explain it?
I'm not sure you understand body tag correctly. You footer is in that body too adding margin to body cant have any effect in this case cause there is no element (at least visible) after body. Padding works cause padding is for the elements inside the body. If you want to add margin before your footer you can use previousSibling property and set its margin.

width different from 100% for div container

I have a simple WebGL code which displays a 3D graph. It works well but I would like to set a value for the width different from 100%; i.e I would like to put the webGL animation in a small box.
Below my code; I tried to put the WebGL into a 500px box with CSS "height" and "width" but it doesn't work : the animation still takes 100% of width :
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - trackball controls</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #000;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #fff;
margin: 0px;
overflow: hidden;
}
.container {
width: 500px;
height: 500px;
}
</style>
</head>
<body>
<center><div id="container"></div></center>
<script src="three.js/build/three.min.js"></script>
<script src="three.js/examples/js/controls/TrackballControls.js"></script>
<script src="three.js/examples/js/Detector.js"></script>
<script src="three.js/examples/js/libs/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
...
}
function onWindowResize() {
...
}
function animate() {
requestAnimationFrame( animate );
controls.update();
// For displaying
render();
}
function render() {
renderer.render( scene, camera );
stats.update();
}
</script>
</body>
</html>
How to circumvent this issue ?
Thanks
UPDATE 1 :
Ok sorry for the class-id confusion.
Concerning the div container, I am using appenChild in WebGL code to add a renderer domElement.
With the following code :
<html lang="en">
<head>
<title>three.js webgl - trackball controls</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
color: #000;
font-family:Monospace;
font-size:13px;
text-align:center;
font-weight: bold;
background-color: #fff;
margin: 0px;
overflow: hidden;
}
#container {
width: 300px;
height: 300px;
margin-left: auto;
margin-right: auto;
}
</style>
</head>
<body>
<div id="container"></div>
<script src="three.js/build/three.min.js"></script>
<script src="three.js/examples/js/controls/TrackballControls.js"></script>
<script src="three.js/examples/js/Detector.js"></script>
<script src="three.js/examples/js/libs/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
...
</script>
</body>
</html>
I don't get a centered box with WebGL animation. The WebGL window is shifted on the right like this (width is set to 300 px) but it is not centered like I would.
PS: margin-left:auto and margin-right:auto don't seem to work for centering.
Thanks.
There are multiple issues with your html.
your container is defined in your css as a class, you have it in your html as an id
you have nothing in the div container
<center></center> is deprecated Use margin-left:auto; margin:right:auto; in your css.
Give that another go and see how you get on
1)
The canvas is still 100% of the page width because you probably have that set up in your onWindowResize function. In order for your canvas to be a certain size, you need to tell three.js that, not CSS.
To highlight, these couple lines are dependent on width and height:
camera = new THREE.PerspectiveCamera(50, width / height, 1, 10000);
renderer.setSize(width, height);
2)
You want to set margin-left: auto; margin-right: auto to the canvas if your container is truly a "container." Also, since canvas' display is by default inline, you need to use display: block.
See it in action: http://jsfiddle.net/60uzdyss/

The drag doesn't work when it has a siblings img in IE

I'm trying to make a drag box with a sibling img and the 'move-obj' can be dragged.It runs correctly in other browser but IE(8,9,10). In IE, just while you hover the border can you drag the 'move-obj', but if you remove the tag 'img' it work correctly.I found that if I add a background-color to the 'move-obj',it will run correctly too, but it isn't what I want. Can somebody give me some advice?Here is the codepen
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
.wrap{
position: relative;
width: 100%;
height: 100%;
background-color: #f0f0f0;
padding: 10%;
}
.wrap-inside{
position: relative;
width: 500px;
height: 500px;
border: 1px solid #ddd;
}
.move-obj{
cursor: move;
position: absolute;
width: 100px;
height: 100px;
border: 1px solid blue;
}
.bg{
width: 500px;
height: 500px;
position: absolute;
}
</style>
</head>
<body>
<div class="wrap">
<img class="bg" src="https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTE2qkLv64zdI4z5uIbE1oSMmI0AiQcbwbhAYAyI0cF2Dwg88tb" alt="">
<div class="wrap-inside">
<div class="move-obj"></div>
</div>
</div>
</body>
</html>
If I understand you correctly if and only if you are hovering over the mov-obj div you want to be able to move around the https://encrypted-tbn3.gstatic.com/images?q=tbn:ANd9GcTE2qkLv64zdI4z5uIbE1oSMmI0AiQcbwbhAYAyI0cF2Dwg88tb image, right?
If this is what you want, look into either using jQuery and selecting the div on a hover event
$(.mov-obj).hover(function(event) {
//change the x and y coordinates of the image dynamically here of the image
//you can use the event.pageX and event.pageY (I think) to get how much/many pixels have been moved since the hover happened
}
or you can use pure JavaScript
document.getElementsByClassName("mov-obj").addEventListener("mouseenter", function( event ) {
//do something to change the img position dynamically
}, false);
//also do it for the mouseleave event
document.getElementsByClassName("mov-obj").addEventListener("mouseleave", function( event ) {
//do something to change the img position dynamically
}, false);
maybe set a flag letting you know that the mouseenter has happened, but not the mouseleave event
and then if and only if the mouse is inside the div add a click event to the div
while the click is pressed and the mouseleave event hasn't been triggered dynamically relocate the image depending on how much the mouse pointer has moved
(you can add a click event like this fyi)
document.getElementsByClassName("mov-obj").addEventListener("click", function( event ) {
//do something to change the img position dynamically
}, false);
or with jQuery
$(.mov-obj).click(function(event) {
//do something
}
hope this helps
Edit, just paste this code into a browser and try it out:
Note: this only works if you don't move the mouse outside of the div's width and height that you are wanting to move. I'll let you figure out how to fix that part if the mouse goes outside the div what happens
<DOCTYPE html>
<html>
<head>
</head>
<body>
<style>
#div1 {
border: 2px orange solid;
width: 500px;
height: 500px;
}
#div2 {
border: 2px purple solid;
width: 250px;
height: 250px;
position: absolute;
}
</style>
<div id="div1">
<div id="div2">
</div>
</div>
<script type="text/javascript">
// add event listeners to div
var div2 = document.getElementById("div2");
div2.addEventListener("mousedown", getOriginalPosition, false);
div2.addEventListener("mouseup", changeLocation, false);
var helperX;
var helperY;
function getOriginalPosition(event) {
//use these to help with the calculation later
helperX = event.offsetX;
helperY = event.offsetY;
}
var end_xPosition;
var end_yPosition;
function changeLocation(event) {
end_xPosition = event.pageX;
end_yPosition = event.pageY;
div2.style.left = end_xPosition - helperX;
div2.style.top = end_yPosition - helperY;
}
</script>
</body>
</html>

Categories