javascript - 如何针对不同的功能多次调用requestAnimationFrame?

标签 javascript html5-canvas

我试图使用canvas绘制动画背景并监视滚动位置和平滑滚动(没有jquery),但我最终多次调用requestAnimationFrame,这很快就减慢了网站速度。

我的app.js

  var delayTransition = 10;
    var padding = 60;
    var last_known_scroll = 0;
    var canvas = document.querySelector("#canvas");
    fitToContainer(canvas);
    function fitToContainer(canvas) {
        canvas.style.width = "100%";
        canvas.style.height = "100%";
        canvas.width = canvas.offsetWidth;
        canvas.height = canvas.offsetHeight;
    }
    var ctx = canvas.getContext("2d");

    document.addEventListener("DOMContentLoaded", function() {
        last_known_scroll = window.scrollY;

        scrollToActive(last_known_scroll);
    });

    var ticking = false;
    document.addEventListener("scroll", function(event) {
        last_known_scroll = window.scrollY;
        if (!ticking) {
        requestAnimationFrame(function(){// and here
            scrollToActive(last_known_scroll)

        });
            ticking = true;
        }
    });
    // change active nav-item on scroll
    function scrollToActive(startScroll) {
        var sections = document.getElementsByTagName("section");
        var i = 0;
        var offSet = padding + 10;
        var length = sections.length;
        while (i < sections.length) {
            if (
                startScroll + offSet >= sections[i].offsetTop - offSet &&
                startScroll + offSet < sections[length - 1].offsetTop - offSet
            ) {
                changeToActive(sections[i].id + "-link");
            } else if (
                startScroll + offSet >= sections[length - 1].offsetTop - offSet &&
                startScroll + offSet > sections[length - 2].offsetTop - offSet
            ) {
                changeToActive(sections[length - 1].id + "-link");
            }
            i++;
        }
    }

    //change active nav-item to active
    function changeToActive(elem) {
      //loop through nav elements and highlight correct one
    }

    function scrollIt(destination, duration = 200, callback) {
        const start = window.pageYOffset;
        const start_time =
            "now" in window.performance ? performance.now() : new Date().getTime();

        const documentHeight = Math.max(
            document.body.scrollHeight,
            document.body.offsetHeight,
            document.documentElement.clientHeight,
            document.documentElement.scrollHeight,
            document.documentElement.offsetHeight
        );
        const windowHeight =
            window.innerHeight ||
            document.documentElement.clientHeight ||
            document.getElementsByTagName("body")[0].clientHeight;
        const destinationOffset =
            typeof destination === "number" ? destination : destination.offsetTop;
        const destinationOffsetToScroll = Math.round(
            documentHeight - destinationOffset < windowHeight
                ? documentHeight - windowHeight
                : destinationOffset - padding
        );
        if ("requestAnimationFrame" in window === false) {
            window.scroll(0, destinationOffsetToScroll);
            if (callback) {
                callback();
            }
            return;
        }
        function scroll() {
            const now =
                "now" in window.performance
                    ? performance.now()
                    : new Date().getTime();
            const time = Math.min(1, (now - start_time) / duration);
            window.scroll(
                0,
                Math.ceil(time * (destinationOffsetToScroll - start) + start)
            );

            if (window.pageYOffset === destinationOffsetToScroll) {
                if (callback) {
                    callback();
                }
                return;
            }

            requestAnimationFrame(scroll);//here
        }

        scroll();
    }
    document
        .querySelector("#about-link")
        .addEventListener("click", () =>
            scrollIt(document.getElementById("about"), 200, () =>
                changeToActive("about-link")
            )
        );

    document
        .querySelector("#contact-link")
        .addEventListener("click", () =>
            scrollIt(document.getElementById("contact"), 200, () =>
                changeToActive("contact-link")
            )
        );

    function Particle(x, y, radius, dx, dy) {
        //create particles
    }
    var particles = [];
    var movingParticles = [];
    function init() {
      // initlaize partciles
    }
    function animate() {
        requestAnimationFrame(animate); //here

        ctx.clearRect(0, 0, innerWidth, canvas.height);

        for (var i = 0; i < particles.length; i++) {
            particles[i].draw();
        }
        for (var j = 0; j < movingParticles.length; j++) {
            movingParticles[j].update();
        }
    }

    init();
    animate();

scrollIt 函数、animate 函数以及 document.addEventListener('scroll') 似乎都需要单独使用 RAF,但这正在减慢一切。关于如何在不影响性能的情况下最好多次调用 RAF 的任何建议

最佳答案

尝试限制 requestAnimationFrame 内发生的数量。现在,它需要找到每个 <section>并迭代该列表。

在开始滚动之前,您能识别出所有部分吗?在调用 requestAnimationFrame() 之前?

关于javascript - 如何针对不同的功能多次调用requestAnimationFrame?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48197155/

相关文章:

javascript - mouseclick 和 mousemove 事件在 react Canvas 中给出偏移错误

javascript - 在另一个窗口的 <canvas> 中显示 <video> - 如何实现全帧率?

javascript - WebRTC 视频流无法通过 http 工作

javascript - 谷歌地图 setCenter 在 IE8 中不工作

javascript - 如何在 html5 Canvas 中绘制 Fabric js strokeRect?

javascript - Canvas context.fillText 抛出 “An invalid or illegal string was specified”

javascript - 重命名没有 id 的按钮文本

Javascript词频书签在输出中省略了一些字母

javascript - Expressjs - 全局对象

html - 为什么“音频”在HTML5游戏中会是这样的问题,请多久才能解决?