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();
});
}
<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();
});
}