javascript - 如何使用 Canvas 在 d3 v4/v5 中平移滚动

标签 javascript d3.js canvas

背景

我正在渲染许多元素,因此我使用带有 Canvas 的 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 来说并不是开箱即用的。

代码

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

...稍后...

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。应该是这样的:

canvas.call(d3.pan()  // ??
              .on("zoom", pan));

我能想到的最后一个替代方案是,我不应该为滚动行为设置任何 JavaScript 处理程序,而只需要一个大于 window.innerHeight 的 Canvas 元素。那么也许浏览器会帮我处理它? (尝试这种天真的方式对我来说不起作用,所以如果这是最好的选择,我会喜欢一些帮助)。

最佳答案

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

<!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>

关于javascript - 如何使用 Canvas 在 d3 v4/v5 中平移滚动,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50777762/

相关文章:

javascript - 是否可以强制取消选择所有对象 onclick?

javascript - Vue.js 无法将数据从获取请求中获取到变量中

javascript - 如何使用qtip触发弹出窗口

select - 如何使用 selectAll 选择多个选择器?

javascript - 如何在html,javascript中的一个范围输入中使用不同的步骤属性

java - 在错误的位置绘制文本

html - html5的 Canvas 里面的 Canvas

javascript - 如果 &lt;input&gt; 元素不可见且仅由 anchor 标记 <a> 引用,我如何设置上传文件的路径?

javascript - 如何正确使用 GraphQL 订阅?

d3.js - D3 Chart version 4 Normalized Stacked Bar Chart 从垂直到水平