先封装一个imageLoader类,新建一个imageLoader.js文件
class ImageLoader {
constructor() {
this.images = []
this.progressCallback = null
}
// 加载图片,并返回一个 Promise
loadImage(url) {
return new Promise((resolve, reject) => {
const image = new Image()
image.onload = () => resolve(image)
image.onerror = reject
image.src = url
})
}
// 加载所有图片
loadImages(urls) {
const totalImages = urls.length
let loadedImages = 0
return Promise.all(
urls.map((url) => {
return this.loadImage(url).then((image) => {
loadedImages++
if (this.progressCallback) {
const progress = (loadedImages / totalImages) * 100
this.progressCallback(progress)
}
return image
})
})
)
}
// 设置进度回调函数
onProgress(callback) {
this.progressCallback = callback
}
// 创建 Canvas 动画
createAnimation(canvas, images, frameRate = 30) {
const ctx = canvas.getContext('2d')
let currentIndex = 0
let isPaused = true
let animationInterval
const drawFrame = () => {
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(images[currentIndex], 0, 0)
currentIndex = (currentIndex + 1) % images.length
}
const startAnimation = () => {
animationInterval = setInterval(drawFrame, 1000 / frameRate)
}
const stopAnimation = () => {
clearInterval(animationInterval)
}
return {
play: () => {
if (isPaused) {
startAnimation()
}
isPaused = false
},
pause: () => {
stopAnimation()
isPaused = true
},
setSpeed: (fps) => {
frameRate = fps
if (!isPaused) {
stopAnimation()
startAnimation()
}
},
}
}
}
在页面中具体使用,创建一个index.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Sequence Animation</title>
<style>
.flex {
display: flex;
}
</style>
</head>
<body>
<canvas id="canvas" width="800" height="600"></canvas>
<div class="flex">
<button id="playButton">开始</button>
<button id="pauseButton">暂停</button>
<input type="range" id="speedSlider" min="1" max="60" value="30">
<span id="speedValue">30 FPS</span>
</div>
<script src="imageLoader.js"></script>
<script>
const imageLoader = new ImageLoader();
const canvas = document.getElementById('canvas');
const urls = [
'https://img.alicdn.com/bao/uploaded/i1/2844183150/O1CN01sk4WyK1Z8kL5J8nCm_!!2844183150.jpg',
'https://img.alicdn.com/bao/uploaded/i2/735011836/O1CN018Dvhtw1PQvyjpdWKH_!!2-item_pic.png',
'https://img.alicdn.com/bao/uploaded/i4/3548771708/O1CN01jqFX831OUJKXuxHpF_!!3548771708.jpg'
// 添加其余图片的 URL
];
imageLoader.loadImages(urls).then(images => {
const animation = imageLoader.createAnimation(canvas, images);
animation.play();
// 示例:监听下载进度
imageLoader.onProgress(progress => {
console.log(`Progress: ${progress}%`);
});
// 示例:动画控制
document.getElementById('playButton').addEventListener('click', () => {
console.log('Play button clicked')
animation.play();
});
document.getElementById('pauseButton').addEventListener('click', () => {
console.log('pause button clicked')
animation.pause();
});
document.getElementById('speedSlider').addEventListener('input', (event) => {
const speed = parseInt(event.target.value);
document.getElementById('speedValue').textContent = `${speed} FPS`;
animation.setSpeed(speed);
});
});
</script>
</body>
</html>