Reputation: 321
I am animating a rocket, which I first drew up using Inkscape (I am practising SVG animation using this codepen - SVG Rocket Animation).
I made the dimensions of the SVG canvas so that the contents of the viewbox would roughly fit into my browser window, so I made the dimensions of the SVG canvas 1280x527px.
Then I made the containing div a flexbox, with width 100% and other attributes as below in the code. (I don't show all of the svg code as it takes up too much space here.)
When I test the svg file by directly opening it in the browser window (i.e. without putting it into an html file first), it looks as expected. (I use Google's Chrome btw.)
When I put the svg into an html file, with the CSS style settings as explained above (so the whole SVG viewbox fits snuggly into the browser window when fully opened), it looks as expected too.
But an unexpected thing happens after I animate the rocket - the animation involves the rocket translating directly vertically upwards and shrinking to nothing (by using scale
and transform (translate)
). After the animation ends, the rocket is not in the middle of the browser window (as it was in the svg and the html before the animation), but is on the right side of the page. In the coding for the animation, I left animation-fill-mode
blank, which by default is backwards
. I also tested the animation with the backwards
animation fill mode, and the rocket still does not end up in the center of the page (on the x-axis.)
I suspect this has something to do with the transform origin of the SVG element, which is (50% 0), and/or the differing coordinate systems of the html file and the SVG canvas.
Can anyone explain the behavior of the element (rocket) shifting to the right after the animation has finished? And how can I fix this, so that the rocket sits in its original place (i.e. near the center of the x-axis) after the animation finishes.
CSS style code:
html, body {
height: 100%;
margin: 0%;
padding: 0%;
}
body {
height: 100vh;
display: flex;
background-color: white;
box-sizing: border-box;
flex-direction: column;
align-items: center;
}
#glass {
position: relative;
width: 100%;
background-color: white;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
svg {position: relative;
}
#rocket {
transform-origin: 50% 0;
animation: takeOff 3s 5 ease-in;
}
@keyframes takeOff {
0% {
transform: scale(0.8) translateY(40px);
}
80%,100% {
transform: scale(0) translateY(20px); }
}
This is the html code (not complete):
<body>
<div id="header"><h1>Rocket Flame</h1></div>
<div id="glass">
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="1280"
height="527"
viewBox="0 0 338.66666 139.43542"
version="1.1"
id="svg8"
inkscape:version="1.0.2 (e86c8708, 2021-01-15)"
sodipodi:docname="rocketflame2.svg">
<defs
id="defs2">
<inkscape:path-effect
effect="fillet_chamfer"
id="path-effect868"
is_visible="true"
lpeversion="1"
satellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,8.9036681,0,1"
unit="px"
method="auto"
mode="F"
radius="0"
chamfer_steps="1"
flexible="false"
use_knot_distance="true"
apply_no_radius="true"
apply_with_radius="true"
only_selected="false"
hide_knots="false" />
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.6046875"
inkscape:cx="672.24809"
inkscape:cy="269.88881"
inkscape:document-units="px"
inkscape:current-layer="layer1"
inkscape:document-rotation="0"
showgrid="false"
units="px"
inkscape:snap-bbox="true"
inkscape:snap-intersection-paths="true"
inkscape:snap-global="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:window-width="1280"
inkscape:window-height="615"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0" />
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1">
<g
id="rocket" transform="matrix(0.41503248,0,0,0.41503248,93.847732,78.606515)">
<path
style="fill:#88aa00;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 171.19276,86.854434 10.93884,2.844101 7.43842,20.127475 -20.78381,-11.157621 z"
id="path851" />
<path
style="fill:#88aa00;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 142.97053,86.854434 -10.93884,2.844101 -7.43842,20.127475 20.78381,-11.157621 z"
id="path853" />
<path
id="path833"
style="fill:#c5d77f;fill-opacity:1;stroke:#000000;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.995968"
d="m 157.08188,7.4383055 0.005,61.2577585 h -0.0103 z m 0,0 c 0,0 -25.37842,28.4410095 -14.87712,76.1343685 l 3.06286,20.127456 h 23.62801 L 171.9585,83.572674 C 182.45978,35.879315 157.08188,7.4383055 157.08188,7.4383055 Z" />
<path
id="outerflame"
style="font-variation-settings:normal;vector-effect:none;fill:#c83737;fill-opacity:1;fill-rule:evenodd;stroke:#ff00ea;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;stop-color:#000000"
d="m 166.66294,108.34207 c 0,-2.6458 -1.67037,-4.68686 -3.2824,-6.29888 -1.61203,-1.61203 -3.83903,-2.609087 -6.2989,-2.609087 -2.45986,0 -4.68685,0.997057 -6.2989,2.609087 -1.61201,1.61202 -3.2824,3.65308 -3.2824,6.29888 0,5.29161 4.66156,17.66111 9.5813,17.66111 4.91974,0 9.5813,-12.3695 9.5813,-17.66111 z"
sodipodi:nodetypes="sssssss" />
<path
id="innerflame"
style="font-variation-settings:normal;vector-effect:none;fill:#ffd42a;fill-opacity:1;fill-rule:evenodd;stroke:#ff00ea;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;stop-color:#000000"
d="m 162.24837,107.2854 c 0,-1.42676 -0.90077,-2.52739 -1.77005,-3.39668 -0.86929,-0.86929 -2.07021,-1.40696 -3.39668,-1.40696 -1.32649,0 -2.52739,0.53767 -3.39669,1.40696 -0.86928,0.86929 -1.77004,1.96992 -1.77004,3.39668 0,2.8535 2.51376,9.52377 5.16673,9.52377 2.65297,0 5.16673,-6.67027 5.16673,-9.52377 z"
sodipodi:nodetypes="sssssss" />
<path
id="rect842"
style="font-variation-settings:normal;vector-effect:none;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;stop-color:#000000"
d="m 143.87804,94.567871 1.38958,9.132259 h 23.62801 l 1.38958,-9.132259 z" />
<path
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-variant-east-asian:normal;font-feature-settings:normal;font-variation-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;shape-margin:0;inline-size:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.05833;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.995968;paint-order:markers fill stroke;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate;stop-color:#000000"
d="m 157.08203,43.09375 c -5.19186,0 -9.41211,4.220252 -9.41211,9.412109 0,5.191858 4.22025,9.414063 9.41211,9.414063 5.19186,0 9.41211,-4.222205 9.41211,-9.414063 0,-5.191857 -4.22025,-9.412109 -9.41211,-9.412109 z"
id="path920" />
</g>
</g>
</svg>
</div>
</body>
Below is the svg file in the browser window. It looks as expected, with the rocket in the middle of the page in the x-axis.
Below is the browser window screenshot of the html file with no animation added, except the size of the rocket was scaled down (0.8x) - it appears as expected, in the center bottom of the page:
Below is the browser window screenshot taken during the animation - the rocket shoots up and gets smaller, as expected:
Below is the browser window screenshot after the animation has ended:
I tested the animation with the transform-origin
as center
, and the rocket still ended up on the right side of the page.
I also animated the clouds, so that they descend (but without shrinking), and they end up as expected, in the middle of the page (on the x-axis).
I also had to scale the rocket to 0.8x its original size at the start of the animation, as well as translate it on the Y-axis by 40px, because if I didn't, the rocket would appear much larger than expected and the animation would start too high in the viewport at the start of the animation.
PS. I tested the animation again by changing the keyframes to this:
@keyframes takeOff {
80%,100% {
transform: scale(0) translateY(20px); }
}
and the rocket ascends as expected and shrinks to nothing, but the rocket is shifted to the right from the beginning of the animation, and stays on the right during the animation and ends on the right at the end of the animation.
I reproduced the codepen (link above) on which I based my animation, and the rocket ends up in the center of the page, but the svg dimensions are different to mine (theirs is viewBox="0 0 446 415
) and not much else is added to the css style sheet in their case.
EDIT: I added the svg code.
Upvotes: 1
Views: 1088
Reputation: 321
Note that I added the svg code to the question.
I found what the problem was. It was a transform matrix that was added to the element.
transform="matrix(0.41503248,0,0,0.41503248,93.847732,78.606515)"
I don't remember adding the transform matrix when making the rocket in Inkscape. However, after removing the transform matrix, the rocket behaves as I want it to (i.e. by ending at the right spot), except the rocket is still larger than it's supposed to be at the beginning of the animation, which I still do not understand.
The transform matrix does not seem to affect the appearance/position of the rocket if there is no animation performed.
This is a partial solution as I do not know how the transform matrix ended up in the coding, or how exactly the matrix affects the animation. But the removal of the matrix did restore the animation to what I wanted, so I put the explanation here.
EDITED: I do know why the rocket appears large at the start of the animation. It's because of the transform matrix that the rocket appears the smaller size. After I removed the transform matrix, and tested the result by putting the svg directly into the browser window, the rocket was very large, like what I see at the start of the animation. See below (no matrix):
When I add the transform matrix back into the html code, the rocket is small again (when there is no animation), so it was probably the matrix that gave the rocket the smaller size.
The effect of the matrix of keeping the rocket size small seems to be removed when I do animation to the rocket. But keeping the matrix affects the ending position of the rocket in an unwanted way (i.e. shifting the rocket to the right).
To get the small size of rocket I want and for the rocket to stay in the middle of the page during and after the animation, I will have to go back to Inkscape and make the rocket small without getting a transform matrix in the code.
Edited: I've solved the sizing problem - by keeping the transform matrix, which keeps the rocket the smaller size I want - as well as solved the end-of-animation position problem - by wrapping the rocket group in a new group tag. I give the group tag an id, and animate this, so I am not touching the rocket element directly.
Upvotes: 1