如何针对不同的函数多次调用requestAnimationFrame?

时间:2018-01-10 22:29:40

标签: javascript html5-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的任何建议

1 个答案:

答案 0 :(得分:1)

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

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