2016-11-19 88 views
3

我有一個svg,我已經通過D3.js實現了縮放。 使用鼠標滾輪時,我不滿意縮放係數。 如何調整縮放係數?如何在D3.js v.4.x中設置縮放因子?

我做了一個JSfiddle與我如何實現縮放的例子。

我想我需要的是這樣的,但它是錯誤的:

zoom.scaleBy() 

我想使我的問題更清楚一點:

我想成立一​​個因素,充當變焦一個鼠標輪革命的因素。 插圖圖片:

無縮放的SVG: Normal SVG

一個滾輪革命之後: But I want some steps in between (like that)

我知道: After one mousewheel revolution.

我想什麼有一個mousewhell革命後這是如何工作在舊版本的D3.js,但有人可以幫助我的當前版本?

+0

如果你正在尋找一些方法來放大綱領性的盟友,那麼你需要做這樣的'zoom.scaleBy(d3.select( 「SVG」),0.08);'但在每次向上滾動時,您需要計算當前爲0.08的新k值。 https://jsfiddle.net/cyril123/z94kt8hn/ – Cyril

+0

好的你的評論我想通了,'zoom.ScaleBy()'是worng的方式。 – frankenapps

+0

我想爲縮放設置一個因子,基本上我希望我的svg不會在每個鼠標輪旋轉時縮小太多。 – frankenapps

回答

2

你非常接近你的JS小提琴!

問題的關鍵在於調用事件回調時自動更新縮放係數k。這裏的目標是當我們從前一個k(old_k)更改爲新k時,我們需要縮放變化delta,並重新應用它以獲得新的k值。

因此,代碼修改要做到這一點是如下......老K值

var old_k = 1; 
    1. 跟蹤計算三角洲ķ

      var delta = d3.event.transform.k - old_k 
      
    2. 更新變換與縮放增量!

      d3.event.transform.k = old_k + zoomFactor*delta 
      
    3. 再塗變換

      svg.attr("transform", d3.event.transform); 
      
    4. 保存新K爲下一個事件

      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如果這個答案適合你,不要忘記將它標記爲已接受的答案! :) –