定位并拖动应用了变换的元素

use*_*806 5 html javascript transform css3

我有一个JavaScript代码,非常适合拖动对象...但是当我将主体缩放到0.5时...

transform:scale(0.5);

鼠标和拖动的对象的位置不同。我怎样才能解决这个问题?还是有可能吗?...谢谢。

这是一个小提琴:http : //jsfiddle.net/Xcb8d/65/

cga*_*ian 5

这非常有趣,让我重新思考我简单使用 offsetHeight 和 offsetWidth 的所有位置,而不知道如果对元素应用转换,JavaScript 中的这些只读属性将返回错误。

这样做的“技巧”是 clientHeight/offsetHeight 将不会正确报告其转换后的属性。为了从元素中获取正确的大小信息,您需要调用getBoundingClientRect()。然后,您可以计算缩放元素的正确像素信息,从而允许您执行正确的定位。

检索边界矩形允许您从视口获取像素信息,然后您可以将此信息与浏览器内的 clientHeight 进行比较,以确定缩放后的偏移高度和位置。

我修改了一些事件接线只是为了测试。此外,我还添加了另一个类来生成四分之一大小的对象,只是为了证明它无论大小如何都有效。

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;
}
Run Code Online (Sandbox Code Playgroud)

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);
};
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

点击下方查看实时预览

http://jsbin.com/moyadici/1/edit (相比 jsFiddle,我更喜欢 jsBin,因为它的实时更新)

我确实为了最初的测试而修改了一些事件接线。我还将变换分解为一种样式,这样我就可以尝试其他变换。渲染“四分之一大小”时,测试看起来是正确的。这只是证明它无论规模如何都有效,并且您不需要神奇的数字来计算位置。


G-C*_*Cyr 1

不是一个真正的答案,但评论太长了,而且因为它仍然很不稳定,也许不是第一次尝试......


在 Firefox 中,使用pointer-events,您可以尝试限制会捕获鼠标的区域。

在中心创建一个内部元素,缩放后其大小与元素本身相同。

你的小提琴说的scale(0.5)是一个正方形100px,所以让我们50px用一个伪元素在中间画一个正方形。

将元素的指针事件设置为 none 并将伪元素重置回正常状态。现在我们有一个50px可以接受鼠标的正方形。一旦元素缩小到50px,我们仍然会让这个区域发生反应。(正方形只是看起来更小,但保持使用相同的空间。

为了完成你的小提琴测试,让我们添加到 body : transform-origin:top left;,现在我们应该能够拖动这个方块。

火狐测试: http: //jsfiddle.net/Xcb8d/78/

Chrome 测试: http: //jsfiddle.net/Xcb8d/79/(添加了负边距)

点击几下后,它真的会受到限制:)


希望它能给出一些提示。


阅读本文:http ://css-tricks.com/get-value-of-css-rotation-through-javascript/

我想,我们可以从主体中获取变换值并更新函数内的计算,这样我们就可以在不接触脚本的情况下修改比例值。

。菜鸟测试: http: //jsfiddle.net/Xcb8d/82/

例如:从原始小提琴更新的功能

// 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';
    }
}
Run Code Online (Sandbox Code Playgroud)