2016-11-19 10 views
3

私はD3.js経由でズームを実装しています。 マウスホイールを使用しているときのズーム係数に満足できません。 ズーム係数を調整するにはどうすればよいですか?D3.js v.4.xでのズーム係数の設定方法は?

JSfiddleにズームの実装例を示しました。

zoom.scaleBy() 

私は私の問題は少し明確にしようとしています:私はこのような何かを必要とするが、それは間違っていると思っ

私は係数を設定したい、それがズームとして働き1つのマウスホイールの回転の要因。写真と イラスト:ズームなし

SVG: Normal SVG

1つのマウスホイールの回転の後:私が知っている But I want some steps in between (like that)

After one mousewheel revolution.

私は1つのmousewhell革命後にしたいと思いますどのような以前のバージョンのD3.jsでこれがどのように機能したのですか?誰かが現在のバージョンで私を助けることができますか?

+0

あなたがプログラム的な味方をズームするためにいくつかの方法を探している場合は、この 'zoom.scaleBy(d3.select( "SVG")、0.08)のように実行する必要があり;'が、各スクロールアップで、現在0.08である新しいk値を計算する必要があります。 https://jsfiddle.net/cyril123/z94kt8hn/ – Cyril

+0

あなたのコメントで、「zoom.ScaleBy()」がわかりました。 – frankenapps

+0

私はズームの要因を設定したい、基本的には私のSVGがマウスホイールの回転ごとに大きくズームしないようにしたい。 – frankenapps

答えて

2

あなたはJSフィドルに非常に近いです!

スケーラビリティファクタkは、イベントコールバックが呼び出されると自動的に更新されます。ここでの目標は、以前のk(old_k)から新しいkに変更するときです。変更のスケールをdeltaに変更し、新しいk値を取得するために再適用する必要があります。古いk値の

次のようにこれを行うには、コードの変更がある...

  1. キープトラック

    var old_k = 1; 
    
  2. デルタKに

    var delta = d3.event.transform.k - old_k 
    
  3. を計算

    変換との縮尺付きデルタで更新!

    d3.event.transform.k = old_k + zoomFactor*delta 
    
  4. 再適用次のイベントのために、新たなK保存

    svg.attr("transform", d3.event.transform); 
    
  5. を変換

    old_k = d3.event.transform.k 
    

それが動作することを確認するためにvar zoomFactor = .7;で遊んでみてください。

console.clear() 
 
//movement and controls 
 
var stepLR = 30; 
 
var controller; 
 
var speed = 0.007; 
 

 
//pendulum vertical 
 
var cx = 609, cy = 0; 
 
var radius = 350; // cm 
 
var g = 981; // cm/s^2 
 
var angle = Math.PI/8; // radians 
 
var vel = 0; // cm/s 
 
var dx = 0.02; // s 
 
var acc, vel, penx, peny; 
 

 
//svg and d3.js 
 
var sphere; 
 
var string; 
 
var string2; 
 
var sphere2; 
 

 
//timing 
 
var start; 
 

 
var old_k = 1; 
 
var zoomFactor = .7; 
 

 
$(document).ready(function() { 
 
    start = (new Date()).getTime(); //start time on page load 
 

 
    var svg = d3.select("body") 
 
      .append("svg") 
 
      .attr("width", '100%') 
 
      .attr("height", '600px') 
 
      .call(d3.zoom().on("zoom", function() { 
 
      var delta = d3.event.transform.k - old_k 
 
      d3.event.transform.k = old_k + zoomFactor*delta 
 
      svg.attr("transform", d3.event.transform); 
 
      old_k = d3.event.transform.k 
 
     })) 
 
     .append("g"); 
 

 
      var viewport = svg.append('g') 
 

 
      var layer1 = viewport.append('g'); 
 
      var layer2 = viewport.append('g'); 
 

 
      sphere = layer2.append("circle") 
 
         .attr("cx", 30) 
 
         .attr("cy", 30) 
 
         .attr("r", 20) 
 
         .attr('fill', '#FF0000'); 
 

 
      string = layer1.append("rect") 
 
          .attr("x", 27) 
 
          .attr("y", 0) 
 
          .attr("width", 6) 
 
          .attr("height", 10); 
 

 
      //The vertical pendulum 
 
      sphere2 = layer2.append("circle") 
 
         .attr("cx", 609) 
 
         .attr("cy", 300) 
 
         .attr("r", 20) 
 
         .attr('fill', '#FF0000'); 
 

 
      string2 = layer1.append("line") 
 
         .attr("x1", 609.5) 
 
         .attr("y1", 0) 
 
         .attr("x2", 609.5) 
 
         .attr("y2", 310) 
 
         .attr("stroke-width", 4) 
 
         .attr("stroke", "black"); 
 

 
      var roof = layer1.append("rect") 
 
          .attr("x", -100000) 
 
          .attr("y", -60) 
 
          .attr("height", 55) 
 
          .attr("width", 200000) 
 
          .attr('fill', 'url(#diagonal-stripe-3)'); 
 
          
 
      var border = layer1.append("rect") 
 
          .attr("x", -100000) 
 
          .attr("y", -10) 
 
          .attr("height", 10) 
 
          .attr("width", 200000) 
 
          .attr('fill', '#000000'); 
 

 

 

 

 
    controller = setInterval(controller, 30); //start controller 
 
}); 
 

 
function controller(){ 
 

 
    //horizontal pendulum 
 
    sphere.attr('cy', Math.sin(start-(new Date()).getTime()/400-(Math.PI/4))*310+350); 
 
    string.attr('height', Math.sin(start-(new Date()).getTime()/400-(Math.PI/4))*310+337); 
 
    string.attr('width', Math.sin((start-(new Date()).getTime()/400-(Math.PI/4))-Math.PI)*3+6); 
 
    string.attr('x', Math.sin((start-(new Date()).getTime()/400-(Math.PI/4)))*1.5-3+stepLR); 
 

 
    //vertical pendulum 
 
    acc = g * Math.cos(angle) * dx; 
 
\t \t \t \t vel += acc * dx; 
 
\t \t \t \t angle += vel * dx; 
 
\t \t \t \t setPenPos(); 
 

 

 
    document.addEventListener("keydown", function (e) { 
 
    if([e.keyCode] == 37){ 
 
     left(); 
 
    } 
 
    if([e.keyCode] == 39){ 
 
     right(); 
 
    } 
 
    }); 
 
} 
 

 
function left(){ 
 
    stepLR=stepLR-speed; 
 
    sphere.attr('cx', stepLR); 
 
    string.attr('x', stepLR); 
 
} 
 

 
function right(){ 
 
    stepLR=stepLR+speed; 
 
    sphere.attr('cx', stepLR); 
 
    string.attr('x', stepLR); 
 
} 
 

 
function setPenPos(){ 
 
\t \t \t \t penx = cx + radius * Math.cos(angle); 
 
\t \t \t \t peny = cy + radius * Math.sin(angle); 
 
\t \t \t \t string2.attr("x2", penx); 
 
\t \t \t \t string2.attr("y2", peny); 
 
\t \t \t \t sphere2.attr("cx", penx); 
 
\t \t \t \t sphere2.attr("cy", peny); 
 
\t \t \t }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 
 
<script src="https://d3js.org/d3.v4.js"></script> 
 

 
<svg height="10" width="10" xmlns="http://www.w3.org/2000/svg" version="1.1"> <defs> <pattern id="diagonal-stripe-3" patternUnits="userSpaceOnUse" width="10" height="10"> <image xlink:href="data:image/svg+xml;base64,PHN2ZyB4bWxucz0naHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnIHdpZHRoPScxMCcgaGVpZ2h0PScxMCc+CiAgPHJlY3Qgd2lkdGg9JzEwJyBoZWlnaHQ9JzEwJyBmaWxsPSd3aGl0ZScvPgogIDxwYXRoIGQ9J00tMSwxIGwyLC0yCiAgICAgICAgICAgTTAsMTAgbDEwLC0xMAogICAgICAgICAgIE05LDExIGwyLC0yJyBzdHJva2U9J2JsYWNrJyBzdHJva2Utd2lkdGg9JzMnLz4KPC9zdmc+" x="0" y="0" width="10" height="10"> </image> </pattern> </defs> </svg>

+0

これは本当にうまく見えます。 tommorowそして最も可能性が高い賞金を寄付する – frankenapps

+0

@frankenappsこの回答がうまくいったら、それを受け入れられた回答としてマークすることを忘れないでください! :) –

関連する問題