Reputation: 4546
I currently have a small SVG that adds a full stroke. However, I am having hard time for a full circle to be completed on hover. When the user hovers off the link, it should go back the other way.
The full animation seems to be working but when integrating it, the animation keeps disappearing when I only want it to happen.
body,
html {
position: relative;
height: 100%;
}
body {
background-color: #D81D3B;
}
.svg-container {
position: absolute;
top: 50%;
left: 50%;
width: 7em;
height: 7em;
transform: translate3d(-50%, -50%, 0);
}
.svg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
.symbol {
fill: transparent;
stroke: #fff;
stroke-width: 1px;
stroke-dasharray: 1600;
stroke-miterlimit: 10;
stroke-dashoffset: 1600;
animation: dash 4s linear 1;
}
@keyframes dash {
from {
stroke-dashoffset: 1600;
}
to {
stroke-dashoffset: -1600;
}
}
<div class="svg-container">
<svg width="100" height="100" class="svg">
<circle cx="50" cy="50" r="40" stroke-width="4" class="symbol" />
</svg>
</div>
<a href="#">Stupid</a>
Upvotes: 2
Views: 2329
Reputation: 89750
Based on your description what you actually need is a transition
and not an animation
. Also, the link (a
) element is currently below the svg
element in DOM and so it can't be used to alter the styles of the SVG element (or the SVG's children). It needs to be above the SVG element (above means that the link should be a previous sibling of the SVG element or a previous sibling of the SVG's parent).
Another thing is you don't actually need to move from stroke-dashoffset:1600
to -1600
because it will paint the circle and immediately wipe it off. We need it to be stroke-dashoffset:0
when hovering on the link element and go back to original state (stroke-dashoffset: 1600
) on hover out. Transitions will automatially create the reverse effect on hover out and there is no need for separate coding.
Below is a sample snippet.
body,
html {
position: relative;
height: 100%;
}
body {
background-color: #D81D3B;
}
.svg-container {
position: absolute;
top: 50%;
left: 50%;
width: 7em;
height: 7em;
transform: translate3d(-50%, -50%, 0);
}
.svg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
.symbol {
fill: transparent;
stroke: #fff;
stroke-width: 1px;
stroke-dasharray: 1600;
stroke-miterlimit: 10;
stroke-dashoffset: 1600;
transition: all 4s linear;
}
a:hover + .svg-container .symbol {
stroke-dashoffset: 0;
}
<a href="#">Stupid</a>
<div class="svg-container">
<svg width="100" height="100" class="svg">
<circle cx="50" cy="50" r="40" stroke-width="4" class="symbol" />
</svg>
</div>
Making the circle wipe out in the same direction (clockwise) on hover out isn't possible with transitions or plain CSS. It can be achieved with some JS like in the below snippet. When using JS, link element can be anywhere in the document as it doesn't have restrictions like CSS and using animations will be more effective than transitions.
(Note: Very quick hover in and out will break the animation because the script expects one iteration to be completed by the time a hover out happens. Fixing this would be very tricky and complex.)
window.onload = function() {
var link = document.querySelector('a');
var symbol = document.querySelector('.svg-container .symbol');
/* clockwise paint on hover in */
link.addEventListener('mouseover', function() {
symbol.setAttribute('style', 'stroke-dashoffset: 1600; animation: paint 4s linear');
}, false);
/* clockwise wipe on hover out */
link.addEventListener('mouseout', function() {
symbol.setAttribute('style', 'stroke-dashoffset: 0; animation: wipe 4s linear');
}, false);
}
body,
html {
position: relative;
height: 100%;
}
body {
background-color: #D81D3B;
}
.svg-container {
position: absolute;
top: 50%;
left: 50%;
width: 7em;
height: 7em;
transform: translate3d(-50%, -50%, 0);
}
.svg {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
width: 100%;
height: 100%;
}
.symbol {
fill: transparent;
stroke: #fff;
stroke-width: 1px;
stroke-dasharray: 1600;
stroke-miterlimit: 10;
stroke-dashoffset: 1600;
}
@keyframes paint {
to {
stroke-dashoffset: 0;
}
}
@keyframes wipe {
to {
stroke-dashoffset: -1600;
}
}
<div class="svg-container">
<svg width="100" height="100" class="svg">
<circle cx="50" cy="50" r="40" stroke-width="4" class="symbol" />
</svg>
</div>
<a href="#">Stupid</a>
Upvotes: 2