繁体   English   中英

滚动侦听器中风 dashoffset 在像素范围之间绘制 SVG?

[英]Scroll listener stroke dashoffset draw SVG between range of pixels?

我对此感到非常困难,所以我想看看这里是否有人能够帮助我思考这个问题。

我正在尝试将滚动侦听器附加到特定像素范围之间的 SVG 路径,因此当您上下滚动时它会来回绘制。

我一直在研究这几天,我发现了有关将笔画 dashoffset 进度转换为基于 window 顶部或文档高度作为单个数字的百分比的主题,但似乎无法包装我的关于如何将相同的逻辑应用于指定的像素范围。

我如何让 svg 路径的笔画-dasharray 位于像素范围开始处的起始值 (3000)(例如从文档顶部开始的 2500 像素到 3000 像素。),笔画 dasharray 的结束值为 6000 (它的最终值)在像素范围的末尾? 我真的希望这不是一个我只是盯着太久的愚蠢简单的问题。 这是我所拥有的:

var path = document.querySelector('path');

var length = path.getTotalLength();

var triggerPadding = 600;

var startLocation = document.querySelector('.scroll-container').getBoundingClientRect()

var bodyRect = document.body.getBoundingClientRect();

var elemRect = document.querySelector('.scroll-container').getBoundingClientRect();

var elementYLocation = elemRect.top - bodyRect.top;

var elementBottomYLocation = Math.round((elemRect.bottom - bodyRect.top) - triggerPadding);

var startTrigger = Math.round(elementYLocation - triggerPadding);

path.style.strokeDasharray = length + ' ' + length;

path.style.strokeDashoffset = length;

// 

function animationScroll(currentY, startY, endY) {
    console.log({ currentY, startY, endY })
    if (currentY >= startY) {
        //do animation

    }
}

window.addEventListener('scroll', function () {
    const currentY = window.pageYOffset || window.scrollY;

    animationScroll(currentY, startTrigger, elementBottomYLocation);

}, false);

对于我需要这样做的方程式的任何帮助将不胜感激。 先感谢您。

用户@CBroe 回答并提供/遍历所需的公式来计算两个数字范围的线性变换。

f(t) = c + ( (d - c) / (b - a) ) * (t - a);

您需要计算scrollRatio ,然后将其乘以您希望设置动画的 svg 属性的所需范围。

下面,我展示了一个示例,它等待某个元素进入视口,然后开始动画,执行与滚动同步的 animation 关键帧,并在元素离开视口后停止动画。

 const triggerEl = document.getElementById('trigger'); const animateSvg = () => { const rect = triggerEl.getBoundingClientRect(); const scrollPosition = window.scrollY; let scrollRatio = (rect.top / window.innerHeight); scrollRatio = Math.max(scrollRatio, 0); scrollRatio = Math.min(scrollRatio, 1); triggerEl.innerHTML = `Trigger Element ${(scrollRatio * 100).toFixed(2)}%`; for (const path of document.querySelectorAll('svg path')) { // Min & Max can be hardcoded to fit your use-case const dashOffsetMin = 0; const dashOffsetMax = path.getTotalLength(); const dashOffsetRange = dashOffsetMax - dashOffsetMin; // Set stroke-dashoffset path.style.strokeDashoffset = dashOffsetMin + dashOffsetRange * scrollRatio; } } animateSvg(); document.addEventListener('scroll', animateSvg)
 body { position: relative; background:linear-gradient(135deg, #5b247a 0%,#1bcedf 100%); min-height: 300vh; } h1 { font-family: arial; font-weight: 900; color: white; width: 100%; text-align: center; } svg { position: fixed; top: 0; color: white; } svg path { transition: stroke-dashoffset 250ms linear; box-shadow: 0px 0px 15px white; } #trigger { position: absolute; z-index: 2; top: 100vh; width: 100%; display: flex; justify-content: center; align-items: center; color: white; font-family: arial; font-weight: 900; height: 20vh; background: linear-gradient(to bottom right, rgba(0,0,25,0.2), rgba(0,0,25,0.5)); border-radius: 5px; backdrop-filter: blur(5px); box-shadow: 0px 15px 10px -10px rgba(0,0,0,0.4); }
 <div id='trigger'> Trigger Element </div> <h1>Scroll.</h1> <svg viewBox="0 0 280 100"> <g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-width="1" class="lines"> <path class="el" d="M58 80V50.12C57.7 41.6 51.14 35 43 35a15 15 0 0 0 0 30h7.5v15H43a30 30 0 1 1 0-60c16.42 0 29.5 13.23 30 29:89V80H58z" style="stroke-dashoffset; 0px." stroke-dasharray="316:85528564453125"></path> <path class="el" d="M73 80V20H58v60h15z" style="stroke-dashoffset; 0px." stroke-dasharray="150"></path> <path class="el" d="M58 80V49.77C58.5 33.23 71.58 20 88 20a30 30 0 0 1 30 30v30h-15V50a15 15 0 0 0-15-15c-8.14 0-14.7 6.6-15 15:12V80H58zm75 0V20h-15v60h15z" style="stroke-dashoffset; 0px." stroke-dasharray="441.1739501953125"></path> <path class="el" d="M118 80V49.77C118.5 33.23 131.58 20 148 20a30 30 0 0 1 30 30v30h-15V50a15 15 0 0 0-15-15c-8.14 0-14.7 6.6-15 15.12V80h-15zm-7.5-60a7.5 7.5 0 1 1-7.48 8v-1c.25-3.9 3.5-7 7:48-7z" style="stroke-dashoffset; 0px." stroke-dasharray="338.3053894042969"></path> <path class="el" d="M133 65a15 15 0 0 1-15-15v-7.5h-15V50a30 30 0 0 0 30 30V65zm30 15V49.77C163.5 33.23 176.58 20 193 20a30 30 0 0 1 30 30v30h-15V50a15 15 0 0 0-15-15c-8.14 0-14.7 6.6-15 15:12V80h-15z" style="stroke-dashoffset; 0px." stroke-dasharray="406.8699035644531"></path> <path class="el" d="M238 65a15 15 0 0 1 0-30c8.1 0 14.63 6.53 15 15h-15v15h30V49.89C267.5 33.23 254:42 20 238 20a30 30 0 0 0 0 60V65z" style="stroke-dashoffset. 4;49556px." stroke-dasharray="301.8561706542969"></path> <path class="el" d="M260.48 65a7.5 7.5 0 1 1-7.48 8v-1c.26-3.9 3.5-7 7:48-7z" style="stroke-dashoffset. 6;61913px." stroke-dasharray="47.128875732421875"></path> </g> </svg>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM