美文网首页JavaScript基础教程
记一次requestAnimationFrame之后页面崩溃、内

记一次requestAnimationFrame之后页面崩溃、内

作者: StevenTang | 来源:发表于2019-12-02 00:44 被阅读0次

    canvas 内存泄漏问题

    前言

    要解决的问题

    公司项目有个地方用到 canvas 做出流光动画。但是做出来之后,造成的内存无法释放,页面挂的时间久了一点点就开始页面崩溃

    源代码

    // 首先获取canvas
    // 在利用 getContext()方法返回一个用于在画布上绘图的环境。
    let c = document.getElementById("myCanvas");
    let context = c.getContext("2d");
    // 获取需要用到的公用属性 canvas的长度和宽度
    let width = c.width;
    let height = c.height;
    let canvasPoints;
    canvasPoints= [{x:100,y:0,r:3},{x:200,y:0,r:3}];
    // 开始在画布上画点
    function canvasChart() {
        for(let i = 0; i < xPoints.length; i++){
    
            boxWidth = box.clientWidth;
            num = (1903 - boxWidth)/2;
    
            context.lineWidth = 0;
            context.shadowBlur = 0;
            context.shadowColor = 'rgba(2, 179, 253,1)';
            context.fillStyle = 'rgba(2, 179, 253,1)';
            context.fill();//画实心圆
            context.beginPath();
            context.arc(canvasPoints[i].x, canvasPoints[i].y, canvasPoints[i].r, 0, Math.PI * 2);
            context.stroke();
        }
        V();
    }
    // 设置运动的速度,当Y坐标到了500的时候,在初始化xPoints坐标
    function V () {
        if (canvasPoints[0].y < 200) {
            canvasPoints[0].x += 1;
            canvasPoints[0].y += 1;
        } else {
            canvasPoints= [{x:100,y:0,r:3},{x:200,y:0,r:3}];
        }
    }
    // 利用 requestAnimationFrame 重复执行该动画
    function render() {
        let prev = context.globalCompositeOperation;
        context.globalCompositeOperation = 'destination-in';
        context.globalAlpha = 0.5;
        context.fillRect(0, 0, width, height);
        context.globalCompositeOperation = prev;
        //在主canvas上画新圆
        canvasChart();
        if (width !== 0) {
        /*这里执行了之后没有停止动画*/
        window.requestAnimationFrame(render);
        }
    }
    
    

    源代码中,执行了requestAnimationFrame之后没有停止,canvasChart()没有加判断,导致requestAnimationFrame会无线重复的执行下去,所以这里需要用到 canceAnimationFrame去停止定时器

    在上述代码中,需要在canvasChart()

    // 利用 requestAnimationFrame 重复执行该动画
    function render() {
        let prev = context.globalCompositeOperation;
        context.globalCompositeOperation = 'destination-in';
        context.globalAlpha = 0.5;
        context.fillRect(0, 0, width, height);
        context.globalCompositeOperation = prev;
        //在主canvas上画新圆
        /*这里执行了之后没有停止动画,加if判断*/
        if(status) {
            canvasChart();
        } else{
            window.canceAnimationFrame (canvasAnimation );
        }
        if (width !== 0) {
        /*这里执行了之后没有停止动画*/
         canvasAnimation = window.requestAnimationFrame(render);
        }
    }
    

    ! 不过需要考虑canceAnimationFrame的兼容性。这里大家自行注意

    参考文献:记一次用canvas做出腾讯云首页banner流光效果的经历

    相关文章

      网友评论

        本文标题:记一次requestAnimationFrame之后页面崩溃、内

        本文链接:https://www.haomeiwen.com/subject/potxgctx.html