首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用画布在d3 v4/v5中滚动平移

如何使用画布在d3 v4/v5中滚动平移
EN

Stack Overflow用户
提问于 2018-06-10 03:25:07
回答 1查看 1.2K关注 0票数 1

背景

我渲染了很多元素,所以我在画布上使用d3,而不是SVG。

This lovely block from @mbostock describes how to zoom the canvas on mouse scroll in d3v4。然而,我喜欢在鼠标滚动上平移,而不是缩放(就像普通网页和this block一样)。

有一个couple folks已经知道如何使用d3和SVG在滚动上进行平移。不幸的是,这些答案对于canvas来说不是开箱即用的。

代码

代码语言:javascript
复制
canvas.call(d3.zoom()
              .scaleExtent([1 / 2, 4])
              .on("zoom", zoomed));

..。稍后..。

代码语言:javascript
复制
function zoomed() {
  context.save();
  context.clearRect(0, 0, w, h);

  // this gives the default zooming and panning behavior in canvas:
  context.translate(d3.event.transform.x, d3.event.transform.y);
  context.scale(d3.event.transform.k, d3.event.transform.k);

  // Instead, something like this might work?:
  current_translate = d3....?
  new_translate = {'x': current_translate.x + d3.event.sourceEvent.wheelDeltaX, 
                   'y': current_translate.y + d3.event.sourceEvent.wheelDeltaY};
  context.translate(new_translate.x, new_translate.y);

  drawCanvas();
  context.restore();
}

或者,我可能根本不应该使用d3.zoom。应该是类似这样的东西:

代码语言:javascript
复制
canvas.call(d3.pan()  // ??
              .on("zoom", pan));

我能想到的最后一种选择是,我不应该为滚动行为设置javascript处理程序,而是只设置一个比window.innerHeight大的画布元素。也许浏览器会帮我解决这个问题呢?(尝试这种天真的方式对我不起作用,所以如果这是最好的选择,我希望能得到一些帮助)。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-06-10 06:20:47

下面是结合了两个链接示例的一些代码:

代码语言:javascript
复制
<!DOCTYPE html>
<meta charset="utf-8">
<canvas width="960" height="500"></canvas>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>

var canvas = d3.select("canvas"),
    context = canvas.node().getContext("2d"),
    width = canvas.property("width"),
    height = canvas.property("height"),
    radius = 2.5;

var points = d3.range(2000).map(phyllotaxis(10));

canvas.call(d3.zoom()
    .scaleExtent([1 / 2, 4])
    .on("zoom", zoomed))
    .on("wheel.zoom", pan);

drawPoints();

var currentTransform = d3.zoomIdentity;

function zoomed() {
  context.save();
  context.clearRect(0, 0, width, height);
  currentTransform = d3.event.transform;
  context.translate(currentTransform.x, currentTransform.y);
  context.scale(currentTransform.k, currentTransform.k);
  drawPoints();
  context.restore();
}

function pan() {
  context.save();
  context.clearRect(0, 0, width, height);
  currentTransform.x += d3.event.wheelDeltaX;
  currentTransform.y += d3.event.wheelDeltaY;
  context.translate(currentTransform.x, currentTransform.y);
  drawPoints();
  context.restore();
}

function drawPoints() {
  context.beginPath();
  points.forEach(drawPoint);
  context.fill();
}

function drawPoint(point) {
  context.moveTo(point[0] + radius, point[1]);
  context.arc(point[0], point[1], radius, 0, 2 * Math.PI);
}

function phyllotaxis(radius) {
  var theta = Math.PI * (3 - Math.sqrt(5));
  return function(i) {
    var r = radius * Math.sqrt(i), a = theta * i;
    return [
      width / 2 + r * Math.cos(a),
      height / 2 + r * Math.sin(a)
    ];
  };
}

</script>

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

https://stackoverflow.com/questions/50777762

复制
相关文章

相似问题

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