svg gradient fill animation percentage jquery - javascript

I'm trying to get some svg animation with jquery, for each class "check" i need summs percentage offset for gradient, and when this class is remove need reduce percentage offset gradient. This all need animation down up when class added, and up down when class removed.
So i got, gradient and get offset to 5% percentage. Trying to get array but stuck. Think about get all elements with class "check" and try to summs for each class.
var firstStop = document.getElementById('F1gst1');
percentage = '5%'; firstStop.setAttribute('offset',percentage);
$(".analysis-li").click(function(){
$(this).toggleClass("check");
if($(this).hasClass('check')){
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li class="analysis-li"></li>
<li class="analysis-li"></li>
<li class="analysis-li"></li>
<li class="list analysis-li"></li>
<li class="analysis-li"></li>
<li class="list analysis-li"></li>
<li class="analysis-li" ></li>
<svg class="thermometr" id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44.3 333.8">
<linearGradient y2="0%" x2="0%" y1="100%" x1="0%" id="F1g"><stop stop-color="#00FF00" offset="0%" id="F1gst1"/><stop stop-color="#FFFFFF" offset="0%" id="F1gst2"/></linearGradient>
<path fill="url(#F1g)" class="st0" d="M30.5 297.5V4.6c0-2.5-2.1-4.6-4.6-4.6-2.5 0-4.6 2.1-4.6 4.6v292.9c-7.9 2-13.8 9.2-13.8 17.8 0 10.2 8.2 18.4 18.4 18.4s18.4-8.2 18.4-18.4c0-8.5-5.9-15.7-13.8-17.8"/><path fill="url(#F1g)" class="st0" d="M9 290.2h7.5v.5H9zM9 284.3h7.5v.6H9zM9 278.4h7.5v.5H9zM9 272.5h7.5v.6H9zM0 266.6h16.5v.6H0zM9 260.7h7.5v.5H9zM9 254.8h7.5v.6H9zM9 248.9h7.5v.5H9zM9 243h7.5v.6H9zM0 237.1h16.5v.6H0zM9 231.3h7.5v.5H9zM9 225.4h7.5v.6H9zM9 219.5h7.5v.6H9zM9 213.6h7.5v.6H9zM0 207.7h16.5v.6H0zM9 201.8h7.5v.6H9zM9 195.9h7.5v.6H9zM9 190h7.5v.6H9zM9 184.1h7.5v.5H9zM0 178.2h16.5v.6H0zM9 172.3h7.5v.6H9zM9 166.4h7.5v.5H9zM9 160.5h7.5v.6H9zM9 154.7h7.5v.6H9zM0 148.8h16.5v.6H0zM9 142.9h7.5v.6H9zM9 137h7.5v.5H9zM9 131.1h7.5v.5H9zM9 125.2h7.5v.6H9zM0 119.3h16.5v.5H0zM9 113.4h7.5v.6H9zM9 107.5h7.5v.6H9zM9 101.6h7.5v.5H9zM9 95.7h7.5v.6H9zM0 89.8h16.5v.6H0zM9 83.9h7.5v.6H9zM9 78.1h7.5v.6H9zM9 72.2h7.5v.6H9zM9 66.3h7.5v.6H9zM0 60.4h16.5v.6H0zM9 54.8h7.5v.6H9zM9 48.9h7.5v.6H9zM9 43h7.5v.5H9zM9 37.1h7.5v.6H9zM0 31.2h16.5v.5H0zM9 26h7.5v.6H9zM9 20.1h7.5v.5H9zM9 14.2h7.5v.6H9zM9 8.3h7.5v.6H9zM0 2.4h16.5V3H0z"/>
</svg>

This is how I would do it. In order to animate the gradient I'm using requestAnimationFrame. I'm animating the second stop offset between 10% and 100% but you can choose the values you want.
Please read the comments in the code.
// the second stop
let laststop = document.getElementById('F1gst2');
// a variable used to toggle the animation
let n = 0;
// the target value of the offset attribute
let target;
// the actual value of the offset attribute
let val = 10;
//the request animation frame id
let rid = null;
$(".analysis-li").click(function(){
n++;
// set the target value
if(n%2 == 1){
target = 100;
}else{target = 10}
// if there is an animation stop it
if(rid){cancelAnimationFrame(rid); rid="null"}
// call the frame function
frame()
});
function frame(){
rid = requestAnimationFrame(frame);
//the distance between the value and the target value
dist = target - val;
//increase the value
val += dist/10;
// set the offset value
laststop.setAttributeNS(null,"offset",`${val}%`)
}
svg{border:1px solid; width:30px}
path{stroke:black;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p class="analysis-li">click here</p>
<svg class="thermometr" id="Layer_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 44.3 333.8" >
<linearGradient y2="0%" x2="0%" y1="100%" x1="0%" id="F1g">
<stop stop-color="#00FF00" offset="0%" id="F1gst1"/>
<stop stop-color="#FFFFFF" offset="10%" id="F1gst2"/>
</linearGradient>
<path fill="url(#F1g)" class="st0" d="M30.5 297.5V4.6c0-2.5-2.1-4.6-4.6-4.6-2.5 0-4.6 2.1-4.6 4.6v292.9c-7.9 2-13.8 9.2-13.8 17.8 0 10.2 8.2 18.4 18.4 18.4s18.4-8.2 18.4-18.4c0-8.5-5.9-15.7-13.8-17.8"/>
<path fill="url(#F1g)" class="st0" d="M9 290.2h7.5v.5H9zM9 284.3h7.5v.6H9zM9 278.4h7.5v.5H9zM9 272.5h7.5v.6H9zM0 266.6h16.5v.6H0zM9 260.7h7.5v.5H9zM9 254.8h7.5v.6H9zM9 248.9h7.5v.5H9zM9 243h7.5v.6H9zM0 237.1h16.5v.6H0zM9 231.3h7.5v.5H9zM9 225.4h7.5v.6H9zM9 219.5h7.5v.6H9zM9 213.6h7.5v.6H9zM0 207.7h16.5v.6H0zM9 201.8h7.5v.6H9zM9 195.9h7.5v.6H9zM9 190h7.5v.6H9zM9 184.1h7.5v.5H9zM0 178.2h16.5v.6H0zM9 172.3h7.5v.6H9zM9 166.4h7.5v.5H9zM9 160.5h7.5v.6H9zM9 154.7h7.5v.6H9zM0 148.8h16.5v.6H0zM9 142.9h7.5v.6H9zM9 137h7.5v.5H9zM9 131.1h7.5v.5H9zM9 125.2h7.5v.6H9zM0 119.3h16.5v.5H0zM9 113.4h7.5v.6H9zM9 107.5h7.5v.6H9zM9 101.6h7.5v.5H9zM9 95.7h7.5v.6H9zM0 89.8h16.5v.6H0zM9 83.9h7.5v.6H9zM9 78.1h7.5v.6H9zM9 72.2h7.5v.6H9zM9 66.3h7.5v.6H9zM0 60.4h16.5v.6H0zM9 54.8h7.5v.6H9zM9 48.9h7.5v.6H9zM9 43h7.5v.5H9zM9 37.1h7.5v.6H9zM0 31.2h16.5v.5H0zM9 26h7.5v.6H9zM9 20.1h7.5v.5H9zM9 14.2h7.5v.6H9zM9 8.3h7.5v.6H9zM0 2.4h16.5V3H0z"/>
</svg>

SVG created programmicaly, only one shape is translated by incoming value:
let path = (y, d, extra) => `<path d="${d}" transform="translate(0,${y})" ${extra||''}></path>`
let multi = (count, html) => Array(count).fill(0).map((e, i) => html(i)).join('');
let toggle = el => el.classList.toggle('on') |
rect.setAttribute('y', 14.6*(7-document.querySelectorAll("path.on").length)+8)
scale.innerHTML = multi(10, i => path(i*10, 'M60,10h10M65,12h5M65,14h5M65,16h5M65,18h5'));
checks.innerHTML = multi(7, i => path(i*12, 'M10,10v8h8v-8z', 'class="on" onclick="toggle(this)"') +
path(i*12, 'M12,14l2.2,2l2.2,-4'))
g#scale path {
stroke: white;
stroke-width: 0.7;
}
#checks {
position: absolute;
top: 20px;
left: 20px;
}
#checks path {
fill: none;
pointer-events: all;
stroke: #f5b53a;
cursor:pointer;
stroke-linejoin:round;
}
#checks path.on + path {
opacity:1;
}
#checks path:nth-child(2n) {
opacity: 0;
pointer-events: none;
transition: 0.5s;
stroke: white;
}
<svg viewbox="0 0 135 135" height="90vh" style="background-color:purple">
<defs><mask id="termometer">
<path d="M80,10v100" stroke="white" stroke-width="5" stroke-linecap="round"></path>
<circle r="10" cy="120" cx="80" fill="white"></circle>
<g id="scale"></g>
</mask></defs>
<rect width="130" height="130" mask="url(#termometer)" fill="white"></rect>
<rect id="rect" style="transition:1s" y="8" width="130" height="130"
mask="url(#termometer)" fill="#f5b53a"></rect>
<g id="checks"></g>
</svg>

Related

SVG - Obtaining ordered list of IDs that appear under mouse/touch hove/click/tap in an SVG

I am trying to extract all layer/group ID names and metadata from the top layer as well as all layers underneath it.
Desired result: Get a list of IDs and Group IDs from an SVG.
In example SVG would see, if hovering over the center of the image, something like this:
Poly 1
Star
Group Begin: Bright Shapes
Group Begin: Gradient Shapes
Gradient Poly Small
Gradient Poly Large
Gradient Star
End Group: Gradient Shapes
Pink Ellipse
Green Square
End Group: Bright Shapes
Ellipse 2
I've also looked at CSS pointer-events.. but that seems limited to extracting from 1 layer.
Modified from: Determine which element the mouse pointer is on top of in Javascript
http://jsfiddle.net/coq4eg0d/1/
setInterval(function(){
var element = $(':hover');
if(element.length)
{
var domElement = element[element.length - 1];
var tagName = domElement.tagName;
var id = domElement.id ? ' id="' + domElement.id + '"' : "";
document.getElementById('test').innerHTML =
"hover: <" + tagName.toLowerCase() + id + ">";
}
}, 100);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="test"></div>
<svg version="1.1" id="Shapes" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 368 373" style="enable-background:new 0 0 368 373;" xml:space="preserve">
<style type="text/css">
.st0{stroke:#FFFFFF;stroke-miterlimit:10;}
.st1{fill:#4BB749;stroke:#1F451F;stroke-miterlimit:10;}
.st2{fill:#CB3694;stroke:#FFFFFF;stroke-miterlimit:10;}
.st3{fill:url(#Gradient_Star_1_);stroke:#FFFFFF;stroke-miterlimit:10;}
.st4{fill:url(#Gradient_Poly_Large_1_);stroke:#FFFFFF;stroke-miterlimit:10;}
.st5{fill:url(#Gradient_Poly_Small_1_);stroke:#FFFFFF;stroke-miterlimit:10;}
</style>
<ellipse id="Ellipse_2" class="st0" cx="261" cy="212" rx="94" ry="79"/>
<g id="Bright_Shapes">
<rect id="Green_Square" x="98" y="161.22" class="st1" width="184" height="174.5"/>
<ellipse id="Pink_Ellipse" class="st2" cx="115.59" cy="268.59" rx="94" ry="79"/>
<g id="Gradient_Shapes">
<radialGradient id="Gradient_Star_1_" cx="115.5932" cy="189.5899" r="147.9309" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#1C75BC"/>
</radialGradient>
<polygon id="Gradient_Star" class="st3" points="109.37,335.15 68.3,238.41 -34.67,217.41 44.63,148.46 32.79,44.03 122.87,98.15
218.53,54.61 194.9,157.01 265.86,234.53 161.17,243.7 "/>
<radialGradient id="Gradient_Poly_Large_1_" cx="167" cy="171" r="88.1134" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#1C75BC"/>
</radialGradient>
<polygon id="Gradient_Poly_Large" class="st4" points="234,233 146.81,260.02 79.81,198.02 100,109 187.19,81.98 254.19,143.98
"/>
<radialGradient id="Gradient_Poly_Small_1_" cx="209.5932" cy="248.4668" r="30.3834" gradientUnits="userSpaceOnUse">
<stop offset="0" style="stop-color:#FFFFFF"/>
<stop offset="1" style="stop-color:#1C75BC"/>
</radialGradient>
<polygon id="Gradient_Poly_Small" class="st5" points="236.59,265.88 208.02,280.55 181.02,263.14 182.59,231.06 211.17,216.38
238.17,233.79 "/>
</g>
</g>
<g id="Pointed_Dark_Shapes">
<polygon id="Star" class="st0" points="249,229 142.84,198.45 57.49,268.59 53.74,158.19 -39.34,98.69 64.5,61 92.32,-45.91
160.25,41.21 270.53,34.63 208.67,126.16 "/>
<polygon id="Poly1" class="st0" points="220,251 124.55,266.33 63.55,191.33 98,101 193.45,85.67 254.45,160.67 "/>
</g>
</svg>
One way to find all elements at a location is to call elementFromPoint() to find the topmost element, and then use the fact that..
Elements with pointer-events set to none will be ignored, and the element below it will be returned.
So, once you've found an element, set its pointer-events: none and then call elementFromPoint() again to find the next element. Repeat until you reach the main SVG element:
function hitTest(e) {
const x = e.clientX,
y = e.clientY,
elms = [];
let elm;
while(true) {
elm = document.elementFromPoint(x, y);
if(!svg.contains(elm)) {
break;
}
elms.push(elm);
//Hide the element from the next round of `elementFromPoint()`:
elm.style.pointerEvents = 'none';
}
output.textContent = elms.map(printElement).join(' ');
//Cleanup:
elms.forEach(elm => elm.style.pointerEvents = '');
}
http://jsfiddle.net/r9k1bgnu/

CSS3 - Animate SVG if visible in viewport (Page Scroll)

I have been pulling my hair out trying to get this to work. Such a challenge.
The goal is to start the css animation when the object is visible, when it scrolls into view, and not before.
Using Javascript from here.
To make things easy, I have a code pen: https://codepen.io/studiotwofold/pen/dyYJWrV
Any ideas on how to fix this?
HTML:
<div class="icon-container" style="width:100px;">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 44 44" style="enable-background:new 0 0 44 44;" xml:space="preserve">
<defs>
<linearGradient id="icon-gradient" gradientUnits="userSpaceOnUse">
<stop offset="0%" style="stop-color:#E21C79"/>
<stop offset="100%" style="stop-color:#FC4C02"/>
</linearGradient>
</defs>
<g class="stf-icon">
<line x1="26" y1="29" x2="32" y2="29"/>
<path d="M29,25h-3l-0.2-0.5c-0.5-1.6-1.5-3.1-2.7-4.4l0,0c-3.3-3.3-3.2-8.8,0.3-12l0,0c3.2-2.9,8-2.9,11.2,0l0,0
c3.5,3.2,3.6,8.6,0.3,12l0,0c-1.2,1.2-2.2,2.7-2.7,4.4L32,25"/>
<line x1="29" y1="3" x2="29" y2="1"/>
<line x1="19.8" y1="7.3" x2="18.3" y2="6"/>
<line x1="23.9" y1="4.1" x2="23.1" y2="2.3"/>
<line x1="40.4" y1="11.3" x2="42.3" y2="10.7"/>
<line x1="38.1" y1="7" x2="39.6" y2="5.7"/>
<line x1="34" y1="3.8" x2="34.8" y2="2"/>
<path d="M17,13H3c-1.1,0-2,0.9-2,2v22c0,1.1,0.9,2,2,2h18l7,4v-4h7c1.1,0,2-0.9,2-2V24"/>
<line x1="5" y1="21" x2="11" y2="21"/>
<line x1="14" y1="21" x2="18" y2="21"/>
<line x1="5" y1="25" x2="13" y2="25"/>
<line x1="16" y1="25" x2="21" y2="25"/>
<line x1="5" y1="29" x2="8" y2="29"/>
<line x1="11" y1="29" x2="23" y2="29"/>
<line x1="5" y1="33" x2="13" y2="33"/>
<line x1="16" y1="33" x2="21" y2="33"/>
<polyline points="30.2,10 27,16 31,15 28.6,21 "/>
</g>
</svg>
</div>
CSS:
.stf-icon{fill:none;stroke: url(#icon-gradient);stroke-width:1;stroke-linecap:round;stroke-miterlimit:10;}
.animated-icon {
stroke-dasharray: 110;
stroke-dashoffset: 110;
animation: icon-animation 6s linear forwards;
animation-fill-mode: forwards;
}
#keyframes icon-animation {
from {stroke-dashoffset: 110;}
to {stroke-dashoffset: 0;}
}
Jquery:
var $fade = $(".stf-icon"); //Calling the class in HTML
$(window).scroll(function () { //Using the scroll global variable
$fade.each(function () {
fadeMiddle = $(this).offset().top + (0.4 *$(this).height());
windowBottom = $(window).scrollTop() + $(window).height();
if (fadeMiddle < windowBottom) {
$(this).addClass("animated-icon"); //add the animated icon class
}
});
});
/* On Load: Trigger Scroll Once*/
$(window).scroll();
To make things easy, I have a code pen: https://codepen.io/studiotwofold/pen/dyYJWrV
EDIT
Can this be done with straight javascript?
var wrapper = document.querySelector('.icon-container');
window.onscroll = function (event) {
if (wrapper.getBoundingClientRect().top < 0) {
wrapper.className = "icon-container animated-icon";
window.onscroll = null;
}
}

How to do an animated dashed svg line?

I've tried to do an animated dashed line in HTML (SVG) / CSS / JS.
This is my first svg animation... and clearly... I don't understand anything.
First of all, this is my dashed line :
<svg id="bf7de8ba-cf75-48ab-a36c-06f8d86635d5" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 690.814 824.302">
<defs>
<style>
.a00cb6af-c716-4d00-9962-797e598003da,
.a6fde9f6-9a2f-4715-ac34-678948a4d015,
.b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
fill:none;
stroke-miterlimit:10;
stroke-width:6px;
}
.a6fde9f6-9a2f-4715-ac34-678948a4d015 {
stroke:url(#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0);
}
.b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
stroke-dasharray:30.322 50.536;
stroke:url(#a958eb71-8928-4250-a898-e2a9df336375);
}
.a00cb6af-c716-4d00-9962-797e598003da {
stroke:url(#a8cb66bd-35fa-45ad-b9b6-1af210f764d2);
}
</style>
<linearGradient id="bef7cd12-3404-46dc-ac0f-c9d91ddd83d0" x1="60.835" y1="123.864" x2="751.668" y2="123.864" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ec6608"/>
<stop offset="0.494" stop-color="#c33089"/>
<stop offset="1" stop-color="#662483"/>
</linearGradient>
<linearGradient id="a958eb71-8928-4250-a898-e2a9df336375" x1="60.835" y1="541.828" x2="751.668" y2="541.828" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
<linearGradient id="a8cb66bd-35fa-45ad-b9b6-1af210f764d2" x1="60.835" y1="932.54" x2="751.668" y2="932.54" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
</defs>
<path class="a6fde9f6-9a2f-4715-ac34-678948a4d015" d="M748.213,116.426c.215,4.461.381,9.478.436,14.992" transform="translate(-60.835 -116.281)"/>
<path id="pathRecrut" class="b963f74d-80cb-4571-80bd-9cf5cd28cce2" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916" transform="translate(-60.835 -116.281)"/>
<path class="a00cb6af-c716-4d00-9962-797e598003da" d="M81.983,925.674a117,117,0,0,0,6.74,13.39" transform="translate(-60.835 -116.281)"/>
</svg>
see on codepen : https://codepen.io/Unrillaz/pen/gNmgjW
I've made it with Illustrator (adobe).
So I've tried to animate this line an I've followed this tutorial fron CSS-TRICKS : https://css-tricks.com/scroll-drawing/
AND .... TADA ! What's I have :
// Get a reference to the <path>
var path = document.querySelector('#pathRecrut');
// Get length of path... ~577px in this case
var pathLength = path.getTotalLength();
// Make very long dashes (the length of the path itself)
path.style.strokeDasharray = pathLength + ' ' + pathLength;
// Offset the dashes so the it appears hidden entirely
path.style.strokeDashoffset = pathLength;
// Jake Archibald says so
// https://jakearchibald.com/2013/animated-line-drawing-svg/
path.getBoundingClientRect();
// When the page scrolls...
window.addEventListener("scroll", function(e) {
// What % down is it?
// https://stackoverflow.com/questions/2387136/cross-browser-method-to-determine-vertical-scroll-percentage-in-javascript/2387222#2387222
// Had to try three or four differnet methods here. Kind of a cross-browser nightmare.
var scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
// Length to offset the dashes
var drawLength = pathLength * scrollPercentage;
// Draw in reverse
path.style.strokeDashoffset = pathLength - drawLength;
// When complete, remove the dash array, otherwise shape isn't quite sharp
// Accounts for fuzzy math
if (scrollPercentage >= 0.99) {
path.style.strokeDasharray = "none";
} else {
path.style.strokeDasharray = pathLength + ' ' + pathLength;
}
});
<svg id="bf7de8ba-cf75-48ab-a36c-06f8d86635d5" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 690.814 824.302">
<defs>
<style>
.a00cb6af-c716-4d00-9962-797e598003da,
.a6fde9f6-9a2f-4715-ac34-678948a4d015,
.b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
fill:none;
stroke-miterlimit:10;
stroke-width:6px;
}
.a6fde9f6-9a2f-4715-ac34-678948a4d015 {
stroke:url(#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0);
}
.b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
stroke-dasharray:30.322 50.536;
stroke:url(#a958eb71-8928-4250-a898-e2a9df336375);
}
.a00cb6af-c716-4d00-9962-797e598003da {
stroke:url(#a8cb66bd-35fa-45ad-b9b6-1af210f764d2);
}
</style>
<linearGradient id="bef7cd12-3404-46dc-ac0f-c9d91ddd83d0" x1="60.835" y1="123.864" x2="751.668" y2="123.864" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ec6608"/>
<stop offset="0.494" stop-color="#c33089"/>
<stop offset="1" stop-color="#662483"/>
</linearGradient>
<linearGradient id="a958eb71-8928-4250-a898-e2a9df336375" x1="60.835" y1="541.828" x2="751.668" y2="541.828" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
<linearGradient id="a8cb66bd-35fa-45ad-b9b6-1af210f764d2" x1="60.835" y1="932.54" x2="751.668" y2="932.54" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
</defs>
<path class="a6fde9f6-9a2f-4715-ac34-678948a4d015" d="M748.213,116.426c.215,4.461.381,9.478.436,14.992" transform="translate(-60.835 -116.281)"/>
<path id="pathRecrut" class="b963f74d-80cb-4571-80bd-9cf5cd28cce2" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916" transform="translate(-60.835 -116.281)"/>
<path class="a00cb6af-c716-4d00-9962-797e598003da" d="M81.983,925.674a117,117,0,0,0,6.74,13.39" transform="translate(-60.835 -116.281)"/>
</svg>
see on codepen : https://codepen.io/Unrillaz/pen/ZdeezN
I don't understand why this line is solid when I animate it.
I want the same animation. A line which is filling itself when you scroll down but I want to keep it dashed. Do you think it's possible ?
The standard "line drawing" technique uses a changing dash length to simulate the drawing effect. So obviously, if your line already has a dash pattern, that technique won't work. Not directly at least.
The best solution to this is to apply a <mask> to the dashed line. The mask consists of a line that covers your original one (the dashed one). We then use the standard line drawing dash technique to animate the version of the line in the mask. Thus slowly unmasking/revealing the original dashed line.
// Get a reference to the <path>
var path = document.querySelector('#pathRecrut');
// Get length of path... ~577px in this case
var pathLength = path.getTotalLength();
// Make very long dashes (the length of the path itself)
path.style.strokeDasharray = pathLength + ' ' + pathLength;
// Offset the dashes so the it appears hidden entirely
path.style.strokeDashoffset = pathLength;
// When the page scrolls...
window.addEventListener("scroll", function(e) {
// What % down is it?
// https://stackoverflow.com/questions/2387136/cross-browser-method-to-determine-vertical-scroll-percentage-in-javascript/2387222#2387222
// Had to try three or four differnet methods here. Kind of a cross-browser nightmare.
var scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
// Length to offset the dashes
var drawLength = pathLength * scrollPercentage;
// Draw in reverse
path.style.strokeDashoffset = pathLength - drawLength;
});
<svg id="bf7de8ba-cf75-48ab-a36c-06f8d86635d5" data-name="Calque 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 690.814 824.302">
<defs>
<style>
.a00cb6af-c716-4d00-9962-797e598003da,
.a6fde9f6-9a2f-4715-ac34-678948a4d015,
.b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
fill:none;
stroke-miterlimit:10;
stroke-width:6px;
}
.a6fde9f6-9a2f-4715-ac34-678948a4d015 {
stroke:url(#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0);
}
.b963f74d-80cb-4571-80bd-9cf5cd28cce2 {
stroke-dasharray:30.322 50.536;
stroke:url(#a958eb71-8928-4250-a898-e2a9df336375);
}
.a00cb6af-c716-4d00-9962-797e598003da {
stroke:url(#a8cb66bd-35fa-45ad-b9b6-1af210f764d2);
}
</style>
<linearGradient id="bef7cd12-3404-46dc-ac0f-c9d91ddd83d0" x1="60.835" y1="123.864" x2="751.668" y2="123.864" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ec6608"/>
<stop offset="0.494" stop-color="#c33089"/>
<stop offset="1" stop-color="#662483"/>
</linearGradient>
<linearGradient id="a958eb71-8928-4250-a898-e2a9df336375" x1="60.835" y1="541.828" x2="751.668" y2="541.828" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
<linearGradient id="a8cb66bd-35fa-45ad-b9b6-1af210f764d2" x1="60.835" y1="932.54" x2="751.668" y2="932.54" xlink:href="#bef7cd12-3404-46dc-ac0f-c9d91ddd83d0"/>
<mask id="linemask">
<path id="pathRecrut" fill="none" stroke="white" stroke-width="10" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916"/>
</mask>
</defs>
<path class="a6fde9f6-9a2f-4715-ac34-678948a4d015" d="M748.213,116.426c.215,4.461.381,9.478.436,14.992" transform="translate(-60.835 -116.281)"/>
<path class="b963f74d-80cb-4571-80bd-9cf5cd28cce2" d="M745.947,181.853c-3.573,34.83-7.4,65.457-20.713,85.466-36.276,54.511-150.309,41.2-247.4,29.872-73.484-8.575-74.824-17.343-139.4-21.446-87.16-5.538-141.016-8.96-191.49,24.51-48.083,31.886-87.4,93.472-82.723,159.319.847,11.934,4.189,59.01,39.83,91.915,35.144,32.448,81.33,32.315,131.744,32.171,53.366-.154,56.932-10.359,130.213-18.383,52.244-5.721,100.335-10.606,160.085,1.532,36.964,7.508,74.081,20.657,109.532,43.659,26.491,17.189,49.773,32.776,59.745,62.809,1.48,4.457,13.436,42.337-6.894,72.766-14.348,21.475-39.623,31.524-81.957,36.766-67.779,8.391-105.681-4.654-182.3-16.086-41.6-6.206-132.521-17.593-227.49-.766-22.971,4.071-60.931,12.4-91.149,42.894-7.9,7.968-23.347,23.951-29.872,49.787a99.225,99.225,0,0,0-1.1,42.916" transform="translate(-60.835 -116.281)" mask="url(#linemask)"/>
<path class="a00cb6af-c716-4d00-9962-797e598003da" d="M81.983,925.674a117,117,0,0,0,6.74,13.39" transform="translate(-60.835 -116.281)"/>
</svg>

Fill color SVG path with animation

I have use following way to fill color of SVG paths. Is there a way to add animation to it. Color filling starting from center and spread.
$(function(){
$("#btn-test1").on("click",function(){
$("#path1").attr("fill","#0000");
});
});
This answer provides four different options to animate the fill color of a SVG path using jQuery.animate(), CSS #keyframes and SVG SMIL-Animation:
#1 jQuery.animate() and SVG <radialGradient>
$(function(){
$("button").on("click",function(){
$(this).animate(
{
textIndent: 1, // or whatever
}, {
duration: 3000,
step: function ( now, fx ) {
// arguments:
// now: numeric value of the property being animated at each step
// fx: reference to the jQuery.fx prototype object
// fx.start: first value of the animated property
// fx.end: last value of the animated property
var from = 0,
to = 700,
r = from + to * ( now - fx.start ) / ( fx.end - fx.start ); // animate r from 0 to 700
$("#gradient").attr( "r", r + "px" );
},
complete: function () {
$("#path").attr("fill", "#000"); // callback
}
}
);
});
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<head>
<body>
<button>Start Animation</button>
<svg height="150" width="300">
<defs>
<radialGradient id="gradient" r="0px" gradientUnits="userSpaceOnUse">
<stop offset="20%" style="stop-color: #000; stop-opacity: 1" />
<stop offset="100%" style="stop-color: #000; stop-opacity: 0" />
</radialGradient>
</defs>
<path id="path" d="M 0 0 Q 300 300 300 0 z" fill="url(#gradient)" />
</svg>
</body>
#2 jQuery.animate() and SVG transform attribute
$(function(){
$("button").on("click",function(){
$(this).animate(
{
textIndent: 1, // or whatever
}, {
duration: 3000,
step: function ( now, fx ) {
// arguments:
// now: numeric value of the property being animated at each step
// fx: reference to the jQuery.fx prototype object
// fx.start: first value of the animated property
// fx.end: last value of the animated property
var from = 0,
to = 1,
scale = from + to * ( now - fx.start ) / ( fx.end - fx.start ); // animate r from 0 to 700
$("#path").attr( "transform", "scale(" + scale + ")" );
}
}
);
});
});
#path {transform-origin: 50% 50%;}
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
</head>
<body>
<button>Start Animation</button>
<svg height="150" width="300">
<path id="path" d="M 0 0 Q 300 300 300 0 z" fill="#000" />
</svg>
</body>
Maybe that isn’t the result you expected, but it’s an option.
#3 CSS #keyframes
stop {
stop-opacity: 0;
animation: 3s animateStopOpacity;
}
stop:last-child {
animation-delay: 2s;
}
#keyframes animateStopOpacity {
from {stop-opacity: 0;}
to {stop-opacity: 1;}
}
<body>
<svg height="150" width="300">
<defs>
<radialGradient id="gradient" r="50%" gradientUnits="userSpaceOnUse">
<stop offset="0%" style="stop-color: #000; stop-opacity: 1" />
<stop offset="100%" style="stop-color: #000; stop-opacity: 0" />
</radialGradient>
</defs>
<path id="path" d="M 0 0 Q 300 300 300 0 z" fill="url(#gradient)" />
</svg>
</body>
#4 SVG SMIL Animation
<body>
<svg height="150" width="300">
<defs>
<radialGradient id="gradient" r="100px" gradientUnits="userSpaceOnUse">
<stop offset="20%" style="stop-color: #000; stop-opacity: 1" />
<stop offset="100%" style="stop-color: #000; stop-opacity: 0" />
<animate
attributeName="r"
from="0"
to="700"
dur="3s"
fill="freeze"
/>
</radialGradient>
</defs>
<path id="path" d="M 0 0 Q 300 300 300 0 z" fill="url(#gradient)" />
</svg>
</body>
I hope I could help you!

SVG lines draw on scroll with jQuery

How i can create draw animation with css for SVG "line" element. I want to draw the line on scroll, with smooth effect. Some one have any ideas? I try to search this but i cant find this effect with line element.
here is my html and svg:
<div class="box">
<svg width="100%" height="100%">
<line x1="0" y1="0" x2="0" y2="100%" stroke="gray" stroke-width="2" />
<line x1="0" y1="100%" x2="100%" y2="100%" stroke="gray" stroke-width="2" />
</svg>
</div>
<div class="box2">
<svg width="100%" height="100%">
<line x1="100%" y1="100%" x2="100%" y2="0" stroke="gray" stroke-width="2" />
<line x1="0" y1="100%" x2="100%" y2="100%" stroke="gray" stroke-width="2" />
</svg>
</div>
<div class="box">
<svg width="100%" height="100%">
<line x1="0" y1="0" x2="0" y2="100%" stroke="gray" stroke-width="2" />
<line x1="0" y1="100%" x2="100%" y2="100%" stroke="gray" stroke-width="2" />
</svg>
</div>
<div class="box2">
<svg width="100%" height="100%">
<line x1="100%" y1="100%" x2="100%" y2="0" stroke="gray" stroke-width="2" />
<line x1="0" y1="100%" x2="100%" y2="100%" stroke="gray" stroke-width="2" />
</svg>
</div>
and css:
.box{
width: 100%;
height: 300px;
position: relative;
}
.box2{
width: 100%;
height: 300px;
position: relative;
}
Demo
I just know that you can run through a path with an custom javascript, maybe you can use that for a line aswell :)
NEW EDIT FOR SCROLLING FEATURE
// Get a reference to the <path>
var path = document.querySelector('#star-path');
// Get length of path... ~577px in this case
var pathLength = path.getTotalLength();
// Make very long dashes (the length of the path itself)
path.style.strokeDasharray = pathLength + ' ' + pathLength;
// Offset the dashes so the it appears hidden entirely
path.style.strokeDashoffset = pathLength;
// Jake Archibald says so
// https://jakearchibald.com/2013/animated-line-drawing-svg/
path.getBoundingClientRect();
// When the page scrolls...
window.addEventListener("scroll", function(e) {
// What % down is it?
// https://stackoverflow.com/questions/2387136/cross-browser-method-to-determine-vertical-scroll-percentage-in-javascript/2387222#2387222
// Had to try three or four differnet methods here. Kind of a cross-browser nightmare.
var scrollPercentage = (document.documentElement.scrollTop + document.body.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
// Length to offset the dashes
var drawLength = pathLength * scrollPercentage;
// Draw in reverse
path.style.strokeDashoffset = pathLength - drawLength;
// When complete, remove the dash array, otherwise shape isn't quite sharp
// Accounts for fuzzy math
if (scrollPercentage >= 0.99) {
path.style.strokeDasharray = "none";
} else {
path.style.strokeDasharray = pathLength + ' ' + pathLength;
}
});
body {
/* feel free to change height */
height: 5000px;
}
#star-svg {
position: fixed;
top: 50%;
left: 50%;
width: 150px;
height: 150px;
margin: -75px 0 0 -75px;
}
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100.6 107.6" id="star-svg">
<path fill="none" stroke="black" stroke-width="2" id="star-path" d="M43.7,65.8L19.9,83.3c-2.9,1.9-5.1,3.2-7.9,3.2c-5.7,0-10.5-5.1-10.5-10.8
c0-4.8,3.8-8.2,7.3-9.8l27.9-12L8.8,41.4c-3.8-1.6-7.3-5.1-7.3-9.8c0-5.7,5.1-10.5,10.8-10.5c2.9,0,4.8,1,7.6,3.2l23.8,17.4
l-3.2-28.2c-1-6.7,3.5-12,9.8-12c6.3,0,10.8,5.1,9.8,11.7L57,41.8l23.8-17.4c2.9-2.2,5.1-3.2,7.9-3.2c5.7,0,10.5,4.8,10.5,10.5
c0,5.1-3.5,8.2-7.3,9.8L63.9,53.8l27.9,12c3.8,1.6,7.3,5.1,7.3,10.1c0,5.7-5.1,10.5-10.8,10.5c-2.5,0-4.8-1.3-7.6-3.2L57,65.8
l3.2,28.2c1,6.7-3.5,12-9.8,12c-6.3,0-10.8-5.1-9.8-11.7L43.7,65.8z"/>
</svg>
Source: https://css-tricks.com/scroll-drawing/
You need to export the svg in a path. and then you can add scroll animation depending on the viewport. Here is the testing server running your instance.demo project

Categories

Resources