how can i make a svg ball roll to the cursor - javascript

hi I am trying to make a game like online bowling and I can not get the ball to lunch correctly in js. when I click on it the ball goes the wrong way or off the screen
var xup
var yup
var x = 50;
var y = 95
document.onmouseup = function(e){
xup = -(e.pageX/screen.width)
yup = -(e.pageY/screen.height)
let d = setInterval(function(){
x += xup
y += yup
document.getElementById("player").innerHTML = '<circle id="ball" cx="'+x+'%" cy="'+y+'%" r="1%" fill="url(#ball)" />'
if(y<=20){
d=null
}
},10)
}
<svg style='position: absolute;left: 0;top: 1%;' width='100%' height='100%'>
<defs>
<radialGradient id="ball" cx="50%" cy="25%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:#ff00ff;stop-opacity:1" />
<stop offset="100%" style="stop-color:#800080;stop-opacity:1" />
</radialGradient>
</defs>
<g id="player">
<circle id="ball" cx="50%" cy="95%" r="1%" fill="url(#ball)" />
</g>

Related

Animation is too choppy when animating inline SVG with javascript according to the window's scrollbar position

I am trying to use JavaScript to retrieve inline SVG elements and set their transform attributes in order to translate them in response to scrolling down the screen. I am using window.requestAnimationFrame() in order to do so.
The animation is very choppy so far and I haven't found a solution to remedy this yet. Any suggestions??
<!doctype html>
<html lang="en">
<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="margin: 0px">
<svg viewBox="0 0 1440 1024" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="">
<g id="AbstractBackground">
<rect id="backgroundRect" width="1440" height="1024" fill="#BDD8DE"/>
<rect id="greenCircleGrad" x="-338" y="-444" width="1440" height="1440" fill="url(#paint0_radial_2005_534273)"/>
<path id="wave1" d="M516 228.015C212 228.015 74 34.0154 -170 36.0154C-414 38.0154 -634 228.015 -634 228.015V988.015H1692V200.015C1692 200.015 1459 36.0154 1208 36.0154C957 36.0153 820 228.015 516 228.015Z" fill="#60AB9E"/>
<rect id="turquoiseCircleGrad" x="508" y="-208" width="1440" height="1440" fill="url(#paint1_radial_2005_534273)"/>
<path id="wave2" d="M872 553.015C568 553.015 430 359.015 186 361.015C-58 363.015 -278 553.015 -278 553.015V1313.02H2048V525.015C2048 525.015 1815 361.015 1564 361.015C1313 361.015 1176 553.015 872 553.015Z" fill="#77ABBB"/>
<rect id="blueCircleGrad" x="-128" y="-42" width="1440" height="1440" fill="url(#paint2_radial_2005_534273)"/>
<path id="wave3" d="M376 853.015C72 853.015 -66 659.015 -310 661.015C-554 663.015 -774 853.015 -774 853.015V1613.02H1552V825.015C1552 825.015 1319 661.015 1068 661.015C817 661.015 680 853.015 376 853.015Z" fill="#C6DAD4"/>
<rect id="blackCircleGrad" x="207" y="221" width="1753" height="1753" fill="url(#paint3_radial_2005_534273)"/>
<defs>
<radialGradient id="paint0_radial_2005_534273" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(382 276) rotate(90) scale(720)">
<stop stop-color="#7B3A5D" stop-opacity="0.67"/>
<stop stop-color="#6DA060" stop-opacity="0.83"/>
<stop offset="0.442708" stop-color="#6DA360" stop-opacity="0.71"/>
<stop offset="1" stop-color="#6CA95D" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint1_radial_2005_534273" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(1228 512) rotate(90) scale(720)">
<stop stop-color="#71EFE3"/>
<stop stop-color="#71EFE3"/>
<stop offset="1" stop-color="#71EFE3" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint2_radial_2005_534273" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(592 678) rotate(90) scale(720)">
<stop stop-color="#8A78B1"/>
<stop stop-color="#58B4C8"/>
<stop offset="1" stop-color="#67C0D4" stop-opacity="0"/>
</radialGradient>
<radialGradient id="paint3_radial_2005_534273" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(1083.5 1097.5) rotate(90) scale(876.5)">
<stop stop-color="#8A78B1" stop-opacity="0.73"/>
<stop stop-color="#20665E" stop-opacity="0.53"/>
<stop offset="0.713542" stop-color="#2F9262" stop-opacity="0"/>
</radialGradient>
</defs>
</svg>
</body>
<script>
// IDs of SVG elements in the SVG background that animate when scrolling down
const SLO_SCROLL_TRANSFORM_IDS = ["turquoiseCircleGrad","wave1"];
const MED_SCROLL_TRANSFORM_IDS = ["blueCircleGrad","wave2"];
const FST_SCROLL_TRANSFORM_IDS = ["blackCircleGrad","wave3"];
const [SLO_SCROLL_DIST, MED_SCROLL_DIST, FST_SCROLL_DIST] = [50, 100, 200];
/**
* applies css translate transformation to an svg element
* #param id svg element id to apply transformation to
* #param distance vertical distance to translate svg element
*/
function translateSvgVertically(id, distance) {
document.querySelector("svg #"+id).setAttribute('transform',"translate(0,"+distance+")");
}
let h = document.documentElement;
let b = document.body;
/**
* returns how much of the page has been scrolled through as a decimal
* #returns {number} returns a decimcal [0,1]
*/
function getScrollFraction() {
return (h['scrollTop']||b['scrollTop']) / ((h['scrollHeight']||b['scrollHeight']) - h.clientHeight);
}
let lastKnownScrollFraction = 0;
let ticking = false;
document.addEventListener("scroll", (e) => {
lastKnownScrollFraction = getScrollFraction();
if (!ticking) {
window.requestAnimationFrame(function() {
SLO_SCROLL_TRANSFORM_IDS.forEach((id) => translateSvgVertically(id, SLO_SCROLL_DIST*lastKnownScrollFraction));
MED_SCROLL_TRANSFORM_IDS.forEach((id) => translateSvgVertically(id, MED_SCROLL_DIST*lastKnownScrollFraction));
FST_SCROLL_TRANSFORM_IDS.forEach((id) => translateSvgVertically(id, FST_SCROLL_DIST*lastKnownScrollFraction));
ticking = false;
});
ticking = true;
}
});
</script>
</html>

how can i make a svg ball roll to the last click

I am trying to make a game like online bowling, and I cannot get the ball to launch correctly in js. when I click on it the ball goes the wrong way or off the screen. I have been trying to fix this for a while.
var xup
var yup
var x = 50;
var y = 95
document.onmouseup = function(e){
xup = -(e.pageX/screen.width)
yup = -(e.pageY/screen.height)
let d = setInterval(function(){
x += xup
y += yup
document.getElementById("player").innerHTML = '<circle id="ball" cx="'+x+'%" cy="'+y+'%" r="1%" fill="url(#ball)" />'
if(y<=20){
d=null
}
},10)
}
<svg style='position: absolute;left: 0;top: 1%;' width='100%' height='100%'>
<defs>
<radialGradient id="ball" cx="50%" cy="25%" r="50%" fx="50%" fy="50%">
<stop offset="0%" style="stop-color:#ff00ff;stop-opacity:1" />
<stop offset="100%" style="stop-color:#800080;stop-opacity:1" />
</radialGradient>
</defs>
<g id="player">
<circle id="ball" cx="50%" cy="95%" r="1%" fill="url(#ball)" />
</g>
</svg>

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/

Smooth animate for svg fill

I have an SVG thermometer and I'm trying to animate filling it smoothly for each class.
I did thermometer with toggle classes. I'm trying to animate smoothly up-down, and down-up animation for each class I have.
https://lore1ei.github.io/ -thermometer.
var firstStop = document.getElementById('F1gst1');
percentage = '0%';
firstStop.setAttribute('offset', percentage);
var CountAllCheckboxes = $('.analysis-li').length;
var CountChecked = 0;
$(".analysis-li").click(function() {
$(this).toggleClass("check");
CountChecked = $('.analysis-li.check').length;
percentage = ((CountChecked / CountAllCheckboxes) * 100) + '%';
firstStop.setAttribute('offset', percentage);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<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>
One solution is to animate it using javascript only instead of using css and/or svg-props. For example:
function anim(fromPercentage) {
var topLimit = 25;
fromPercentage += 1;
if(fromPercentage < topLimit) {
$('#F1gst1').attr('offset', fromPercentage + '%');
setTimeout( function() {
anim(fromPercentage);
}, 35);
}
};
/*
* Animates the bar from 10 to 25 percentage.
* Change the topLimit inside the anim-function to the current desired top level.
* Also tweek the timeout to get smoother transition.
*/
anim(10);
#Thomas But i need this for ((CountChecked / CountAllCheckboxes) * 100) + '%'. It will be so many mask and functions.
it's one mask and one function, here a quick snippet:
const scale = Array.from(Array(101), (_,i,a) => 90*(100-i)/100);
document.querySelector("svg #scale").setAttributeNS(null, "d", scale.filter((v,i) => i && i<100 && i%10 === 0).map(v => `M20,${v},25,${v}`).join(""));
setInterval(function(){
let percent = Math.floor(Math.random() * 100);
document.querySelector("div").textContent = percent + "%";
document.querySelector("svg #red").style.setProperty("transform", `translateY(${scale[percent]}px)`)
}, 1000);
svg {
max-width: 100px;
max-height: 200px;
}
svg #red {
transition: transform 300ms;
}
<div></div>
<svg viewbox="0,0,50,100">
<mask id="myMask">
<line x1=25 y1=5 x2=25 y2=80 stroke="white" stroke-width="10" stroke-linecap="round" />
<circle cx=25 cy=90 r=10 fill="white" />
</mask>
<g mask="url(#myMask)">
<rect x=0 y=0 width=50 height=100 fill="#AAA" />
<rect id="red" x=0 y=0 width=50 height=100 fill="red" />
<path id="scale" stroke="#888" stroke-width="0.5" d=""/>
</g>
</svg>
<linearGradient y2="0%" x2="0%" y1="100%" x1="0%" id="F1g">
<stop stop-color="#00FF00" offset="0%" id="F1gst1">
<animate id="g0" attributeName="offset" to="5%" dur="0.5s" begin="indefinite" />
<animate id="g1" attributeName="offset" to="19.285714285714285%" dur="0.5s" begin="indefinite" />
<animate id="g2" attributeName="offset" to="33.57142857142857%" dur="0.5s" begin="indefinite" />
<animate id="g3" attributeName="offset" to="47.857142857142854%" dur="0.5s" begin="indefinite" />
<animate id="g4" attributeName="offset" to="62.14285714285714%" dur="0.5s" begin="indefinite" />
<animate id="g5" attributeName="offset" to="76.42857142857143%" dur="0.5s" begin="indefinite" />
<animate id="g6" attributeName="offset" to="90.71428571428571%" dur="0.5s" begin="indefinite" />
<animate id="g7" attributeName="offset" to="105%" dur="0.5s" begin="indefinite" />
</stop>
<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 solution from my friend.
var firstStop = document.getElementById('F1gst1');
percentage = '5%'; firstStop.setAttribute('offset',percentage);
var CountAllCheckboxes = $('.analysis-li').length;
var CountChecked = 0;
$(".analysis-li").click(function(){
$(this).toggleClass("check");
CountChecked = $('.analysis-li.check').length;
percentage = ((CountChecked / CountAllCheckboxes) * 100 + 5)+'%';
$('#g'+CountChecked)[0].beginElement();
setTimeout("firstStop.setAttribute('offset',percentage)", 450);
});

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>

Categories

Resources