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

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,674评论 1 32
  • Activity是什么 Activity是四大组件之一,它提供一个界面让用户点击和各种滑动操作 Activity栈...
    叫我吹神阅读 2,873评论 0 4
  • LM58:大家现在好,我是耐心,快到下班的时候了,每天九点半下班,今天活没有安排下来,看了一天的面试题,听说有个测...
    心羽暖姐姐阅读 176评论 2 0
  • 【书籍名称】《穿搭有术》chapter2 找到你的气质:气质九宫格 【精华摘抄】1、为了方便大家理解,我用基膜联想...
    sissy西西阅读 484评论 0 2
  • 夏日的恋情,总是因为各种各样的原因而终结. 有些看起来没心没肺飞扬跋扈的人,你对她一好,她盔甲就碎了,开始...
    宁子111阅读 241评论 0 0

友情链接更多精彩内容