实现思路,使用canvas绘制图像,然后使用动画帧刷新页面
<template>
<canvas ref="imageCanvas" :style="canvasStyle"></canvas>
</template>
<script>
export default {
props: {
info: {
type: Object,
default: () => ({ url: '', index: '' }),
},
},
data() {
return {
currentImage: null,
isFullScreen: false,
canvas: null,
ctx: null,
canvasStyle: {
height: '100%',
width: '100%',
cursor: 'pointer',
transition: 'transform 0.3s ease-in-out',
},
animationFrameId: null,
};
},
mounted() {
this.initCanvas();
this.startAnimation();
this.addEventListeners();
},
watch: {
'info.url'(newVal) {
if (newVal) {
this.loadImage();
}
},
},
beforeDestroy() {
this.stopAnimation();
this.destroyCanvas();
this.destroyImage();
this.removeEventListeners();
},
methods: {
initCanvas() {
this.canvas = this.$refs.imageCanvas;
this.ctx = this.canvas.getContext('2d');
},
loadImage() {
if (!this.info || !this.info.url) return;
this.currentImage = new Image();
this.currentImage.onload = () => {
this.drawCanvas();
};
this.currentImage.src = this.info.url;
},
drawCanvas() {
if (this.currentImage) {
this.canvas.width = this.currentImage.width;
this.canvas.height = this.currentImage.height;
this.ctx.drawImage(this.currentImage, 0, 0, this.canvas.width, this.canvas.height);
}
},
startAnimation() {
const animate = () => {
this.loadImage();
this.animationFrameId = requestAnimationFrame(animate);
};
this.animationFrameId = requestAnimationFrame(animate);
},
stopAnimation() {
if (this.animationFrameId) {
cancelAnimationFrame(this.animationFrameId);
this.animationFrameId = null;
}
},
addEventListeners() {
if (this.canvas) {
this.canvas.addEventListener('dblclick', this.toggleFullscreen);
}
document.addEventListener('fullscreenchange', this.handleFullscreenChange);
},
removeEventListeners() {
if (this.canvas) {
this.canvas.removeEventListener('dblclick', this.toggleFullscreen);
}
document.removeEventListener('fullscreenchange', this.handleFullscreenChange);
},
toggleFullscreen() {
if (!this.isFullScreen) {
if (this.canvas.requestFullscreen) {
this.canvas.requestFullscreen();
} else if (this.canvas.mozRequestFullScreen) {
this.canvas.mozRequestFullScreen();
} else if (this.canvas.webkitRequestFullscreen) {
this.canvas.webkitRequestFullscreen();
} else if (this.canvas.msRequestFullscreen) {
this.canvas.msRequestFullscreen();
}
} else {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
}
}
},
handleFullscreenChange() {
this.isFullScreen = !this.isFullScreen;
if (this.isFullScreen) {
this.canvasStyle = {
position: 'fixed',
top: '0',
left: '0',
width: '100vw',
height: '100vh',
backgroundColor: 'rgba(0, 0, 0, 0.9)',
cursor: 'default',
objectFit: 'contain',
objectPosition: 'center',
transition: 'transform 0.3s ease-in-out',
zIndex: 9999,
};
document.body.style.overflow = 'hidden';
} else {
this.canvasStyle = {
height: '100%',
width: '100%',
cursor: 'pointer',
transition: 'transform 0.3s ease-in-out',
};
document.body.style.overflow = 'auto';
}
},
destroyCanvas() {
if (this.canvas) {
this.canvas.width = 0;
this.canvas.height = 0;
this.ctx = null;
this.canvas = null;
}
},
destroyImage() {
if (this.currentImage) {
this.currentImage.onload = null;
this.currentImage.onerror = null;
this.currentImage.src = '';
this.currentImage = null;
}
},
},
};
</script>
<style scoped>
/* 可以根据需要添加 scoped 样式 */
</style>