これが私が思いついたもので、あなたが探していたものに近いことを願っています: jsfiddle
基本的に、回転したい角度を計算するには、2 つのポイントを保存する必要があります。
- 形状の原点(中心座標)
- マウスクリックの座標
それができたら、少し三角法を使って 2 点間の角度を計算できます (ここで正確でない場合は申し訳ありませんが、三角法は私の得意分野ではありません)。2 点間の距離を計算し(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 を超えて回転すると、常に回転がジャンプします。それ以外の場合は、回転が適切に機能していることがわかります。
したがって、これを手動で修正するには、次の 2 つのケースを考慮する必要があります。
- 時計回りに 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();
}
});