Related
I have an svg animation, I want to be able to stop/pause the animation on click but I can't figure out how and I need help, I tried to toggle but I think I have to toggle each line which I don't know how to.
<div class="loader">
<svg id="wave" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 38.05">
<path id="Line_1" class="t" data-name="Line 1" d="M0.91,15L0.78,15A1,1,0,0,0,0,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H0.91Z"/>
<path id="Line_1" class="t" data-name="Line 2" d="M6.91,9L6.78,9A1,1,0,0,0,6,10V28a1,1,0,1,0,2,0s0,0,0,0V10A1,1,0,0,0,7,9H6.91Z"/>
<path id="Line_1" class="t" data-name="Line 3" d="M12.91,0L12.78,0A1,1,0,0,0,12,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H12.91Z"/>
<path id="Line_1" class="t" data-name="Line 4" d="M18.91,10l-0.12,0A1,1,0,0,0,18,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H18.91Z"/>
<path id="Line_1" class="t" data-name="Line 5" d="M24.91,15l-0.12,0A1,1,0,0,0,24,16v6a1,1,0,0,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H24.91Z"/>
<path id="Line_1" class="t" data-name="Line 6" d="M30.91,10l-0.12,0A1,1,0,0,0,30,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H30.91Z"/>
<path id="Line_1" class="t" data-name="Line 7" d="M36.91,0L36.78,0A1,1,0,0,0,36,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H36.91Z"/>
<path id="Line_1" class="t" data-name="Line 8" d="M42.91,9L42.78,9A1,1,0,0,0,42,10V28a1,1,0,1,0,2,0s0,0,0,0V10a1,1,0,0,0-1-1H42.91Z"/>
<path id="Line_1" class="t" data-name="Line 9" d="M48.91,15l-0.12,0A1,1,0,0,0,48,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H48.91Z"/>
</svg>
</div>
css
.loader {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
#wave {
height: 70px;
width: 70px;
fill: black;
}
#wave.stop {
animation-play-state: paused;
}
#Line_1 {
animation: pulse 1s infinite;
animation-delay: 0.15s;
}
#Line_2 {
animation: pulse 1s infinite;
animation-delay: 0.3s;
}
#Line_3 {
animation: pulse 1s infinite;
animation-delay: 0.45s;
}
#Line_4 {
animation: pulse 1s infinite;
animation-delay: 0.6s;
}
#Line_5 {
animation: pulse 1s infinite;
animation-delay: 0.75s;
}
#Line_6 {
animation: pulse 1s infinite;
animation-delay: 0.9s;
}
#Line_7 {
animation: pulse 1s infinite;
animation-delay: 1.05s;
}
#Line_8 {
animation: pulse 1s infinite;
animation-delay: 1.2s;
}
#Line_9 {
animation: pulse 1s infinite;
animation-delay: 1.35s;
}
js
var vawe = document.getElementById("vawe")
vawe.addEventListener('click',function() {
vawe.classList.toggle('stop');
})
when I click on the svg I want to stop pause the animation, so that the music stop, and then click again the animation starts again.
#wave.stop {
animation-play-state: paused;
}
Doesn't apply the animation-play-state to the actually animated (line) elements.
The css rule should rather look something like this:
#wave.stop .t {
animation-play-state: paused;
}
I also recommend to use class selectors to avoid unnecessarily high specificity
(introduced by id selectors in your css rules).
var wave = document.getElementById("wave")
wave.addEventListener('click', function(e) {
e.currentTarget.classList.toggle('stop');
})
.loader {
display: flex;
align-items: center;
justify-content: center;
height: 100%;
}
#wave {
height: 10em;
fill: black;
}
.stop {
border: 1px solid red;
}
.stop .t {
animation-play-state: paused;
}
.t {
transform-origin: center;
animation: pulse 1s infinite forwards;
transform: scale(1, 0.5)
}
.Line_1 {
animation-delay: 0.15s;
}
.Line_2 {
animation-delay: 0.3s;
}
.Line_3 {
animation-delay: 0.45s;
}
.Line_4 {
animation-delay: 0.6s;
}
.Line_5 {
animation-delay: 0.75s;
}
.Line_6 {
animation-delay: 0.9s;
}
.Line_7 {
animation-delay: 1.05s;
}
.Line_8 {
animation-delay: 1.2s;
}
.Line_9 {
animation-delay: 1.35s;
}
#keyframes pulse {
0% {
transform: scale(1, 0.5)
}
50% {
transform: scale(1, 1)
}
100% {
transform: scale(1, 0.5)
}
}
<div class="loader">
<svg class="wave" id="wave" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 38.05">
<path id="Line_1" class="t Line_1" data-name="Line 1" d="M0.91,15L0.78,15A1,1,0,0,0,0,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H0.91Z"/>
<path id="Line_2" class="t Line_2" data-name="Line 2" d="M6.91,9L6.78,9A1,1,0,0,0,6,10V28a1,1,0,1,0,2,0s0,0,0,0V10A1,1,0,0,0,7,9H6.91Z"/>
<path id="Line_3" class="t Line_3" data-name="Line 3" d="M12.91,0L12.78,0A1,1,0,0,0,12,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H12.91Z"/>
<path id="Line_4" class="t Line_4" data-name="Line 4" d="M18.91,10l-0.12,0A1,1,0,0,0,18,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H18.91Z"/>
<path id="Line_5" class="t Line_5" data-name="Line 5" d="M24.91,15l-0.12,0A1,1,0,0,0,24,16v6a1,1,0,0,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H24.91Z"/>
<path id="Line_6" class="t Line_6" data-name="Line 6" d="M30.91,10l-0.12,0A1,1,0,0,0,30,11V27a1,1,0,1,0,2,0s0,0,0,0V11a1,1,0,0,0-1-1H30.91Z"/>
<path id="Line_7" class="t Line_7" data-name="Line 7" d="M36.91,0L36.78,0A1,1,0,0,0,36,1V37a1,1,0,1,0,2,0s0,0,0,0V1a1,1,0,0,0-1-1H36.91Z"/>
<path id="Line_8" class="t Line_8" data-name="Line 8" d="M42.91,9L42.78,9A1,1,0,0,0,42,10V28a1,1,0,1,0,2,0s0,0,0,0V10a1,1,0,0,0-1-1H42.91Z"/>
<path id="Line_9" class="t Line_9" data-name="Line 9" d="M48.91,15l-0.12,0A1,1,0,0,0,48,16v6a1,1,0,1,0,2,0s0,0,0,0V16a1,1,0,0,0-1-1H48.91Z"/>
</svg>
</div>
Since the delay is required on resume, try this JavaScript alternative. The animation property of the element is individually set or unset depending upon the state.
let el = document.getElementById("vawe")
el.addEventListener('click', (e) => {
let value = 'unset';
if ( e.currentTarget.classList.contains('stop') ) {
e.currentTarget.classList.remove('stop');
value = 'pulse 1s infinite';
} else {
e.currentTarget.classList.add('stop');
}
e.currentTarget.childNodes.forEach(child => {
child.style.setProperty('animation-name', value);
});
});
I have a tough question! I have several SVG graphics on some of my pages which play when the page loads. But because many of them are below the fold, I would like them to start playing (and play once) when they scroll into view.
NOTE: I have searched everywhere for a solution and even hired a freelancer who couldn't make it work. The difference with my SVGs I think is that they use #keyframe and have more than one path that play in sequence which may be why other solutions do not work? The reason for more than one path is that it is a calligraphic arrow shape that overlaps when revealed by the SVG mask.
My HTML for one of the SVGs (inside a DIV to make it responsive):
<div id="arrow-1id" class="arrow-1 leftarrows">
<!--START ARROW 1-->
<svg id="arrow1svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 436.55 256.959">
<mask id="arrow1-mask1" maskUnits="userSpaceOnUse">
<path d="M4.537,54.288
c96.333-80.667,213.667,135.333,90.667,96.333"/>
</mask>
<mask id="arrow1-mask2" maskUnits="userSpaceOnUse">
<path d="M100.87,156.955
c-29.667-100.667,29.666-152,78.333-146.667s151.667,255.667,29.667,234"/>
</mask>
<mask id="arrow1-mask3" maskUnits="userSpaceOnUse">
<path d="M214.87,248.956
c-53.667-43.667,15.334-337.334,195.667-169.667"/>
</mask>
<mask id="arrow1-mask4" maskUnits="userSpaceOnUse">
<path d="M322.203,53.955c108.667,43,117,69.09,68-53.955"/>
</mask>
<path mask="url(#arrow1-mask1)" fill="#42A8FC" d="M98.168,50.639C66.146,29.84,27.535,21.405,0.142,44.781c-1.983,1.692,17.501,16.275,21.915,12.509
c21.17-18.066,49.736-15.119,72.854-0.936c11.126,6.518,19.094,15.658,19.094,15.658c8.426,9.078,14.961,19.84,18.385,31.416
c4.701,15.891,0.705,30.535-10.91,41.153c-0.855,0.782-1.803,1.409-2.783,1.981c-0.01,0.004-6.326,4.56-16.162,2.465l-6.889,7.466
c9.913,8.681,22.827,13.119,36.498,7.999c43.123-16.156,23.759-65.003-14.488-98.967C117.654,65.526,108.286,57.122,98.168,50.639z"/>
<path mask="url(#arrow1-mask2)" fill="#42A8FC" d="M231.959,50.614c-17.516-25.197-43.061-49.605-73.761-50.592c-20.618-0.664-34.757,13.81-44.931,27.774
c-5.189,7.124-10.349,14.789-15.1,22.843l-3.258,5.715C84.467,75.328,76.75,96.273,76.766,117.7
c0.01,13.138,7.45,28.785,18.879,38.794l6.889-7.466c-0.658-1.355-1.329-2.721-1.771-4.061
c-7.573-22.907,0.716-49.699,13.241-72.955l3.65-6.486c7.376-12.557,15.713-23.818,23.057-32.426
c8.87-10.398,23.658-23.112,40.648-19.129c14.01,3.285,24.33,19.391,31.584,30.21c3.548,5.288,7.105,11.241,10.578,17.655
l12.133,25.446c22.227,53.15,32.844,122.106-8.789,151.369c-3.873,2.722-8.496,4.636-12.935,6.029l-3.878,7.245
c25.657,15.113,52.242-6.228,60.439-31.938c14.138-44.338-1.676-101.902-24.266-145.678
C246.227,74.311,238.632,60.523,231.959,50.614z"/>
<path mask="url(#arrow1-mask3)" fill="#42A8FC" d="M406.734,68.147c-17.148-17.841-37.951-33.412-59.953-44.124c-50.594-24.632-88.095-5.991-114.822,26.591
l-8.438,11.223c-3.395,4.914-6.599,10.027-9.592,15.281c-17.29,30.335-29.316,64.641-31.375,100.486
c-1.105,19.22-1.053,44.238,13.145,61.586c4.664,5.7,9.492,9.873,14.354,12.736l3.878-7.245c-3.323-4.796-5.046-11.189-6.378-16.149
c-5.317-19.783-3.871-40.435-0.658-59.469c4.553-26.978,14.076-56.253,28.76-81.78l9.521-14.934
c8.408-11.894,18.098-22.568,29.177-31.183c41.766-32.474,90.141-8.049,122.342,30.429
C404.036,81.622,413.766,75.922,406.734,68.147z"/>
<path mask="url(#arrow1-mask4)" fill="#42A8FC" d="M404.413,71.956c0,0-3.166,0-12.344-3.026c-17.545-5.735-35.092-11.471-52.635-17.206
c-15.207-4.971-15.507,16.587-1.976,21.011c27.503,8.99,55.004,17.981,82.506,26.972c9.534,3.115,13.706-5.336,11.287-12.662
c-8.52-25.797-17.039-51.594-25.558-77.392c-4.546-13.767-25.338-10.047-20.597,4.315c5.671,17.17,11.341,34.342,17.013,51.514
L404.413,71.956z"/>
</svg>
<style>
#arrow1-mask1 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 265.809 265.809;
stroke-dashoffset: 0;
animation: brush1a 2s linear;
animation-fill-mode: forwards;
}
#arrow1-mask2 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 499.444 499.444;
stroke-dashoffset: 0;
animation: brush1b 2s linear;
animation-fill-mode: forwards;
}
#arrow1-mask3 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 396.144 396.144;
stroke-dashoffset: 0;
animation: brush1c 2s linear;
animation-fill-mode: forwards;
}
#arrow1-mask4 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 195.971 195.971;
stroke-dashoffset: 0;
animation: brush1d 2s linear;
animation-fill-mode: forwards;
}
#keyframes brush1a {
0% {
stroke-dashoffset: 265.809;
}
1% {
stroke-dashoffset: 265.809;
}
20% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 0;
}
}
#keyframes brush1b {
0% {
stroke-dashoffset: 499.444;
}
20% {
stroke-dashoffset: 499.444;
}
60% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 0;
}
}
#keyframes brush1c {
0% {
stroke-dashoffset: 396.144;
}
60% {
stroke-dashoffset: 396.144;
}
80% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 0;
}
}
#keyframes brush1d {
0% {
stroke-dashoffset: 195.971;
}
80% {
stroke-dashoffset: 195.971;
}
100% {
stroke-dashoffset: 0;
}
}
</style>
<!--END ARROW 1-->
</div>
I haven't posted any JS because none of the code I have tried works.
You can achieve that by running the animation if the container #arrow-1id as a specific class (lets say .play). Then you just check with javascript when the container appear in the screen. When it's the case, just add the .play class to the container:
var body = document.getElementsByTagName("body")[0];
var div = document.getElementById("arrow-1id");
body.onscroll = function() {
if (document.documentElement.scrollTop >= div.offsetTop - 200) {
div.classList.add("play");
}
};
body {
height: 2000px;
}
#arrow-1id {
margin-top: 400px;
background-color: lightgrey;
}
.play #arrow1-mask1 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 265.809 265.809;
stroke-dashoffset: 0;
animation: brush1a 2s linear;
animation-fill-mode: forwards;
}
.play #arrow1-mask2 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 499.444 499.444;
stroke-dashoffset: 0;
animation: brush1b 2s linear;
animation-fill-mode: forwards;
}
.play #arrow1-mask3 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 396.144 396.144;
stroke-dashoffset: 0;
animation: brush1c 2s linear;
animation-fill-mode: forwards;
}
.play #arrow1-mask4 path {
fill: none;
stroke: white;
stroke-width: 39;
stroke-dasharray: 195.971 195.971;
stroke-dashoffset: 0;
animation: brush1d 2s linear;
animation-fill-mode: forwards;
}
#keyframes brush1a {
0% {
stroke-dashoffset: 265.809;
}
1% {
stroke-dashoffset: 265.809;
}
20% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 0;
}
}
#keyframes brush1b {
0% {
stroke-dashoffset: 499.444;
}
20% {
stroke-dashoffset: 499.444;
}
60% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 0;
}
}
#keyframes brush1c {
0% {
stroke-dashoffset: 396.144;
}
60% {
stroke-dashoffset: 396.144;
}
80% {
stroke-dashoffset: 0;
}
100% {
stroke-dashoffset: 0;
}
}
#keyframes brush1d {
0% {
stroke-dashoffset: 195.971;
}
80% {
stroke-dashoffset: 195.971;
}
100% {
stroke-dashoffset: 0;
}
}
<div id="arrow-1id" class="arrow-1 leftarrows">
<!--START ARROW 1-->
<svg id="arrow1svg" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 436.55 256.959">
<mask id="arrow1-mask1" maskUnits="userSpaceOnUse">
<path d="M4.537,54.288
c96.333-80.667,213.667,135.333,90.667,96.333" />
</mask>
<mask id="arrow1-mask2" maskUnits="userSpaceOnUse">
<path d="M100.87,156.955
c-29.667-100.667,29.666-152,78.333-146.667s151.667,255.667,29.667,234" />
</mask>
<mask id="arrow1-mask3" maskUnits="userSpaceOnUse">
<path d="M214.87,248.956
c-53.667-43.667,15.334-337.334,195.667-169.667" />
</mask>
<mask id="arrow1-mask4" maskUnits="userSpaceOnUse">
<path d="M322.203,53.955c108.667,43,117,69.09,68-53.955" />
</mask>
<path mask="url(#arrow1-mask1)" fill="#42A8FC" d="M98.168,50.639C66.146,29.84,27.535,21.405,0.142,44.781c-1.983,1.692,17.501,16.275,21.915,12.509
c21.17-18.066,49.736-15.119,72.854-0.936c11.126,6.518,19.094,15.658,19.094,15.658c8.426,9.078,14.961,19.84,18.385,31.416
c4.701,15.891,0.705,30.535-10.91,41.153c-0.855,0.782-1.803,1.409-2.783,1.981c-0.01,0.004-6.326,4.56-16.162,2.465l-6.889,7.466
c9.913,8.681,22.827,13.119,36.498,7.999c43.123-16.156,23.759-65.003-14.488-98.967C117.654,65.526,108.286,57.122,98.168,50.639z" />
<path mask="url(#arrow1-mask2)" fill="#42A8FC" d="M231.959,50.614c-17.516-25.197-43.061-49.605-73.761-50.592c-20.618-0.664-34.757,13.81-44.931,27.774
c-5.189,7.124-10.349,14.789-15.1,22.843l-3.258,5.715C84.467,75.328,76.75,96.273,76.766,117.7
c0.01,13.138,7.45,28.785,18.879,38.794l6.889-7.466c-0.658-1.355-1.329-2.721-1.771-4.061
c-7.573-22.907,0.716-49.699,13.241-72.955l3.65-6.486c7.376-12.557,15.713-23.818,23.057-32.426
c8.87-10.398,23.658-23.112,40.648-19.129c14.01,3.285,24.33,19.391,31.584,30.21c3.548,5.288,7.105,11.241,10.578,17.655
l12.133,25.446c22.227,53.15,32.844,122.106-8.789,151.369c-3.873,2.722-8.496,4.636-12.935,6.029l-3.878,7.245
c25.657,15.113,52.242-6.228,60.439-31.938c14.138-44.338-1.676-101.902-24.266-145.678
C246.227,74.311,238.632,60.523,231.959,50.614z" />
<path mask="url(#arrow1-mask3)" fill="#42A8FC" d="M406.734,68.147c-17.148-17.841-37.951-33.412-59.953-44.124c-50.594-24.632-88.095-5.991-114.822,26.591
l-8.438,11.223c-3.395,4.914-6.599,10.027-9.592,15.281c-17.29,30.335-29.316,64.641-31.375,100.486
c-1.105,19.22-1.053,44.238,13.145,61.586c4.664,5.7,9.492,9.873,14.354,12.736l3.878-7.245c-3.323-4.796-5.046-11.189-6.378-16.149
c-5.317-19.783-3.871-40.435-0.658-59.469c4.553-26.978,14.076-56.253,28.76-81.78l9.521-14.934
c8.408-11.894,18.098-22.568,29.177-31.183c41.766-32.474,90.141-8.049,122.342,30.429
C404.036,81.622,413.766,75.922,406.734,68.147z" />
<path mask="url(#arrow1-mask4)" fill="#42A8FC" d="M404.413,71.956c0,0-3.166,0-12.344-3.026c-17.545-5.735-35.092-11.471-52.635-17.206
c-15.207-4.971-15.507,16.587-1.976,21.011c27.503,8.99,55.004,17.981,82.506,26.972c9.534,3.115,13.706-5.336,11.287-12.662
c-8.52-25.797-17.039-51.594-25.558-77.392c-4.546-13.767-25.338-10.047-20.597,4.315c5.671,17.17,11.341,34.342,17.013,51.514
L404.413,71.956z" />
</svg>
<!--END ARROW 1-->
</div>
I tried this and it works but it seems only supported in Firefox, no other browser???
<script type="text/javascript">
var diva2 = document.getElementById("arrow-2id");
window.addEventListener("scroll", function() {
if (document.documentElement.scrollTop >= diva2.offsetTop - -500) {
diva2.classList.add("play");
}
}
);
</script>
I have an SVG circle, it has a small svg circle inside it and a polygon inside the small circle, when i click on the polygon it should rotate and it's working fine, but after rotation a tool-tip should appear above the polygon and i don't know how to show it, i put it in a div above my svg, here is my code:
document.querySelector('polygon').addEventListener('click', function() {
this.classList.toggle('rotated');
});
.rotated {
transform: rotate(-90deg);
}
polygon {
transition: all 1s;
}
<div class="marker marker-index-0" style="display: none;">
<h3>I should be a tooltip</h3>
</div>
<svg>
<circle cx="40" cy="122.5" r="26" fill="red"></circle>
<g class="markerG" transform="matrix(1,0,0,1,40,122.5)"><circle cx="0" cy="0" r="14" fill="#000000" style="cursor: pointer;"></circle><polygon points="1 -1 1 -7 -1 -7 -1 -1 -7 -1 -7 1 -1 1 -1 7 1 7 1 1 7 1 7 -1" fill="#ffffff"></polygon></g>
</svg>
Looks to me like you never specified to show the tool-tip ;)
document.querySelector('svg').addEventListener('click', function() {
document.querySelector('polygon').classList.toggle('rotated');
document.getElementById('marker').classList.toggle('show');
});
.rotated {
transform: rotate(-90deg);
}
polygon {
transition: all 1s;
}
.show {
display: block !important;
}
<div class="marker marker-index-0" id="marker" style="display: none;">
<h3>I should be a tooltip</h3>
</div>
<svg>
<circle cx="40" cy="122.5" r="26" fill="red"></circle>
<g class="markerG" transform="matrix(1,0,0,1,40,122.5)"><circle cx="0" cy="0" r="14" fill="#000000" style="cursor: pointer;"></circle><polygon points="1 -1 1 -7 -1 -7 -1 -1 -7 -1 -7 1 -1 1 -1 7 1 7 1 1 7 1 7 -1" fill="#ffffff"></polygon></g>
</svg>
Hope this helps!
A transition alone won't do it, because you can't do anything after it's done.
Instead, it would be a good time for you to learn CSS Animations.
Note that I applied the classes to a container involving both the polygon and the tooltip, in order to avoid synchronization errors.
document.querySelector('polygon').addEventListener('click', function() {
if(!document.getElementById('animationContainer').classList.contains("animated")) {
document.getElementById('animationContainer').classList.add("animated");
document.getElementById('animationContainer').classList.add("rotated");
} elseĀ {
document.getElementById('animationContainer').classList.toggle('rotated');
document.getElementById('animationContainer').classList.toggle('faded');
}
});
#keyframes polygonAnimation {
0% { transform: rotate(0deg); }
50% { transform: rotate(-90deg); }
100% { transform: rotate(-90deg); }
}
#keyframes polygonReverseAnimation {
0% { transform: rotate(-90deg); }
50% { transform: rotate(0deg); }
100% { transform: rotate(0deg); }
}
#keyframes markerAnimation {
0% { display: none; opacity: 0; }
50% { display: block; opacity: 0; }
100% { display: block; opacity: 1; }
}
#keyframes markerReverseAnimation {
0% { display: block; opacity: 1; }
50% { display: block; opacity: 0; }
100% { display: none; opacity: 0; }
}
#animationContainer .marker {
opacity: 0;
position: absolute;
z-index: 10;
}
.rotated polygon {
animation-name: polygonAnimation;
animation-duration: 2s;
animation-fill-mode: both;
}
.rotated .marker {
animation-name: markerAnimation;
animation-duration: 2s;
animation-fill-mode: both;
}
.faded polygon {
animation-name: polygonReverseAnimation;
animation-duration: 2s;
animation-fill-mode: both;
}
.faded .marker {
animation-name: markerReverseAnimation;
animation-duration: 2s;
animation-fill-mode: both;
}
<div id="animationContainer">
<div class="marker marker-index-0">
<h3>I should be a tooltip</h3>
</div>
<svg>
<circle cx="40" cy="122.5" r="26" fill="red"></circle>
<g class="markerG" transform="matrix(1,0,0,1,40,122.5)"><circle cx="0" cy="0" r="14" fill="#000000" style="cursor: pointer;"></circle><polygon points="1 -1 1 -7 -1 -7 -1 -1 -7 -1 -7 1 -1 1 -1 7 1 7 1 1 7 1 7 -1" fill="#ffffff"></polygon></g>
</svg>
</div>
Just add the following to your event listener that rotates the svg. The rest is just css.
$('.marker-index-0').show();
Btw you have cursor pointer on the inner circle, but it only works on clicking the polygon. That's not intuitive design.
I am trying to animate a text that I created and saved as SVG. So far, I've only been able to animate the stroke, but that's not what I am trying to achieve. How can I implement animation like the two examples, below?
http://codepen.io/se7ensky/pen/waoMyx
https://codepen.io/munkholm/pen/EaZJQE
Here is what I have so far:
.test {
width: 300px
/* margin:0 auto; */
}
.l1 {
animation: dash 15s 1;
stroke-linecap: round;
stroke-miterlimit: 10;
stroke-dasharray: 300;
stroke-dashoffset: 300;
animation-fill-mode: forwards;
/*fill: none;*/
}
.l2 {
stroke-dasharray: 300;
stroke-dashoffset: 300;
animation: dash 20s linear forwards;
-webkit-animation-delay: 1s;
/* Chrome, Safari, Opera */
animation-delay: 1s;
}
.l3 {
stroke-dasharray: 300;
stroke-dashoffset: 300;
animation: dash 25s linear forwards;
-webkit-animation-delay: 2.5s;
/* Chrome, Safari, Opera */
animation-delay: 2.5s;
}
.l4 {
stroke-dasharray: 300;
stroke-dashoffset: 300;
animation: dash 25s linear forwards;
-webkit-animation-delay: 4.5s;
/* Chrome, Safari, Opera */
animation-delay: 4.5s;
}
#keyframes dash {
to {
stroke-dashoffset: 0;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 19.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg class="test" 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 30.1 21.8" style="enable-background:new 0 0 30.1 21.8;" xml:space="preserve">
<g>
<path class="text l1" d="M16.5,9.2c-0.2-0.2-0.2-1,0.1-1.5c0.1-0.1,0.2-0.3,0.3-0.4c-1.6,0-3.2-0.3-4.7-0.1C10.8,7.3,9.5,8,9.3,8.9
c-0.1,0.6,0.5,0.8,0.7,1c0.1,0.1,0,0.2-0.1,0.1C9.5,10,8.7,9.4,9,8.7c0,0,0-0.1,0-0.2c0.3-1.2,1.7-1.8,3.3-1.9
c1.8-0.1,3.9,0.4,4.8,0.4c0.2-0.2,0.4-0.4,0.5-0.4c0.3-0.1,0.6,0.1,0.3,0.4c-0.1,0.1-0.4,0.3-0.6,0.5c-0.4,0.4-0.8,1-0.5,1.5
C16.8,9.2,16.7,9.3,16.5,9.2z M12.1,12.8c0.1,0.1-0.1,0.3-0.1,0.3c-0.2,0.3-0.5,0.8-0.8,0.8c-0.1,0-0.5-0.1-0.5-0.1
c-0.1-0.8,1.5-3.5,1.9-4.2c0.2-0.3,0.1-0.4,0.1-0.5c0.1-0.4,0.9-1.4,1.5-1.4c0.2,0,0.8,0.2,0.7,0.5c0,0-0.1-0.1-0.2-0.1
c-1.1,0-2.9,3.6-3.4,4.7c-0.3,0.7,0.1,0.6,0.4,0.3C11.8,13,12,12.8,12.1,12.8z" fill="red" stroke="#000" stroke-miterlimit="10" stroke-width="0.5" />
<path class="text l2" d="M14.4,12.3c-0.2,0-0.3-0.2-0.1-0.2c0.4,0,1.1-0.4,1.5-0.8c0.2-0.2,0.6-0.5,0.5-0.8c0-0.3-0.4-0.2-0.6-0.1
c-0.7,0.3-1.7,1.3-2,2.2c-0.3,1,0.6,1,1.4,0.7c0.9-0.4,1.7-1,2.1-1.7c0-0.1,0.1-0.1,0.1,0c0.1,0,0.1,0.1,0,0.1
c-0.5,0.8-1.2,1.5-2.1,1.8c-1.2,0.5-2.8,0-2.1-1.5c0.4-0.8,2.2-2.4,3.1-2.1c0.5,0.2,0.4,0.8,0.2,1.1C16.1,11.8,15,12.2,14.4,12.3z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"
/>
<path class="text l3" d="M17.3,13.6c-0.2,0.2-0.1,0.5,0.4,0.4c0.6-0.2,1.5-0.9,1.5-1.6c0-0.3-0.7-0.6-0.9-0.7c-0.2-0.1-0.3-0.3-0.4-0.4
c-0.1,0.2-0.3,0.5-0.5,0.8c-0.1,0.1-0.3,0-0.2-0.1c0.3-0.5,0.6-0.9,0.6-1.1c0.1-0.9,1.7-1.7,2.6-1.7c0.5,0,1,0.3,0.7,0.8
c-0.1,0.2-0.2,0.3-0.4,0.4c-0.1,0-0.2,0-0.1-0.2c0.2-0.2,0.3-0.6,0-0.6c-0.4,0-1,0.2-1.3,0.4c-0.4,0.2-0.7,0.4-1,0.9
c-0.3,0.3-0.2,0.6,0.1,0.8c0.8,0.5,1.8,0.8,0.9,1.8c-0.4,0.5-1.1,0.7-1.7,0.9c-0.2,0-0.7,0.1-0.9-0.1c-0.1-0.1,0-0.3,0.2-0.5
c0.1-0.1,0.3-0.3,0.6-0.3c0.1,0,0.1,0.1,0,0.1C17.5,13.4,17.3,13.5,17.3,13.6z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"/>
<path class="text l4" d="M23.6,10.2c-0.2,0.1-0.8,0.1-1.4,0.2c-0.2,0.3-0.3,0.5-0.3,0.6c-0.4,0.7-0.7,1.4-0.7,1.7c-0.1,0.5,0.2,0.8,0.6,0.6
c0.4-0.2,1.3-1,1.8-1.7c0.1-0.1,0.2,0,0.1,0.1c-0.2,0.4-1,1.2-1.6,1.6c-0.4,0.3-1.3,0.6-1.5-0.1c-0.1-0.3,0.1-0.9,0.4-1.5
c-0.1,0.1-0.2,0.3-0.5,0.6c-0.1,0.1-0.2,0-0.1-0.2c0.4-0.5,0.7-1,0.9-1.2c0,0,0.1-0.2,0.3-0.5c-0.1,0-0.2,0-0.3,0
c-0.1,0-0.2-0.1-0.2-0.3c0.1-0.2,0.4-0.2,0.6-0.2c0,0,0,0,0,0l0.6-1.1c0.3-0.5,0.3-0.6,0.5-0.7c0.2,0,0.4,0,0.5,0.1
c0.1,0.1,0,0.4-0.1,0.5C23.2,9,23.1,9,23,9.1l-0.6,1l0.2,0c0.4,0,0.7-0.1,1.1-0.1C23.9,10,24.1,10.1,23.6,10.2z" fill="none" stroke="#000" stroke-miterlimit="5" stroke-width="0.5"/>
</g>
<g></g>
<g></g>
<g></g>
<g></g>
<g></g>
<g></g>
</svg>
View on CodePen
How the Se7ensky animation works is that it uses the standard dash animation technique, but clips the animated stroke with an outline representing the hand-drawn look of the logo.
So the standard dash animation technique works as follows. You take a standard line:
<svg>
<path d="M 10,75 L 290,75" stroke="red" stroke-width="50"/>
</svg>
Then you add a dash pattern to it and animate it's position (stroke-dashoffset).
.pen {
stroke-dasharray: 280 280;
stroke-dashoffset: 280;
animation-duration: 2s;
animation-name: draw;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: linear;
}
#keyframes draw {
from {
stroke-dashoffset: 280;
}
to {
stroke-dashoffset: 0;
}
}
<svg>
<path class="pen" d="M 10,75 L 290,75" stroke="red" stroke-width="50"/>
</svg>
Finally to get the fancy variable stroke width of the Se7ensky example, you clip that line with the outline of your logo.
So let's pretend this simple path below represents your logo:
<svg>
<path stroke="black" stroke-width="1" fill="lightgrey"
d="M 40,50
C 110,55 195,60, 265,55
C 290,55 290,85 265,85
C 195,85 110,85 40,100
C 0,100 0,50 40,50 Z"/>
</svg>
We turn that into a clipPath element and use it to trim our animated stroke to the shape of our logo:
.pen {
stroke-dasharray: 280 280;
stroke-dashoffset: 280;
animation-duration: 2s;
animation-name: draw;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: linear;
}
#keyframes draw {
from {
stroke-dashoffset: 280;
}
to {
stroke-dashoffset: 0;
}
}
<svg>
<clipPath id="logo">
<path d="M 40,50
C 110,55 195,60, 265,55
C 290,55 290,85 265,85
C 195,85 110,85 40,100
C 0,100 0,50 40,50 Z"/>
</clipPath>
<path class="pen" d="M 10,75 L 290,75" stroke="red" stroke-width="50" clip-path="url(#logo)"/>
</svg>
So to replicate their example, you'll need to add a continuous path (or paths if you want) to your SVG that represents the path that a pen would take if it were writing the letters in your logo.
Then animate that path using the dashoffset technique while clipping it with your original logo.
Update
Here's a final demo with a more realistic letter shape:
// Simple code to enable and disable the clipping path
var chk = document.getElementById("chk");
var penpath = document.getElementById("penpath");
chk.addEventListener("input", function(evt) {
if (evt.target.checked) {
penpath.classList.add("clipped");
} else {
penpath.classList.remove("clipped");
}
});
.pen {
fill: none;
stroke: red;
stroke-width: 18;
stroke-linecap: round;
stroke-dasharray: 206 206;
stroke-dashoffset: 206;
animation-duration: 2s;
animation-name: draw;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: linear;
}
.clipped {
clip-path: url(#logo);
}
#keyframes draw {
from {
stroke-dashoffset: 206;
}
to {
stroke-dashoffset: 0;
}
}
<svg>
<defs>
<clipPath id="logo">
<path d="m85.77 49.77c-10.59 8.017-27.38 21.95-41.58 21.95-6.396 0-12.99-2.481-12.39-9.735l0.3998-4.199c38.38-12.03 48.17-26.15 48.17-35.5 0-7.635-7.995-9.162-14.39-9.162-25.98-0.1909-54.97 25.39-54.17 50.39 0.3998 12.6 7.196 25.01 21.79 25.01 19.79 0 41.78-17.94 53.97-31.5zm-52.37-1.336c5.397-12.6 16.99-21.76 26.98-24.24 1.399-0.3818 2.399 0.7635 2.399 2.1 0.1999 3.245-11.79 16.42-29.38 22.14z"/>
</clipPath>
</defs>
<path id="penpath" d="m39.02 51.1c5.361-1.771 10.04-4.182 15.98-7.857 6.019-3.933 9.841-7.728 12.77-10.71 1.403-1.369 12.03-15.97-7.857-13.93-9.824 1.01-19.62 8.3-26.16 14.91-6.538 6.61-10.42 14.51-11.96 22.23-2.559 12.76 1.807 26.19 21.07 23.48 13.96-1.965 32.59-14.55 43.66-25.54" class="pen clipped"/>
</svg>
<p>
<input id="chk" type="checkbox" checked="true"/> <label for="chk">Enable clipping path</label>
</p>
The example looks like a combination of svg paths and delayed animations.
This blog post by CSS-Tricks explains it pretty well (Note that the svg must have strokes for this to work):
https://css-tricks.com/svg-line-animation-works/
Here's a guide on stroke-dashoffset (used on the example) that might be useful:
https://css-tricks.com/almanac/properties/s/stroke-dashoffset/
https://jsfiddle.net/u1sqa210/
I want to make a spinner that will draw in clockwise, rotate 2 full cycles at a faster rate than the draw in, then draw out counter clockwise. I have it pretty close, but I am not sure how to coordinate the rotation with the drawing animations. I usually end up with it rotation not enough, or during the draw out animation, which is not what I want.
$spinnerSize: 100;
svg.spinner {
width: $spinnerSize + px;
height: $spinnerSize + px;
x: 100px;
y: 100px;
viewBox: 0 0 $spinnerSize $spinnerSize;
circle {
fill: transparent;
stroke-width: 12;
stroke-dasharray: (3.14 * $spinnerSize);
transform-origin: (0.5px * $spinnerSize) (0.5px * $spinnerSize) 0;
animation:
spinner 3s linear infinite,
rotation 3s linear infinite;
transform: ScaleX(-1) rotate(270deg);
}
}
#keyframes spinner {
0% { stroke-dashoffset: 350; }
10% { stroke-dashoffset: 630; }
30% { stroke-dashoffset: 630; }
100% { stroke-dashoffset: 1000; }
}
#keyframes rotation
{
0% {transform: rotate(270deg)}
10% {transform: rotate(270deg)}
15% {transform: rotate(300deg)}
30% {transform: rotate(270deg)}
100% {transform: rotate(360deg);}
}
<svg class="spinner" stroke="url(#linear)">
<circle cx="50" cy="50" r="40"></circle>
<defs>
<linearGradient id="linear" x1="0%" y1="0%" x2="100%" y2="0%">
<stop offset="0%" stop-color="rgba(231,60,99,1)"/>
<stop offset="100%" stop-color="rgba(150,77,135,1)"/>
</linearGradient>
</defs>
</svg>
I think this is what you're technically asking for. I combined two animations into one:
#keyframes spinner {
0% { stroke-dashoffset: 350; transform: rotate(270deg) }
25% { stroke-dashoffset: 630; transform: rotate(270deg)}
50% { stroke-dashoffset: 630; transform: rotate(990deg)}
75% { stroke-dashoffset: 630; transform: rotate(990deg)}
100% { stroke-dashoffset: 1000; transform: rotate(990deg)}
}
https://jsfiddle.net/ocs3dkrm/