如何在不看到“闪烁”的情况下更新SVG图像

时间:2014-12-12 11:14:06

标签: javascript jquery svg

我有一个SVG-Image,现在,当有更新时,服务器向我发送更新图像,我想在浏览器中重新加载图像而不会看到闪烁(白色空间而不是像100ms的图像)。

我的第一个方法:

$("#svg").html(newSVG); // With blinking

我的第二种方法:

在Frame2中加载更新的SVG,然后将其放入Frame1。还是眨着眼睛。

// Load SVG in frame2
$("#svg .frame2").hide().html(content).delay(500).show();

// Overwrite frame1 content  with frame2 content
$("#svg .frame1").delay(500).hide().html(content).delay(500).show();

// Remove frame2 content
$("#svg .frame2").hide().html("").show();

有没有办法以干净的方式进入,所以用户不会在短时间内看到白色的空图像?我可以使用jQuery和AngularJS。

非常感谢!

2 个答案:

答案 0 :(得分:2)

将新框架置于旧框架下(绝对定位和z-index将帮助您),将新图像数据加载到新框架中,在新图像的onload事件中将其z-index移动到旧框架之上帧。

或者您可以在新图像加载时将旧图像的不透明度转换为0,并将新图像的不透明度转换为1.

答案 1 :(得分:1)

在图形编程的最低级别,他们使用称为双缓冲的技巧来更新图像而不会闪烁。这个想法是你在某个地方有一个显示驱动程序,你可以告诉你绘制存储在你记忆某个区域的图像。

在这种情况下处理图形的直观方法是简单地将所有绘图都放入该区域。但是使用双缓冲,你可以使用两个区域:一个用于保存你完成的最后一帧,另一个用于绘制你正在处理的帧。完成绘制后,将显示驱动程序指向该区域,然后在其他区域中绘制下一帧。因为来回切换只涉及改变一个变量(告诉显示驱动器绘制哪个区域的变量),所以转换非常快。而且因为显示驱动程序只能看到完成的图像,所以没有闪烁。

我们无法在浏览器中访问此类低级技术,但我们可以调整其背后的基本理念。您可以通过将图像加载到视线之外的某个位置,用户无法看到它。完成后,将旧图像替换为新图像。一种可能性如下:

// Assume that the new SVG has been loaded into newSVG, like your first example.
var oldSVG = document.getElementById("svg");
oldSVG.parentNode.replaceChild(newSVG, oldSVG);

魔术发生在对replaceChild的调用中。 它会在一步中将旧图像换成新图像,这样浏览器就无法显示任何中间步骤。这可以防止闪烁,并可能节省性能,因为浏览器只需要重排一次(因为元素已更改)而不是两次(因为元素被删除,然后因为添加了元素)。

从技术上讲,对replaceChild的调用会返回已被换出的节点,因此如果您愿意为同一元素调用document.getElementById两次,那么可以将其作为单行调用即可。但这很浪费,特别是如果你要这么做的话,我们使用这个变量来避免不得不比我们更频繁地调用document.getElementById