0

私は多くの例を見ましたが、これまでのところ何もうまくいきませんでした。mousemove で円を回転させたいのですが、中心に回転しているので、今のところ問題はありません。でも、ステージの半分を過ぎると180度ジャンプ。ですから、ステージの半分を通過するまではすべて問題ありません。明らかに何かが足りないのです。Math.atan2エラーが表示されます。円はステージの (0,0) にジャンプします。

これが本当に必要なのを助けてください。

前もって感謝します!

new Kinetic.Tween({
  node: cGrad1, 
  x: stage.getWidth()/2, 
  y: stage.getHeight()/2,
  duration: 1,
  opacity:1,
  easing: Kinetic.Easings.EaseInOut
}).play();

clickO.on('mousemove', function() {  
  for(var n = 0; n < 16; n++) {
    var shape = cGradlayer1.getChildren()[n];
    var stage = shape.getStage();
    var mousePos = stage.getMousePosition();
    var x =  mousePos.x - shape.getPosition().x;
    var y = mousePos.y -shape.getPosition().y ;
    var degree = (Math.PI)+(Math.atan(y/x));

    shape.setAttrs({
      rotation: degree
    })
    cGradlayer1.draw()
  }
})
4

2 に答える 2

2

これが私が思いついたもので、あなたが探していたものに近いことを願っています: jsfiddle

基本的に、回転したい角度を計算するには、2 つのポイントを保存する必要があります。

  1. 形状の原点(中心座標)
  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 つのケースを考慮する必要があります。

  1. 時計回りに 360 度を超えて回転すると。
  2. 反時計回りに 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();
    }
});
于 2013-07-12T20:27:24.680 に答える