javascript - Vanilla js平滑滚动中的计时功能

标签 javascript html css

我的单页网站在 vanilla js 中有一个平滑的滚动,我尝试在没有 jquery 的情况下实现它,我想添加一个像 cubic bezier 这样的计时函数。有没有办法在 javascript 中做到这一点?这是代码:

{
    'use strict';

    let currentY = 0;
    let destination = 0;
    let speed = 40;
    let scroller = null;


    function smoothScroll(id) {

        destination = document.getElementById(id).offsetTop;

        //if the user scrolls down
        if (window.pageYOffset < destination) {

            scroller = setTimeout(function () {
                smoothScroll(id);
            }, 1);

            currentY = currentY + speed;

            if (currentY >= destination) {
                clearTimeout(scroller);
            }

            //if the user scrolls up
        } else {

            scroller = setTimeout(function () {
                smoothScroll(id);
            }, 1);

            currentY = currentY - speed;

            if (currentY <= destination) {
                clearTimeout(scroller);
            }

        }

        window.scroll(0, currentY);

    }

    window.onscroll = function () {
        currentY = this.pageYOffset;
    };


    Array.from(document.querySelectorAll(".scroll")).forEach(e => {

        e.addEventListener('click', () => {

            smoothScroll(e.href.split('#')[1]);

        });
    });

}

这是一个代码笔来观看它的运行:https://codepen.io/anon/pen/NYNQym

提前致谢。

最佳答案

首先,您应该使用 requestAnimationFrame(fn) 而不是 setTimeout(fn,1)

您的动画系统是增量式的——它会说“我到了吗?”如果没有,靠近点;如果是,停止。这没问题,但它为您提供的关于动画的唯一信息是它是否已完成。

缓和就像“接近尾声时,放慢速度”,但您不知道何时接近尾声。

假设我们要从滚动位置 100 移动到滚动位置 200,从时间 0 开始到时间 500 结束。这是时间到位置的映射。如果是时间 250,我们应该在位置 150 - 他们都在中间。同样的事情适用于任何其他时间。这称为补间动画,它是制作动画的最常见方式。

一旦我们以这种方式工作,我们就可以进行缓动。缓动函数本身非常简单 - here are all the classic ones .

如果你愿意,我可以发布代码,但听起来你正在尝试自己解决这个问题,希望这对你有所帮助,祝你好运。

关于javascript - Vanilla js平滑滚动中的计时功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49299283/

相关文章:

javascript - 使用c3 js,有没有办法在放大时显示更多的x轴值?

javascript - jquery slider 未初始化值

javascript - Twitter Bootstrap 中的滑动侧面板 z-index 问题

html - 如果用户上传了一张 2000x2000 像素的图片,然后我将其显示为 400x400 像素,页面是否会像图片是 2000x2000 像素一样使用带宽?

html - CSS - 将条件样式应用于表格行

javascript - react-redux 获取组件父 div 的宽度

javascript - 密码验证脚本不会返回 false 以防止表单在提交时提交

javascript - Knockout.js 中嵌套 View 模型和 json

javascript - ReactJS 输入没有获得焦点

CSS 未在 ASP.NET Core 中完全呈现