简体   繁体   English

部分渲染HTML5画布-性能

[英]Partial render html5 canvas - Performance

I was working against a financial library that requires me to provide realtime updates to a line chart in canvas. 我在一个金融库中工作,该库要求我实时更新画布中的折线图。 To optimize the process of updating the chart, I thought of just updated the latest data-point rather than clearing and re-drawing the entire canvas. 为了优化更新图表的过程,我想到的只是更新最新的数据点,而不是清除并重新绘制整个画布。

When re-rendering only the latest datapoint frequently, I'm noticing that the line is not clear(there's a spot in the image). 当经常仅重新渲染最新数据点时,我注意到该行不清楚(图像中有斑点)。

Here's how the line looks initially(no redraw) 这是该行的初始外观(不重绘)

初始

And after a few updates of calling "partial_rerender", this is how the line looks: 在几次调用“ partial_rerender”之后,这是该行的外观: 重画

Notice the "joining" of the 2 lines is visible with a darker shade . 注意, 两行“连接”以较深的阴影可见

Is there a way to achieve partial re-drawing of lines only for the latest data point & not drawing the entire line completely? 有没有一种方法可以仅针对最新的数据点实现部分线的重绘而不能完全绘制整个线?

Reference code 参考代码

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.lineWidth = 2;
ctx.lineJoin = "miter";
ctx.moveTo(20, 50);
ctx.lineTo(100, 50);
ctx.save();
ctx.lineTo(150, 60);
ctx.stroke();

/*Call this every second to re-draw only the latest data point*/
function partial_rerender(){
ctx.clearRect(100,50, 400,400);
ctx.restore();
ctx.lineTo(150, 60);
ctx.stroke();
}

You need to create a new path each time you render or you end up re- rendering the same content over and over. 您每次渲染时都需要创建一个新路径,否则最终将一遍又一遍地重新渲染相同的内容。

ctx.save() and ctx.restore() push and pop from a stack, for every restore you need to have a matching save. ctx.save()ctx.restore()从堆栈中推送和弹出,对于每个还原,您都需要具有匹配的保存。 ctx.save() , ctx.restore() , ctx.restore() the second restore does nothing as there is no matching save. ctx.save()ctx.restore()ctx.restore()第二个还原不执行任何操作,因为没有匹配的保存。

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.lineWidth = 2;
ctx.lineJoin = "miter";
ctx.moveTo(20, 50);
ctx.lineTo(100, 50);
ctx.save();
ctx.lineTo(150, 60);
ctx.stroke();

// Your function should look more like this
function partial_rerender(){
   ctx.lineWidth = 2;
   ctx.lineJoin = "miter";
   ctx.save();  // needed to remove clip
   ctx.beginPath(); // removes old path ready to create a new one
   ctx.rect(100,50, 400,400); // create a clip area
   ctx.clip(); // activate the clip area
   ctx.clearRect(100,50, 400,400);
   ctx.beginPath(); // needed to draw the new path 
   ctx.moveTo(100,50)
   ctx.lineTo(150, 60);
   ctx.stroke();
   ctx.restore(); // remove the clip area
}

When you draw onto the canvas you do override the necessary pixels. 在画布上绘制时,您会覆盖必要的像素。 But the rest stays the same. 但是其余的保持不变。 What you are trying to achieve is not possible. 您试图实现的目标是不可能的。 You have to clear the canvas (canvas.clear()) and then redraw all elements to remove these artifacts from previous draw calls and to achieve your desired result. 您必须清除画布(canvas.clear()),然后重新绘制所有元素,以从先前的绘制调用中删除这些工件,并获得所需的结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM