Как получить анимацию svg пунктирной линией при соответствующей прокрутке?
Всякий раз, когда я применяю анимацию прокрутки на пунктирной линии svg, она превращается в простую линию без пунктира.
Мне нужна та же анимация, которая в настоящее время работает, но чтобы линия была пунктирной, как показано в приведенном выше примере. "Svg Before animation"
// Получить идентификатор элемента <path> и длину <path>
var triangle = document.getElementById("dashed-path");
var length = triangle.getTotalLength();
// Начальная позиция линии рисунка
triangle.style.strokeDasharray = length;
// Скрыть треугольник, сместив тире на максимальную длину. Это для того, чтобы отобразить треугольник перед прокруткой.
triangle.style.strokeDashoffset = length;
// Найдите процент прокрутки при прокрутке (используя свойства кросс-браузера) и присваиваете смещение тире, равное проценту прокрутки
window.addEventListener("scroll", myFunction);
function myFunction() {
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
var draw = length * scrollpercent;
// Обратное рисование линии (при прокрутке вверх)
triangle.style.strokeDashoffset = length - draw;
}
.height-div{
height: 500px; width: 100%; background:#eeeeee;
}
.desktop-pattern-wrap{display: inline-block;vertical-align: top;width: 100%;}
.desktop-pattern-wrap > div{float: left;width: 50%;}
<div class="desktop-pattern-wrap">
<div class="desktop-pattern">
<h2>Svg after animation</h2>
<svg width="198px" height="1458px" viewBox="0 0 198 1458" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="50%" y1="7.06935325%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#DE1652" offset="0%"></stop>
<stop stop-color="#F37121" offset="50.2239948%"></stop>
<stop stop-color="#FBAB26" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-dasharray="12,16" stroke-linejoin="round">
<g id="Desktop-Homepage-1" transform="translate(-646.000000, -825.000000)" stroke="url(#linearGradient-1)" stroke-width="4">
<g id="content" transform="translate(0.000000, 560.000000)">
<path d="M702,266 C682,424 795.064639,474.307498 716,600 C599,786 769,821 688,988 C548.560405,1275.48657 822.815807,1223 840.843207,1373 C858.870608,1523 605.485477,1528 687.610302,1728" id="dashed-path"></path>
</g>
</g>
</g>
</svg>
</div>
<div class="desktop-pattern-right">
<h2>Svg Before animation</h2>
<svg width="198px" height="1458px" viewBox="0 0 198 1458" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="50%" y1="7.06935325%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#DE1652" offset="0%"></stop>
<stop stop-color="#F37121" offset="50.2239948%"></stop>
<stop stop-color="#FBAB26" offset="100%"></stop>
</linearGradient>
</defs>
<g id="Homepage" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-dasharray="12,16" stroke-linejoin="round">
<g id="Desktop-Homepage-1" transform="translate(-646.000000, -825.000000)" stroke="url(#linearGradient-1)" stroke-width="4">
<g id="content" transform="translate(0.000000, 560.000000)">
<path d="M702,266 C682,424 795.064639,474.307498 716,600 C599,786 769,821 688,988 C548.560405,1275.48657 822.815807,1223 840.843207,1373 C858.870608,1523 605.485477,1528 687.610302,1728" id="dashed-path"></path>
</g>
</g>
</g>
</svg>
</div>
</div>
<div class="height-div">
</div>
Свободный перевод вопроса How to get dashed line svg animation on accordingly scroll? от участника @Jignesh Panchal.
Ответы (1 шт):
Это можно сделать, добавив маску SVG и затем нарисовав ее по пути:
var path = document.getElementById("thePath");
var mask = document.getElementById("maskPath");
var pathLength = path.getTotalLength();
var maskLength = 1050;
mask.style.strokeDashoffset = maskLength;
window.addEventListener("scroll", myFunction);
function myFunction() {
var scrollpercent = (document.body.scrollTop + document.documentElement.scrollTop) / (document.documentElement.scrollHeight - document.documentElement.clientHeight);
var draw = pathLength * scrollpercent;
mask.style.strokeDashoffset = maskLength - draw;
}
<h1>Scroll down</h1>
<svg width="198px" height="1458px" viewBox="0 0 198 1458">
<defs>
<linearGradient x1="50%" y1="7.06935325%" x2="50%" y2="100%" id="linearGradient-1">
<stop stop-color="#DE1652" offset="0%"></stop>
<stop stop-color="#F37121" offset="50.2239948%"></stop>
<stop stop-color="#FBAB26" offset="100%"></stop>
</linearGradient>
<mask id="theMask" maskUnits="userSpaceOnUse">
<path id="maskPath"
d="M702,266 C682,424 795.064639,474.307498 716,600 C599,786 769,821 688,988 C548.560405,1275.48657 822.815807,1223 840.843207,1373 C858.870608,1523 605.485477,1528 687.610302,1728"
fill="none"
fill-rule="evenodd"
stroke-dasharray="1637"
stroke-dashoffset="1050"
transform="translate(-646.000000, -825.000000)"
stroke-width="4"
stroke="#fff"/>
</mask>
</defs>
<g id="content" mask="url(#theMask)">
<path id="thePath"
d="M702,266 C682,424 795.064639,474.307498 716,600 C599,786 769,821 688,988 C548.560405,1275.48657 822.815807,1223 840.843207,1373 C858.870608,1523 605.485477,1528 687.610302,1728"
fill="none"
fill-rule="evenodd"
stroke-dasharray="12,16"
transform="translate(-646.000000, -825.000000)"
stroke-width="4"
stroke="url(#linearGradient-1)"
></path>
</g>
</svg>
Примечание переводчика:
Обычным путем невозможно анимировать появление пунктирной линии, так как stroke-dasharray="12,16" разбивает сразу всю линию на отрезки длиной 12px с пробелом 16px
Поэтому, если сразу применить анимацию сдвига начала линии stroke-dashoffset, то линия просто побежит, анимации заполнения штриховой линией при этом не будет.
В таком случае, применяется техника открывания прерывистой линии с помощью другой линии, которая находится поверх прерывистой линии и выступает в роли маски.
Свободный перевод ответа от участника @barhatsor.
