I have a javascript code that works perfectly for dragging object...but when I scaled the body down to 0.5...
transform:scale(0.5);
the position of mouse and the object dragged is not the same. How can I fix this? or is this possible?... thank you.
Heres a fiddle : http://jsfiddle.net/Xcb8d/65/
The transform CSS property lets you rotate, scale, skew, or translate an element. It modifies the coordinate space of the CSS visual formatting model.
The transformOrigin property allows you to change the position on transformed elements. 2D transformed element can change the x- and y-axis of the element. 3D transformed element can also change the z-axis of the element. Note: This property must be used together with the transform property.
The CSS -webkit-transform property enables web authors to transform an element in two-dimensional (2D) or three-dimensional (3D) space. For example, you can rotate elements, scale them, skew them, and more.
This was pretty interesting and makes me rethink all the locations I simply used offsetHeight and offsetWidth without knowing that if a transformation was applied to the element, these readonly properties in JavaScript would return incorrect.
The "trick" to this is the clientHeight/offsetHeight will not report their transformed properties correctly. In order to get the correct sizing information from the element you need to call getBoundingClientRect(). You then can calculate the correct pixel information of the scaled element, allowing you then to perform the correct positioning.
Retrieving the bounding rectangle allows you to get the pixel information off the viewport, you then can compare this information to the clientHeight within the browser to determine the scaled offset height, and position.
I modified some of the event wire ups just for testing. Also I added another class to produce a quarter sized object just to prove it works regardless of scale.
CSS:
html,
body {
width:100%;
height:100%;
}
.half-size
{
transform:scale(0.5);
-moz-transform:scale(0.5);
-webkit-transform:scale(0.5);
}
.quarter-size
{
transform:scale(0.25);
-moz-transform:scale(0.25);
-webkit-transform:scale(0.25);
}
#draggable-element {
width:100px;
height:100px;
background-color:#666;
color:white;
padding:10px 12px;
cursor:move;
position:relative; /* important (all position that's not `static`) */
display:block;
}
JavaScript:
var selected = null, // Object of the element to be moved
x_pos = 0, y_pos = 0, // Stores x & y coordinates of the mouse pointer
x_elem = 0, y_elem = 0; // Stores top, left values (edge) of the element
var elem_height = 0;
var elem_width = 0;
// Will be called when user starts dragging an element
function _drag_init(elem) {
// Store the object of the element which needs to be moved
selected = elem;
var boundingRectangle = selected.getBoundingClientRect();
y_elem = (selected.offsetHeight - (boundingRectangle.bottom - boundingRectangle.top)) / 2;
x_elem = (selected.offsetWidth - (boundingRectangle.right - boundingRectangle.left)) / 2
half_elem_height = (boundingRectangle.bottom - boundingRectangle.top) / 2;
half_elem_width = (boundingRectangle.right - boundingRectangle.left) /2;
document.addEventListener('mousemove', _move_elem, false);
document.addEventListener('mouseup', _destroy, false);
};
// Will be called when user dragging an element
function _move_elem(e)
{
x_pos = e.clientX;
y_pos = e.clientY;
selected.style.left = ((x_pos - x_elem) - half_elem_width) + 'px';
selected.style.top = ((y_pos - y_elem) - half_elem_height) + 'px';
}
// Destroy the object when we are done and remove event binds
function _destroy() {
selected = null;
document.removeEventListener('mousemove', _move_elem);
document.removeEventListener('mouseup', _destroy);
}
// Bind the functions...
document.getElementById('draggable-element').onmousedown = function () {
_drag_init(this);
};
HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>JS Bin</title>
</head>
<body>
<div id="draggable-element" class='half-size'>Drag me!</div>
</body>
</html>
Click below for a live preview
http://jsbin.com/moyadici/1/edit (I prefer jsBin over jsFiddle for its live updates)
I did modify some of the event wire ups just for my initial testing. Also I broke the transform into a style so I could try other transforms. Tests look correct when rendering the 'quarter-size'. This just proves out it works regardless of scale and you don't need a magic number for your position calculations.
Not a real answer , but too long for a comment and because it is still jumpy, maybe not on first try ...
In Firefox, using pointer-events
, you could try to restrain the area that will catch the mouse.
create an inside element right in center wich has the size of the element itself once scaled.
Your fiddle says scale(0.5)
a square of 100px
, so lets draw a square of 50px
right in the middle with a pseudo element.
Set pointer-events to none to the element and reset it back to normal for the pseudo element. Now we have a square of 50px
that will accept the mouse. once the element scaled down to 50px
, we still have this area reacting. (the square only looks smaller, but keeping using same space.
To finalize your fiddle test, let's add to body : transform-origin:top left;
, now we should be abble to drag this square.
Firefox test :http://jsfiddle.net/Xcb8d/78/
Chrome test : http://jsfiddle.net/Xcb8d/79/ (negative margins added )
after a few clicks, it really gets jumpy of limits :)
hope it gives some hints.
reading this : http://css-tricks.com/get-value-of-css-rotation-through-javascript/
I thought , we could get the transform value from body and update calculation within the function , so we can modify scale value without touching script
. rookie test : http://jsfiddle.net/Xcb8d/82/
ex: function updated from original fiddle
// Will be called when user dragging an element
function _move_elem(e) {
var el = window.document.body;
var st = window.getComputedStyle(el, null);
var tr = st.getPropertyValue("transform") ;
var values = tr.split('(')[1];
values = values.split(')')[0];
values = values.split(',');
var a = values[0];
var b = values[1];
var c = values[2];
var d = values[3];
x_pos = document.all ? window.event.clientX : e.pageX;
y_pos = document.all ? window.event.clientY : e.pageY;
if (selected !== null) {
selected.style.left = ((x_pos / a) - x_elem) + 'px';
selected.style.top = ((y_pos / d) - y_elem) + 'px';
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With