所以,我的表格在其单元格上有动态绘制的背景,并且会定期更新。这个表可以有数百行,因此效率非常重要。
我目前的解决方案是将背景绘制到画布上,然后通过数据URI将此图形用作单元格上的背景图像。
cell.css({backgroundImage:'url(' + canvas.toDataURL('image/png')+ ')' });
这样做没问题,但是html源代码变得非常大,编码图像中的所有重复内容都会变得很大,最终会让一些浏览器挣扎。
有没有办法以某种方式重复使用相同的数据URI而不重复它?
我考虑过的其他想法:
- 直接使用canvas元素作为-webkit-canvas
或-moz-element
的背景,但这似乎与Internet Explorer不兼容。
- 绝对在每个单元格中放置画布并重新绘制内容,但是当我们达到数百行时,这并不是非常有效。
答案 0 :(得分:1)
选项1:
使用Canvas2Blob。
基本上,您可以通过调用URL.createObjectURL(blob);
来获取网址字符串,其中blob
是从polyfill返回的对象canvas.toBlob(function (blob) {...});
这样做的好处是,由于编码,Blob
的大小是dataURI字符串的3/4,并且在使用100次时不应该是内存/处理器密集型。
选项2:
如果你真的想使用canvas.toDataURL('image/png');
,那么将它存储到像
var str = canvas.toDataURL('image/png');
// ...
cell.css({backgroundImage:'url(' + str + ')' });
根据浏览器的实现,调用.toDataURL()
可能是一个非常昂贵的函数调用,并且因为所有单元格需要相同的背景,所以最好只将它存储到字符串中。
答案 1 :(得分:1)
有没有办法以某种方式重用相同的数据URI而不重复它?
不,数据URI只是二进制数据的文本表示,这里是生成的PNG(或JPEG)文件。如果您需要更改内容,则必须首先更改二进制数据,然后根据该数据对URI进行编码。因此无法重复使用。
.nohistory {margin-top: 20px;}
也是一个非常缓慢的过程,使用这种技术还涉及每次构建,编码,压缩,解析,解压缩和解码位图数据,这在编码/解码文件之上并从Base-64表示。
如何有效地更新数百个元素的动态绘制背景
以下是我要做的事情:
<footer class="nohistory columns" style="margin-top: 20px;">
&#13;
toDataURL()
&#13;
var table = document.querySelector("table"),
canvas = document.querySelector("canvas"),
ctx = canvas.getContext("2d");
getArray(); // and on resize if needed
function getArray() {
// todo: iterate table here to find sizes for each cell.
// For simplicity just the table width and height is measured in this example:
var rect = table.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;
}
// render for demo -
(function loop() {
render();
requestAnimationFrame(loop)
})();
function render() {
var cw = canvas.width * 0.5,
ch = canvas.height * 0.5;
for(var y = 0; y < 2; y++) {
for(var x = 0; x < 2; x++) {
ctx.fillStyle = "hsl(" + (360*Math.random()) + ",80%,70%)";
ctx.fillRect(x * cw, y * ch, cw, ch);
}
}
}
&#13;
另一种方法是使用图像预生成数组并将其源设置为data-uri。
然后直接将图像用作表格的背景。