2016-05-12 5 views
3

モバイルデバイスで動作するd3.jsを使用して、幸運のインタラクティブホイールを作成しようとしています。ここで私は、これまでに取り組んできたされているもの:http://plnkr.co/edit/JBJ1odoGvfWFODuIRqKZd3ホイールオブフォーチュン

svg.on("mousemove", function(d) { 
    if (isDown){ 
     var angleDeg = Math.atan2(lastY - d3.event.y, lastX - d3.event.x) * 180/Math.PI; 
     lastX = d3.event.x; 
     lastY = d3.event.y; 
     curAngle = angleDeg; 
     svg.attr("transform", "translate(" + width/2 + "," + height/2 + ") rotate(" + curAngle + "," + 0 + "," + 0 + ")"); 
    } 
    }); 

を今あなたがドラッグをクリックすることができるように円グラフのスライスと「スピン」は、それが周りにいる限り、マウスがあるように私はそれを作るしようとしていますダウン。私はmousemove中に円上の2つの点の間の角度を取得し、それに応じて円グラフの角度を変更するためにMath.atan2を使用しています。私が持っているものはほとんどそこにあるようですが、ラグ/ジッタがあります。このように見えるようにこれを滑らかにするために私ができることはありますか? :http://www.fusioncharts.com/charts/pie2d_5/

理想的には、長期的には、mouseupイベントでスピンの速度を作成し、上方を向いているスライスを照会できるようにすることが理想です。

しかし、今のところ私は滑らかなドラッグ - アローを作成しようとしています。

答えて

4

あなたが「ジッタィ」である理由は、お互いにマウス座標を使用しているためです。あなたがしたいことは、静止点、すなわち車輪の中心を使用することです。代わりにd.event.xでlastXとlastYを更新する

だから、/ yが同じように、これを維持する:

var lastX = width/2; //center points of circle 
var lastY = height/2; 

そしてそうのようなあなたのアルゴリズムでこれを使用します。私は入れている

if (isDown) { 
    var thisX = d3.event.x - lastX, 
     thisY = d3.event.y - lastY; 
    var angleDeg = Math.atan2(lastY - d3.event.y, lastX - d3.event.x) * 180/Math.PI; 
    svg.attr("transform", "translate(" + width/2 + "," + height/2 + ") rotate(" + angleDeg + "," + 0 + "," + 0 + ")"); 
    } 

これはJSFiddle上でplnkrがマウスイベントなどで正しく動作していなかったためです。https://jsfiddle.net/thatOneGuy/ourpo8p7/1/

これは完璧ではありません。

ここでは、マウスの座標を取得し、その座標に回転することが基本的に起こります。しかし、あなたはこれを望んでいません。あなたはマウスを動かすときに動かすだけで、カーソルを動かすだけで動かすだけで、カーソルにジャンプすることはありません。

あなたがしなければならないことは、0から始まります。マウスが押されているときにカーソルを動かすと、回転の位置が保存されるので、やり直したところからやり直すことができます。これは説明が難しい。

とにかくマウスがダウンしたときに、マウスの座標と円の中心との間の角度保存:あなたは0から始まるので、離れて算出した角度からこの値を取らなければならない、マウスの動きに今

var thisX = d3.event.x - lastX, 
    thisY = d3.event.y - lastY; 
    curAngle = Math.atan2(lastY - d3.event.y, lastX - d3.event.x) 
    if (curAngle < 0) curAngle += 2 * Math.PI; //make sure its positive 
    curAngle = curAngle * 180/Math.PI; //change to degrees 

を、しかし、ホイールを回転させたときに計算された最後の角度(ある場合)を追加します。

var thisX = d3.event.x - lastX, 
     thisY = d3.event.y - lastY; 
    angleDeg = Math.atan2(lastY - d3.event.y, lastX - d3.event.x) // * 180/Math.PI) - curAngle 
    if (angleDeg < 0) angleDeg += 2 * Math.PI; 
    angleDeg = angleDeg * 180/Math.PI; 
    angleDeg = angleDeg - curAngle + finishAngle; //reset to 0 and add last rotation calculated 
    if (angleDeg < 0) angleDeg += 360; 
    d3.select('#degrees').text(Math.round(angleDeg)) 
    svg.attr("transform", "translate(" + width/2 + "," + height/2 + ") rotate(" + angleDeg + "," + 0 + "," + 0 + ")"); 

そして最後に、フィドルを作業するときmouseup

finishAngle = angleDeg; 

上で使用する回転の角度をうまく:https://jsfiddle.net/thatOneGuy/v8xce8k3/1/

+0

は、詳細な応答をありがとう!それは非常に意味があり、それはとてもうまくいく。 – QuantumRich

+0

また、タッチイベントで同じことをする方法があることを知っていたかどうか聞いてみたかったのです。タッチスタート/エンドイベントのX、Yはありますか? – QuantumRich

+1

@QuantumRichこの例http://bl.ocksを見てください。org/emeeks/9e6b87735d2da05813e3 – thatOneGuy