Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: 滚轮控制缩放,拖动图片查看 #44

Open
wants to merge 14 commits into
base: dev
Choose a base branch
from
85 changes: 73 additions & 12 deletions src/img-preview.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
<template>
<div class="img-preview">
<div class="dialog-mask" v-if="url"></div>
<div class="dialog-mask" @click="handleClose" v-if="url">
<div class="button-close" @click="handleClose">+</div>
</div>
<transition name="dialog-fade">
<div class="dialog-box" v-if="url" @click="handleClose">
<div class="dialog-box" v-if="url">
<div
ref="imgContainer"
class="dialog-img-box"
:style="{width: `${size.width}px`, height: `${size.height}px`, transform: `translate(-50%, -50%) scale(${size.scale})`}"
:class="[moving ? 'grabbing' : '']"
@wheel="handleImgScale"
@mousedown="handleMouseDown"
@mousemove="handleMouseMove"
@mouseup="handleMouseUp"
:style="{
width: `${size.width}px`,
height: `${size.height}px`,
transform: `translate(${-50 + distanceX / 10}%, ${-50 + distanceY / 10}%) scale(${size.scale})`,}"
></div>
</div>
</transition>
Expand Down Expand Up @@ -52,6 +62,8 @@ export default {
const img = new Image()
img.className = 'dialog-img'
img.src = url
img.draggable = 'false'
img.ondragstart = this.stopDrag
return new Promise(resolve => {
img.onload = () => resolve(computedSize(img))
}).then(size => {
Expand All @@ -69,17 +81,57 @@ export default {
data() {
return {
size: {},
cache: {}
cache: {},
moving: false,
startX: 0,
startY: 0,
distanceX: 0,
distanceY: 0
}
},
methods: {
// 阻止默认拖拽事件,兼容火狐
stopDrag(e) {
e.preventDefault()
return false
},
initPosition() {
this.moving = false
this.startX = 0
this.startY = 0
this.distanceX = 0
this.distanceY = 0
},
handleMouseDown(e) {
this.moving = true
this.startX = e.clientX - this.distanceX
this.startY = e.clientY - this.distanceY
},
handleMouseUp(e) {
this.moving = false
},
handleMouseMove(e) {
if (!this.moving) return
this.distanceX = e.clientX - this.startX
this.distanceY = e.clientY - this.startY
},
handleImgScale(e) {
e.preventDefault()
if (e.deltaY < 0) {
this.size.scale += 0.1
DeepenLau marked this conversation as resolved.
Show resolved Hide resolved
} else {
if (this.size.scale <= 0.5) return
this.size.scale -= 0.1
}
},
handleClose() {
this.$emit('input', '')
/**
* 预览窗口关闭事件
* @event close
*/
this.$emit('close')
this.initPosition()
},
handelKeyUp(event) {
if (event.key === 'Escape' && this.url) {
Expand All @@ -92,6 +144,15 @@ export default {

<style lang="stylus">
.img-preview {
.button-close {
position: fixed;
top: 20px;
right: 40px;
font-size: 40px;
color: #fff;
transform: rotate(45deg);
cursor: pointer;
}
.dialog-mask {
position: fixed;
top: 0;
Expand All @@ -101,25 +162,25 @@ export default {
background-color: rgba(0,0,0,.65);
height: 100%;
z-index: 2100;
cursor: zoom-out;
}
.dialog-box {
position: fixed;
overflow: hidden;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 2200;
outline: 0;
cursor: zoom-out;
}
.dialog-img-box {
position: relative;
position: fixed;
z-index: 2200;
top: 50%;
left: 50%;
border-radius: 4px;
background-color: #fff;
box-shadow: 0 4px 12px rgba(0,0,0,.15);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
cursor: grab;
&.grabbing {
cursor: grabbing;
}
.dialog-img {
width: 100%;
}
Expand Down