D3 arc 和 SVG 2d 到 3d 透视变化
D3 arc and SVG 2d to 3d perspective change
我有一个 SVG,其中有一组围绕共同原点移动的独立圆弧。在用户事件中,这些圆弧可以改变它们的半径和 start/end 角度。在其他用户事件中,用户可以通过以下 css 转换将视图从 2d 更改为假 3d(正交?),如 here:
所述
translate(0px, ${t*5 - i*t*40}px)
rotateX(${t*60}deg)
rotateZ(${t*-30}deg)
scale(1.0)
t 是一个布尔标志,指示透视图是打开还是关闭,如果标志 = 0 则不会进行实际转换。
可以在此处查看说明该示例的我的代码:https://codepen.io/stopyransky/pen/MZPbjg
单击按钮触发透视图后,它会正确更改,但弧形过渡 (radii/angle) 现在乱七八糟。
我的问题是如何修复以使圆弧的过渡保持正确?我想我需要修改函数来改变 arc 在 tweenAngles 和 tweenRadii 中的构建方式,但我不知道这些过渡应该是什么。我试图在标志为 0 时反转转换,但没有帮助。
经过 Animation at Work slack channel 的讨论和频道用户 'mamboleoo' 的帮助,我可以为我的问题提供答案。
第一个问题是在 togglePerspective
函数中使用 node.style.transition = "ease 1s all";
。如果没有它,路径会在 3d 视图中正确动画,但我们会错过按钮单击时 2d 和 3d 视图之间的转换。
要修复它,我们需要在 togglePerspective
中创建自定义 d3.styleTween:
function togglePerspective() {
perspective = !perspective;
d3.selectAll('path').each((d, i, n) => {
const node = n[i];
// OLD
// node.style.transition = "ease 1s all";
// node.style.transform = perspectiveTween(perspective, i);
node.style.transformOrigin = "20% 20%";
// NEW LINES
const tr = d3.transition().duration(3000);
d3.select(node).transition(tr)
.styleTween('transform', () => {
return function(time) { // interpolation fn (time = 0...1)
return perspectiveTween(perspective, i, time);
}
});
});
}
在 perspectiveTween
函数中,我们将先前固定的转换值参数化:
function perspectiveTween(perspective, i, time) {
const T = perspective ? time : (1-time);
const xRotation = (60 * T);
const yRotation = (-30 * T);
const yTranslation = (T*5) - i*(T * 10);
return `
translate(0px, ${yTranslation}px)
rotateX(${xRotation}deg)
rotateZ(${yRotation}deg)
scale(1.0)`
};
我有一个 SVG,其中有一组围绕共同原点移动的独立圆弧。在用户事件中,这些圆弧可以改变它们的半径和 start/end 角度。在其他用户事件中,用户可以通过以下 css 转换将视图从 2d 更改为假 3d(正交?),如 here:
所述translate(0px, ${t*5 - i*t*40}px)
rotateX(${t*60}deg)
rotateZ(${t*-30}deg)
scale(1.0)
t 是一个布尔标志,指示透视图是打开还是关闭,如果标志 = 0 则不会进行实际转换。
可以在此处查看说明该示例的我的代码:https://codepen.io/stopyransky/pen/MZPbjg
单击按钮触发透视图后,它会正确更改,但弧形过渡 (radii/angle) 现在乱七八糟。
我的问题是如何修复以使圆弧的过渡保持正确?我想我需要修改函数来改变 arc 在 tweenAngles 和 tweenRadii 中的构建方式,但我不知道这些过渡应该是什么。我试图在标志为 0 时反转转换,但没有帮助。
经过 Animation at Work slack channel 的讨论和频道用户 'mamboleoo' 的帮助,我可以为我的问题提供答案。
第一个问题是在 togglePerspective
函数中使用 node.style.transition = "ease 1s all";
。如果没有它,路径会在 3d 视图中正确动画,但我们会错过按钮单击时 2d 和 3d 视图之间的转换。
要修复它,我们需要在 togglePerspective
中创建自定义 d3.styleTween:
function togglePerspective() {
perspective = !perspective;
d3.selectAll('path').each((d, i, n) => {
const node = n[i];
// OLD
// node.style.transition = "ease 1s all";
// node.style.transform = perspectiveTween(perspective, i);
node.style.transformOrigin = "20% 20%";
// NEW LINES
const tr = d3.transition().duration(3000);
d3.select(node).transition(tr)
.styleTween('transform', () => {
return function(time) { // interpolation fn (time = 0...1)
return perspectiveTween(perspective, i, time);
}
});
});
}
在 perspectiveTween
函数中,我们将先前固定的转换值参数化:
function perspectiveTween(perspective, i, time) {
const T = perspective ? time : (1-time);
const xRotation = (60 * T);
const yRotation = (-30 * T);
const yTranslation = (T*5) - i*(T * 10);
return `
translate(0px, ${yTranslation}px)
rotateX(${xRotation}deg)
rotateZ(${yRotation}deg)
scale(1.0)`
};