SVG CSS animation after hover off - css

I tried several ways to svg animation, but i can't do finish animation after hover off. I have seen some hints on stackoverflow, but in my situation it does not work. In my example I have few options animations in keyframes.
https://codepen.io/GuyDiamond/pen/QBpQze
<rect x="0" y="5" width="100" height="100" fill="red" />
<path id="heart" class="heart" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" fill="#fff"/>
<style type="text/css">
svg:hover .heart {
animation-timing-function: ease-in-out;
animation-duration: 4s;
animation-iteration-count: infinite;
animation-name: rotation;
transition: .5s;
animation-direction: normal;
animation-fill-mode: forwards;
}
#keyframes rotation {
50% {
transform: rotateY(180deg);
opacity:0;
}
60% {
transform: translate(100px, 0);
opacity:0;
}
100% {
transform: translate(0, 0);
opacity:1;
}
}

You can't do what you want with pure CSS. You need to use JS.
Here's one way, using the animationiteration event, which fires each time the animation loop ends.
// Get the SVG DOM object
var mysvg = document.getElementById("mysvg");
var running = false;
// On hover add the "run" class, which makes the animation run
mysvg.addEventListener("mouseenter", function(evt) {
evt.target.classList.add("run");
running = true;
});
// On mouse out, arrange to remove the "run" class when the animation loop ends
mysvg.addEventListener("mouseleave", function(evt) {
running = false;
});
// When animation loop ends, remove the "run" class if we no longer want to continue running
mysvg.addEventListener("animationiteration", function(evt) {
if (!running) {
evt.target.ownerSVGElement.classList.remove("run");
}
});
.box {
width: 300px;
height: 500px;
}
<div class="box">
<svg id="mysvg" width="100%" height="100%" viewBox="-30 0 250 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<rect x="0" y="5" width="100" height="100" fill="red" />
<path id="heart" class="heart" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" fill="#fff"/>
<style type="text/css">
svg .heart {
}
.run .heart {
animation-timing-function: ease-in-out;
animation-duration: 4s;
animation-iteration-count: infinite;
animation-name: rotation;
animation-direction: normal;
animation-fill-mode: forwards;
}
#keyframes rotation {
50% {
transform: rotateY(180deg);
opacity:0;
}
60% {
transform: translate(100px, 0);
opacity:0;
}
100% {
transform: translate(0, 0);
opacity:1;
}
}
</style>
</svg>
</div>

You mean the animation ends suddenly? That's because you've defined the transition in the hover so as soon as the hover ends there's no active transition any more.
.box {
width: 300px;
height: 500px;
}
<div class="box">
<svg width="100%" height="100%" viewBox="-30 0 250 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:1.41421;">
<rect x="0" y="5" width="100" height="100" fill="red" />
<path id="heart" class="heart" d="M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z" fill="#fff"/>
<style type="text/css">
svg .heart {
transition: .5s;
}
svg:hover .heart {
animation-timing-function: ease-in-out;
animation-duration: 4s;
animation-iteration-count: infinite;
animation-name: rotation;
animation-direction: normal;
animation-fill-mode: forwards; }
#keyframes rotation {
50% {
transform: rotateY(180deg);
opacity:0;
}
60% {
transform: translate(100px, 0);
opacity:0;
}
100% {
transform: translate(0, 0);
opacity:1;
}
}
</style>
</svg>
</div>

By changing the animation-play-state on hover I think it could work
https://codepen.io/dok/pen/ZjKGRE
svg #heart {
animation-timing-function: ease-in-out;
animation-duration: 4s;
animation-iteration-count: infinite;
animation-name: rotation;
animation-direction: normal;
animation-fill-mode: forwards;
animation-play-state: paused;
}
svg .heart:hover #heart {
animation-play-state: running;
}

Related

SVG stroke appearing only during css animation

I'm trying to figure out why there's a line in this SVG animation that I'm trying to make. But it's only an effect of animating it with css, and it's not part of the SVG itself. It seems to be some stroke but stroke: none doesn't affect it.
image showing the stroke
https://jsfiddle.net/bgu2e7pn/
PS: I would also appreciate if you can point out how to have the full width of the coffee content svg exceed the cup width so it looks more seamless.
You can work around this bug by using a mask instead of a clip-path.
body {
background: grey;
}
#coffee-cup .fill {
animation-name: coffeeFill;
animation-iteration-count: 1;
animation-timing-function: cubic-bezier(.2, .6, .8, .4);
animation-duration: 4s;
animation-fill-mode: forwards;
}
#coffee-cup #waveShape {
animation-name: waveMotion;
animation-iteration-count: infinite;
animation-timing-function: linear;
animation-duration: 0.5s;
fill: #8C5926;
stroke: #3D2518;
stroke-width: 10px;
}
#keyframes coffeeFill {
0% {
transform: translate(0, 150px);
}
100% {
transform: translate(0, -15px);
}
}
#keyframes waveMotion {
0% {
transform: translate(-150px, 0);
}
100% {
transform: translate(0, 0);
}
}
<div id="coffee-cup">
<div>
<svg class="position-absolute" width="259" height="180" viewBox="0 0 259 180" fill="none"
xmlns="http://www.w3.org/2000/svg">
<path d="M259 0H53L55.8218 23.0874C24.0777 28.8271 0 56.6017 0 90C0 127.555 30.4446 158 68 158C69.4425 158 70.8746 157.955 72.2948 157.867L75 180H238L259 0ZM57.7548 38.9028L70.4677 142.918C69.4854 142.972 68.496 143 67.5 143C38.5051 143 15 119.495 15 90.5C15 64.835 33.4162 43.4713 57.7548 38.9028Z"
fill="white" fill-opacity="0.7" />
<mask id="coffee">
<rect width="100%" height="100%" fill="black"/>
<path d="M70 49H244L232.139 156H82.2489L70 49Z" fill="white" />
</mask>
<g mask="url(#coffee)">
<g class="fill">
<path id="waveShape" d="M300,300V2.5c0,0-0.6-0.1-1.1-0.1c0,0-25.5-2.3-40.5-2.4c-15,0-40.6,2.4-40.6,2.4
c-12.3,1.1-30.3,1.8-31.9,1.9c-2-0.1-19.7-0.8-32-1.9c0,0-25.8-2.3-40.8-2.4c-15,0-40.8,2.4-40.8,2.4c-12.3,1.1-30.4,1.8-32,1.9
c-2-0.1-20-0.8-32.2-1.9c0,0-3.1-0.3-8.1-0.7V300H300z" />
</g>
</g>
</svg>

SVG CSS animation smooth transition and point of origin

I have the following setup where multiple objects are zoomed out in a staggered delay. I am facing the following issues:
The zoom-out animation is set up to accelerate from 0% to 15% and then slow down the rest of the keyframes. But when the animation transitions from 15% to 16% the motion is visibly jarring. How can I make this transition smooth?
When the circles start out they appear from the left, not centered on their point of origin. How can I fix this?
HTML:
<div>
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle class="blk" cx="10" cy="10" r="5"/>
<circle class="red" cx="20" cy="10" r="5" color="red" stroke="red" fill="red"/>
<circle class="green" cx="30" cy="20" r="5" color="red" stroke="green" fill="green"/>
</svg>
</div>
CSS:
.blk{
animation-name: zoom-out;
animation-duration: 2s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-delay: 2.5s;
}
.red{
animation-name: zoom-out;
animation-duration: 2s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-delay: 1.5s;
}
.green{
animation-name: zoom-out;
animation-duration: 2s;
animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;
animation-iteration-count: infinite;
animation-delay: 0.5s;
}
#keyframes zoom-out {
0% {
transform: scale(5,5);
}
15% {
transform: scale(2,2);
}
100% {
transform: scale(1,1);
}
}
One posible solution would be having the circles with cx="0" and cy="0" and using those circles with an x and y position like so:
circle {
animation-name: zoom-out;
animation-duration: 2s;
/*animation-timing-function: ease-in-out;
-webkit-animation-timing-function: ease-in-out;*/
animation-iteration-count: infinite;
}
#blk {
animation-delay: 2.5s;
}
#red {
stroke: red;
fill: red;
animation-delay: 1.5s;
}
#green {
stroke: green;
fill: green;
animation-delay: 0.5s;
}
#keyframes zoom-out {
0% {
transform: scale(5, 5);
}
15% {
transform: scale(2, 2);
}
100% {
transform: scale(1, 1);
}
}
<div>
<svg viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<circle id="blk" r="5" />
<circle id="red" r="5" />
<circle id="green" r="5" />
</defs>
<use xlink:href="#blk" x="10" y="10" />
<use xlink:href="#red" x="20" y="10" />
<use xlink:href="#green" x="30" y="20" />
</svg>
</div>
Also in order to make the transition smooth you may use animation-timing-function: linear; instead of ease-in-out
UPDATE
The OP is commenting:
As for the point of origin, the actual SVG I am using is an illustator vector and each object in it has multiple paths and shapes. So, the red circle would actually be an object with 50 paths/shapes. How would I zero out the coordinates for a collection of paths?
Next comes an example where I'm using a collection of paths:
let wrap = document.querySelector("#red .wrap")
let bb = wrap.getBBox();
wrap.setAttribute("transform",`translate(${-(bb.x + bb.width/2)}, ${-(bb.y + bb.height/2)})`)
g[id] {
animation-name: zoom-out;
animation-duration: 2s;
animation-iteration-count: infinite;
}
#red {
stroke: red;
fill: red;
animation-delay: 1.5s;
}
#keyframes zoom-out {
0% {
transform: scale(5, 5);
}
15% {
transform: scale(2, 2);
}
100% {
transform: scale(1, 1);
}
}
svg{border:solid}
<svg viewBox="0 0 1000 500">
<defs>
<g id="red">
<g class="wrap">
<path id="body" fill-rule="evenodd" clip-rule="evenodd" d="M121.506,108.953c3.145-2.115,5.896-3.967,8.624-5.802 c20.948,12.522,42.66,12.281,65.725,4.354c0.778,3.128,1.687,6.18,2.285,9.291c3.208,16.677,0.616,36.326-2.758,52.719
c0,0-152.162,0.035-154.82,0.035c8.408,10.604,18.647,16.674,31.173,16.227c15.059-0.536,30.099-2.491,45.07-4.433
c26.453-3.431,50.783,0.317,70.991,19.392c1.675,1.581,7.179,9.382,3.632,13.47c-3.524,4.062-12.062-1.289-13.795-3.036
c-10.215-10.294-22.693-16.145-37.008-15.98c-14.568,0.166-29.103,2.376-43.679,3.216c-11.405,0.656-22.888,1.255-34.268,0.634
c-9.862-0.538-18.646-5.258-25.691-12.131c-15.127-14.758-26.56-31.716-26.923-53.792c-0.396-24.125,17.008-44.198,40.835-48.153
c23.477-3.897,43.372,4.666,62.051,17.569C115.82,104.515,118.537,106.717,121.506,108.953z"/>
<path id="head" fill-rule="evenodd" clip-rule="evenodd" d="M129.747,18.651c3.646,6.147,7.048,11.646,10.189,17.291
c1.404,2.523,2.761,3.481,5.888,2.718c14.09-3.439,28.227-3.932,42.396-0.046c1.308,0.358,3.815-0.733,4.608-1.923
c4.043-6.072,7.705-12.398,11.814-19.149c8.693,15.648,15.012,31.447,13.169,49.204c-1.48,14.266-9.114,24.946-22.028,31.172
c-17.641,8.503-35.969,9.511-54.067,1.823c-15.169-6.443-22.96-18.723-23.677-35.151C117.396,49.828,122.038,32.188,129.747,18.651z
M189.467,81.017c7.232,0.084,15.334-6.867,14.292-13.652c-0.832-5.418-11.566-6.019-11.732-6.025
c-7.238-0.308-13.768,6.133-14.144,13.949C177.731,78.444,182.773,80.938,189.467,81.017z M145.369,81.453
c3.597,0.294,11.258-2.441,11.324-6.992c0.079-5.443-3.357-10.158-8.897-12.255c-5.807-2.197-16.523,1.484-17.065,5.19
C129.692,74.494,138.107,81.089,145.369,81.453z"/>
</g>
</g>
</defs>
<use xlink:href="#red" x="300" y="175" />
</svg>
In order to zero out the coordinates for a collection of paths I'm using javaScript.
first I'm wrapping the paths in a group class="wrap"
I'm getting the bounding box of the wrap: let bb = wrap.getBBox();
I'm using the bounding box values to calculate the required translation and set the transform attribute of the wrap.

CSS animation rotate then wiggle SVG

I have an SVG compass with an arrow in it. I want to be able to add a class to the arrow and have it rotate a certain degree then stay there and wiggle.
I have the rotation and wiggle working just not together. Not sure how to combine the two so they work together. Here is my code:
div {
max-width: 40%;
}
.st0 {
fill: none;
stroke: #505050;
stroke-width: 4.11;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st1 {
fill: none;
stroke: #808080;
stroke-width: 2.57;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st2 {
fill: #505050;
}
.st3 {
opacity: 0.5;
}
.st4 {
fill: none;
}
/* Fill Colors */
.green {
fill: rgba(21, 255, 0, 0.5);
}
.dgreen {
fill: rgba(12, 140, 0, 0.5);
}
.red {
fill: rgba(255, 42, 0, 0.5);
}
.dred {
fill: rgba(140, 23, 0, 0.5);
}
/* Arrow */
#arrow {
transform-origin: 50% 59.7%;
animation-name: wiggle;
animation-duration: 1s;
animation-fill-mode: forward;
-webkit-animation-fill-mode: forward;
-webkit-animation-iteration-count: infinite;
/* Safari 4.0 - 8.0 */
animation-iteration-count: infinite;
}
/* Rotations */
.north#arrow {
-webkit-transform: rotate(45deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northEast#arrow {
-webkit-transform: rotate(90deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.west#arrow {
-webkit-transform: rotate(135deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southWest#arrow {
-webkit-transform: rotate(180deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.south#arrow {
-webkit-transform: rotate(225deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southWest#arrow {
-webkit-transform: rotate(270deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.west#arrow {
-webkit-transform: rotate(315deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northWest#arrow {
-webkit-transform: rotate(0deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
/* Wiggle Animation */
/* safari and chrome */
#-webkit-keyframes wiggle {
0% {
-webkit-transform: rotate(4deg);
}
50% {
-webkit-transform: rotate(-4deg);
}
100% {
-webkit-transform: rotate(4deg);
}
}
/* firefox */
#-moz-keyframes wiggle {
0% {
-moz-transform: rotate(4deg);
}
50% {
-moz-transform: rotate(-4deg);
}
100% {
-moz-transform: rotate(4deg);
}
}
#keyframes wiggle {
0% {
transform: rotate(4deg);
}
50% {
transform: rotate(-4deg);
}
100% {
transform: rotate(4deg);
}
}
<div>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 116.3 144" style="enable-background:new 0 0 116.3 144;" xml:space="preserve">
<title>compass</title>
<line id="N" class="st0" x1="58.2" y1="31.3" x2="58.2" y2="49.6"/>
<line id="NW" class="st1" x1="18.5" y1="46.1" x2="31.4" y2="59"/>
<line id="W" class="st0" x1="3.6" y1="85.7" x2="21.9" y2="85.7"/>
<line id="SW" class="st1" x1="18.3" y1="125.5" x2="31.3" y2="112.5"/>
<line id="S" class="st0" x1="58" y1="140.3" x2="58" y2="122"/>
<line id="SE" class="st1" x1="97.7" y1="125.6" x2="84.8" y2="112.6"/>
<line id="E" class="st0" x1="113.4" y1="85.9" x2="95.1" y2="85.9"/>
<line id="NE" class="st1" x1="97.8" y1="46.2" x2="84.9" y2="59.1"/>
<path id="compass" class="st2" d="M69.6,28.8c6.7-6.3,7-16.9,0.7-23.6s-16.9-7-23.6-0.7s-7,16.9-0.7,23.6c0.2,0.2,0.4,0.5,0.7,0.7
c-31.5,6.3-51.9,37-45.6,68.5s37,51.9,68.5,45.6c31.5-6.3,51.9-37,45.6-68.5C110.6,51.4,92.6,33.4,69.6,28.8z M58.2,6.5
c5.6,0,10.2,4.6,10.2,10.2H48C48,11.1,52.6,6.5,58.2,6.5z M58.2,138.3c-29,0-52.5-23.5-52.5-52.5s23.5-52.5,52.5-52.5
c29,0,52.5,23.5,52.5,52.5c0,0,0,0,0,0C110.6,114.8,87.1,138.3,58.2,138.3z"/>
<path id="inner_compass" class="st2" d="M58.2,130.8c-24.9,0-45.2-20.2-45.2-45.2s20.2-45.2,45.2-45.2c24.9,0,45.2,20.2,45.2,45.1
c0,0,0,0,0,0C103.3,110.6,83.1,130.8,58.2,130.8z M58.2,43.8c-23.1,0-41.9,18.8-41.9,41.9s18.8,41.9,41.9,41.9s41.9-18.8,41.9-41.9
C100.1,62.6,81.3,43.8,58.2,43.8L58.2,43.8z"/>
<g id="NNW" class="st3">
<path id="nnwPie" class="st4 green" d="M57.9,27.7v58.2l-41-41C27.8,33.9,42.5,27.7,57.9,27.7z"/>
</g>
<g id="WNW" class="st3">
<path id="wnwPie" class="st4 dgreen" d="M57.9,85.8H0.2v-0.2c0-15.3,6-30,16.8-40.8L57.9,85.8z"/>
</g>
<g id="WSW">
<path id="wswPie" class="st4" d="M57.9,85.8l-40.8,40.8c-10.8-10.8-16.9-25.5-17-40.8H57.9z"/>
</g>
<g id="SSW">
<path id="sswPie" class="st4" d="M57.9,85.8v57.8c-15.3,0-30-6.2-40.8-17L57.9,85.8z"/>
</g>
<g id="SSE">
<path id="ssePie" class="st4 red" d="M99,126.9c-10.8,10.8-25.5,16.8-40.8,16.8H58V85.8L99,126.9z"/>
</g>
<g id="ESE">
<path id="esePie" class="st4 dred" d="M116.2,85.8c0,15.4-6.2,30.2-17.2,41l-41-41H116.2z"/>
</g>
<g id="ENE">
<path id="enePie" class="st4" d="M116.2,85.7v0.2H57.9l41.2-41.2C110.1,55.5,116.2,70.3,116.2,85.7z"/>
</g>
<g id="NNE">
<path id="nnePie" class="st4" d="M99.1,44.6L57.9,85.8V27.7h0.2C73.5,27.6,88.3,33.7,99.1,44.6z"/>
</g>
<polygon id="arrow" class="st2 west" points="78.4,105.3 80.2,107.1 79.1,108.3 77.2,106.4 75.5,109.7 74.1,108.6 75.9,105.1 75.1,104.3
73.3,107.7 71.9,106.6 73.8,103 72.9,102.1 71.2,105.6 69.8,104.5 71.7,100.9 63.5,92.7 63.5,92.7 41.5,70.7 41.4,70.8 39,74.3
34.5,62.5 46.3,67.1 42.5,69.5 64.6,91.6 65.2,92.1 72.9,99.8 76.5,98 77.6,99.5 74.1,101.1 74.9,101.9 78.6,100 79.7,101.4
76.2,103.1 75.9,102.9 77.1,104 80.8,102.3 81.9,103.8 "/>
</svg>
</div>
You need to chain animations together and use a delay between them so one plays after the other has finished.
You were previously using a transition and then an animation which are two separate things. Also browser prefixes are now pretty redundant for animations, I personally would use the non-prefixed syntax.
Here is one example where the arrow moves to the south and then wiggles, you will need to add in the others:
Example CSS
.wrap:hover #arrow {
transform-origin: 50% 59.7%;
animation-name: spinSouth, wiggleSouth;
animation-delay: 0s, 1s;
animation-duration: 1s, 1s;
animation-iteration-count: 1, infinite;
}
/* Spin south Animation */
#keyframes spinSouth {
0% {
transform: rotate(4deg);
}
100% {
transform: rotate(225deg);
}
}
/* Wiggle Animation */
#keyframes wiggleSouth {
0% {
transform: rotate(225deg);
}
50% {
transform: rotate(220deg);
}
100% {
transform: rotate(225deg);
}
}
Fiddle:
http://jsfiddle.net/5cn9sm99/
I think this may be a shorter solution with the code you already have. You could wrap your arrow in an arrow container like this:
<g id="arrowContainer">
<polygon id="arrow" class="st2 west" points="78.4,105.3 80.2,107.1 79.1,108.3 77.2,106.4 75.5,109.7 74.1,108.6 75.9,105.1 75.1,104.3
73.3,107.7 71.9,106.6 73.8,103 72.9,102.1 71.2,105.6 69.8,104.5 71.7,100.9 63.5,92.7 63.5,92.7 41.5,70.7 41.4,70.8 39,74.3
34.5,62.5 46.3,67.1 42.5,69.5 64.6,91.6 65.2,92.1 72.9,99.8 76.5,98 77.6,99.5 74.1,101.1 74.9,101.9 78.6,100 79.7,101.4
76.2,103.1 75.9,102.9 77.1,104 80.8,102.3 81.9,103.8 "/>
</g>
Then add this styles to center the pivot point of the container:
#arrowContainer{ transform-origin: 50% 50%; }
Now replace the Rotations to target the arrowContainer and use Javascript or jQuery to add the classes you already created. Here is the full code.
var changeDirection = function changeClass(myClass){
$('#compass').attr("class", myClass);
}
div {
max-width: 300px;
}
.st0 {
fill: none;
stroke: #505050;
stroke-width: 4.11;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st1 {
fill: none;
stroke: #808080;
stroke-width: 2.57;
stroke-linecap: round;
stroke-miterlimit: 10;
}
.st2 {
fill: #505050;
}
.st3 {
opacity: 0.5;
}
.st4 {
fill: none;
}
/* Fill Colors */
.green {
fill: rgba(21, 255, 0, 0.5);
}
.dgreen {
fill: rgba(12, 140, 0, 0.5);
}
.red {
fill: rgba(255, 42, 0, 0.5);
}
.dred {
fill: rgba(140, 23, 0, 0.5);
}
/* Arrow */
#arrowContainer{
transform-origin: 50% 50%;
}
#arrow {
transform-origin: 50% 59.7%;
animation-name: wiggle;
animation-duration: 1s;
animation-fill-mode: forward;
-webkit-animation-fill-mode: forward;
-webkit-animation-iteration-count: infinite;
/* Safari 4.0 - 8.0 */
animation-iteration-count: infinite;
}
/* Rotations */
.north #arrowContainer {
-webkit-transform: rotate(45deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northEast #arrowContainer {
-webkit-transform: rotate(90deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.east #arrowContainer {
-webkit-transform: rotate(135deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southEast #arrowContainer {
-webkit-transform: rotate(180deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.south #arrowContainer {
-webkit-transform: rotate(225deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.southWest #arrowContainer {
-webkit-transform: rotate(270deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.west #arrowContainer {
-webkit-transform: rotate(315deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
.northWest #arrowContainer {
-webkit-transform: rotate(0deg);
-webkit-transition: -webkit-transform 0.5s ease-in;
}
/* Wiggle Animation */
/* safari and chrome */
#-webkit-keyframes compass {
0% {
-webkit-transform: rotate(0deg);
}
100% {
-webkit-transform: rotate(0deg);
}
}
#-webkit-keyframes wiggle {
0% {
-webkit-transform: rotate(4deg);
}
50% {
-webkit-transform: rotate(-4deg);
}
100% {
-webkit-transform: rotate(4deg);
}
}
/* firefox */
#-moz-keyframes wiggle {
0% {
-moz-transform: rotate(4deg);
}
50% {
-moz-transform: rotate(-4deg);
}
100% {
-moz-transform: rotate(4deg);
}
}
#keyframes wiggle {
0% {
transform: rotate(4deg);
}
50% {
transform: rotate(-4deg);
}
100% {
transform: rotate(4deg);
}
}
/* Button Styles */
.buttons{
float: left;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
<button onclick="changeDirection('north')">North</button>
<button onclick="changeDirection('northEast')">NorthEast</button>
<button onclick="changeDirection('east')">East</button>
<button onclick="changeDirection('southEast')">South East</button>
<button onclick="changeDirection('south')">South</button>
<button onclick="changeDirection('southWest')">South West</button>
<button onclick="changeDirection('west')">West</button>
<button onclick="changeDirection('northWest')">North West</button>
</div>
<div id="compass" class="addClassHere">
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_4" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 116.3 144" style="enable-background:new 0 0 116.3 144;" xml:space="preserve">
<title>compass</title>
<line id="N" class="st0" x1="58.2" y1="31.3" x2="58.2" y2="49.6"/>
<line id="NW" class="st1" x1="18.5" y1="46.1" x2="31.4" y2="59"/>
<line id="W" class="st0" x1="3.6" y1="85.7" x2="21.9" y2="85.7"/>
<line id="SW" class="st1" x1="18.3" y1="125.5" x2="31.3" y2="112.5"/>
<line id="S" class="st0" x1="58" y1="140.3" x2="58" y2="122"/>
<line id="SE" class="st1" x1="97.7" y1="125.6" x2="84.8" y2="112.6"/>
<line id="E" class="st0" x1="113.4" y1="85.9" x2="95.1" y2="85.9"/>
<line id="NE" class="st1" x1="97.8" y1="46.2" x2="84.9" y2="59.1"/>
<path id="compass" class="st2" d="M69.6,28.8c6.7-6.3,7-16.9,0.7-23.6s-16.9-7-23.6-0.7s-7,16.9-0.7,23.6c0.2,0.2,0.4,0.5,0.7,0.7
c-31.5,6.3-51.9,37-45.6,68.5s37,51.9,68.5,45.6c31.5-6.3,51.9-37,45.6-68.5C110.6,51.4,92.6,33.4,69.6,28.8z M58.2,6.5
c5.6,0,10.2,4.6,10.2,10.2H48C48,11.1,52.6,6.5,58.2,6.5z M58.2,138.3c-29,0-52.5-23.5-52.5-52.5s23.5-52.5,52.5-52.5
c29,0,52.5,23.5,52.5,52.5c0,0,0,0,0,0C110.6,114.8,87.1,138.3,58.2,138.3z"/>
<path id="inner_compass" class="st2" d="M58.2,130.8c-24.9,0-45.2-20.2-45.2-45.2s20.2-45.2,45.2-45.2c24.9,0,45.2,20.2,45.2,45.1
c0,0,0,0,0,0C103.3,110.6,83.1,130.8,58.2,130.8z M58.2,43.8c-23.1,0-41.9,18.8-41.9,41.9s18.8,41.9,41.9,41.9s41.9-18.8,41.9-41.9
C100.1,62.6,81.3,43.8,58.2,43.8L58.2,43.8z"/>
<g id="NNW" class="st3">
<path id="nnwPie" class="st4 green" d="M57.9,27.7v58.2l-41-41C27.8,33.9,42.5,27.7,57.9,27.7z"/>
</g>
<g id="WNW" class="st3">
<path id="wnwPie" class="st4 dgreen" d="M57.9,85.8H0.2v-0.2c0-15.3,6-30,16.8-40.8L57.9,85.8z"/>
</g>
<g id="WSW">
<path id="wswPie" class="st4" d="M57.9,85.8l-40.8,40.8c-10.8-10.8-16.9-25.5-17-40.8H57.9z"/>
</g>
<g id="SSW">
<path id="sswPie" class="st4" d="M57.9,85.8v57.8c-15.3,0-30-6.2-40.8-17L57.9,85.8z"/>
</g>
<g id="SSE">
<path id="ssePie" class="st4 red" d="M99,126.9c-10.8,10.8-25.5,16.8-40.8,16.8H58V85.8L99,126.9z"/>
</g>
<g id="ESE">
<path id="esePie" class="st4 dred" d="M116.2,85.8c0,15.4-6.2,30.2-17.2,41l-41-41H116.2z"/>
</g>
<g id="ENE">
<path id="enePie" class="st4" d="M116.2,85.7v0.2H57.9l41.2-41.2C110.1,55.5,116.2,70.3,116.2,85.7z"/>
</g>
<g id="NNE">
<path id="nnePie" class="st4" d="M99.1,44.6L57.9,85.8V27.7h0.2C73.5,27.6,88.3,33.7,99.1,44.6z"/>
</g>
<g id="arrowContainer">
<polygon id="arrow" class="st2 west" points="78.4,105.3 80.2,107.1 79.1,108.3 77.2,106.4 75.5,109.7 74.1,108.6 75.9,105.1 75.1,104.3
73.3,107.7 71.9,106.6 73.8,103 72.9,102.1 71.2,105.6 69.8,104.5 71.7,100.9 63.5,92.7 63.5,92.7 41.5,70.7 41.4,70.8 39,74.3
34.5,62.5 46.3,67.1 42.5,69.5 64.6,91.6 65.2,92.1 72.9,99.8 76.5,98 77.6,99.5 74.1,101.1 74.9,101.9 78.6,100 79.7,101.4
76.2,103.1 75.9,102.9 77.1,104 80.8,102.3 81.9,103.8 "/>
</g>
</svg>
</div>

stroke-dashoffset not working with SVG

i am new to SVG and animation.
just created a path and wanted to draw it with animation, i am using "stroke-dashoffset" but its not working.
Here is my HTML :
<div class="Q">
<svg height="100%" width="100%" viewBox="200 0 400 400">
<path id="latter_q" d="M1003.3425022861358,2828.211816939241a655.718421,655.718421,0,1,1,-397.5557043956452,543.2070169791295" style="fill: none; stroke-width: 300px; stroke-linecap: round;" transform="matrix(-0.220662 -0.00474159 0.00474159 -0.220662 452.115 953.136)" stroke="purple"/>
<circle id="e4_circle" cx="322" cy="293" stroke="purple" style="stroke-width: 1px; vector-effect: non-scaling-stroke;" r="38.1936" fill="purple" />
<polygon stroke="purple" id="e5_polygon" style="stroke-width: 1px;" points="625.5 543.206 885.5 7.20558 1149.5 535.206 1021.5 481.206 889.5 225.206 767.5 481.206" fill="purple" transform="matrix(0.618136 0 0 0.618136 -4.20822 17.3249)"/>
</svg>
</div>
and CSS
#latter_q{
animation: DrwaQ 2s linear alternate infinite;
animation-delay: 1s;
/*stroke-dashArray: 1100;*/
stroke-dashoffset: 1100;
}
.Q{
width: 100%;
height: 100%;
position: absolute;
/*opacity: 0;*/
}
#keyframes DrawQ {
to { stroke-dashOffset: 0; }
}
finally got it worked.
CSS :
#latter_q{
animation: DrwaQ 2s ease-in ;
animation-delay: 0s;
stroke-dasharray: 3435;
}
#keyframes DrwaQ {
to {
stroke-dashoffset: 6904;
}
from {
stroke-dashoffset: 3447;
}
}
stroke-dashoffset is not a CSS property (yet) - you have to do this with JavaScript
https://developer.mozilla.org/en-US/docs/Web/CSS/Reference

SVG icon animation leaves a pixel gap

I'm working on SVG animations with CSS and I've noticed that with my line drawing animations, any SVG rect (#clipboard-border and #clipboard-clip-border) stroke always excludes a bit of the top-left corner, which makes it an incomplete rectangle.
I've tried adjusting the stroke-dasharray and stroke-dashoffset measurements within the CSS, as well as adjusting the sizes and pixel coordinated within the SVG code, but neither are the problem it seems. Help?
html,
body {
width: 100%;
height: 100%;
background-color: #CECECE;
}
div {
text-align: center;
}
svg {
display: inline-block;
width: 120px;
margin: 3% auto;
padding: 0px 100px;
}
/* ---------------------
SVG RULES
--------------------- */
/* All grey strokes */
#clipboard-border,
.clipboard-content,
.clipboard-borders,
.mech-pencil-borders {
fill: none;
stroke: #4D5152;
stroke-width: 6;
stroke-miterlimit: 10;
}
/* All things white */
#clipboard-paper-fill,
#mech-pencil-eraser-fill {
fill: #F3F7F6;
}
/* All things green */
#mech-pencil-point-fill,
#mech-pencil-top-fill {
fill: #25B686;
}
/* All things blue */
#clipboard-fill {
fill: #85D0D3;
}
/* All things yellow */
#clipboard-clip-fill,
#mech-pencil-grip {
fill: #FBFBCE;
}
#clipboard-knob-1,
#clipboard-knob-2,
#clipboard-knob-3,
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
stroke-dasharray: 8px;
stroke-dashoffset: 8px;
animation: trace .5s ease-out forwards;
}
/* ---------------------
ANIMATION KEYFRAMES
--------------------- */
#keyframes trace {
100% {
stroke-dashoffset: 0px;
}
}
#keyframes fill-it {
100% {
opacity: 1;
}
}
#keyframes grow {
0% {
transform: scale(0);
}
30% {
transform: scale(1.1);
}
60% {
transform: scale(.9);
}
}
/* ---------------------
SVG ANIMATION: INSIGHT & PLANNING ICON
--------------------- */
#clipboard-clip-border {
stroke-dasharray: 180px;
stroke-dashoffset: 180px;
animation: trace .2s ease-out forwards;
}
#clipboard-clip-fill {
opacity: 0;
animation: fill-it .2s .2s ease-in-out forwards;
}
#clipboard-border {
stroke-dasharray: 640px;
stroke-dashoffset: 640px;
animation: trace 1.25s ease-in-out forwards;
}
#clipboard-fill,
#mech-pencil-point-fill,
#mech-pencil-top-fill {
opacity: 0;
animation: fill-it .25s 1.25s ease-in-out forwards;
}
#clipboard-paper-border {
stroke-dasharray: 400px;
stroke-dashoffset: 400px;
animation: trace 1s ease-out forwards;
}
#clipboard-paper-fill,
#mech-pencil-eraser-fill,
#mech-pencil-grip {
opacity: 0;
animation: fill-it .75s 1s ease-in-out forwards;
}
#clipboard-content-line-1 {
stroke-dasharray: 30px;
stroke-dashoffset: 30px;
animation: trace .5s ease-out forwards;
}
#clipboard-content-line-7,
#clipboard-clip-detail {
stroke-dasharray: 52px;
stroke-dashoffset: 52px;
animation: trace .5s ease-out forwards;
}
#clipboard-content-line,
#clipboard-content-line-even,
#mech-pencil-eraser-border {
stroke-dasharray: 80px;
stroke-dashoffset: 80px;
animation: trace .75s ease-out forwards;
}
#mech-pencil-border-left,
#mech-pencil-border-right {
stroke-dasharray: 115px;
stroke-dashoffset: 115px;
animation: trace .75s ease-out forwards;
}
#mech-pencil-point-border {
stroke-dasharray: 60px;
stroke-dashoffset: 60px;
animation: trace .5s ease-out forwards;
}
#mech-pencil-tip,
#mech-pencil-top {
stroke-dasharray: 10px;
stroke-dashoffset: 10px;
animation: trace .4s ease-out forwards;
}
/* ---------------------
ANIMATION DELAYS
--------------------- */
#clipboard-knob-1,
#clipboard-knob-2 {
animation-delay: .25s;
}
#clipboard-clip-detail,
#clipboard-content-line,
#clipboard-content-line-7,
#clipboard-knob-2 {
animation-delay: .5s;
}
#mech-pencil-bottom-btn,
#mech-pencil-top-btn {
animation-delay: 1.25s;
}
<div class="wrapper">
<!-- INSIGHT & PLANNING ICON -->
<svg id="insight-planning" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="200px" height="200px" viewBox="0 0 200 200">
<g class="clipboard">
<rect id="clipboard-fill" x="15.015" y="11.44" width="132" height="182" />
<rect id="clipboard-paper-fill" x="30.753" y="11.44" width="100" height="151" />
<g class="clipboard-content">
<line id="clipboard-content-line-even" x1="46.491" y1="68.096" x2="115.738" y2="68.096" />
<line id="clipboard-content-line" x1="46.491" y1="80.687" x2="115.738" y2="80.687" />
<line id="clipboard-content-line-even" x1="46.491" y1="93.277" x2="115.738" y2="93.277" />
<line id="clipboard-content-line" x1="46.491" y1="105.867" x2="115.738" y2="105.867" />
<line id="clipboard-content-line-even" x1="46.491" y1="118.458" x2="115.738" y2="118.458" />
<line id="clipboard-content-line-7" x1="46.491" y1="131.048" x2="96.852" y2="131.048" />
<line id="clipboard-content-line-1" x1="115.738" y1="49.211" x2="90.557" y2="49.211" />
</g>
<rect id="clipboard-border" x="15.015" y="11.44" width="132" height="182" />
</g>
<g class="mech-pencil-fills">
<rect id="mech-pencil-grip" x="166.099" y="96.425" width="18" height="47" />
<rect id="mech-pencil-top-fill" x="166.099" y="30.325" width="18" height="66" />
<rect id="mech-pencil-eraser-fill" x="166.099" y="11.44" width="18" height="18" />
<polygon id="mech-pencil-point-fill" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
</g>
<g class="mech-pencil-borders">
<line id="mech-pencil-border-left" x1="166.099" y1="143.639" x2="166.099" y2="30.325" />
<line id="mech-pencil-border-right" x1="184.985" y1="30.325" x2="184.985" y2="145" />
<rect id="mech-pencil-eraser-border" x="166.099" y="11.44" width="18" height="18" />
<polygon id="mech-pencil-point-border" points="184.985,143.639 184.985,159.376 175.542,168.819 166.099,159.376 166.099,143.639" />
<line id="mech-pencil-top" x1="175.542" y1="11.44" x2="175.542" y2="1.997" />
<line id="mech-pencil-tip" x1="175.542" y1="168.819" x2="175.542" y2="175.114" />
<line id="mech-pencil-bottom-btn" x1="175.542" y1="127.901" x2="175.542" y2="121.605" />
<line id="mech-pencil-top-btn" x1="175.542" y1="115.31" x2="175.542" y2="109.015" />
</g>
<g class="clipboard-clip">
<rect id="clipboard-clip-fill" x="49.639" y="5.144" width="62" height="25" />
</g>
<g class="clipboard-borders">
<polyline id="clipboard-paper-border" points="131.476,11.44 131.476,162.524 30.753,162.524 30.753,11.44" />
<rect id="clipboard-clip-border" x="49.639" y="5.144" width="62" height="25" />
<line id="clipboard-clip-detail" x1="59.081" y1="17.735" x2="103.148" y2="17.735" />
<line id="clipboard-knob-1" x1="65.376" y1="178.262" x2="71.672" y2="178.262" />
<line id="clipboard-knob-2" x1="77.967" y1="178.262" x2="84.262" y2="178.262" />
<line id="clipboard-knob-3" x1="90.557" y1="178.262" x2="96.852" y2="178.262" />
</g>
</svg>
</div>
Also posted in Codepen.
Just add stroke-linecap: square; to the CSS declarations for the SVG object.
svg {
display: inline-block;
width: 120px;
margin: 3% auto;
padding: 0px 100px;
stroke-linecap: square; /* <-- Add this */
}
Example:
Here's an SVG with two paths (open, not closed). The path drawn with "butt" line endings has a bit missing in the top corner, but the other path (drawn with "square" line endings) doesn't have this issue.
<svg width="250" height="100" viewBox="0 0 250 100">
<path d="M10 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: square;"/>
<text x="50" y="70" text-anchor="middle">Square</text>
<path d="M160 10h80v80h-80v-80" style="stroke:#000; stroke-width:10px; fill:none; stroke-linecap: butt;"/>
<text x="200" y="70" text-anchor="middle">Butt</text>
</svg>
P.S. I like your work, but next time please consider making a minimal, complete and verifiable example to illustrate the problem. That way people won't have to wade through reams of code to discover what's going wrong :-)

Resources