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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM