使用Kinetic拖动同一个对象后,如何在旋转动画中保留以前的偏移量?

时间:2015-04-06 08:57:54

标签: javascript kineticjs

任何人都可以展示我如何拖动我的对象,但仍然保持其在旋转动画中的先前偏移。我尝试了很多次但仍未找到解决方案。当我拖动一个物体时,它没有在轨道上旋转:(。

这是我的代码

HTML

<!DOCTYPE HTML>
<html>
  <body>
    <div id="container"></div>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.0.2.min.js"></script>
  </body>
</html> 

CSS

  body {
    margin: 0px;
    padding: 0px;
  }
  canvas {
    border: 1px solid #9C9898;
  }

JS

 window.onload = function() {
        var stage = new Kinetic.Stage({
          container: 'container',
          width: 500,
          height: 500
        });
        var layer = new Kinetic.Layer(),
            cx = stage.getWidth() / 2,
            cy = stage.getWidth() / 2;


        var bigCircle = new Kinetic.Circle({
                  x: cx ,
                  y: cy,
         radius: 200,
                  stroke: 'lightgray',
                  strokeWidth: 8,
                });


        /*
         * move center point outside of the rectangle
         * with offset
         */
        var smallCirlce = new Kinetic.Circle({
          x: cx,
          y: cy,
          radius: 20,
          fill:'rgb(0,102,204)',
          strokeWidth: 4,
          offset: {x:getRandom(-150,150), y:getRandom(-150,150)}
        });

function getRandom(minNum, maxNum){
return Math.random() * (maxNum - minNum) + minNum;
};

        layer.add(bigCircle);
layer.add(smallCirlce);
        stage.add(layer);

        // one revolution per 4 seconds
        var angularSpeed = 360 / 4;
        var anim = new Kinetic.Animation(function(frame) {
          var angleDiff = frame.timeDiff * angularSpeed / 1000;
          smallCirlce.rotate(angleDiff);
        }, layer);

        anim.start();
      };

1 个答案:

答案 0 :(得分:0)

不确定这是不是你所追求的。我从你的描述中得到的是你想要能够拖动蓝色球并让它继续绕其初始点绕轨道运行,但是在更大的半径范围内。

首先,这是一个小提琴:

http://jsfiddle.net/Paul_Smith/206meq0a/

此解决方案的作用是在mousedown上,将圆的位置,偏移和旋转转换为表示圆在空间中的实际位置的单个坐标。

然后它允许您拖动圆圈,并通过从原始位置减去其实际位置将其偏移重置为新的。

可能不是那里最好的解决方案,但我不是一个非常注重数学的程序员:)

重要功能如下:

//Calculate an angle in radians given degrees
function degreesToRadians(degrees) {
    return degrees * Math.PI / 180;
}

//Transform a coordinate by way of a rotation in degrees.
//Rotated about { x: 0, y: 0 }
function translateCoordinate(coordinate, degrees) {    
    var radians = degreesToRadians(degrees);

    return {
        x: (coordinate.x * Math.cos(radians)) - (coordinate.y * Math.sin(radians)),
        y: (coordinate.x * Math.sin(radians)) + (coordinate.y * Math.cos(radians))
    };
}

smallCircle.on("mousedown", function () {
    var rotation = smallCircle.rotation(),
        offset = smallCircle.offset(),
        position = smallCircle.position(),
        translatedOffset;

    //Calculate how the offset has changed due to the rotation   
    translatedOffset = translateCoordinate(offset, rotation);

    //Set the position to that of the current position - the offset
    smallCircle.position({
        x: position.x - translatedOffset.x,
        y: position.y - translatedOffset.y
    });

    //set the offset to 0 as it has now been added to the position
    smallCircle.offset({
        x: 0,
        y: 0
    });

    //Set the rotation to 0 as it is now part of the position due to the   
    //translation which has taken place
    smallCircle.rotation(0);

    //Reset the drag position
    smallCircle.stopDrag();
    smallCircle.startDrag();
});

smallCircle.on("mouseup", function () {
    var position = smallCircle.position();

    //Calculate the new offset (original position - new position)
    smallCircle.offset({
        x: cx - position.x,
        y: cy - position.y
    });

    //Set the position back to the original position
    smallCircle.position({
        x: cx,
        y: cy
    });
});

希望这有帮助