在某个边界内拖动旋转的元素

Dragging a rotated element within a certain boundary

本文关键字:旋转 元素 拖动 边界      更新时间:2023-09-26

在下图中,您可以点击并拖动图像,它将无法退出蓝色边框。通过单击红色和绿色矩形,您可以旋转图像。但是,当您单击并拖动旋转的对象时,图像不会跟随鼠标移动。我希望图像跟随鼠标,即使它是旋转的。

http://jsfiddle.net/n3Sn5/

我认为问题发生在我的move函数

move = function (dx, dy)
{
  nowX = Math.min(boundary.attr("x")+boundary.attr("width")-this.attr("width"), this.ox + dx);
  nowY = Math.min(boundary.attr("y")+boundary.attr("height")-this.attr("height"), this.oy + dy);
  nowX = Math.max(boundary.attr("x"), nowX);
  nowY = Math.max(boundary.attr("y"), nowY);
  this.attr({x: nowX, y: nowY });
}

需要注意的一点是,当你点击并拖动一个旋转的对象时,在你释放鼠标点击后,如果你旋转图像,它会在你释放鼠标点击时捕捉到鼠标所在的位置,甚至服从边界。

我以前可以用鼠标拖动旋转后的图像,但是通过添加边界矩形,我不得不使用更复杂的方法。

如果有人知道我需要改变什么,我会非常感激!谢谢!

所需的输出可以通过稍微不同的方式实现。请在http://jsfiddle.net/6BbRL/查看小提琴。我已经修剪了代码,以保持演示的基本部分。

var paper = Raphael(0, 0, 475, 475),
    boxX = 100,
    boxY = 100,
    boxWidth = 300,
    boxHeight = 200,
    // EDITED
    imgWidth = 50,
    imgHeight = 50,
    box = paper.rect(boxX, boxY, boxWidth, boxHeight).attr({fill:"#ffffff"}),
    // EDITED
    html5 = paper.image("http://www.w3.org/html/logo/downloads/HTML5_Badge_512.png",boxX+boxWidth-imgWidth,boxY+boxHeight-imgHeight,imgWidth,imgHeight)
        .attr({cursor: "move"}),
    elementCounterClockwise = paper.rect(180, 0, 50, 50).attr({fill:"#ff5555", cursor:"pointer"}),
    elementClockwise = paper.rect(250, 0, 50, 50).attr({ fill: "#55ff55", cursor: "pointer" }),
    boundary = paper.rect(50,50,400,300).attr({stroke: '#3333FF'}),
    transform,
    // EDITED
    xBound = {min: 50 + imgWidth/2, max: 450 - imgWidth/2},
    yBound = {min: 50 + imgHeight/2, max: 350 - imgHeight/2};
start = function (x, y) {
    // Find min and max values of dx and dy for "html5" element and store them for validating dx and dy in move()
    // This is required to impose a rectagular bound on drag movement of "html5" element.
    transform = html5.transform();
}
move = function (dx, dy, x, y) {
    // To restrict movement of the dragged element, Validate dx and dy before applying below.
    // Here, dx and dy are shifts along x and y axes, with respect to drag start position.
    // EDITED 
    var deltaX = x > xBound.max && xBound.max - x || x < xBound.min && xBound.min - x || 0;
        deltaY = y > yBound.max && yBound.max - y || y < yBound.min && yBound.min - y || 0;
    this.attr({transform: transform + 'T'+ [dx + deltaX, dy + deltaY]});     
}
up = function () {
};
html5.drag(move, start, up);
elementClockwise.click(function() {
  html5.animate({transform: '...r90'}, 100);
})
elementCounterClockwise.click(function() {
  html5.animate({transform: '...r-90'}, 100);
})

使用"…"将转换附加到已存在的转换状态(Raphael API)对于旋转问题很重要。而在拖动时平移元素需要绝对平移,在平移元素时忽略了元素的旋转状态。

//编辑注意

拖动边界正在工作并更新。但是,在合并鼠标位置和图像中心之间的差异时仍然存在一个问题。

我可以帮助你解决旋转和拖动问题,你需要存储旋转并在移动对象后应用它。

elementClockwise.node.onclick = function()
{
    html5.animate({'transform': html5.transform() +'r90'}, 100, onAnimComplete);
}
elementCounterClockwise.node.onclick = function()
{
    html5.animate({'transform': html5.transform() +'r-90'}, 100, onAnimComplete);
}
function onAnimComplete(){
    default_transform = html5.transform();
}

目前我无法使边界工作,但稍后会尝试。

http://jsfiddle.net/n3Sn5/2/