I want to create an animation like this that revolves around the two shapes. And I want to achieve it in SVG with no external CSS. Can anyone help me out on how to do it?
This is my code
<svg xmlns="http://www.w3.org/2000/svg" width="542" height="542" viewBox="0 0 542 542">
<g id="svg" transform="translate(-655 -265)">
<circle id="Ellipse_3" data-name="Ellipse 3" cx="271" cy="271" r="271" transform="translate(655 265)" fill="none"/>
<path id="Path_1" data-name="Path 1" d="M818.25,412.875l.71.931c116.417,110.219-.023,204.664-.382,205.428-.045.089-.2.312-.375.672-2.758,5.713,3.239,3.015,3.594,2.858,147.217-64.969,210.869-212.39,210.672-213.249-.359-1.7-3.069-1.088-3.344-.781-4.366,4.893-81.574,88.727-207.317.617-.169-.118.317.2-.673-.473s-2.369-1.12-3.148-.181-.909,2.256.388,4.35" fill="none" stroke="#707070" stroke-width="1"/>
<path id="Path_2" data-name="Path 2" d="M927.651,569.319s69.788,5.194,99.3,51.994c.017.04,4.351,6.826,5.406-.172a1.6,1.6,0,0,0,.069-.516,5.747,5.747,0,0,0-.21-2.031c-3.036-7.836-31.037-76.552-54.932-98.845-.009-.009-35.627,38.007-49.635,49.57" fill="none" stroke="#707070" stroke-width="1"/>
<g id="Ellipse_1" data-name="Ellipse 1" transform="translate(655 496)" fill="#f90a2a" stroke="#000" stroke-width="1">
<circle cx="34.5" cy="34.5" r="34.5" stroke="none"/>
<circle cx="34.5" cy="34.5" r="34" fill="none"/>
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0" to="360" dur="10s" repeatCount="indefinite"/>
</g>
</g>
</svg>
If you load your file into a vector editor, we will see that the shapes are outside the SVG canvas.
Because of this, you were forced to use transform commands to bring the forms back to the custom viewport.
Practical advice
It is necessary to draw in a vector editor so that the shapes do not go beyond the boundaries of the SVG canvas.
After redrawing in a vector editor and cleaning the file:
To get a segment, use stroke-dasharray="251,1004",
where 251 -
dash, 1004 - gap
To animate the rotation, it was necessary, in addition to the angle,
to additionally specify the coordinates of the rotation center
<animateTransform attributeName="transform" attributeType="XML" type="rotate"
from="0,266,278" to="360,266,278" dur="4s" repeatCount="indefinite"/>
.container {
width:75vw;
height:auto;
}
<div class="container">
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" id="svg5" width="50%" height="50%" viewBox="0 0 542 542" >
<defs>
<linearGradient id="Lg" x1="0" x2="0" y1="1" y2="0">
<stop offset="0" stop-color="#DC143C" />
<stop offset="0.8" stop-color="white" stop-opacity="0.05" />
</linearGradient>
</defs>
<g id="g820" transform="translate(-658 -238)" fill="none" stroke="#707070" stroke-width="1">
<path id="Path_1" fill="black" stroke="black" d="m818 413 1 1c116 110 0 204 0 205l-1 1c-3 6 3 3 4 3a446 446 0 0 0 210-213c0-2-3-2-3-1-4 5-81 88-207 0h-4v4" data-name="Path 1" />
<path id="Path_2" fill="#DC143C" d="M928 569s69 6 99 52c0 0 4 7 5 0a6 6 0 0 0 0-2c-3-8-31-77-55-99 0 0-35 38-49 49" data-name="Path 2" />
</g>
<circle id="Ellipse_3" data-name="Ellipse 3" stroke="url(#Lg)" cx="266" cy="278" r="220" fill="none" stroke="#DC143C" stroke-width="45" stroke-dasharray="251,1004" stroke-linecap="round" >
<animateTransform attributeName="transform" attributeType="XML" type="rotate" from="0,266,278" to="360,266,278" dur="4s" repeatCount="indefinite"/>
</circle>
</svg>
</div>
The experimental <sprite-meister> Web Component can generate the CSS for you
After cleaning up your SVG: no translates, no self-closing tags
You are left with the first frame of your animation
this is not SVG, but a String Template Literal you can program
Sprite-Meister generates the other steps=48 frames for you
the circlepath function calculates an x,y position for every frame
each <circle cx="${v1.x}" cy="${v1.y}" doesn't rotate the circle;
it draws the circle at different positions in each frame
and animates the generated SVG sprite-sheet with CSS
<script src="//sprite-meister.github.io/element.js"></script>
<script>console.log=()=>{/*don't bloat SO snippet console*/}</script>
<sprite-meister duration="5s" w="542" h="542" width="180px" steps="48">
${ setv1( circlepath({ radius:200 }) , "yellow circle position" )}
<text y="10%" font-size="50px">frame: ${framenr} </text>
<path fill="green" d="m163 158 1 1c116 110 0 204 0 205l-1 1c-3 6 3 3 4 3a446 446 0 0 0 210-213c0-2-3-2-3-1-4 5-81 88-207 0h-4v4m105 150s69 6 99 52c0 0 4 7 5 0a6 6 0 0 0 0-2c-3-8-31-77-55-99 0 0-35 38-49 49"></path>
<circle cx="${v1.x}" cy="${v1.y}" r="34" fill="yellow" stroke="blue"></circle>
</sprite-meister>
Sources:
https://dev.to/dannyengelman/create-svg-spritesheet-animations-with-1-template-literal-string-3hee
https://sprite-meister.github.io/
https://sprite-meister.github.io/documentation.html
<sprite-meister> is NOT version 1.0
You need a decent amount of SVG knowlegde, and learn (at least the basics) of SVG SMIL animations first, so you understand the difference with sprite-sheet animations
I have a specific animation I want with an SVG circle. I found the code below from this question (Animated semicircles in logo with SVG). It gets me half of the way there, but i can't figure out how to make it the rest of the way there. I want the circle to start unfolding so to speak from the left side to the right side. This code starts the animation correctly, but I need it to keep going until there is no more circle. That is, the gray lines should keep disappearing as they are now, with the top disappearing at the same rate as the bottom. How do I do this?
<svg height="200" width="200" viewBox="0 0 144 144">
<circle cx="72" cy="72" r="49"
stroke-width="6" stroke="#838588" fill="none">
<animate id="a" attributeName="stroke-dasharray" values="154 0;77 154;" dur="1s" repeatCount="indefinite"/>
</circle>
</svg>
That is, the gray lines should keep disappearing as they are now,
with the top disappearing at the same rate as the bottom. How do I do
this?
To do this, you must change the parameters of the stroke-dasharray attribute.
With a radius of a circle r = 49, the total circumference is 308
To make a symmetrical disappearance of a stroke with two lines from one point, you need to use two groups of parameters stroke-dasharray
values="154, 0 154, 0; 0, 308, 0, 0" where
154 - dash parameter of the first group stroke-dasharray
0 - gap parameter of the first group stroke-dasharray
As a result, the circle will be filled with a cavity at the first moment of the animation.
0, 308, 0, 0 - at this value, the length of the gap is maximum and the border of the circle becomes invisible
<svg height="200" width="200" viewBox="0 0 144 144">
<circle cx="72" cy="72" r="49"
stroke-width="6" stroke="#838588" fill="none">
<animate id="a" attributeName="stroke-dasharray" values="154, 0 154, 0; 0, 308, 0, 0" dur="2s" repeatCount="indefinite"/>
</circle>
</svg>
An example of filling the border of a circle from one point
values="0, 154 0, 154; 0, 0, 308, 0"
<svg height="200" width="200" viewBox="0 0 144 144">
<circle cx="72" cy="72" r="49"
stroke-width="6" stroke="#838588" fill="none">
<animate id="a" attributeName="stroke-dasharray" values="0, 154 0, 154; 0, 0, 308, 0" dur="2s" repeatCount="indefinite"/>
</circle>
</svg>
Update
#User9375050's comment:
is there a way to avoid having that small remnant (slither of a line)
on the right side before it is filled?
The streak does not actually remain. This visual effect is due to the continuous repetition of the animation. To remove this illusion, you need to add a pause at the end of the animation
Example 1 with a pause at the end of the animation
begin="0s;an.end+1s" where
First start of animation -0s;
an.end+1s - restarting the animation after a pause of 1 second after the end of the first animation
<svg height="200" width="200" viewBox="0 0 144 144">
<circle cx="72" cy="72" r="49"
stroke-width="6" stroke="#838588" fill="none">
<animate id="an"
attributeName="stroke-dasharray"
values="
154, 0 154, 0;
0, 308, 0, 0"
dur="2s"
begin="0s;an.end+1s"
repeatCount="1"
fill="freeze"/>
</circle>
</svg>
Example 2 with a pause
<svg height="200" width="200" viewBox="0 0 144 144">
<circle cx="72" cy="72" r="49" stroke-dashoffset="154"
stroke-width="6" stroke="#838588" fill="none">
<animate id="an"
attributeName="stroke-dasharray"
values="0, 154 0, 154; 0, 0, 308, 0"
begin="0s;an.end+1s"
dur="2s"
repeatCount="1"
fill="feeze"/>
</circle>
</svg>
I have a sag group.
And I'm trying to rotate them.
I'm reciving a rotate effect like earth :)
But I want it to spin in one place.
What should be the right way to do it?
Thanks!
<g>
<g>
<path class="st0" d="M206.5,44.6l-2.2,0c-0.4,0-0.8-0.2-1.1-0.5c-0.3-0.3-0.5-0.7-0.5-1.1l0-1.3l-0.6-0.2l-0.9,0.9
c-0.6,0.6-1.7,0.6-2.3,0l-1.5-1.6c-0.6-0.6-0.6-1.7,0-2.3l0.9-0.9l-0.2-0.6l-1.3,0c-0.9,0-1.6-0.7-1.6-1.6l0-2.2
c0-0.9,0.7-1.6,1.6-1.6l1.3,0l0.2-0.5l-0.9-0.9c-0.3-0.3-0.5-0.7-0.5-1.1c0-0.4,0.2-0.8,0.5-1.1l1.6-1.5c0.6-0.6,1.7-0.6,2.3,0
l0.9,1l0.5-0.2l0-1.3c0-0.9,0.7-1.6,1.6-1.6l2.2,0c0.4,0,0.8,0.2,1.1,0.5c0.3,0.3,0.5,0.7,0.5,1.1l0,1.3l0.5,0.2l0.9-0.9
c0.6-0.6,1.7-0.6,2.3,0l1.5,1.6c0.3,0.3,0.5,0.7,0.5,1.1c0,0.4-0.2,0.8-0.5,1.1l-0.9,0.9l0.2,0.6l1.3,0c0.9,0,1.6,0.7,1.6,1.6
l0,2.2c0,0.9-0.7,1.6-1.6,1.6l0,0l-1.3,0l-0.2,0.6l0.9,0.9c0.3,0.3,0.5,0.7,0.5,1.1c0,0.4-0.2,0.8-0.5,1.1l-1.6,1.5
c-0.6,0.6-1.7,0.6-2.3,0l-0.9-1l-0.5,0.2l0,1.3C208.1,43.9,207.3,44.6,206.5,44.6z M204.7,42.6l1.4,0l0-1c0-0.8,0.5-1.5,1.3-1.7
l0.6-0.2c0.2-0.1,0.4-0.1,0.7-0.1c0.5,0,1,0.2,1.3,0.5l0.7,0.7l1-1L211,39c-0.5-0.5-0.7-1.4-0.3-2.1l0.2-0.6
c0.2-0.6,0.9-1.2,1.7-1.2l1,0l0-1.4l-1,0c-0.8,0-1.5-0.5-1.7-1.3l-0.2-0.6c-0.3-0.6-0.2-1.5,0.4-2l0.7-0.7l-1-1l-0.7,0.7
c-0.5,0.5-1.5,0.7-2.1,0.3l-0.6-0.2c-0.7-0.2-1.2-1-1.2-1.7l0-1l-1.4,0l0,1c0,0.8-0.5,1.5-1.3,1.7l-0.6,0.2
c-0.2,0.1-0.4,0.1-0.7,0.1c-0.5,0-1-0.2-1.3-0.5l-0.7-0.7l-1,1l0.7,0.7c0.5,0.6,0.7,1.4,0.3,2.1l-0.2,0.6c-0.2,0.7-1,1.2-1.7,1.2
l-1,0l0,1.4l1,0c0.8,0,1.5,0.5,1.7,1.3l0.2,0.6c0.3,0.6,0.1,1.5-0.4,2l-0.7,0.7l1,1l0.7-0.7c0.5-0.5,1.5-0.7,2.1-0.3l0.6,0.2
c0.7,0.2,1.2,1,1.2,1.7L204.7,42.6z M205.5,38.3c-1.1,0-2.1-0.4-2.8-1.2c-0.7-0.7-1.1-1.7-1.1-2.8c0-2.1,1.8-3.9,3.9-3.9h0
c2.2,0,3.9,1.8,3.9,3.9C209.3,36.6,207.6,38.3,205.5,38.3z M205.5,31.5v1c-1,0-1.9,0.8-1.9,1.9c0,0.5,0.2,1,0.5,1.4
c0.4,0.4,0.8,0.6,1.3,0.6l0,0c1.1,0,1.9-0.8,1.9-1.9c0-1.1-0.8-1.9-1.9-1.9L205.5,31.5z"/>
<animateTransform attributeName="transform"
atributeType="XML"
type="rotate"
from="0"
to="360"
dur="10s"
repeatCount="indefinite"/>
</g>
</g>
Just include the rotating center in these two lines:
from="0"
to="360"
to something like (I do not know the center , just a guess)
from="0 203.5 34.6"
to="360 204.6 24.3 "
<svg width="400" height="200" viewBox="0 0 400 200">
<g>
<g>
<path class="st0" d="M206.5,44.6l-2.2,0c-0.4,0-0.8-0.2-1.1-0.5c-0.3-0.3-0.5-0.7-0.5-1.1l0-1.3l-0.6-0.2l-0.9,0.9
c-0.6,0.6-1.7,0.6-2.3,0l-1.5-1.6c-0.6-0.6-0.6-1.7,0-2.3l0.9-0.9l-0.2-0.6l-1.3,0c-0.9,0-1.6-0.7-1.6-1.6l0-2.2
c0-0.9,0.7-1.6,1.6-1.6l1.3,0l0.2-0.5l-0.9-0.9c-0.3-0.3-0.5-0.7-0.5-1.1c0-0.4,0.2-0.8,0.5-1.1l1.6-1.5c0.6-0.6,1.7-0.6,2.3,0
l0.9,1l0.5-0.2l0-1.3c0-0.9,0.7-1.6,1.6-1.6l2.2,0c0.4,0,0.8,0.2,1.1,0.5c0.3,0.3,0.5,0.7,0.5,1.1l0,1.3l0.5,0.2l0.9-0.9
c0.6-0.6,1.7-0.6,2.3,0l1.5,1.6c0.3,0.3,0.5,0.7,0.5,1.1c0,0.4-0.2,0.8-0.5,1.1l-0.9,0.9l0.2,0.6l1.3,0c0.9,0,1.6,0.7,1.6,1.6
l0,2.2c0,0.9-0.7,1.6-1.6,1.6l0,0l-1.3,0l-0.2,0.6l0.9,0.9c0.3,0.3,0.5,0.7,0.5,1.1c0,0.4-0.2,0.8-0.5,1.1l-1.6,1.5
c-0.6,0.6-1.7,0.6-2.3,0l-0.9-1l-0.5,0.2l0,1.3C208.1,43.9,207.3,44.6,206.5,44.6z M204.7,42.6l1.4,0l0-1c0-0.8,0.5-1.5,1.3-1.7
l0.6-0.2c0.2-0.1,0.4-0.1,0.7-0.1c0.5,0,1,0.2,1.3,0.5l0.7,0.7l1-1L211,39c-0.5-0.5-0.7-1.4-0.3-2.1l0.2-0.6
c0.2-0.6,0.9-1.2,1.7-1.2l1,0l0-1.4l-1,0c-0.8,0-1.5-0.5-1.7-1.3l-0.2-0.6c-0.3-0.6-0.2-1.5,0.4-2l0.7-0.7l-1-1l-0.7,0.7
c-0.5,0.5-1.5,0.7-2.1,0.3l-0.6-0.2c-0.7-0.2-1.2-1-1.2-1.7l0-1l-1.4,0l0,1c0,0.8-0.5,1.5-1.3,1.7l-0.6,0.2
c-0.2,0.1-0.4,0.1-0.7,0.1c-0.5,0-1-0.2-1.3-0.5l-0.7-0.7l-1,1l0.7,0.7c0.5,0.6,0.7,1.4,0.3,2.1l-0.2,0.6c-0.2,0.7-1,1.2-1.7,1.2
l-1,0l0,1.4l1,0c0.8,0,1.5,0.5,1.7,1.3l0.2,0.6c0.3,0.6,0.1,1.5-0.4,2l-0.7,0.7l1,1l0.7-0.7c0.5-0.5,1.5-0.7,2.1-0.3l0.6,0.2
c0.7,0.2,1.2,1,1.2,1.7L204.7,42.6z M205.5,38.3c-1.1,0-2.1-0.4-2.8-1.2c-0.7-0.7-1.1-1.7-1.1-2.8c0-2.1,1.8-3.9,3.9-3.9h0
c2.2,0,3.9,1.8,3.9,3.9C209.3,36.6,207.6,38.3,205.5,38.3z M205.5,31.5v1c-1,0-1.9,0.8-1.9,1.9c0,0.5,0.2,1,0.5,1.4
c0.4,0.4,0.8,0.6,1.3,0.6l0,0c1.1,0,1.9-0.8,1.9-1.9c0-1.1-0.8-1.9-1.9-1.9L205.5,31.5z"/>
<animateTransform attributeName="transform"
atributeType="XML"
type="rotate"
from="0 211 39"
to="360 211 39"
dur="2s"
repeatCount="indefinite"/>
</g>
</g>
</svg>
In the following, the text (CLICK ME) is supposed to reappear .5 seconds after the morphMe animation ends. (See the last line of code other than closing tags)
It works fine, making the text appear the first time the animation ends. But it does not ever work after that. I can't figure why it works only once;
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" viewBox="0 0 300 300">
<defs>
<text id="startText" >CLICK ANYWHERE</text>
</defs>
<rect id="startMe" x="0" y="0" width="300" height="300" fill= "red"> </rect>
<g transform="translate(50, 50)">
<path d="M 100,0 200,200 0,200 50,100 z;" fill="green" stroke="black" stroke-linecap="round" stroke-width="32" stroke-linejoin="round" stroke-dasharray="68">
<animate id="morphMe"
restart="always"
begin="startMe.click;startText.click;click;"
attributeName="d"
dur="2s"
calcmode="spline"
repeatCount="2"
values=
"M 100,0 200,200 0,200 50,100 z ;
M 200,0 200,200 0,200 00,0 z ;
M 200,200 0,200 0,0 200,0 z ;
M 200,0 200,200 0,200 00,0 z ;
M 100,0 200,200 0,200 50,100 z:"
keyTimes="0; .25; .5; .75; 1"
keySplines="1 0 1 1; 1 0 1 1; 1 0 1 1; 1 0 1 1;"
fill="freeze"
/>
</path>
</g>
<g>
<use xlink:href="#startText" x="150" y="160" style="font-size: 18pt; fill: white; stroke: none; font-family: Rockwell; text-anchor: middle;"/>
<set attributeName="visibility" attributeType="CSS" to="hidden" begin="morphMe.begin"/>
<set attributeName="visibility" attributeType="CSS" to="visible" begin="morphMe.end+.5s"/>
</g>
</svg
You've got repeatCount="2" so change that to repeatCount="indefinite" and that should ensure your animation doesn't stop.
See the docs here; https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/repeatCount
There seem to be two problems.
A semicolon has been mistyped as a colon in the animation
Fractional time offsets in SMIL must begin with a leading 0 (although Chrome does not enforce this)
I'd also probably just make the text and shape pointer-events: none since you don't want to manage clicks on them and just process clicks on the rect. I've also made that change below.
After that everything seems to work (at least on Firefox where I'm testing it).
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="300" height="300" viewBox="0 0 300 300">
<defs>
<text id="startText" pointer-events="none">CLICK ANYWHERE</text>
</defs>
<rect id="startMe" x="0" y="0" width="300" height="300" fill= "red"> </rect>
<g transform="translate(50, 50)" pointer-events="none">
<path d="M 100,0 200,200 0,200 50,100 z;" fill="green" stroke="black" stroke-linecap="round" stroke-width="32" stroke-linejoin="round" stroke-dasharray="68">
<animate id="morphMe"
restart="always"
begin="startMe.click"
attributeName="d"
dur="2s"
calcmode="spline"
repeatCount="2"
values=
"M 100,0 200,200 0,200 50,100 z ;
M 200,0 200,200 0,200 00,0 z ;
M 200,200 0,200 0,0 200,0 z ;
M 200,0 200,200 0,200 00,0 z ;
M 100,0 200,200 0,200 50,100 z;"
keyTimes="0; .25; .5; .75; 1"
keySplines="1 0 1 1; 1 0 1 1; 1 0 1 1; 1 0 1 1;"
fill="freeze"
/>
</path>
</g>
<g>
<use xlink:href="#startText" x="150" y="160" style="font-size: 18pt; fill: white; stroke: none; font-family: Rockwell; text-anchor: middle;"/>
<set attributeName="visibility" attributeType="CSS" to="hidden" begin="morphMe.begin"/>
<set attributeName="visibility" attributeType="CSS" to="visible" begin="morphMe.end+0.5s"/>
</g>
</svg