Animate scale rotate svg element
假设我有一个用inkscape制作的svg。
在带有视图框的SVG集中,我想为SVG中的每个元素设置动画。
平移或不透明度没有问题...但是当我需要旋转或缩放单个元素时,它表现得很奇怪。
我试图正确理解视图框的概念,但是我需要一些帮助。
我了解只有一个视图框时我只有一个原点,应该设置多个视图框吗?
1 2 3 4 5 6 7 8 9 10 11 | <?xml version="1.0" encoding="UTF-8"?> <svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3.org/2000/svg"> // rotate or scale acting weird <ellipse id="path9238" cx="332.91" cy="143.85" rx="64.941" ry="67.676" style="fill-rule:evenodd;fill:#f00;stroke:#000"/> // rotate or scale acting weird <rect id="rect9240" x="400.59" y="270.31" width="173.63" height="177.73" style="fill-rule:evenodd;fill:#f00;paint-order:normal"/> // rotate or scale acting weird <path id="path9242" d="m233.79 453.52-153.64-138.25 196.55-63.937z" style="fill-rule:evenodd;fill:#f00;paint-order:normal"/> </svg> |
我正在使用anime.js 3.0或CSS,或者我可以尝试其他任何方式
在Svg中,任何图形的坐标始终具有从SVG画布的左上角计算出的绝对值。
因此,当应用scale(2)命令时,图形中心的坐标也将加倍,并且图形将向右和向下移动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | <svg id="SVGRoot" version="1.1" width="500" height="500" viewBox="0 0 500 500" xmlns="http://www.w3.org/2000/svg" style="border:1px solid grey;"> <rect id="rect9240" transform="scale(2)" x="100" y="100" width="100" height="100" style="fill-rule:evenodd;fill:#f00;> stroke:#000; paint-order:normal"> \t<animateTransform \txlink:href="#rect9240" \t\tattributeName="transform" \t\ttype="scale" \t\tvalues="1;2;2;1;1" \t\tdur="8s" \t\tfill="freeze" \t\trepeatcount="indefinite" \t\t/> </rect>\t\t <circle cx="150" cy="150" r="3" fill="black" /> \t\t<circle cx="300" cy="300" r="3" fill="dodgerblue" /> \t <text x="150" y="140" font-size="16px" text-anchor="middle"> Center (150,150)\t</text> \t <text x="300" y="290" font-size="16px" text-anchor="middle"> Center (300,300)\t</text> </svg> |
要将放大的图形恢复到原始位置,必须使用命令
@Paul LeBeau在这里发表了一篇很棒的文章,对此进行了详细说明。
CSS解决方案
为了不计算图形中心的位置,可以使用CSS规则transform-b??ox:fill-box
当选择
The object bounding box is used as the reference box.
下面是增加和减小图形大小的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | svg { width:50%; } .ellipse1, .rect1, .path1 { transform-box: fill-box; animation: scale 3s linear infinite alternate; \tanimation-direction: alternate; transform-origin:50% 50%; } @keyframes scale { 0% { transform: scale(0.5); } 100% { transform: scale(1); } } |
1 2 3 4 5 6 7 | <svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3.org/2000/svg"> <ellipse class="ellipse1" id="path9238" cx="332.91" cy="143.85" rx="64.941" ry="67.676" style="fill-rule:evenodd;fill:#f00;stroke:#000"/> <rect class="rect1" id="rect9240" x="400.59" y="270.31" width="173.63" height="177.73" style="fill-rule:evenodd;fill:#f00; stroke:#000; paint-order:normal"/> <path class="path1" id="path9242" d="m233.79 453.52-153.64-138.25 196.55-63.937z" style="fill-rule:evenodd;fill:#f00;stroke:#000; paint-order:normal"/> </svg> |
- 旋转示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | svg { width:50%; } .ellipse1, .rect1, .path1 { transform-box: fill-box; animation: spin 4s linear infinite alternate; transform-origin:50% 50%; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(359deg); } } <path class="path1" id="path9242" d="m233.79 453.52-153.64-138.25 196.55-63.937z" style="fill-rule:evenodd;fill:#f00;stroke:#000; paint-order:normal"/> </svg> |
1 2 3 4 5 6 7 8 9 | <svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3.org/2000/svg"> <ellipse class="ellipse1" id="path9238" cx="332.91" cy="143.85" rx="64.941" ry="67.676" style="fill-rule:evenodd;fill:#f00;stroke:#000"/> <rect class="rect1" id="rect9240" x="400.59" y="270.31" width="173.63" height="177.73" style="fill-rule:evenodd;fill:#f00; stroke:#000; paint-order:normal"/> <path class="path1" id="path9242" d="m233.79 453.52-153.64-138.25 196.55-63.937z" style="fill-rule:evenodd;fill:#f00;stroke:#000; paint-order:normal"/> </svg> |
- 增加和轮换
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | svg { width:50%; } .ellipse1, .rect1, .path1 { transform-box: fill-box; animation: scale1 4s linear, spin 4s linear 4s infinite alternate; \ttransform-origin:50% 50%; } @keyframes spin { 0% { transform: rotate(0deg);\t} 100% { transform: rotate(360deg); } } @keyframes scale1 { 0% { transform: scale(0.5);} 100% { transform: scale(1);} } |
1 2 3 4 5 6 7 8 9 | <svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3.org/2000/svg"> <ellipse class="ellipse1" id="path9238" cx="332.91" cy="143.85" rx="64.941" ry="67.676" style="fill-rule:evenodd;fill:#f00;stroke:#000"/> <rect class="rect1" id="rect9240" x="400.59" y="270.31" width="173.63" height="177.73" style="fill-rule:evenodd;fill:#f00; stroke:#000; paint-order:normal"/> <path class="path1" id="path9242" d="m233.79 453.52-153.64-138.25 196.55-63.937z" style="fill-rule:evenodd;fill:#f00;stroke:#000; paint-order:normal"/> </svg> |
viewBox的基本原理是4个数字为"
为此,您将viewBox左上移一半宽度和一半高度。您的情况是"
我想你的意思是起源于CSS的转换属性。它与svg文件的中心点有关。然后,您需要计算元素的中心点,以使其与文档的中心点相关联。
对于动画,可以使用CSS动画。