请帮助我理解使用普通 javascript 操作 svg 元素及其转换的最佳实践。
我知道坐标系是通过节点和链接等传递的。
我想要实现的是在旋转后继续对元素进行原始翻译。应用旋转后不沿轴。
我是否必须克隆复制第一个转换转换并将其添加到转换列表的末尾?
非常感谢如果有人能以一种雄辩的方式阐明一些观点。
实现这一点的方法是嵌套变换。例如,查看以下示例 SVG。
<svg width="600" height="200">
<g>
<rect x="0" y="50" width="100" height="100" fill="blue"/>
</g>
</svg>Run Code Online (Sandbox Code Playgroud)
你可以申请一个转换到<g>与另一对<rect>。它们将是独立的,但会结合起来以获得整体效果。
例如,如果我想正确移动所有内容,我可以对组应用平移变换。
<svg width="600" height="200">
<g transform="translate(200,0)">
<rect x="0" y="50" width="100" height="100" fill="blue"/>
</g>
</svg>Run Code Online (Sandbox Code Playgroud)
然后,如果我想将矩形旋转到位,我可以通过对其应用旋转变换来实现。
<svg width="600" height="200">
<g transform="translate(200,0)">
<rect x="0" y="50" width="100" height="100" fill="blue"
transform="rotate(45,50,100)"/>
</g>
</svg>Run Code Online (Sandbox Code Playgroud)
然后,如果我愿意,我可以通过更新组的变换将 rect 进一步向右移动。
<svg width="600" height="200">
<g transform="translate(400,0)">
<rect x="0" y="50" width="100" height="100" fill="blue"
transform="rotate(45,50,100)"/>
</g>
</svg>Run Code Online (Sandbox Code Playgroud)
思考这个问题的方式是它<rect>在它自己的小世界中(“坐标空间”是官方术语:),并且完全不知道它的父元素中发生了什么。
因此,如果我们使用上面学到的知识,我们可以轻松创建您想要的那种动画。以下动画由三个阶段组成。首先我们向右移动矩形,然后旋转它,然后再次向右移动。中间阶段的旋转不会影响我们再次向右移动的第三阶段。
var outer = document.getElementById("outer");
var inner = document.getElementById("inner");
var tx = 0; // the animated X position
var angle = 0; // the animated angle
/*
* The first phase of the animation.
* Function to step to the right until we hit tx=200.
*/
var stepRightTo200 = function() {
setTimeout(function() {
tx += 4;
outer.setAttribute('transform', 'translate('+tx+',0)');
if (tx < 200) // schedule another step in this phase
stepRightTo200();
else // start next phase of animation
rotateTo45();
}, 32);
};
/*
* The second phase of the animation.
* Step the angle around until we hit 45 degrees.
*/
var rotateTo45 = function() {
setTimeout(function() {
angle += 1;
inner.setAttribute('transform', 'rotate('+angle+',50,100)');
if (angle < 45)
rotateTo45()
else
stepRightTo400(); // start third phase of animation
}, 32);
};
/*
* The third phase of the animation.
* Step to the right until we hit tx=400.
*/
var stepRightTo400 = function() {
setTimeout(function() {
tx += 4;
outer.setAttribute('transform', 'translate('+tx+',0)');
if (tx < 400)
stepRightTo400();
}, 32);
};
// Kick off first phase of animation
stepRightTo200();Run Code Online (Sandbox Code Playgroud)
<svg width="600" height="200">
<g id="outer">
<rect id="inner" x="0" y="50" width="100" height="100" fill="blue"/>
</g>
</svg>Run Code Online (Sandbox Code Playgroud)
在上面的示例中,我已经将“外部”变换分离到父组中,但我们实际上不必这样做。我们可以将变换操作嵌套到单个变换中。
所以我们可以将上面的第三个 SVG 示例简化为:
<svg width="600" height="200">
<rect x="0" y="50" width="100" height="100" fill="blue"
transform="translate(400,0) rotate(45,50,100)"/>
</svg>Run Code Online (Sandbox Code Playgroud)
“外部”变换成为变换列表中的第一个。如果您需要创建一个多部分转换,这是一种概念化多部分转换的好方法。首先创建(或想象)一个嵌套的组结构,然后将您的变换应用于从“外部”(左)到“内部”(右)的结构。
所以最后,我们可以使用这种非嵌套形式重写我们的动画脚本。
var inner = document.getElementById("inner");
var tx = 0; // the animated X position
var angle = 0; // the animated angle
/*
* The first phase of the animation.
* Function to step to the right until we hit tx=200.
*/
var stepRightTo200 = function() {
setTimeout(function() {
tx += 4;
inner.setAttribute('transform',
'translate('+tx+',0) rotate('+angle+',50,100)');
if (tx < 200) // schedule another step in this phase
stepRightTo200();
else // start next phase of animation
rotateTo45();
}, 32);
};
/*
* The second phase of the animation.
* Step the angle around until we hit 45 degrees.
*/
var rotateTo45 = function() {
setTimeout(function() {
angle += 1;
inner.setAttribute('transform',
'translate('+tx+',0) rotate('+angle+',50,100)');
if (angle < 45)
rotateTo45()
else
stepRightTo400(); // start third phase of animation
}, 32);
};
/*
* The third phase of the animation.
* Step to the right until we hit tx=400.
*/
var stepRightTo400 = function() {
setTimeout(function() {
tx += 4;
inner.setAttribute('transform',
'translate('+tx+',0) rotate('+angle+',50,100)');
if (tx < 400)
stepRightTo400();
}, 32);
};
// Kick off first phase of animation
stepRightTo200();Run Code Online (Sandbox Code Playgroud)
<svg width="600" height="200">
<rect id="inner" x="0" y="50" width="100" height="100" fill="blue"/>
</svg>Run Code Online (Sandbox Code Playgroud)
希望这可以帮助您了解转换的工作原理。
| 归档时间: |
|
| 查看次数: |
2128 次 |
| 最近记录: |