JavaScript基础教程

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

2019-12-02  本文已影响0人  StevenTang

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流光效果的经历

上一篇下一篇

猜你喜欢

热点阅读