admin管理员组文章数量:1420606
Assuming I have an svg made with inkscape. In this SVG set with a viewbox, I want to animate each element inside the SVG. There is no problem for translate or opacity ... but when I need to rotate or scale a single element, it acting weird.
I try to correctly understand the concept of the viewbox but I need some help.
I understand that I have only one origin point when I have only one viewbox should I set multiple viewbox ?
<?xml version="1.0" encoding="UTF-8"?>
<svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="">
// 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>
Assuming I have an svg made with inkscape. In this SVG set with a viewbox, I want to animate each element inside the SVG. There is no problem for translate or opacity ... but when I need to rotate or scale a single element, it acting weird.
I try to correctly understand the concept of the viewbox but I need some help.
I understand that I have only one origin point when I have only one viewbox should I set multiple viewbox ?
<?xml version="1.0" encoding="UTF-8"?>
<svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3/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>
I'm using anime.js 3.0 or CSS or I can try anything else
Share Improve this question asked Mar 29, 2019 at 20:43 user7637140user7637140 4- hmm maybe I can take a look to transform-box : fill-box... – user7637140 Commented Mar 29, 2019 at 22:05
- Rotation and scale often need to be translated prior to performing the transformation then translated back so that the object being transformed is at the origin when it changes – mike510a Commented Mar 31, 2019 at 0:38
- Specifically the object should have its center point set to the origin... there are many ways to do this but without providing the animation code, its impossible to tell you how you should go about it.. – mike510a Commented Mar 31, 2019 at 0:43
- @Cedric Gourville If you want a detailed explanation about svg transformations and tricks, you can check out this link css-tricks./transforms-on-svg-elements – Syam Commented Jul 27, 2019 at 15:51
3 Answers
Reset to default 6In Svg, the coordinates of any figure always have an absolute value that is calculated from the upper left corner of the SVG canvas.
Therefore, when applying the scale (2) mand, the coordinates of the center of the figure will also be doubled and the figure will shift to the right and down.
<svg id="SVGRoot" version="1.1" width="500" height="500" viewBox="0 0 500 500" xmlns="http://www.w3/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">
<animateTransform
xlink:href="#rect9240"
attributeName="transform"
type="scale"
values="1;2;2;1;1"
dur="8s"
fill="freeze"
repeatcount="indefinite"
/>
</rect>
<circle cx="150" cy="150" r="3" fill="black" />
<circle cx="300" cy="300" r="3" fill="dodgerblue" />
<text x="150" y="140" font-size="16px" text-anchor="middle" > Center (150,150) </text>
<text x="300" y="290" font-size="16px" text-anchor="middle" > Center (300,300) </text>
</svg>
To return the enlarged figure to its original position, you must use the mand translate (X, Y)
There is a great post here by @Paul LeBeau where this is explained in detail.
CSS solution
In order not to calculate the position of the center of the figure, you can use the CSS rule transform-box: fill-box
When the value of the fill-box
attribute is selected
The object bounding box is used as the reference box.
Below is an example of increasing and decreasing the size of figures:
svg {
width:50%;
}
.ellipse1, .rect1, .path1 {
transform-box: fill-box;
animation: scale 3s linear infinite alternate;
animation-direction: alternate;
transform-origin:50% 50%;
}
@keyframes scale {
0% { transform: scale(0.5); }
100% { transform: scale(1); }
}
<svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3/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>
- Rotation example
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>
<svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3/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>
- Increase and rotation
svg {
width:50%;
}
.ellipse1, .rect1, .path1 {
transform-box: fill-box;
animation: scale1 4s linear, spin 4s linear 4s infinite alternate;
transform-origin:50% 50%;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@keyframes scale1 {
0% { transform: scale(0.5);}
100% { transform: scale(1);}
}
<svg id="SVGRoot" version="1.1" viewBox="0 0 700 500" xmlns="http://www.w3/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>
I guess you mean the transform-origin CSS propierty. It is related to the center point of the svg file. Then, you need to calculate the center point of the element to animate related to document's center point.
For the animations you can use CSS animations.
The basics of viewBox is that the 4 numbers are "x y width height
”. Generally the x/y coordinates are 0 which keeps your origin in the top left corner. Something people often do is place the origin in the middle.
In order to do that you move your viewBox top left by half of the width and half the height. In your case "-350 -250 700 500
".
本文标签: javascriptAnimate scale rotate svg elementStack Overflow
版权声明:本文标题:javascript - Animate scale rotate svg element - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745322923a2653459.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论