vue数据可视化大屏项目中,为了让数据大屏更加酷炫,会增加帧动画,在以前的项目中为了让是将帧动画转为雪碧图然后再使用的。今天反向操作一波,将雪碧图转为序列帧图片。
在线地址
关键代码
这里通过选择图片然后输入序列帧图片的宽和高,输入序列帧图片的数量,然后将雪碧图拆解为序列帧图片,压缩为zip文件进行下载。
<script>
import JSZip from 'jszip';
export default {
data() {
return {
frameWidth: 200,
frameHeight: 200,
canvas: null,
ctx: null,
fileName: '',
frameCount: 80, // 新增数量数据属性,默认为80
zip: new JSZip(),
};
},
mounted() {
this.canvas = document.createElement('canvas');
this.ctx = this.canvas.getContext('2d');
},
methods: {
// 新增方法,用于显示文件名
showFileName() {
const fileInput = this.$refs.fileInput;
const file = fileInput.files[0];
console.log(file)
if (file) {
this.fileName = file.name;
}
},
async splitImage() {
const fileInput = this.$refs.fileInput;
const file = fileInput.files[0];
if (!file) {
alert('请先选择图片文件');
return;
}
const img = new Image();
img.src = URL.createObjectURL(file);
await new Promise(resolve => img.onload = resolve);
this.canvas.width = this.frameWidth;
this.canvas.height = this.frameHeight;
let x = 0;
let y = 0;
for (let i = 0; i < this.frameCount; i++) {
this.ctx.clearRect(0, 0, this.frameWidth, this.frameHeight);
this.ctx.drawImage(img, x, y, this.frameWidth, this.frameHeight, 0, 0, this.frameWidth, this.frameHeight);
const frameData = this.canvas.toDataURL('image/png').split(',')[1];
if (frameData) {
this.zip.file(`frame_${i + 1}.png`, frameData, {base64: true});
} else {
console.error('生成图像数据失败');
}
x += this.frameWidth;
if (x >= img.width) {
x = 0;
y += this.frameHeight;
}
}
this.zip.generateAsync({type: "blob"}).then((blob) => {
this.downloadZip(blob, "frames.zip");
});
},
downloadZip(blob, filename) {
const link = document.createElement('a');
link.href = URL.createObjectURL(blob);
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
}
}
};
</script>