CSS生成GIF,为什么获取的都是同一帧?
我使用html2canvas库截取页面元素,为什么生成的图片全是最后一帧的?以下代码可直接复制运行
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
.index {
width: 300px;
height: 200px;
background-color: #eee;
}
.box {
width: 100px;
height: 50px;
background-color: #bbb;
}
.box2 {
width: 300px;
height: 200px;
background-color: #ccc;
}
.animate {
transform: translateX(200px);
transition: all 3s ease;
}
</style>
<body>
<div class="index">
<button class="btn">do</button>
<button class="btn2">transform</button>
<div class="box"></div>
</div>
<div class="box2"></div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/0.5.0-beta4/html2canvas.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gifshot/build/gifshot.min.js"></script>
<script>
const btn = document.querySelector('.btn')
const btn2 = document.querySelector('.btn2')
const ele = document.querySelector('.index')
const box = document.querySelector('.box')
const box2 = document.querySelector('.box2')
let frameArr = []
btn.addEventListener('click', () => {
box.classList.add('animate')
const dur = 3000 // 动画持续时间
frameArr = [] // 存储每一帧
const now = Date.now()
const captureFrame = async () => {
const canvas = await html2canvas(ele, {
useCORS: true, // 【重要】开启跨域配置
scale: window.devicePixelRatio < 3 ? window.devicePixelRatio : 2,
allowTaint: true, // 允许跨域图片
})
const url = canvas.toDataURL("image/png", 1.0)
console.log('url', url)
frameArr.push(url)
if (Date.now() - now < dur) {
requestAnimationFrame(captureFrame)
} else {
console.log('frameArr---22', frameArr)
// 获取完所有截图后,可以进行下一步操作
}
}
captureFrame()
})
btn2.addEventListener('click', () => {
console.log('btn2 click', frameArr)
gifshot.createGIF({
images: frameArr,
gifWidth: 300,
gifHeight: 200,
interval: 0.15,
numWorkers: 2,
progressCallback: function (progress) {
// 显示 GIF 转换进度
console.log('GIF 转换进度:' + progress * 100 + '%');
},
completeCallback: function (gifUrl) {
// 在页面上显示 GIF 图像
console.log('GIF 转换完成:' + gifUrl);
}
}, (obj) => {
console.log('obj', obj);
if (!obj.error) {
const animatedImage = document.createElement('img');
animatedImage.src = obj.image
box2.appendChild(animatedImage);
}
});
})
</script>
</html>
回复
1个回答

test
2024-07-01
因为 html2canvas,顾名思义,它是自己画的界面,不是直接从浏览器获取的画面截图,那么自然每次 GIF 都是第一帧。
要解决的话,可能必须在截图的时候手动替换成按时间换算出来的那一帧截图。
回复

适合作为回答的
- 经过验证的有效解决办法
- 自己的经验指引,对解决问题有帮助
- 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
- 询问内容细节或回复楼层
- 与题目无关的内容
- “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容