嗯,这就是我想出的,希望它接近你想要的:jsfiddle
基本上,要计算要旋转到的角度,我们需要存储两个点:
- 形状的原点(中心坐标)
- 鼠标点击的坐标
一旦你有了它,你可以用一点三角函数计算两点之间的角度(对不起,如果我在这里不准确,三角函数不是我的强项)。计算两点之间的距离(dx, dy)
,然后使用三角公式找到以度为单位的角度。
layer.on('click', function() {
var mousePos = stage.getMousePosition();
var x = mousePos.x;
var y = mousePos.y;
var rectX = rect.getX()+rect.getWidth()/2;
var rectY = rect.getY()+rect.getHeight()/2;
var dx = x - rectX;
var dy = y - rectY;
var rotation = (Math.atan2(dy, dx)*180/Math.PI+360)%360;
var rotateOnClick = new Kinetic.Tween({
node: rect,
duration: 1,
rotationDeg: rotation,
easing: Kinetic.Easings.EaseInOut
});
rotateOnClick.play();
});
编辑:
根据下面收集到的信息(我得出了相同的结论),我更新了我的小提琴:jsfiddle
正如下面评论中提到的markE,KineticJS 不支持“强制顺时针标志”,因此当顺时针方向旋转超过360 度或逆时针方向旋转超过0 时,旋转总是跳跃。否则,我们知道旋转工作正常。
因此,要手动修复此问题,我们需要考虑两种情况:
- 当我们顺时针旋转超过 360 度时。
- 当我们以逆时针方向旋转超过 0 时。
这是我用来计算是否抵消旋转的数学:
var currentDeg = rect.getRotationDeg();
var oneWay = rotation - currentDeg;
var oneWayAbsolute = Math.abs(rotation - currentDeg);
var otherWay = 360-oneWayAbsolute;
if (otherWay < oneWayAbsolute) {
//Take the other way
if (oneWay > 0) {
//Clicked direction was positive/clockwise
var trueRotation = currentDeg - otherWay;
} else {
//Clicked direction was negative/counter clockwise
var trueRotation = currentDeg + otherWay;
}
} else {
//Take the clicked way
var trueRotation = rotation;
}
基本上,我们想通过比较哪个方向更接近的角度、我们点击的方向或相反的方向来确定旋转的方式。
如果我们确定otherWay
更接近currentDeg
,那么我们需要查看我们点击的方向是逆时针(负)还是顺时针(正)方向,我们将otherWay
方向设置为相反的方向。
然后你可以规范化rotationDeg
onFinish
事件。
var rotateOnClick = new Kinetic.Tween({
node: rect,
duration: 1,
rotationDeg: trueRotation,
easing: Kinetic.Easings.EaseInOut,
onFinish: function() {
trueRotation = (trueRotation+360)%360;
rect.setRotationDeg(trueRotation);
layer.draw();
}
});