zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    学习方式的反省
    我又辞职了!
    mysql完全备份,增量备份及恢复脚本
    marquee.js jQuery 多功能无缝滚动插件
    ul与li应用样式及其兼容性
    闲谈 JavaScript 之事件绑定(转载自万戈)
    JavaScript 中万变不离其宗的 this 应用场景
    ScrollUp – 超轻量的可定制的回到顶部 jQuery 插件
    jQuery之Tab切换代码改进
    jQuery Unveil – 另一款非常轻量的延迟加载插件
  • 原文地址:https://www.cnblogs.com/kenkofox/p/4624362.html
Copyright © 2011-2022 走看看