d3 缩放相对于视口大小
d3 zoom relative to viewport size
我目前正在尝试使用 d3 缩放库为我的 canvas 元素添加平滑的缩放和平移。它应该适用于不同的视口大小,所以我需要 canvas 元素相对于视口的大小。
当尽可能缩小(由 scaleExtent 控制)时,元素应该在所有设备上很好地填充屏幕宽度。
const canvas = document.querySelector('canvas')
const context = canvas.getContext('2d')
canvas.width = canvas.offsetWidth
canvas.height = canvas.offsetHeight
const zoom = d3.zoom()
.scaleExtent([0.4, 2])
.on('zoom', ({transform}) => zoomed(transform))
d3.select(canvas).call(zoom)
zoomed(d3.zoomIdentity)
function zoomed(transform) {
console.log(transform);
context.save()
context.clearRect(0,0, canvas.width, canvas.height)
const scale = transform.k * canvas.width/2000
context.translate(transform.x, transform.y)
context.scale(scale, scale)
drawPaths()
context.restore()
}
我尝试将某种值(相对于 canvas 宽度)添加到比例值,但我只是猜测 2000,我担心稍后它可能会弄乱我的代码,当我不操作 d3 转换对象时。
我在初始化时使用缩放到适合的方法解决了这个问题:
function initCanvas() {
const midX = bbox.x + bbox.width / 2;
const midY = bbox.y + bbox.height / 2;
const scale = Math.min(viewportWidth / bbox.width, viewportHeight / bbox.height);
const translateX = viewportWidth / 2 - midX * scale;
const translateY = viewportHeight / 2 - midY * scale;
d3.select(canvas).call(
zoom_function.transform,
d3.zoomIdentity.translate(translateX, translateY).scale(scale)
);
}
这将使您的路径在初始化时居中,但不会使 zoomExtent 相对于视口大小。然而,这也可以通过给 scaleExtent 函数一个相对值来完成。
关于边界框的附加信息:
在我的例子中,由于路径没有改变,找出边界框不是我必须以编程方式做的事情,但有一些方法可以这样做:
https://codepen.io/TomashKhamlai/pen/KNrjqE
我目前正在尝试使用 d3 缩放库为我的 canvas 元素添加平滑的缩放和平移。它应该适用于不同的视口大小,所以我需要 canvas 元素相对于视口的大小。
当尽可能缩小(由 scaleExtent 控制)时,元素应该在所有设备上很好地填充屏幕宽度。
const canvas = document.querySelector('canvas')
const context = canvas.getContext('2d')
canvas.width = canvas.offsetWidth
canvas.height = canvas.offsetHeight
const zoom = d3.zoom()
.scaleExtent([0.4, 2])
.on('zoom', ({transform}) => zoomed(transform))
d3.select(canvas).call(zoom)
zoomed(d3.zoomIdentity)
function zoomed(transform) {
console.log(transform);
context.save()
context.clearRect(0,0, canvas.width, canvas.height)
const scale = transform.k * canvas.width/2000
context.translate(transform.x, transform.y)
context.scale(scale, scale)
drawPaths()
context.restore()
}
我尝试将某种值(相对于 canvas 宽度)添加到比例值,但我只是猜测 2000,我担心稍后它可能会弄乱我的代码,当我不操作 d3 转换对象时。
我在初始化时使用缩放到适合的方法解决了这个问题:
function initCanvas() {
const midX = bbox.x + bbox.width / 2;
const midY = bbox.y + bbox.height / 2;
const scale = Math.min(viewportWidth / bbox.width, viewportHeight / bbox.height);
const translateX = viewportWidth / 2 - midX * scale;
const translateY = viewportHeight / 2 - midY * scale;
d3.select(canvas).call(
zoom_function.transform,
d3.zoomIdentity.translate(translateX, translateY).scale(scale)
);
}
这将使您的路径在初始化时居中,但不会使 zoomExtent 相对于视口大小。然而,这也可以通过给 scaleExtent 函数一个相对值来完成。
关于边界框的附加信息: 在我的例子中,由于路径没有改变,找出边界框不是我必须以编程方式做的事情,但有一些方法可以这样做: https://codepen.io/TomashKhamlai/pen/KNrjqE