在javascript中,我引用了DOM <img>
元素。我需要在JavaScript中更改<img>
显示的图像。
到目前为止,我已经通过将image.src
属性更改为新图像的URL进行了尝试。这行得通,但是仍然存在一个问题:我需要每秒更改图像多次,并且更改src
属性会导致浏览器对图像(已经缓存)进行新的GET请求,由于将有数百个同时进行的客户端,因此对Web服务器造成了压力。
我当前(低效)的解决方案是这样完成的:
let image = document.querySelector("img");
setInterval(function(){
image.src = getNextImageURL();//this causes a GET request
}, 10);
function getNextImageURL() {
/*...implementation...*/
}
<img>
我正在寻找一种更有效的更改图像的方法,该方法不会引起任何不必要的HTTP请求。
答案 0 :(得分:3)
我认为您需要以其他方式进行编码...
如果要减少请求,则应将所有图像组合在一张Sprite Sheet中。
许多游戏内动画都使用了这个技巧。
但是您需要将 1 2 3 4 5 6 7 8
0 R 2654 R 1536 510 2590 2777 1677
1 1676 2824 3079 1677 R 3090 R 1709
2 2651 R 1677 1409 1664 2252 1710 1536
3 1676 1677 2085 R 1710 2916 3140 1963
标记更改为另一个标记,例如<img/>
这里的想法是我们只有一个图像,我们只是根据需要更改视口
用于精灵表的样本
<div></div>
let element = document.querySelector("div");
let i = 1
setInterval(function(){
element.style.backgroundPosition= getNextImagePostion(i++);//this will change the posion
}, 100);
function getNextImagePostion(nextPos) {
/*...implementation...*/
// this just for try
// 6 is the number of images in sheet
// 20 is the height for one segment in sheet
var posX = 100*(nextPos%6);
// first is position on x and latter is position on y
return "-"+posX+"px 0px ";
}
.image {
width: 100px; /* width of single image*/
height: 100px; /*height of single image*/
background-image: url(https://picsum.photos/500/100?image=8) /*path to your sprite sheet*/
}
答案 1 :(得分:2)
如果Sprite-sheet想法不起作用(例如,因为您的图片很大),请使用canvas。
您只需要预加载所有图像,将它们存储在数组中,然后在画布上一个接一个地绘制它们即可:
const urls = new Array(35).fill(0).map((v, i) =>
'https://picsum.photos/500/500?image=' + i
);
// load all the images
const loadImg = Promise.all(
urls.map(url =>
new Promise((res, rej) => {
// each url will have its own <img>
const img = new Image();
img.onload = e => res(img);
img.onerror = rej;
img.src = url;
})
)
);
// when they're all loaded
loadImg.then(imgs => {
// prepare the canvas
const canvas = document.getElementById('canvas');
// set its size
canvas.width = canvas.height = 500;
// get the drawing context
const ctx = canvas.getContext('2d');
let i = 0;
// start the animation
anim();
function anim() {
// do it again at next screen refresh (~16ms on a 60Hz monitor)
requestAnimationFrame(anim);
// increment our index
i = (i + 1) % imgs.length;
// draw the required image
ctx.drawImage(imgs[i], 0, 0);
}
})
.catch(console.error);
<canvas id="canvas"></canvas>
如果您希望时间控制:
const urls = new Array(35).fill(0).map((v, i) =>
'https://picsum.photos/500/500?image=' + i
);
// load all the images
const loadImg = Promise.all(
urls.map(url =>
new Promise((res, rej) => {
// each url will have its own <img>
const img = new Image();
img.onload = e => res(img);
img.onerror = rej;
img.src = url;
})
)
);
// when they're all loaded
loadImg.then(imgs => {
// prepare the canvas
const canvas = document.getElementById('canvas');
// set its size
canvas.width = canvas.height = 500;
// get the drawing context
const ctx = canvas.getContext('2d');
const duration = 100; // the number of ms each image should last
let i = 0;
let lastTime = performance.now();
// start the animation
requestAnimationFrame(anim);
// rAF passes a timestamp
function anim(time) {
// do it again at next screen refresh (~16ms on a 60Hz monitor)
requestAnimationFrame(anim);
const timeDiff = time - lastTime;
if(timeDiff < duration) { // duration has not yet elapsed
return;
}
// update lastTime
lastTime = time - (timeDiff - duration);
// increment our index
i = (i + 1) % (imgs.length);
// draw the required image
ctx.drawImage(imgs[i], 0, 0);
}
})
.catch(console.error);
<canvas id="canvas"></canvas>