elementui+js+vue——实现图片组件的封装
1. 实现图片的放大缩小
2. 实现图片的拖动功能
3. 实现图片的预览
最近同事在写一个关于 图片放大缩小拖动的功能,其实不止是图片,只要是在以下组件中的内容,都是可以支持放大缩小拖动的。
功能:
1.鼠标拖动:拖动改变位置
2.鼠标滚动:实现放大缩小功能
3.根据是否有图片,展示三种不同的效果
一:先上效果图:
1.没有内容的时候
2.有一张图片的时候
3.有两张图片的时候
二:分析组件
首先是一个弹层,可以使用el-dialog
组件才处理,其次,根据图片的数量,分为 0张图片/1张图片/2张图片等。
三: inc_imgsvg.vue组件的封装
1.html部分的代码
<template>
<div class="drag-outer"
ref="dragWrap"
:style="'width:'+(imgWidth=='auto'?'calc(50% - 10px)':imgWidth)"
@mouseenter="isHover = true"
@mouseleave="isHover = isMousedown = false"
@mousemove="dragMousemove">
<div class="drag-inner"
ref="dragElement"
@mousedown="dragMousedown"
@mouseup.stop="isMousedown = false">
<slot></slot>
</div>
</div>
</template>
2.script部分的代码
<script>
export default {
name: 'inc_imgsvg',
props: {
imgWidth: {
type:String,
default () {
return '400px'
}
},
scaleZoom: {
type: Object,
default () {
return {
max: 5,
min: 0.2
}
}
}
},
data() {
return {
isMousedown: false,
isHover: false,
moveStart: {},
translate: {x: 0, y: 0},
scale: 1
}
},
methods: {
handleScroll(e) {
if(this.isHover) {
let speed = e.wheelDelta/120
if(e.wheelDelta > 0 && this.scale < this.scaleZoom.max) {
this.scale+=0.2*speed
this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
}else if(e.wheelDelta < 0 && this.scale > this.scaleZoom.min){
this.scale+=0.2*speed
this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
}
}
},
dragMousedown() {
this.moveStart.x = event.clientX
this.moveStart.y = event.clientY
this.isMousedown = true
},
dragMousemove() {
if(this.isMousedown) {
this.translate.x += (event.clientX - this.moveStart.x) / this.scale
this.translate.y += (event.clientY - this.moveStart.y) / this.scale
this.$refs.dragElement.style.transform = `scale(${this.scale}) translate(${this.translate.x}px, ${this.translate.y}px)`
this.moveStart.x = event.clientX
this.moveStart.y = event.clientY
}
}
},
mounted() {
window.addEventListener('mousewheel',this.handleScroll,false)
}
}
</script>
3.css部分的代码
<style lang="scss" scoped>
.drag-outer {
overflow: hidden;
height:500px; float: left;
display: flex;
background-color:#fff;
justify-content: center;
align-items: center;
.drag-inner {
transform-origin: center center;
display: flex;
justify-content: center;
align-items: center;
cursor: move;
user-select: none;
width:100%;
height:100%;
>* {
-webkit-user-drag: none;
user-drag: none;
}
img{object-fit:contain; width:100%; height:100%}
}
}
</style>
四:组件的使用
1.弹层的代码——html部分
<template>
<el-dialog class="boxEDA" title="查看EDA模型信息" :visible.sync="show" width="80%" :before-close="handleClose">
<div class="imgs" :class="{no:!showImg}" v-loading="load">
<template v-if="showImg">
<inc_imgsvg v-if="this.edaInfo.thumbnail" :imgWidth="this.edaInfo.ethumbnail?'auto':'100%'">
<img :src="edaInfo.thumbnail" alt="">
</inc_imgsvg>
<inc_imgsvg v-if="this.edaInfo.ethumbnail" :imgWidth="this.edaInfo.thumbnail?'auto':'100%'">
<img :src="edaInfo.ethumbnail" alt="">
</inc_imgsvg>
</template>
<el-empty v-if="!showImg" description="暂无信息"></el-empty>
</div>
<p class="note" v-if="showImg">支持鼠标点击拖拽、鼠标滚轮放大缩小操作</p>
</el-dialog>
</template>
2.弹层的代码——script部分
<script>
import {searchSvc} from "@/api";
import inc_imgsvg from "@/pages/componentDetailCloud/inc_imgsvg";
export default {
name: "inc_showeda",
components: {inc_imgsvg},
props:['show','currentId'],
data(){
return{
load:false,pid:'',
edaInfo:{},
showImg:false,
}
},
mounted() {
this.load = true;
searchSvc.componentApi.getComponentFindSchById(this.currentId).then(res=>{
this.edaInfo = res.data;
this.showImg = res.data.thumbnail || res.data.ethumbnail;
}).finally(()=>{
this.load = false;
})
},
methods: {
handleClose() {
this.$parent.showEDA = false;
},
}
}
</script>
3.弹层的代码——css部分
<style scoped lang="scss">
.boxEDA ::v-deep .el-dialog__body{background-color:#eee;
.imgs{overflow: hidden; display:flex; justify-content:space-between;}
.imgs.no{background-color:#fff; justify-content: center}
}
.note{display: block; padding:1em 0 0 0; margin:0; color:#999; text-align: center}
</style>
完成!!!多多积累,多多收获!!!