Canvas 元素渲染在更新属性后终止

Canvas Element Rendering killed after updating an attribute

<polymer-element name="canvas-diagram" attributes="type width height json">
  <template>
    <div id="canvasField">
        Typ: {{type}}, Width:{{width}}, Height:{{height}}, json:{{json}}
        <div id="canvasContainer">
            <canvas id="canvasObj" width="{{width}}" height="{{height}}"></canvas>
        </div>    
    </div>
  </template>
  <script>
    function getMaxOfArray(numArray) {
        return Math.max.apply(null, numArray);
    }
    Polymer("canvas-diagram",{
        type: "bar",
        width: "300",
        height: "200",
        ready: function() {
            console.log("this.ready()");

            this.writeDiagram();
        },
        attributeChanged: function(attrName, oldVal, newVal) {
            console.log("this.attributeChanged()");

            this.writeDiagram();
        },
        writeDiagram : function(){
            console.log("this.writeDiagram()");

            if(typeof this.cv == "undefined"){
                this.cv = this.$.canvasObj.getContext("2d");
            }

            var values = new Array();
            for (var i=0; i<this.json.data.length;i++)
            {
                if(this.json.data[i].value)
                {
                    values.push(this.json.data[i].value*1);
                }
                else
                {
                    values.push(0);
                }
            }

            tmpBarLeft = 15;
            tmpBarWidth = (this.width-30)/values.length-10;

            for (var i=0; i<this.json.data.length;i++)
            {
                tmpBarHeight = this.json.data[i].value*1/getMaxOfArray(values) * (this.height-2*10-20);
                tmpBarTop = this.height-tmpBarHeight - 15;

                this.cv.fillStyle = "#aaa";
                this.cv.fillRect(tmpBarLeft, tmpBarTop, tmpBarWidth, tmpBarHeight);

                tmpBarLeft+=(tmpBarWidth+10);

            }
            console.log("rendering complete");

        },

      json: {
        data:[
            {"name":"Texts","value":"150"},
            {"name":"Videos","value":"50"},
            {"name":"Audio","value":"30"},
            {"name":"Test","value":"20"},
            {"name":"Test","value":"20"},
            {"name":"Test","value":"20"}
        ]}
    });
  </script>
</polymer-element>

http://plnkr.co/edit/GdbN7JVPSKSTItEfIFLG?p=preview

有一些值的简单渲染。但是当我将属性高度或宽度设置为另一个值时,渲染开始但不久之后一切都变成了空白。我完全不知道为什么。控制台显示 "undefined" 但不知道这是从哪里来的。不是来自我的代码。

attibuteChanged 方法在 canvas 可以重绘自身之前触发,因此它也在清除下一个 writeDiagram() 绘制操作。

您可以使用内置的 Polymer Async 方法允许 canvas 在重绘之前清除屏幕,如下所示:

attributeChanged: function(attrName, oldVal, newVal) {
 console.log("this.attributeChanged()");

 this.async(function() {
    this.writeDiagram();
 });        
}