<template>
|
<div class="image-preview-container" v-loading="loading">
|
<!-- 控制工具栏 -->
|
<div class="image-controls">
|
<el-button-group>
|
<el-button size="mini" @click="zoomOut" :disabled="scale <= 0.2">
|
<i class="el-icon-zoom-out"></i> 缩小
|
</el-button>
|
<el-button size="mini" @click="resetZoom">
|
<i class="el-icon-refresh-left"></i> 重置 ({{ Math.round(scale * 100) }}%)
|
</el-button>
|
<el-button size="mini" @click="zoomIn" :disabled="scale >= 3">
|
<i class="el-icon-zoom-in"></i> 放大
|
</el-button>
|
</el-button-group>
|
|
<el-button-group>
|
<el-button size="mini" @click="rotate(-90)">
|
<i class="el-icon-refresh-left"></i> 左旋
|
</el-button>
|
<el-button size="mini" @click="rotate(90)">
|
<i class="el-icon-refresh-right"></i> 右旋
|
</el-button>
|
</el-button-group>
|
|
<el-button size="mini" type="success" @click="handleDownload" icon="el-icon-download">
|
下载
|
</el-button>
|
</div>
|
|
<!-- 图片渲染区域 -->
|
<div class="image-render-area" @mousemove="onMouseMove" @mouseleave="onMouseLeave">
|
<div class="image-wrapper" :style="imageWrapperStyle">
|
<img
|
ref="imageEl"
|
:src="imageUrl"
|
:alt="fileName"
|
:style="imageStyle"
|
@load="onImageLoad"
|
@error="onImageError"
|
/>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
name: 'ImagePreview',
|
props: {
|
imageUrl: {
|
type: String,
|
required: true
|
},
|
fileName: {
|
type: String,
|
default: ''
|
}
|
},
|
data() {
|
return {
|
loading: false,
|
scale: 1.0,
|
rotation: 0,
|
naturalWidth: 0,
|
naturalHeight: 0
|
}
|
},
|
computed: {
|
imageStyle() {
|
return {
|
transform: `scale(${this.scale}) rotate(${this.rotation}deg)`,
|
cursor: 'default',
|
maxWidth: '100%',
|
maxHeight: '100%',
|
transition: 'transform 0.3s ease'
|
}
|
},
|
|
imageWrapperStyle() {
|
return {
|
width: '100%',
|
height: '100%',
|
display: 'flex',
|
justifyContent: 'center',
|
alignItems: 'center',
|
overflow: 'auto'
|
}
|
}
|
},
|
methods: {
|
onImageLoad() {
|
this.loading = false;
|
},
|
|
onImageError() {
|
this.loading = false;
|
this.$message.error('图片加载失败');
|
},
|
|
zoomIn() {
|
this.scale = Math.min(this.scale + 0.1, 3.0);
|
},
|
|
zoomOut() {
|
this.scale = Math.max(this.scale - 0.1, 0.2);
|
},
|
|
resetZoom() {
|
this.scale = 1.0;
|
this.rotation = 0;
|
},
|
|
rotate(degrees) {
|
this.rotation = (this.rotation + degrees) % 360;
|
},
|
|
onMouseMove() {
|
// 可添加鼠标交互效果
|
},
|
|
onMouseLeave() {
|
// 可添加鼠标离开效果
|
},
|
|
handleDownload() {
|
const link = document.createElement('a');
|
link.href = this.imageUrl;
|
link.download = this.fileName;
|
link.style.display = 'none';
|
document.body.appendChild(link);
|
link.click();
|
document.body.removeChild(link);
|
this.$message.success('开始下载文件');
|
}
|
},
|
mounted() {
|
this.loading = true;
|
}
|
}
|
</script>
|
|
<style scoped>
|
.image-preview-container {
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
border: 1px solid #ebeef5;
|
border-radius: 4px;
|
}
|
|
.image-controls {
|
padding: 15px 20px;
|
background: #f5f7fa;
|
border-bottom: 1px solid #ebeef5;
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
flex-wrap: wrap;
|
gap: 10px;
|
}
|
|
.image-render-area {
|
flex: 1;
|
position: relative;
|
overflow: hidden;
|
background: #f8f9fa;
|
}
|
|
.image-wrapper {
|
padding: 20px;
|
}
|
|
.image-wrapper img {
|
max-width: 100%;
|
max-height: 100%;
|
object-fit: contain;
|
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
}
|
|
@media (max-width: 768px) {
|
.image-controls {
|
flex-direction: column;
|
gap: 10px;
|
}
|
}
|
</style>
|