【问题标题】:KinectJS: Rotate an image about an absolute rotate point per drag and dropKinectJS:每次拖放围绕绝对旋转点旋转图像
【发布时间】:2013-07-24 07:08:50
【问题描述】:

我想使用 kinectJS 围绕绝对旋转点旋转图像。比如关于

var rotatePoint = {x: 500, y: 500}

应该通过单击图像并移动鼠标来初始化旋转,即通过拖放图像。这样它应该旋转大约相同的角度,鼠标正在绘图。

昨天我整天在这个问题上工作,但找不到解决方案。

有什么想法吗?

谢谢!

【问题讨论】:

    标签: javascript canvas drag-and-drop rotation kineticjs


    【解决方案1】:

    谢谢!

    我终于明白了。 在以下示例代码中,图像 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() 获取角度时,您必须注意,您不是在 xy 坐标系中,而是在 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};
                            });
    

    【讨论】:

      【解决方案2】:

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

      使用 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>
      

      【讨论】:

        猜你喜欢
        • 2023-04-07
        • 1970-01-01
        • 1970-01-01
        • 2021-09-13
        • 2013-02-16
        • 1970-01-01
        • 1970-01-01
        • 2011-10-30
        • 2011-10-13
        相关资源
        最近更新 更多