避免闪烁的解决方案是将两个图像绝对定位在同一位置。计时器将在每一帧中交替加载一个或另一个。为每个图像设置一个load
处理程序,以便在加载图像时更改 z-index 并重新启动计时器。
向图像 url 添加一个额外的参数,使浏览器每次都要求服务器绕过其缓存。
如果帧之间的时间很短,通常浏览器会在服务器中正确配置keep-alive的情况下重复使用相同的连接 。它通常以 5-15 秒的典型值启用,您可以增加该值,因此如果您的 .jpg 图像以这种周期性更新,您不必担心并寻找更好的解决方案。
我基于这些想法提出了一个 UI 解决方案。但是,如果您使用 websocket/comet 机制为您提供 base64 格式的最后一个 .jpg 文件(只需通过返回的值更改 url),它也会起作用。
GWT 代码:
public void onModuleLoad() {
final Image i1 = new Image();
i1.setWidth("400px");
final Image i2 = new Image();
i2.setWidth("400px");
AbsolutePanel panel = new AbsolutePanel();
panel.add(i1, 0, 0);
panel.add(i2, 0, 0);
panel.setSize("600px", "400px");
RootPanel.get().add(panel);
// You could change this by base64 data if you use comet/websockets
String url = "my_image_url.jpg?";
final Timer loadNext = new Timer() {
boolean b;
int c;
public void run() {
// the counter parameter forces to load the next frame instead of using cache
if (b = !b) {
i1.setUrl(url + c++);
} else {
i2.setUrl(url + c++);
}
}
};
i1.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
i1.getElement().getStyle().setZIndex(1);
i2.getElement().getStyle().setZIndex(0);
loadNext.schedule(1000);
}
});
i2.addLoadHandler(new LoadHandler() {
public void onLoad(LoadEvent event) {
i1.getElement().getStyle().setZIndex(0);
i2.getElement().getStyle().setZIndex(1);
loadNext.schedule(1000);
}
});
loadNext.schedule(1000);
}
如果你想使用gwtquery,代码显然更小:
// You could change this by base64 data if you use comet/websockets
final String url = "my_image_url.jpg?";
final GQuery images = $("<img/><img/>").appendTo(document);
images.css($$("position: fixed, top: 10px, left: 600px, width: 400px"));
final Timer timer = new Timer() {
int c;
public void run() {
images.eq(c%2).attr("src", url + c++);
}
};
images.bind("load", new Function(){
public void f() {
$(this).css($$("z-index: 1")).siblings("img").css($$("z-index: 0"));
timer.schedule(1000);
}
});
timer.schedule(1000);