我在一个HTML网页上有很多<img>
个标签,其中一些标签共享相同的动画GIF文件。 src
网址是由JavaScript动态设置的,但是我的代码会重新播放相同的字符,或者跟随字符会立即显示最后一帧。
这个想法:这是一个艺术项目。在输入一些文本后,字符以特殊字体显示,并且一些转换是每个字符字符(一个接一个)完成,我只能通过使用动画GIF来实现。文本被拆分为单个字符,<img>
标签的创建方式如下:
<!-- delivered HTML at page load -->
<img src="initial/f.png"> <!-- I used to PNG here to outline -->
<img src="initial/o.png"> <!-- the animation is NOT set a first -->
<img src="initial/o.png">
动画开始时,第一个<img>
的网址设为transition/f.gif
。只有在完成播放(由时间确定)后才会设置第二张图像等。
<!-- while 2nd animation is running -->
<img src="transition/f.gif"> <!-- already finished, displays last frame -->
<img src="transition/o.gif"> <!-- being animated right now -->
<img src="transition/o.png"> <!-- will be reset to o.gif in next step -->
我无法解决的问题:从示例中播放o.gif
之后,下一个O的动画无效。
我尝试为每个角色定义一个类,并将图像指定为background-image
。一旦出现任何字符,任何后续出现的同一个字母在显示时立即显示该GIF的最后一帧(结束状态)。
我还尝试直接使用JavaScript设置src
属性,但是当第二个字母O设置为这样时,第一个字母O的动画会同步重新启动。但它应该停留在最后一帧。
由于HTML页面也应该在本地文件系统上工作,我认为绕过缓存机制的o.gif?random=argument
这样的参数将不起作用或者不会产生任何影响(可能在某些计算机上,我自己测试' t falsify)。
答案 0 :(得分:2)
您必须为图像创建唯一的网址,因此浏览器将始终重新加载字母而不是使用缓存的字母。 你可以用一个小的php来实现这个目的,它为参数输出正确的gif。
<img src="gif_printer.php?letter=o&t=1234567">
t参数应该是创建img标记时的时间戳。这为重新下载提供了足够的差异。
在php set标题中限制/禁用缓存和输出类型为gif,并简单地将图像的内容倒入stdout。
时间戳参数和缓存控制标题应足以让浏览器重新下载外翻字母。
如果您的测试环境没有做出正确的反应,您可以尝试使用htaccess解决方案,但为此您必须使用Web服务器(这可能已足以使之前的解决方案正常工作)。
这意味着将图像/ [a-z] .gif的任何网址重写为images / [a-z] .gif,所以只需删除除第一个字母和扩展名之外的其他噪音。
答案 1 :(得分:2)
考虑不使用GIF,而是使用图像序列和Javascript。我把一个粗略的可实例化的Javascript对象放在一起就是这样:
<html>
<head>
<script>
function Animator(target, frames, delay)
{
var _this = this;
// array of frames (image objects)
var f = [];
// a reference to the object where our frames will appear
var t = document.getElementById(target);
// the interval variable. Used to stop and start
var t_loop;
// create a new image element and remember it
var img_el = document.createElement("img");
// current frame
var c_frame = 0;
t.innerHTML = "";
t.appendChild(img_el);
var i, img;
// preload immediately
for(i = 0; i < frames.length; i++)
{
img = new Image();
img.src = frames[i];
f.push(img);
}
this.play = function()
{
t_loop = window.setInterval(_this.frame, delay);
}
this.stop = function()
{
clearInterval(t_loop);
}
this.gotoFrame = function(frame)
{
c_frame = frame;
_this.frame();
}
this.frame = function()
{
img_el.src = f[c_frame].src;
c_frame++;
if(c_frame >= f.length)
{
c_frame = 0;
}
}
}
function loaded()
{
var quip_frames = [
"http://www.abcteach.com/images/abma_thumb.gif",
"http://www.abcteach.com/images/abcu_thumb.gif",
"http://www.abcteach.com/images/zbma_thumb.gif",
"http://www.abcteach.com/images/zbcu_thumb.gif",
"http://www.abcteach.com/images/dnma_thumb.gif",
"http://www.abcteach.com/images/dncu_thumb.gif"
];
var anim1 = new Animator("target1", quip_frames, 100);
var anim2 = new Animator("target2", quip_frames, 100);
var anim3 = new Animator("target3", quip_frames, 100);
anim1.play();
window.setTimeout(anim2.play, 200);
window.setTimeout(anim3.play, 300);
}
</script>
</head>
<body onload="loaded()">
<div id="target1">
</div>
<div id="target2">
</div>
<div id="target3">
</div>
</body>
</html>
感谢ABCTeach的图片
对象将图像加载到循环中,将它们存储在一个数组中,然后通过简单地使用setInterval()
以所需的速率交换帧。当页面加载时,它会生成其中三个对象,每个对象指向不同的DIV,但每个对象都有相同的帧。然后它告诉每个人玩一个不同的延迟(第一个立即,第二个在200ms之后,第三个在300ms之后)。在您的情况下,您将为您使用的每个字母创建一个数组:
var A = [*array of URLs to images of the letter A*];
var B = [*array of URLs to images of the letter B*];
...
然后为页面上的每个div创建一个新的Animator
对象,并向其发送相应的字母数组:
var letter_so_and_so = new Animator("div_so_and_so", A, 100);
var letter_this_and_that = new Animator("div_this_and_that", B, 100);
var another_letter = new Animator("another_div", B, 100);
最后给每个人一个偏移开始,或者调用他们的Animator.gotoFrame(f)
方法在不同的帧上启动它们(不要忘记Animator.play()
!)。
尝试在你的代码中采用这样的东西,我认为你会发现它有奇效。