自学内容网 自学内容网

js自定义丝滑滚动

最近做官网,实现一个分屏滚动效果,考虑到滚动结束后还要自定义,每屏的触发动画效果,又要满足响应式,所以只能自己写一个滚动方法;

核心方法
/*
 @params targetY:500, 目标距离 Number 
 @params duration: 1000, 毫秒 ms 
 @params callback: () => {} 执行完毕回调 Function
*/
function smoothScrollTo(targetY, duration, callback) {
            // 计算每一帧需要滚动的距离
            let start = window.scrollY || window.pageYOffset || document.body.scrollTop + (document.documentElement && document.documentElement.scrollTop || 0);  
            let change = targetY - start;  
            let currentTime = 0;  
            let increment = 20; // 假设每次动画帧之间的时间大约为20ms 
            /* 缓入快出_start */
            function easeInOutQuad(t) {  
                return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;  
            }
            /* 缓入快出_end */
            
            /* 快入缓出_start*/
            function cubicBezier(t, p1, p2) {  
                return 3 * p1 * (1 - t) * (1 - t) * t + 3 * p2 * (1 - t) * t * t + t * t * t;  
            }
            function fastInSlowOut(t) {  
                // 使用快入缓出的贝塞尔曲线参数  
                return cubicBezier(t, 0.4, 0.2);
            }
            /* 快入缓出_end*/
            
            /* 中间快,开始结束慢_start */
            function slowStartFastEnd(t) {  
                // 自定义缓动函数,开始和结束慢,中间快  
                t = t * 2;  
                if (t < 1) {  
                    return 0.5 * t * t;  
                } else {  
                    t -= 1;  
                    return -0.5 * (t * (t - 2) - 1);  
                }  
            }  
            /* 中间快,开始结束慢_end */
            
            function animate(timestamp) {  
                if (currentTime >= duration) {  
                    window.scrollTo(0, targetY);  
                    callback && callback();
                    return;  
                }  
        
                let progress = currentTime / duration;  
                let easeProgress = slowStartFastEnd(progress);  
                let run = easeProgress * change;  
        
                window.scrollTo(0, start + run);  
                currentTime += increment;
                if (window.requestAnimationFrame) {
                    requestAnimationFrame(animate);  
                } else {
                    setTimeout(animate, 16);
                }
            }
            animate();

        }
基本使用
/*
 @params targetY:500, 目标距离 Number 
 @params duration: 1000, 毫秒 ms 
 @params callback: () => {} 执行完毕回调 Function
*/
smoothScrollTo(500, 1000, () => {
    console.log('执行完毕了');
})
3种过渡方式核心方法
  • 缓入快出
  • 快入缓出
  • 中间快,开始结束慢
缓入快出
function easeInOutQuad(t) {  
    return t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t;  
}
快入缓出
function cubicBezier(t, p1, p2) {  
    return 3 * p1 * (1 - t) * (1 - t) * t + 3 * p2 * (1 - t) * t * t + t * t * t;  
}
function fastInSlowOut(t) {  
    // 使用快入缓出的贝塞尔曲线参数  
    return cubicBezier(t, 0.4, 0.2);
}
中间快,开始结束慢
function slowStartFastEnd(t) {  
    // 自定义缓动函数,开始和结束慢,中间快  
    t = t * 2;  
    if (t < 1) {  
        return 0.5 * t * t;  
    } else {  
        t -= 1;  
        return -0.5 * (t * (t - 2) - 1);  
    }  
}  

原文地址:https://blog.csdn.net/u014708123/article/details/137824013

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!