Canvas动画 位图缓存提高效率和对应的内存问题

对一个矢量图动画,开启位图缓存能大大提高运行效率。所谓开启位图缓存,其实要自己动手,先创建一个临时canvas,然后把矢量图绘制到这个canvas上,到了实际绘制时,直接把这个临时canvas拷贝到真正canvas上。而位图拷贝的速度是非常快的,比重新绘制矢量图要快很多。

三部曲:

1、建立临时canvas(位图缓存)

    p.cache = function(x, y, width, height, scale) {
        // draw to canvas.
        scale = scale||1;
        if (!this.cacheCanvas) { this.cacheCanvas = document.createElement("canvas");}
        this._cacheWidth = width;
        this._cacheHeight = height;
        this._cacheOffsetX = x;
        this._cacheOffsetY = y;
        this._cacheScale = scale;
        this.updateCache();
    }

2、绘制到临时canvas

    p.updateCache = function(compositeOperation) {
        var cacheCanvas = this.cacheCanvas, scale = this._cacheScale, offX = this._cacheOffsetX*scale, offY = this._cacheOffsetY*scale;
        var w = this._cacheWidth, h = this._cacheHeight, fBounds;
        if (!cacheCanvas) return;
        var ctx = cacheCanvas.getContext("2d");
        
        w = Math.ceil(w*scale);
        h = Math.ceil(h*scale);
        if (w != cacheCanvas.width || h != cacheCanvas.height) {
            cacheCanvas.width = w;
            cacheCanvas.height = h;
        } else if (!compositeOperation) {
            ctx.clearRect(0, 0, w+1, h+1);
        }
        
        ctx.save();
        ctx.globalCompositeOperation = compositeOperation;
        ctx.setTransform(scale, 0, 0, scale, -offX, -offY);
        this.draw(ctx, true);
        this._applyFilters();
        ctx.restore();
    };

3、copy到真正canvas

    p.drawFromCache = function(ctx) {
        var cacheCanvas = this.cacheCanvas;
        if (!cacheCanvas) { return false; }
        var scale = this._cacheScale, offX = this._cacheOffsetX, offY = this._cacheOffsetY, fBounds;
        if (fBounds = this._applyFilterBounds(offX, offY, 0, 0)) {
            offX = fBounds.x;
            offY = fBounds.y;
        }
        ctx.drawImage(cacheCanvas, offX, offY, cacheCanvas.width/scale, cacheCanvas.height/scale);
        return true;
    };

但是,这样会引起问题。在Android上运行,可以发现webview native层的内存占用飞涨,关键因素就是这个位图缓存。

虽然矢量图可能在舞台上被移除了,但由于JS层和DOM层两个关联,导致垃圾回收机制没有正常发挥。

需要注意的是,在矢量图被移除的时候,必须在JS侧显式地把临时canvas置为null

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏林德熙的博客

wpf DoEvents 用法原理存在的坑推荐方法

如果在执行一段卡UI的代码,这时如何让UI响应。如果存在代码需要获得依赖属性,那么代码就需要在UI线程执行,但是这时就会卡UI,为了让UI响应,所以就需要使用D...

1151
来自专栏漫漫全栈路

HTML页面中的lang属性

最近想做点小项目,好久没写前端了,打开VScode,输了个HTML,突然忘记了中文的lang标识是什么了,只是隐约记得是zh,然而科普之后才知道,14年学习的...

3814
来自专栏酷玩时刻

微信公众号开发之自定义菜单

在Jfinal-weixin中有封装菜单的创建、查询、删除、以及个性化菜单的创建、查询、删除、测试个性化菜单匹配结果

762
来自专栏张善友的专栏

JQuery相关资料

将SEO,WEB标准与AJAX进行到底 - JQuery(翻译+学习总结) jQuery——JavaScript冲击波 《15天漫游jQuery》 小试牛刀——...

2008
来自专栏我有一个梦想

UE4新手之编程指南

  虚幻引擎4为程序员提供了两套工具集,可共同使用来加速开发的工作流程。 新的游戏类、Slate和Canvas用户接口元素以及编辑器功能可以使用C++语言来编写...

3518
来自专栏程序员互动联盟

解密FFmpeg播放track mode控制

上一篇文章我们解决了在FFmpeg下如何处理H264和AAC的扩展数据,根据解出的NALU长度恢复了H264的起始码和AAC的ADTS头,这样一般来说播...

37712
来自专栏林德熙的博客

WPF 修改图片颜色

在 WPF 可以使用很多图片处理的方法,本文告诉大家的是一个图片处理,可以把处理的图片保存在文件。

1941
来自专栏python爬虫日记

python3下搜狗AI API实现

a、搜狗也发布了自己的人工智能 api,包括身份证ocr、名片ocr、文本翻译等API,初试感觉准确率一般般。

1283
来自专栏向治洪

MobX 在 React Native开发中的应用

MobX 是一款精准的状态管理工具库,如果你在 React 和 React Native 应用中使用过 Flux、Alt、Redux 和 Reflux,那毫不犹...

4218
来自专栏友弟技术工作室

GoLang实现google authenticator的CLI工具

两步认证在很多验证中都要使用。如果在手机客户端上,如果使用电脑,每次都要拿出手机,手动输入。还要担心会过时。效率不是很高。

933

扫码关注云+社区