SVG icon animation leaves a pixel gap - css
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 :-)
Related
Animated CSS play button
I'm trying to reproduce this piece of code (animated button using SVG and CSS): https://codepen.io/jscottsmith/pen/azRObp/ To keep the code clean, I wanted to use xlink with that. My current code looks as follows: #import "compass/css3"; body {background:violet} #keyframes spin { to { transform: rotate(360deg); } } .stroke-dotted { opacity: 0; stroke-dasharray: 4,5; stroke-width: 1px; transform-origin: 50% 50%; animation: spin 4s infinite linear; transition: opacity 1s ease, stroke-width 1s ease; } .stroke-solid { stroke-dashoffset: 0; stroke-dashArray: 300; stroke-width: 4px; transition: stroke-dashoffset 1s ease, opacity 1s ease; } .icon { transform-origin: 50% 50%; transition: transform 200ms ease-out; } #play:hover .stroke-dotted { stroke-width: 4px; opacity: 1; } #play:hover .stroke-solid { opacity: 0; stroke-dashoffset: 300; } #play:hover .icon { transform: scale(1.05); } #PlayNow { cursor: pointer; position: absolute; top: 50%; left: 50%; transform: translateY(-50%) translateX(-50%); width:10em; height:auto; display:block; } <a href="#"> <svg xmlns="http://www.w3.org/2000/svg" id="PlayNow" viewBox="0 0 100 100" x="0px" y="0px" ><use xlink:href="#play" id="playTrailerButton" /></svg> </a> <svg xmlns="http://www.w3.org/2000/svg"> <symbol id="play" viewBox="0 0 100 100"> <path class="stroke-solid" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5"/> <path class="stroke-dotted" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5"/> <path class="icon" fill="white" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z"/> </symbol> </svg> But the animation doesn't work.. Any ideas or hints - why? jsfiddle is here: https://jsfiddle.net/4ztwr3c9/6
You have this: #PlayNow { cursor: pointer; position: absolute; top: 50%; left: 50%; transform: translateY(-50%) translateX(-50%); width:10em; height:auto; display:block; } There is no element with the id #PlayNow. The example below has #PlayNow selector replaced by the original #play and your changes have been added, and I removed the Compass as well which I guess you can add it back, just be mindful of each change and retest so it's easier to debug and backtrack. #keyframes spin { to { transform: rotate(360deg); } } .stroke-dotted { opacity: 0; stroke-dasharray: 4, 5; stroke-width: 1px; transform-origin: 50% 50%; animation: spin 4s infinite linear; transition: opacity 1s ease, stroke-width 1s ease; } .stroke-solid { stroke-dashoffset: 0; stroke-dashArray: 300; stroke-width: 4px; transition: stroke-dashoffset 1s ease, opacity 1s ease; } .icon { transform-origin: 50% 50%; transition: transform 200ms ease-out; } #play:hover .stroke-dotted { stroke-width: 4px; opacity: 1; } #play:hover .stroke-solid { opacity: 0; stroke-dashoffset: 300; } #play:hover .icon { transform: scale(1.05); } html { height: 100%; } body { height: 100%; /*background-color: #30FF98; background: radial-gradient(#71edb5, #30ff98);*/ } #play { cursor: pointer; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); /* Your Changes */ width:10em; height:auto; display:block; } body {background:violet} <svg version="1.1" id="play" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" height="100px" width="100px" viewBox="0 0 100 100" enable-background="new 0 0 100 100" xml:space="preserve"> <path class="stroke-solid" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5"/> <path class="stroke-dotted" fill="none" stroke="white" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5"/> <path class="icon" fill="white" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z"/> </svg>
You can change/override some properties of a <use> element - provided these are not already set in your <symbol> element (see first example). Since you need to change the dash-array values for different elements you can use css variables, that could be changed on hover. body { background: violet; } #keyframes spin { to { transform: rotate(360deg); } } :root { --fill: #fff; --strokeWidth: 4px; --scale: 1; --strokeDashOffset: 10; --strokeDashArray: 4 5; --opacity: 0; --strokeDashArraySolid: 300; --strokeDashOffsetSolid: 0; --opacitySolid: 1; } .PlayNow { display: inline-block; height: 10em; } .PlayNow2 { --fill: #ccc; --strokeWidth: 6px; --scale: 1.5; } .PlayNow:hover { --scale: 1.05; --strokeDashOffset: 10; --strokeDashArray: 4 5; --strokeDashArraySolid: 300; --strokeDashOffsetSolid: 300; --opacity: 1; --opacitySolid: 0; } #playTrailerButtonSimple:hover { fill: green!important; stroke: green!important; stroke-dasharray: 10 5; } <a href="#"> <svg class="PlayNow PlayNowSimple" xmlns="http://www.w3.org/2000/svg" id="PlayNowSimple" viewBox="0 0 100 100"> <use href="#playSimple" id="playTrailerButtonSimple" stroke-width="4" fill="red" stroke="red"/> </svg> Simple icon </a> <a href="#"> <svg class="PlayNow" xmlns="http://www.w3.org/2000/svg" id="PlayNow" viewBox="0 0 100 100"> <use href="#play" id="playTrailerButton" /> </svg> </a> <a href="#"> <svg class="PlayNow PlayNow2" xmlns="http://www.w3.org/2000/svg" id="PlayNow2" viewBox="0 0 100 100"> <use href="#play" id="playTrailerButton" /> </svg> </a> <svg xmlns="http://www.w3.org/2000/svg"> <symbol id="circle"> <path fill="none" style="stroke:var(--fill)" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5" /> </symbol> <symbol id="play" viewBox="0 0 100 100"> <use href="#circle" transform-origin="center" class="stroke-solid" style="stroke-width: var(--strokeWidth); stroke-dasharray: var(--strokeDashArraySolid); stroke-dashoffset: var(--strokeDashOffsetSolid); opacity:var(--opacitySolid); transition: stroke-dashoffset 1s ease, opacity 1s ease;" /> <use href="#circle" transform-origin="center" class="stroke-dotted" style="stroke-width: var(--strokeWidth); stroke-dasharray: var(--strokeDashArray); stroke-dashoffset: var(--strokeDashOffset); opacity:var(--opacity); animation: spin 4s infinite linear; transition: opacity 1s ease, stroke-width 1s ease;" /> <path class="icon" transform-origin="center" style="fill:var(--fill);transform:scale(var(--scale));transition:0.3s" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z" /> </symbol> </svg> <svg xmlns="http://www.w3.org/2000/svg"> <symbol id="circle2"> <path fill="none" d="M49.9,2.5C23.6,2.8,2.1,24.4,2.5,50.4C2.9,76.5,24.7,98,50.3,97.5c26.4-0.6,47.4-21.8,47.2-47.7 C97.3,23.7,75.7,2.3,49.9,2.5" /> </symbol> <symbol id="playSimple" viewBox="0 0 100 100"> <use href="#circle2" transform-origin="center" class="stroke-solid" /> <path stroke-width="0" class="icon" transform-origin="center" d="M38,69c-1,0.5-1.8,0-1.8-1.1V32.1c0-1.1,0.8-1.6,1.8-1.1l34,18c1,0.5,1,1.4,0,1.9L38,69z" /> </symbol> </svg> External <use> reference To some extent, you could also use external svg files like so: <a href="#"> <svg class="svgBtn" xmlns="http://www.w3.org/2000/svg" id="PlayNow" viewBox="0 0 100 100" x="0px" y="0px"> <use href="button.svg#play" id="playTrailerButton" style="transition:0.3s"/> </svg> </a> ** Drawback:** Your animations/transitions won#t work in most browsers (Firefox can render them)
Awesome css animation not working on iOS even setting -webkit- on classes and #-webkit-keyframes
I have the following cshtml file content working perfectly on all browsers, except on my mobile (iPhone 8). On Android mobiles it works fine. I've also added everywhere where necessary the prefix -webkits- on all #keyframesand on all classes as you can see in the following code-lines: <div class="footer-top section bg-white m-0 p-0" id="footer"> <svg width="100%" height="100%" viewBox="0 0 100 25"> <defs> <filter id="goo"> <feGaussianBlur in="SourceGraphic" stdDeviation="1" result="blur" /> <feColorMatrix in="blur" mode="matrix" values=" 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 13 -9" result="goo" /> <xfeBlend in="SourceGraphic" in2="goo" /> </filter> <path id="wave" d="M 0,10 C 30,10 30,15 60,15 90,15 90,10 120,10 150,10 150,15 180,15 210,15 210,10 240,10 v 28 h -240 z" /> </defs> <use id="wave3" class="wave" xlink:href="#wave" x="0" y="-2"></use> <use id="wave2" class="wave" xlink:href="#wave" x="0" y="0"></use> <use id="wave4" class="wave" xlink:href="#wave" x="0" y="2"></use> <g class="gooeff" filter="url(#goo)"> <circle class="drop drop1" cx="20" cy="2" r="8.8" /> <circle class="drop drop2" cx="25" cy="2.5" r="7.5" /> <circle class="drop drop3" cx="16" cy="2.8" r="9.2" /> <circle class="drop drop4" cx="18" cy="2" r="8.8" /> <circle class="drop drop5" cx="22" cy="2.5" r="7.5" /> <circle class="drop drop6" cx="26" cy="2.8" r="9.2" /> <circle class="drop drop1" cx="5" cy="4.4" r="8.8" /> <circle class="drop drop2" cx="5" cy="4.1" r="7.5" /> <circle class="drop drop3" cx="8" cy="3.8" r="9.2" /> <circle class="drop drop4" cx="3" cy="4.4" r="8.8" /> <circle class="drop drop5" cx="7" cy="4.1" r="7.5" /> <circle class="drop drop6" cx="10" cy="4.3" r="9.2" /> <circle class="drop drop1" cx="1.2" cy="5.4" r="8.8" /> <circle class="drop drop2" cx="5.2" cy="5.1" r="7.5" /> <circle class="drop drop3" cx="10.2" cy="5.3" r="9.2" /> <circle class="drop drop4" cx="3.2" cy="5.4" r="8.8" /> <circle class="drop drop5" cx="14.2" cy="5.1" r="7.5" /> <circle class="drop drop6" cx="17.2" cy="4.8" r="9.2" /> <use id="wave1" class="wave" xlink:href="#wave" x="0" y="1" /> </g> <path id="wave1" class="wave" d="M 0,10 C 30,10 30,15 60,15 90,15 90,10 120,10 150,10 150,15 180,15 210,15 210,10 240,10 v 28 h -240 z" /> </g> </svg> and the related css style sheet: .footer-top { --col-deepblue: #4478e3; width: 100vw; height: auto; overflow: auto; position: relative; margin: 0; padding: 0; } svg { width: 100%; overflow: auto; overflow-x: hidden; } .wave { animation: wave 3s linear; animation-iteration-count: infinite; fill: #222222; -webkit-animation: wave 3s linear; -webkit-animation-iteration-count: infinite; } .drop { fill: var(--col-deepblue); xfill: #99000055; animation: drop 3.2s linear infinite normal; stroke: var(--col-deepblue); stroke-width: 1; transform: translateY(25px); transform-box: fill-box; transform-origin: 50% 100%; /*-webkit-*/ -webkit-text-stroke: var(--col-deepblue); -webkit-text-stroke-width: 1; -webkit-animation: drop 3.2s linear infinite normal; -webkit-transform: translateY(25px); -webkit-transform-box: fill-box; -webkit-transform-origin: 50% 100%; } .drop1 { } .drop2 { animation-delay: 3s; animation-duration: 3s; -webkit-animation-delay: 3s; -webkit-animation-duration: 3s; } .drop3 { animation-delay: -2s; animation-duration: 3.4s; -webkit-animation-delay: -2s; -webkit-animation-duration: 3.4s; } .drop4 { animation-delay: 1.7s; -webkit-animation-delay: 1.7s; } .drop5 { animation-delay: 2.7s; animation-duration: 3.1s; -webkit-animation-delay: 2.7s; -webkit-animation-duration: 3.1s; } .drop6 { animation-delay: -2.1s; animation-duration: 3.2s; -webkit-animation-delay: -2.1s; -webkit-animation-duration: 3.2s; } .gooeff { filter: url(#goo); -webkit-filter: url(#goo); } #wave2 { animation-duration: 5s; animation-direction: reverse; -webkit-animation-duration: 5s; -webkit-animation-direction: reverse; opacity: .6 } #wave3 { animation-duration: 7s; -webkit-animation-duration: 7s; opacity: .3; } #wave4 { animation-duration: 9s; -webkit-animation-duration: 9s; opacity: .5; } #keyframes drop { 0% { transform: translateY(25px); } 30% { transform: translateY(-10px) scale(.1); } 30.001% { transform: translateY(25px) scale(1); } 70% { transform: translateY(25px); } 100% { transform: translateY(-10px) scale(.1); } } #-webkit-keyframes drop { 0% { -webkit-transform: translateY(25px); } 30% { -webkit-transform: translateY(-10px) scale(.1); } 30.001% { -webkit-transform: translateY(25px) scale(1); } 70% { -webkit-transform: translateY(25px); } 100% { -webkit-transform: translateY(-10px) scale(.1); } } #keyframes wave { to { transform: translateX(-100%); } } #-webkit-keyframes wave { to { -webkit-transform: translateX(-100%); } } #supports (-webkit-backdrop-filter: blur(1px)) { svg { height: 100%; } } The animation works well in all browsers except on iOS. I'm using an iPhone 8. I've tried several suggestions, among them also this one. But it does not solve my problem. On Android mobile it works fine. Any idea?
Your code doesn't work not only in iOS but also in Safari on macOS, this is a strange problem, but an error in feColorMatrix, move values to one line <feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 13 -9" result="goo" />
SVG CSS animation after hover off
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; }
Inline Animated SVG not loading in IE/Edge
I've been trying to create a donut chart not too dissimilar to this example here: https://jsfiddle.net/4azpfk3r/ HTML: <div class="item html"> <h2>HTML</h2> <svg width="160" height="160" xmlns="http://www.w3.org/2000/svg"> <g> <title>Layer 1</title> <circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/> </g> </svg> </div> <div class="item css"> <h2>CSS</h2> <svg width="160" height="160" xmlns="http://www.w3.org/2000/svg"> <g> <title>Layer 1</title> <circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#69aff4" fill="none"/> </g> </svg> </div> CSS .item { position: relative; float: left; } .item h2 { text-align:center; position: absolute; line-height: 125px; width: 100%; } svg { transform: rotate(-90deg); } .circle_animation { stroke-dasharray: 440; stroke-dashoffset: 440; } .html .circle_animation { -webkit-animation: html 1s ease-out forwards; animation: html 1s ease-out forwards; } .css .circle_animation { -webkit-animation: css 1s ease-out forwards; animation: css 1s ease-out forwards; } #-webkit-keyframes html { to { stroke-dashoffset: 80; } } #keyframes html { to { stroke-dashoffset: 80; } } #-webkit-keyframes css { to { stroke-dashoffset: 160; } } #keyframes css { to { stroke-dashoffset: 160; } } However, in both the above example, and my altered version I have trouble running them in IE 11 and Edge. I'm fairly certain it is due to the animation on the stroke-dashoffset but I'm not sure if there is any work around. Note: I have already tried adding the line below as some similar questions have suggested but this provides no change in the behaviour <meta http-equiv="X-UA-Compatible" content="IE=edge">
IE11 does not support CSS animations of SVG elements. So you would need to use a different approach if you want to support non-Edge IE. However Edge has supported CSS animations of SVG elements since build 10240. The reason your animations aren't working on Edge is because Edge insists that you include units with CSS values. Other browsers are more forgiving with SVG values. So to fix, add px to all your dasharray and dashoffset values. .circle_animation { stroke-dasharray: 440px; stroke-dashoffset: 440px; } #keyframes html { to { stroke-dashoffset: 80px; } } .item { position: relative; float: left; } .item h2 { text-align:center; position: absolute; line-height: 125px; width: 100%; } svg { transform: rotate(-90deg); } .circle_animation { stroke-dasharray: 440px; stroke-dashoffset: 440px; } .html .circle_animation { -webkit-animation: html 1s ease-out forwards; animation: html 1s ease-out forwards; } .css .circle_animation { -webkit-animation: css 1s ease-out forwards; animation: css 1s ease-out forwards; } #-webkit-keyframes html { to { stroke-dashoffset: 80px; } } #keyframes html { to { stroke-dashoffset: 80px; } } #-webkit-keyframes css { to { stroke-dashoffset: 160px; } } #keyframes css { to { stroke-dashoffset: 160px; } } <div class="item html"> <h2>HTML</h2> <svg width="160" height="160" xmlns="http://www.w3.org/2000/svg"> <g> <title>Layer 1</title> <circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#6fdb6f" fill="none"/> </g> </svg> </div> <div class="item css"> <h2>CSS</h2> <svg width="160" height="160" xmlns="http://www.w3.org/2000/svg"> <g> <title>Layer 1</title> <circle id="circle" class="circle_animation" r="69.85699" cy="81" cx="81" stroke-width="8" stroke="#69aff4" fill="none"/> </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