Javascript KinectJS:每次拖放时围绕绝对旋转点旋转图像

Javascript KinectJS:每次拖放时围绕绝对旋转点旋转图像,javascript,canvas,drag-and-drop,rotation,kineticjs,Javascript,Canvas,Drag And Drop,Rotation,Kineticjs,我想用kinectJS围绕一个绝对旋转点旋转一个图像。例如关于 var rotatePoint = {x: 500, y: 500} 可以通过单击图像并移动鼠标(即拖放图像)来初始化旋转。当鼠标旋转到相同的角度时,鼠标开始画图 昨天我整天都在研究这个问题,找不到解决办法 有什么想法吗 谢谢 您可以使用一些三角函数围绕固定旋转点移动图像 使用Math.atan2计算鼠标位置相对于旋转点的角度: var dx=mouseX-rotationPointX; var dy=mouseY

我想用kinectJS围绕一个绝对旋转点旋转一个图像。例如关于

var rotatePoint = {x: 500, y: 500}
可以通过单击图像并移动鼠标(即拖放图像)来初始化旋转。当鼠标旋转到相同的角度时,鼠标开始画图

昨天我整天都在研究这个问题,找不到解决办法

有什么想法吗


谢谢

您可以使用一些三角函数围绕固定旋转点移动图像

使用Math.atan2计算鼠标位置相对于旋转点的角度:

    var dx=mouseX-rotationPointX;
    var dy=mouseY-rotationPointY;
    var radianAngle=Math.atan2(dy,dx);
使用Math.cos和Math.sin围绕旋转点移动图像:

    var x=rotationPointX+radius*Math.cos(radianAngle)-imgWidth/2;
    var y=rotationPointY+radius*Math.sin(radianAngle)-imgHeight/2;
    image.setPosition(x,y);
下面是工作示例代码:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.5.4.min.js"></script>

<style>
body{ padding:15px; }
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
  width:300px;
  height:300px;
}
</style>        
<script>
$(function(){

    var stage = new Kinetic.Stage({
        container: 'container',
        width: 300,
        height: 300
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);

    var rx=150;
    var ry=150;
    var radius=75;

    var image;;
    var imgWidth=50;
    var imgHeight=50;

    var rotationPoint=new Kinetic.Circle({
        x:rx,
        y:ry,
        radius:10,
        fill:"green"
    });
    layer.add(rotationPoint);


    $(stage.getContent()).on('mousemove', function (event) {

        // get the current mouse position on the stage
        var pos=stage.getMousePosition();
        var mouseX=parseInt(pos.x);
        var mouseY=parseInt(pos.y);

        // calculate the mouse angle relative 
        // to the rotation point [rx,ry]
        var dx=mouseX-rx;
        var dy=mouseY-ry;
        var radianAngle=Math.atan2(dy,dx);

        // "normalize" the angle so it always is in a proper range (0-2*PI)
        radianAngle=(radianAngle+Math.PI*2)%(Math.PI*2);

        // calculate the new image x,y 
        // based on the angle
        var x=rx+radius*Math.cos(radianAngle)-imgWidth/2;
        var y=ry+radius*Math.sin(radianAngle)-imgHeight/2;
        image.setPosition(x,y);

        layer.draw();
    });


    var img=new Image();
    img.onload=function(){
        image=new Kinetic.Image({
            image:img,
            x:0,
            y:0,
            width:imgWidth,
            height:imgHeight,
        });
        layer.add(image);
        layer.draw();
    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png";


}); // end $(function(){});

</script>       
</head>

<body>
    <p>Move mouse to rotate image around</p>
    <p>the green dot which is located at</p>
    <p>the rotation point</p>
    <div id="container"></div>
</body>
</html>

原型
正文{padding:15px;}
#容器{
边框:实心1px#ccc;
边缘顶部:10px;
宽度:300px;
高度:300px;
}
$(函数(){
var阶段=新的动力学阶段({
容器:'容器',
宽度:300,
身高:300
});
var layer=新的动能层();
阶段。添加(层);
var rx=150;
var-ry=150;
var半径=75;
var图像;;
var imgWidth=50;
var imgHeight=50;
var旋转点=新的动力学圆({
x:rx,
y:嗯,
半径:10,
填充:“绿色”
});
图层。添加(旋转点);
$(stage.getContent()).on('mousemove',函数(事件){
//获取舞台上的当前鼠标位置
var pos=stage.getMousePosition();
var mouseX=parseInt(位置x);
var mouseY=parseInt(位置y);
//计算鼠标相对角度
//至旋转点[rx,ry]
var dx=鼠标x rx;
var dy=老鼠ry;
var弧度角=数学常数2(dy,dx);
//“规格化”角度,使其始终处于适当范围内(0-2*PI)
弧度角=(弧度角+数学PI*2)%(数学PI*2);
//计算新图像x,y
//基于角度
var x=rx+半径*数学cos(弧度角)-imgWidth/2;
变量y=ry+半径*数学sin(弧度角)-imgHeight/2;
图像。设置位置(x,y);
layer.draw();
});
var img=新图像();
img.onload=函数(){
图像=新的动力学图像({
图片:img,
x:0,,
y:0,
宽度:imgWidth,
身高:imgHeight,
});
图层。添加(图像);
layer.draw();
}
img.src=”https://dl.dropboxusercontent.com/u/139992952/stackoverflow/house-icon.png";
}); // end$(函数(){});
移动鼠标以旋转图像

位于的绿点

旋转点

谢谢

我终于找到了线索。 在下面的示例代码中,图像imgObj围绕

imgObj.rotPoint = {x: 500, y: 500}
有几个问题需要解决: 不能只设置绝对旋转点,必须更改相对于其标准位置(图像左上边缘)的偏移。然后,您必须将图像向后移动,因为偏移量的更改移动了图像

对于漫游,我启用了拖动并使用了dragBoundFunc

背景

return {x: this.getAbsolutePosition().x, y: this.getAbsolutePosition().y};
将测量你,将不会有真正的拖动-只是旋转

对于旋转本身,需要六个值: 拖动开始时有三个值:

  • posMouseStart:鼠标的x-y位置
  • radMouseStart:正x轴与从旋转点到posMouseStart的矢量之间的角度(弧度)
  • radImageStart:图像的当前旋转(可能已经旋转?)
我通过绑定onmousedown获得这些值,如果存在拖放操作,则只需使用这些值

拖放时,三个值会一直更改:

  • posMouseNow:此时鼠标右键的x-y位置
  • radMouseNow:x轴正方向与从旋转点到posMouseStart的矢量之间的角度,以弧度表示,此时正方向
  • radImageNow:此时图像的当前旋转(可能已经旋转?)
我在dragBoundFunc中获得这些值

当使用Math.atan2()获取角度时,您必须考虑,您不是在x-y坐标系中,而是在x-y坐标系中-因此使用:Math.atan2(-y,x)

通过从radMouseNow中减去radMouseStart,您可以得到必须旋转的角度,以获得从开始位置到现在位置的图像。但是,当我们围绕这个角度旋转时,图像会疯狂地旋转。 为什么会这样在“开始”和“现在”之间有几毫秒的时间,此时图像已经在旋转。所以:当你“现在”旋转时,你不是从radMouseStart开始,而是从radImageNow-radImageStart+radMouseStart开始

\o/所有问题都已解决\o/

守则:

var imgObj = new Kinetic.Image
                 ({
                        image: YourImg,
                        x: YourSize.x,
                        y: YourSize.y,
                        draggable: true
                 });
imgObj.rotPoint = {x: 500, y: 500};
imgObj.setOffset
(
    imgObj.rotPoint.x - imgObj.getAbsolutePosition().x,
    imgObj.rotPoint.y - imgObj.getAbsolutePosition().y
);
imgObj.move(imgObj.getOffsetX(),imgObj.getOffsetY());
var o = {x: imgObj.rotPoint.x, y: imgObj.rotPoint.y}; // shortcut
imgObj.on('mousedown', function()
                         {
                             posMouseStart = stage.getMousePosition();
                             radMouseStart = Math.atan2(-(posMouseStart.y - o.y), posMouseStart.x - o.x);
                             radImageStart = this.getRotation();
                         });
imgObj.setDragBoundFunc(function(pos)
                        {
                            var posMouseNow = stage.getMousePosition();
                            var radMouseNow = Math.atan2(-(posMouseNow.y - o.y), posMouseNow.x - o.x);
                            var radImageNow = this.getRotation();

                            var radMouseDiff = -(radMouseNow - radMouseStart);

                            this.rotate(radImageStart + radMouseDiff - radImageNow);

                            return {x: this.getAbsolutePosition().x, y: this.getAbsolutePosition().y};
                        });