I have a svg that circle is moving around through path. I want the circles' color are changed at some points (ex. mid of the path)
https://codepen.io/lzwdct/pen/poRYVXZ
<circle r="20" fill="blue" mask="url(#myMask)">
<animateMotion dur="5s" repeatCount="indefinite"
path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
c-48.89-48.89-128.09-48.95-176.91-0.13" />
</circle>
Please guide me how to update the color. The color eventually will be changed multiple times with long paths.
I'm not sure if there's anything in SVG that would enable you to do that directly.
But you can check currentTime vs the duration of the animateMotion element and set a color via javascript based on that.
const color = (n) => {
const R = Math.round((255 * n) / 100);
const G = Math.round((255 * (100 - n)) / 100);
const B = 0;
return `rgb(${R}, ${G}, ${B})`;
};
const circles = document.querySelectorAll("circle");
window.setInterval(() => {
circles.forEach(circle => {
const ani = circle.querySelector('animateMotion');
const duration = ani.getSimpleDuration();
const currentTime = ani.getCurrentTime() % duration;
const colorValue = color((currentTime / duration) * 100);
circle.parentNode.style.fill = colorValue;
});
}, 500);
circle {
transition: 500ms;
}
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 2549.62 3338.72" style="enable-background:new 0 0 2549.62 3338.72;" xml:space="preserve">
<style type="text/css">
.st0{fill:none;stroke:#8EA5AE;stroke-width:50;stroke-miterlimit:10;}
.st1{fill:none;stroke:#8EA5AE;stroke-width:50;stroke-linecap:round;stroke-miterlimit:10;}
.st2{fill:none;stroke:#758992;stroke-width:50;stroke-miterlimit:10;}
.st3{fill:none;stroke:#758992;stroke-width:50;stroke-linecap:round;stroke-miterlimit:10;}
.st4{fill:none;stroke:#4E5F65;stroke-width:50;stroke-miterlimit:10;}
.st5{fill:none;stroke:#4E5F65;stroke-width:50;stroke-linecap:round;stroke-miterlimit:10;}
</style>
<g>
<mask id="myMask">
<!-- Pixels under white are rendered -->
<rect x="0" y="0" width="1015" height="855" fill="white" />
<!-- Pixels under black are hidden -->
<rect class="moveme" x="315" y="335" height="150" width="150" transform="rotate(45 395 395)">
<animateTransform attributeName="transform"
attributeType="XML"
type="scale"
keyTimes="0; 0.25999; 0.26; 1"
values="1; 1; 0; 0"
dur="5s"
additive="sum"
repeatCount="indefinite"/>
</rect>
</mask>
<g>
<path class="st0" d="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
s128.09-48.95,176.91-0.13" />
<path class="st1" d="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07
c29.29-29.29,76.78-29.29,106.07,0"/>
<path class="st2" d="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
s179.15-68.34,247.49,0"/>
</g>
<g>
<path class="st0" d="M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
c-48.89-48.89-128.09-48.95-176.91-0.13"/>
<path class="st2" d="M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07
s-76.78-29.29-106.07,0"/>
<path class="st1" d="M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49
s-179.15-68.34-247.49,0"/>
</g>
</g>
<g mask="url(#myMask)">
<circle r="20" mask="url(#myMask)">
<animateMotion dur="5s" repeatCount="indefinite"
path="M718.54,66.06L294.41,490.19c-48.89,48.89-128.09,48.95-176.91,0.13c-48.82-48.82-48.76-128.02,0.13-176.91
s128.09-48.95,176.91-0.13 M294.28,313.55l424.13,424.13c48.89,48.89,128.09,48.95,176.91,0.13c48.82-48.82,48.76-128.02-0.13-176.91
c-48.89-48.89-128.09-48.95-176.91-0.13" />
</circle>
<circle r="20">
<animateMotion dur="5s" repeatCount="indefinite"
path="M753.9,101.42c0,0-424.26,424.26-424.26,424.26c-68.34,68.34-179.15,68.34-247.49,0s-68.34-179.15,0-247.49
s179.15-68.34,247.49,0 M329.63,278.19L753.9,702.46c29.29,29.29,76.78,29.29,106.07,0c29.29-29.29,29.29-76.78,0-106.07 s-76.78-29.29-106.07,0" />
</circle>
<circle r="20">
<animateMotion id="circle1" dur="5s" repeatCount="indefinite"
path="M683.19,30.7L258.92,454.97c-29.29,29.29-76.78,29.29-106.07,0c-29.29-29.29-29.29-76.78,0-106.07 c29.29-29.29,76.78-29.29,106.07,0 M258.92,348.9c0,0,424.26,424.26,424.26,424.26c68.34,68.34,179.15,68.34,247.49,0s68.34-179.15,0-247.49 s-179.15-68.34-247.49,0" /></circle></g>
</svg>
You need to tweak it for your paths, basic concept is to add an animate on the element you want to change and use values and keyTimes (the whole animation is 0 to 1)
As you will notice, you get a color-gradient for free.
If you don't want that, add more keyTimes so the color fades occur faster
<svg width="450" height="180">
<path id="PATH" d="M 50 90 H400" stroke="black"/>
<g>
<circle class="circle" r="30" fill="black"></circle>
<circle class="circle" r=25 fill="red" >
<animate
attributeName="fill"
attributeType="XML"
values="red;green;yellow;hotpink;blue"
keyTimes= "0;0.4;0.6;0.8;1"
dur="3s"
repeatCount="indefinite"/>
</circle>
<animateMotion dur="3s" repeatCount="indefinite">
<mpath href="#PATH" />
</animateMotion>
</g>
</svg>
svga
I am making an animated snow-flakes pattern in SVG and it works nicely in Chrome/ium but in Firefox the pattern will only make the occasional tiny movement when you move the mouse in and out of the patterned area but otherwise doesn't move.
The underlying problem seems to be the same firefox bug as in this question where animating a <use> element doesn't work. My additional problem is that I am animating the position of a <path> element by changing its x and y position separately to avoid an obvious looping movement and since <path> elements don't have those attributes I need to reference them in a <use> element.
I'm hoping that I'm missing some completely obvious solution where the <path> gets embedded in some other element which has x and y attributes which I can animate and avoid the use of <use>.
<svg xmlns="http://www.w3.org/2000/svg" width="800px" height="150px">
<defs>
<!-- two identical snow-flake paths but slightly different scaling and rotation -->
<!-- could be two uses of the same path but the firefox animation bug is from use so that's probably not what we want -->
<path
id="snow-flake-1"
fill="#fff" stroke="none"
d="M183.3125,43.09375 L183.3125,83.8125 L152.71875,66.125 L137.1875,92.9375 L183.3125,119.65625 L183.3125,179.75 L131.5,149.8125 L131.40625,96.28125 L100.40625,96.34375 L100.46875,131.90625 L65.09375,111.46875 L49.59375,138.3125 L84.875,158.6875 L54.25,176.3125 L69.6875,203.1875 L115.90625,176.59375 L167.90625,206.625 L116.09375,236.53125 L69.6875,209.84375 L54.25,236.71875 L85.0625,254.46875 L49.6875,274.875 L65.1875,301.71875 L100.46875,281.34375 L100.40625,316.6875 L131.40625,316.75 L131.5,263.4375 L183.5,233.4375 L183.5,293.25 L137.1875,320.09375 L152.71875,346.90625 L183.5,329.09375 L183.5,369.9375 L214.5,369.9375 L214.5,329.21875 L245.09375,346.90625 L260.625,320.09375 L214.5,293.375 L214.5,233.28125 L266.3125,263.21875 L266.40625,316.75 L297.40625,316.6875 L297.34375,281.125 L332.71875,301.5625 L348.21875,274.71875 L312.9375,254.34375 L343.5625,236.71875 L328.125,209.84375 L281.9375,236.4375 L229.90625,206.40625 L281.75,176.46875 L328.125,203.1875 L343.5625,176.3125 L312.75,158.5625 L348.125,138.15625 L332.625,111.3125 L297.34375,131.6875 L297.40625,96.34375 L266.40625,96.28125 L266.3125,149.59375 L214.3125,179.59375 L214.3125,119.78125 L260.625,92.9375 L245.09375,66.125 L214.3125,83.9375 L214.3125,43.09375 L183.3125,43.09375 z"
transform="scale(0.02) rotate(-15) translate(-202 -202)">
</path>
<path id="snow-flake-2"
fill="#fff" stroke="none"
d="M183.3125,43.09375 L183.3125,83.8125 L152.71875,66.125 L137.1875,92.9375 L183.3125,119.65625 L183.3125,179.75 L131.5,149.8125 L131.40625,96.28125 L100.40625,96.34375 L100.46875,131.90625 L65.09375,111.46875 L49.59375,138.3125 L84.875,158.6875 L54.25,176.3125 L69.6875,203.1875 L115.90625,176.59375 L167.90625,206.625 L116.09375,236.53125 L69.6875,209.84375 L54.25,236.71875 L85.0625,254.46875 L49.6875,274.875 L65.1875,301.71875 L100.46875,281.34375 L100.40625,316.6875 L131.40625,316.75 L131.5,263.4375 L183.5,233.4375 L183.5,293.25 L137.1875,320.09375 L152.71875,346.90625 L183.5,329.09375 L183.5,369.9375 L214.5,369.9375 L214.5,329.21875 L245.09375,346.90625 L260.625,320.09375 L214.5,293.375 L214.5,233.28125 L266.3125,263.21875 L266.40625,316.75 L297.40625,316.6875 L297.34375,281.125 L332.71875,301.5625 L348.21875,274.71875 L312.9375,254.34375 L343.5625,236.71875 L328.125,209.84375 L281.9375,236.4375 L229.90625,206.40625 L281.75,176.46875 L328.125,203.1875 L343.5625,176.3125 L312.75,158.5625 L348.125,138.15625 L332.625,111.3125 L297.34375,131.6875 L297.40625,96.34375 L266.40625,96.28125 L266.3125,149.59375 L214.3125,179.59375 L214.3125,119.78125 L260.625,92.9375 L245.09375,66.125 L214.3125,83.9375 L214.3125,43.09375 L183.3125,43.09375 z"
transform="scale(0.027) rotate(15) translate(-202 -202)">
</path>
<!-- A couple of animated snow flakes. Animate x and y separately to avoid obvious cycles. -->
<!-- Pick dur values with large smallest common multiple to make a long cycle. -->
<pattern id="pt-snow-3" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<use x="5" y="5" href="#snow-flake-1">
<animate attributeName="x" dur="4.2357s" repeatCount="indefinite" values="5; 5.7; 5; 3; 6.5; 5"/>
<animate attributeName="y" dur="3.9s" repeatCount="indefinite" values="5; 3; 5.7; 5; 6.5; 5"/>
</use>
<use x="15" y="15" href="#snow-flake-2">
<animate attributeName="x" dur="5.0s" repeatCount="indefinite" values="15; 13; 16.5; 15; 15.7; 15"/>
<animate attributeName="y" dur="3.7357s" repeatCount="indefinite" values="15; 13; 16.5; 15; 15.7; 15"/>
</use>
</pattern>
</defs>
<g>
<rect x="0" width="800" y="0" height="150" fill="#bbb"/>
<rect x="0" width="800" y="0" height="150" fill="url(#pt-snow-3)" stroke="#888"/>
</g>
</svg>
Based on comments by #PaulLeBeau and #RobertLongson I have made a version where there are two <animateTransform> tags attached to a <g> where the second one has addititve="sum". This <g> also contains the <path> to animate.
The two animations can have different durations to make for a long cycle and both can affect both x and y to make the illusion even more complete.
<svg xmlns="http://www.w3.org/2000/svg" width="500px" height="150px">
<defs>
<path
id="snow-flake"
fill=#fff stroke="none"
d="M183.3125,43.09375 L183.3125,83.8125 L152.71875,66.125 L137.1875,92.9375 L183.3125,119.65625 L183.3125,179.75 L131.5,149.8125 L131.40625,96.28125 L100.40625,96.34375 L100.46875,131.90625 L65.09375,111.46875 L49.59375,138.3125 L84.875,158.6875 L54.25,176.3125 L69.6875,203.1875 L115.90625,176.59375 L167.90625,206.625 L116.09375,236.53125 L69.6875,209.84375 L54.25,236.71875 L85.0625,254.46875 L49.6875,274.875 L65.1875,301.71875 L100.46875,281.34375 L100.40625,316.6875 L131.40625,316.75 L131.5,263.4375 L183.5,233.4375 L183.5,293.25 L137.1875,320.09375 L152.71875,346.90625 L183.5,329.09375 L183.5,369.9375 L214.5,369.9375 L214.5,329.21875 L245.09375,346.90625 L260.625,320.09375 L214.5,293.375 L214.5,233.28125 L266.3125,263.21875 L266.40625,316.75 L297.40625,316.6875 L297.34375,281.125 L332.71875,301.5625 L348.21875,274.71875 L312.9375,254.34375 L343.5625,236.71875 L328.125,209.84375 L281.9375,236.4375 L229.90625,206.40625 L281.75,176.46875 L328.125,203.1875 L343.5625,176.3125 L312.75,158.5625 L348.125,138.15625 L332.625,111.3125 L297.34375,131.6875 L297.40625,96.34375 L266.40625,96.28125 L266.3125,149.59375 L214.3125,179.59375 L214.3125,119.78125 L260.625,92.9375 L245.09375,66.125 L214.3125,83.9375 L214.3125,43.09375 L183.3125,43.09375 z"
transform="translate(-202 -202)">
</path>
<!-- A couple of animated snow flakes. Each has two animation loops to avoid obvious cycles. -->
<!-- Pick dur values with large smallest common multiple to make a long cycle. -->
<pattern id="pt-snow-3" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<g>
<use href="#snow-flake" transform="scale(0.02) rotate(-15)"/>
<animateTransform dur="5.000s" values="5,5; 5.7,4.7; 5.4,5; 3.7,5.2; 6.2,4.7; 5,5" attributeName="transform" type="translate" repeatCount="indefinite"/>
<animateTransform dur="4.789s" values="0,0; -1,3; -1,1; 0,-2; 2,-1; 0,0" additive="sum" attributeName="transform" type="translate" repeatCount="indefinite"/>
</g>
<g>
<use href="#snow-flake" transform="scale(0.027) rotate(15)"/>
<animateTransform dur="4.000s" values="15,14; 14.7,14; 15.2,14.1; 13,14; 15.5,14; 15,14" attributeName="transform" type="translate" repeatCount="indefinite"/>
<animateTransform dur="5.789s" values="0,0; 0,-2; -1,1; -1,1; 1,-1; 0,0" additive="sum" attributeName="transform" type="translate" repeatCount="indefinite"/>
</g>
</pattern>
</defs>
<g>
<rect x="0" width="500" y="0" height="150" fill="#bbb"/>
<rect x="0" width="500" y="0" height="150" fill="url(#pt-snow-3)" stroke="#888"/>
</g>
</svg>
I want to use the same svg, but instead want the half circle svg to be rotated 90 degrees. How do I do this? Thanks.
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" fill="orange" />
</svg>
SVG syntax
must not use units in the rotate() function
can state the rotation center only as part of the attribute
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" transform="rotate(90, 50 50)" fill="orange" />
</svg>
CSS syntax
must use units for rotate() function and transform origin
can state the rotation center only as CSS transform-origin
path {
transform: rotate(90deg);
transform-origin: 50px 50px;
}
<svg width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" fill="orange" />
</svg>
To use the same SVG (which is what is desired and differentiates this answer from other answers) you can reference the original SVG from a <use> element in a new SVG and apply a CSS rotation.
.rotate90 {
transform: rotate(90deg);
}
<svg id="mySVG" width="100" height="100">
<circle cx="50" cy="50" r="50" fill="grey" />
<path d="M0,50 a1,1 0 0,0 100,0" fill="orange" />
</svg>
<svg class="rotate90" width="100" height="100">
<use href="#mySVG"/>
</svg>
This may be a duplicate of a similar question asked by Ruby several years ago, but following the suggestions posted has not resulted in a solution for me. Of course it could be me that is the problem.
I am trying to generate cycloid curves (circles rotating around other curves) BUT I would like to create the curve of a circle rotating around an ellipse - not a circle.
I can animate a circle to follow an elliptical path.
I can animate a circle to rotate about its center.
I need to do both animations simultaneously, but my object follows a path somewhere else in my viewbox.
html, body, svg {
width: 100%;
height: 100%;
}
<svg viewBox="0 0 700 700">
<path id="OUT" d="M200,250
a220,110 0 1,0 600,0
a220,110 0 1,0 -600,0"
style="fill:none;stroke:#ccc; stroke-width:2" />
<g id="CC">
<circle r=40 cx=200 cy=250 fill="none" stroke="black" stroke- width="2"/>
<g id="C1">
<circle r=5 cx=200 cy=250 fill="green"/>
</g>
<circle cx="240" cy="250" r="3" fill="blue" />
</g>
<animateTransForm
xlink:href="#CC"
attributeName="transform"
attributeType="XML"
type="rotate"
from="0 200 250" to="360 200 250" begin="1s" dur="10s"
additive="sum" />
<animateTransform
xlink:href="#CC"
attributeName="transform"
attributeType="XML"
type="rotate"
mpath xlink:href="#OUT"
from="0 300 250" to="360 300 250"
begin="1s" dur="10s" fill="freeze"
additive="sum"/>
</svg>
Hopefully this will give someone an idea of my effort, and trigger a solution. Many thanks.
www.softouch.on.ca
you just need to use animateMotion to apply line animation on any
shape just set so animation can know in which line it has to walk
because of transform translate issue i manually set transform
translate, it will work without setting transform translate in
circle
i used css key frame animation to rotate small circle and both
animation not working at a time so i added one layer(as <g> tag)
inside main <g> tag
html, body, svg {
width: 100%;
height: 100%;
}
<svg width="500" height="500" viewBox="0 0 1000 1000" >
<def>
<style>
#-webkit-keyframes rotation {
from {
-webkit-transform: rotate(0deg);
}
to {
-webkit-transform: rotate(359deg);
}
}
#extrag{
transform-origin: left;
animation: rotation 5s infinite linear;
transform-origin: 201px 250px;
}
</style>
</def>
<path id="OUT" d="M200,250
a220,110 0 1,0 600,0
a220,110 0 1,0 -600,0"
style="fill:none;stroke:#ccc; stroke-width:2" />
<g id="CC" transform="translate(-190,-245)">
<g id="extrag">
<circle r=40 cx=200 cy=250 fill="none" stroke="black" stroke-width="2"/>
<g id="C1" >
<circle r=5 cx=200 cy=250 fill="green"/>
</g>
<circle cx="240" cy="250" r="3" fill="blue">
</circle>
</g>
<animateMotion
xlink:href="#CC"
attributeName="motion"
attributeType="XML"
additive="sum"
dur="6s"
repeatCount="indefinite">
<mpath xlink:href="#OUT"/>
</animateMotion>
</g>
</svg>