首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在D3.js v.4.x中设置缩放因子?

如何在D3.js v.4.x中设置缩放因子?
EN

Stack Overflow用户
提问于 2016-11-19 19:22:36
回答 1查看 2.2K关注 0票数 3

我有一个svg,在这里我通过D3.js实现了缩放。当使用鼠标轮时,我对变焦系数不满意。如何调整变焦因子?

我制作了一个JSfiddle,并举例说明了如何实现缩放。

我以为我需要这样的东西,但这是错误的:

代码语言:javascript
复制
zoom.scaleBy()

我想把我的问题弄得更清楚一点:

我想设置一个因子,作为一个鼠标轮革命的变焦因子。插图附图:

SVG没有缩放:

在一次鼠标轮革命之后:

我想在一场口耳相传的革命之后:

我知道这在较早版本的D3.js中是如何工作的,但是有人能帮助我完成当前的版本吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-01 17:46:45

你在你的JS Fiddle非常接近!

这里问题的症结在于,当调用事件回调时,缩放因子k会自动更新。这里的目标是当我们从以前的k (old_k)更改为新k时,我们需要缩放更改,delta,并重新应用它来获得新的k值。

因此,代码更改如下.

  1. 跟踪旧k值 变量old_k = 1;
  2. 计算δk var delta =d3.vent.Trans.k- old_k
  3. 使用transform 更新缩放的delta! D3.vent.Trans.k= old_k + zoomFactor*delta
  4. 再应用变换 Svg.attr(“变换”,d3.event.transform);
  5. 为下一个事件保存新k old_k =d3.vent.Trans.k

var zoomFactor = .7;玩一玩,看看它是否有效。

代码语言:javascript
复制
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;
				vel += acc * dx;
				angle += vel * dx;
				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(){
				penx = cx + radius * Math.cos(angle);
				peny = cy + radius * Math.sin(angle);
				string2.attr("x2", penx);
				string2.attr("y2", peny);
				sphere2.attr("cx", penx);
				sphere2.attr("cy", peny);
			}
代码语言:javascript
复制
<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>

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40696963

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档