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

How to update a SVG-Image without seeing a "blinking"

本文关键字:情况下 更新 SVG 图像 闪烁 不看      更新时间:2023-09-26

我有一个SVG图像,现在,当有更新时,服务器会向我发送更新图像,我想在浏览器中重新加载图像而不会看到闪烁(空白而不是图像,例如100毫秒(。

我的第一个方法:

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

我的第二种方法:

将更新的 SVG 加载到 Frame2 中,然后将其放入 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。

谢谢!

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

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

我们无法在浏览器中访问此类低级技术,但我们可以调整其背后的基本思想。为此,您可以将图像加载到用户看不到它的地方。完成后,将旧映像换成新映像。一种可能性可能如下:

// 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

将新帧放在旧帧下(绝对定位和 z 索引将在这里为您提供帮助(,将新图像数据加载到新帧中,在新图像的 onload 事件中将其 z 索引移动到旧帧上方。

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

0,将新图像的不透明度转换为 1。