记一次requestAnimationFrame之后页面崩溃、内存泄漏问题

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

可以关注一下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值