SVG balls animated along a path - css

I am trying to make SVG dots/balls run along a path. What i am struggling with is using multiple animations on one page. The dots all seem to listen to the first path and I would like each set to be unique. What i have below.
Also I am inserting this code inside an html code block on a wordpress page so I like how this doesn't require the head css style and the traditional css transform codes etc and is nicely contained to use inside svg tag. It works perfectly but when i use another wave further down the page is listens to the first path motion.
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
width="3000" height="400" viewBox="0 0 3000 400">
<path d="M0,58.5c201.2,0,296.3,141.4,498.4,141.4S801.6,58.5,999.8,58.5s302.9,141.4,500.2,141.4
s306.3-141.4,502.5-141.4s305.2,141.4,499.4,141.4c194.2,0,299.2-141.4,498.1-141.4"
stroke="#444444" stroke-width="2" fill="none" id="wire"></path>
<circle cx="" cy="" r="8" fill="#444444">
<animatemotion dur="10s" repeatCount="indefinite" calcMode="spline" keyTimes="0;1" keySplines="0.1 0.4 0.8 0.9">
<mpath xlink:href="#wire"></mpath>
</animatemotion>
</circle>
<circle cx="" cy="" r="4" fill="#444444">
<animatemotion dur="5s" repeatCount="indefinite" calcMode="spline" keyTimes="0;1" keySplines="0.1 0.2 0.8 0.9">
<mpath xlink:href="#wire"></mpath>
</animatemotion>
</circle>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink"
width="3000" height="400" viewBox="0 0 3000 400">
<path d="M0,135.5c501.6-4.4,502.9,150.6,1004.5,146.2c501.6-4.4,500.2-159.3,1001.8-163.7
c501.6-4.4,502.9,150.6,1004.5,146.2"
stroke="#222222" stroke-width="2" fill="none" id="wire"></path>
<circle cx="" cy="" r="8" fill="#222222">
<animatemotion dur="10s" repeatCount="indefinite" calcMode="spline" keyTimes="0;1" keySplines="0.1 0.4 0.8 0.9">
<mpath xlink:href="#wire"></mpath>
</animatemotion>
</circle>
<circle cx="" cy="" r="4" fill="#222222">
<animatemotion dur="5s" repeatCount="indefinite" calcMode="spline" keyTimes="0;1" keySplines="0.1 0.2 0.8 0.9">
<mpath xlink:href="#wire"></mpath>
</animatemotion>
</circle>
</svg>
https://codepen.io/Tuff-Lover/pen/ZEodgPY

Related

PaperJS: Exporting then Importing an SVG creates extra data (clippath)

I have a drawing tool that needs to be able to export, store and then import a drawing. I am using the following code for exporting:
const savedData = scope.project.exportSVG({
asString: true,
bounds: scope.view.bounds
});
Here is the code for importing:
scope.project.importSVG(savedData);
If I draw a simple line, console what is imported (the line I just drew), and console what is exported I SHOULD get the same result. Instead this is what I get:
Import:
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1422"
height="498"
viewBox="0,0,1422,498"
>
<g
fill="none"
fill-rule="nonzero"
stroke="#990000"
stroke-width="3"
stroke-linecap="butt"
stroke-linejoin="miter"
stroke-miterlimit="10"
stroke-dasharray=""
stroke-dashoffset="0"
font-family="none"
font-weight="none"
font-size="none"
text-anchor="none"
style="mix-blend-mode: normal"
>
<path
d="M426,41l4,5l4,7l4,5l2,4l3,6l3,5l3,4l2,4l3,3l1,4l1,1l1,4l2,2l1,2l2,4l1,1l1,3l2,2l1,1v1"
style="mix-blend-mode: destination-over"
/>
</g>
</svg>
Export:
<svg
version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
width="1422"
height="498"
viewBox="0,0,1422,498"
>
<defs>
<clipPath id="clip-1">
<rect
x="0"
y="0"
width="1422"
height="498"
stroke="none"
stroke-width="1"
/>
</clipPath>
</defs>
<g
fill="none"
fill-rule="nonzero"
stroke="none"
stroke-width="none"
stroke-linecap="butt"
stroke-linejoin="miter"
stroke-miterlimit="10"
stroke-dasharray=""
stroke-dashoffset="0"
font-family="none"
font-weight="none"
font-size="none"
text-anchor="none"
style="mix-blend-mode: normal"
>
<g clip-path="url(#clip-1)">
<g stroke="#990000" stroke-width="3">
<path
d="M426,41l4,5l4,7l4,5l2,4l3,6l3,5l3,4l2,4l3,3l1,4l1,1l1,4l2,2l1,2l2,4l1,1l1,3l2,2l1,1v1"
/>
</g>
</g>
</g>
</svg>
The defs and clippath are causing layering issues when adding more to the loaded drawing. Why is it converting my svg this way? Where is that clippath coming from? Is there a property I am missing?

How to make an SVG object follow a path correctly using SMIL [duplicate]

This question already has an answer here:
svg animateMotion is offset from path
(1 answer)
Closed 2 years ago.
I am trying t create a simple SVG animation(using SMIL) and I can't seem to figure out why the orb isn't following the arc, instead the orb it is at the bottom of the page.
Here is my code:
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 1240 768" style="enable-background:new 0 0 1240 768;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill:#0FBA70;}
</style>
<animateMotion xlink:href="#orb" dur="10s" begin="0s" fill="freeze" repeatCount="indefinite">
<mpath xlink:href="#motionPath" />
</animateMotion>
<g>
<polygon class="st0" points="389.5,405.5 394,405.5 926.8,400.5 930.5,400.5 "/>
<path id="motionPath" d="M390.9,407.5l-2.9-4.1C426,377,625,248.9,820.4,327.2c40.5,16.2,78.1,40.3,111.8,71.5l-3.4,3.7
c-33.2-30.8-70.3-54.5-110.2-70.5C625.5,254.5,428.5,381.3,390.9,407.5z"/>
</g>
<g>
<circle id="orb" class="st1" cx="389.5" cy="400.5" r="56.5"/>
</g>
</svg>
The orb is currently being offset with the cx and cy values:
<circle id="orb" class="st1" cx="389.5" cy="400.5" r="56.5"/>
If you remove those values, the orb follows the path:
<circle id="orb" class="st1" r="56.5"/>
See https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animateMotion for a working example, and if you open that in JSFiddle or Codepen and add a cx or cy value you will observe the same behavior (circle is animating offset from the path).
.st0 {
fill: #FFFFFF;
}
.st1 {
fill: #0FBA70;
}
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1240 768" style="enable-background:new 0 0 1240 768;" xml:space="preserve">
<animateMotion xlink:href="#orb" dur="10s" begin="0s" fill="freeze" repeatCount="indefinite">
<mpath xlink:href="#motionPath" />
</animateMotion>
<g>
<polygon class="st0" points="389.5,405.5 394,405.5 926.8,400.5 930.5,400.5 "/>
<path id="motionPath" d="M390.9,407.5l-2.9-4.1C426,377,625,248.9,820.4,327.2c40.5,16.2,78.1,40.3,111.8,71.5l-3.4,3.7
c-33.2-30.8-70.3-54.5-110.2-70.5C625.5,254.5,428.5,381.3,390.9,407.5z"/>
</g>
<g>
<circle id="orb" class="st1" r="56.5"/>
</g>
</svg>

Set origin and rotation on animateMotion's path

I'd like to apply a rotation on a path animated with SVG's animateMotion tag.
It seems that the rule transform-origin:50%;transform: rotate(240deg); applied on the path that the animateMotion tag follows doesn't alter the animation.
<path id="theMotionPathIdLikeToRotate" d="m 100,100 -3e-6,-52.916668 45.82718,26.458333 0,52.916665" stroke-width="5px" stroke="aqua" fill="none" style="transform-origin:50%;transform: rotate(120deg);" stroke-linecap="round" stroke-linejoin="round" />
My aim was to create an animation and repeat it transformed. In this example I wanted to create other moving circles, rotated 120 and 240 degrees around the center of the hexagon.
Only the path definition (d) of the path referenced by an <mpath> element is used. Any transform it might have is ignored.
You would need to apply the transform to the circle and the <mpath> together.
<g style="transform-origin:50%;transform: rotate(240deg);">
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="4.45s" repeatCount="once">
<mpath xlink:href="#theMotionPath3"/>
</animateMotion>
</circle>
</g>"
<!DOCTYPE HTML>
<html>
<body>
<?xml version="1.0"?>
<svg width="400" height="400" viewBox="0 0 200 200"
xmlns="http://www.w3.org/2000/svg" version="1.1"
xmlns:xlink="http://www.w3.org/1999/xlink" style="background:aquamarine">
<style>
path {
animation-name:animateDash;
animation-duration:5s;
animation-iteration-count:once;
}
#keyframes animateDash {
from{stroke-dasharray:0,2305}
to {stroke-dasharray:2305,0}
}
</style>
<circle cx="50%" cy="50%" r="1" fill="firebrick" />
<path id="theMotionPath" d="m 100,100 -3e-6,-52.916668 45.82718,26.458333 0,52.916665" stroke-width="5px" stroke="antiquewhite" fill="none" stroke-linecap="round" stroke-linejoin="round" />
<path id="theMotionPath2" d="m 100,100 -3e-6,-52.916668 45.82718,26.458333 0,52.916665" stroke-width="5px" stroke="aqua" fill="none" style="transform-origin:50%;transform: rotate(120deg);" stroke-linecap="round" stroke-linejoin="round" />
<path id="theMotionPath3" d="m 100,100 -3e-6,-52.916668 45.82718,26.458333 0,52.916665" stroke-width="5px" stroke="azure" fill="none" style="transform-origin:50%;transform: rotate(240deg);" stroke-linecap="round" stroke-linejoin="round" />
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="4.45s" repeatCount="once">
<mpath xlink:href="#theMotionPath3"/>
</animateMotion>
</circle>
<g style="transform-origin:50%;transform: rotate(120deg);">
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="4.45s" repeatCount="once">
<mpath xlink:href="#theMotionPath3"/>
</animateMotion>
</circle>
</g>"
<g style="transform-origin:50%;transform: rotate(240deg);">
<circle cx="0" cy="0" r="5" fill="#333333">
<animateMotion dur="4.45s" repeatCount="once">
<mpath xlink:href="#theMotionPath3"/>
</animateMotion>
</circle>
</g>"
<!--- HIDES animateMotion's reset-->
<circle cx="" cy="" r="20" fill="aquamarine" />
<script type="text/javascript">
console.log(theMotionPath.getTotalLength());
</script>
</svg>
</body>
</html>

SMIL Animation Not Ending On Mouseout

I'm trying to make an SVG icon that animates using SMIL (well, I don't care if it's SMIL or CSS, I just don't want to use JS) on hover and I've gotten pretty far but I've run into a problem that I can't find answered or even mentioned online. The animation starts on mouseover (hover) but on mouseout one of the animated elements (2nd circle) keeps animating and I'm at a total loss as to why.
You can also see it at https://codepen.io/anon/pen/LmjpVQ
Thanks for any help you can provide in advance.
svg { width: 100px; color: red; }
<svg id="location" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="circleClip">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#circleClip)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="location.mouseover+2s" end="location.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="location.mouseover+2" end="location.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" stroke-width="0" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" stroke-width="0" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
</svg>
The trap you got caught in was that, unlike HTML elements, mouse events are raised as a default only when the pointer is over an area that is painted (stroke or fill)., but no matter what opacity is set to. You can even fine-tune pointer-events to either include or exclude events for visibility: hidden or fill: none.
The mouseover event is raised every time the spreading circle you animated passes under the pointer, With pointer-events:all you could prevent mousout when the mouse ends up over the interior, but only until the animation repeat resets the radius. This makes things pretty confusing.
The most simple solution is to lay an invisible rect with opacity="0" on top of the whole icon, so that there are clearly defined borders for "inside" and "outside". For more finetuning, define a shape that covers the area where you want to capture mouse moves.
svg { width: 100px; color: red; }
<svg id="loc" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60">
<defs>
<clipPath id="c">
<path d="M49,19c0,7-12,26-18.97,26C23,45,12,26,12,19H49z M72-12h-84v84h84V-12z" />
</clipPath>
</defs>
<g clip-path="url(#c)">
<g transform="matrix(1, 0, 0, 0.43999, 0, 25.2)">
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="14">
<animate attributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
<circle transform="rotate(-90, 30, 47)" fill="none" stroke="currentColor" stroke-width="2" cx="30" cy="47" r="0">
<animate ttributeType="XML" attributeName="r" from="0" to="20" begin="loc.mouseover+2s" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
<animate attributeType="CSS" attributeName="opacity" from="1" to="0" begin="loc.mouseover+2" end="loc.mouseout" dur="3s" repeatCount="indefinite" />
</circle>
</g>
</g>
<path fill="currentColor" stroke="currentColor" d="M30,7c7.18,0,13,5.82,13,13S30,45,30,45S17,27.18,17,20S22.82,7,30,7z" />
<path fill="#fff" d="M30,15c2.76,0,5,2.24,5,5s-2.24,5-5,5c-2.76,0-5-2.24-5-5S27.24,15,30,15" />
<rect opacity="0" width="100%" height="100%" />
</svg>

Loading more complex SVG as background image

I have an input field with a SVG background image. This works like a charm, the image is showing:
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="%239a5371"><path d="M14.5 8h-0.5v-1.5c0-2.481-2.019-4.5-4.5-4.5s-4.5 2.019-4.5 4.5v1.5h-0.5c-0.827 0-1.5 0.673-1.5 1.5v8c0 0.827 0.673 1.5 1.5 1.5h10c0.827 0 1.5-0.673 1.5-1.5v-8c0-0.827-0.673-1.5-1.5-1.5zM6 6.5c0-1.93 1.57-3.5 3.5-3.5s3.5 1.57 3.5 3.5v1.5h-7v-1.5zM15 17.5c0 0.276-0.224 0.5-0.5 0.5h-10c-0.276 0-0.5-0.224-0.5-0.5v-8c0-0.276 0.224-0.5 0.5-0.5h10c0.276 0 0.5 0.224 0.5 0.5v8z"></path></svg>');
But this does NOT work:
background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="48px" height="48px"><g transform="translate(0.5, 0.5)"> <path stroke-linejoin="round" fill="none" stroke="#444444" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" d="M24,2L24,2 c-5.5,0-10,4.5-10,10v6h20v-6C34,6.5,29.5,2,24,2z"></path> <rect stroke-linejoin="round" x="8" y="18" fill="none" stroke="#444444" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" width="32" height="28"></rect> <circle stroke-linejoin="round" data-color="color-2" fill="none" stroke="#444444" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" cx="24" cy="30" r="4"></circle> <line stroke-linejoin="round" data-color="color-2" fill="none" stroke="#444444" stroke-width="3" stroke-linecap="round" stroke-miterlimit="10" x1="24" y1="34" x2="24" y2="38"></line> </g></svg>');
The second one is a little more complex, but not THAT much, hm? Can someone tell me why this is not loaded? (firebug says image could not be loaded).
EDIT: Sorry I was dumb, it was the hex color. Now it's working with something like "%239a5371" instead of "#9a5371".

Resources