|
@@ -10,14 +10,18 @@
|
|
|
<ui-icon type="right"></ui-icon>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="over-box">
|
|
|
+ <div class="over-box" ref="containerRef">
|
|
|
<div v-show="!loading" class="image-list" :style="`transform:translateX(${-100 * imageNum}%);`">
|
|
|
- <div
|
|
|
+ <!-- <div
|
|
|
@click="openScale(i.src)"
|
|
|
:style="`transform:translateX(${100 * index}%);background-image:url(${common.changeUrl(i.src)});`"
|
|
|
class="image-item"
|
|
|
v-for="(i, index) in imageList"
|
|
|
- ></div>
|
|
|
+ ></div> -->
|
|
|
+ <div @click="openScale(i.src)" :style="`transform:translateX(${100 * index}%);`" class="image-item" v-for="(i, index) in imageList">
|
|
|
+ <img :id="`domImg${index}`" :src="common.changeUrl(i.src)" alt="" />
|
|
|
+ </div>
|
|
|
+
|
|
|
<!-- <div v-else :style="`transform:translateX(${100 * index}%);`" class="image-item" v-for="(i, index) in imageList">
|
|
|
<img @error="filesError(index)" :src="common.changeUrl(i.src)" alt="" />
|
|
|
</div> -->
|
|
@@ -120,12 +124,13 @@ const chengeImgae = type => {
|
|
|
} else {
|
|
|
imageNum.value++
|
|
|
}
|
|
|
+ if (props.viewer && !isMobile.value) {
|
|
|
+ resetScale()
|
|
|
+ }
|
|
|
}
|
|
|
const hanlderFiles = data => {
|
|
|
- console.log(data[0])
|
|
|
// store.commit('tag/setImageList', data[0])
|
|
|
setImageList(data[0])
|
|
|
- console.log(imageList.value.length, data[0].length - 1)
|
|
|
// if (imageNum.value < imageList.value.length + data[0].length - 1) {
|
|
|
// imageNum.value = imageList.value.length + data[0].length - 1
|
|
|
// }
|
|
@@ -153,6 +158,128 @@ const setImageList = data => {
|
|
|
}
|
|
|
store.commit('tag/setImageList', list)
|
|
|
}
|
|
|
+let result = { width: 0, height: 0 },
|
|
|
+ x,
|
|
|
+ y,
|
|
|
+ scale = 1,
|
|
|
+ minScale = 0.5,
|
|
|
+ maxScale = 4,
|
|
|
+ isPointerdown = false, // 按下标识
|
|
|
+ diff = { x: 0, y: 0 }, // 相对于上一次pointermove移动差值
|
|
|
+ lastPointermove = { x: 0, y: 0 }, // 用于计算diff
|
|
|
+ transform = { x: 0, y: 0 }
|
|
|
+
|
|
|
+const drag = image => {
|
|
|
+ // 绑定 pointerdown
|
|
|
+ image.addEventListener('pointerdown', function (e) {
|
|
|
+ isPointerdown = true
|
|
|
+ image.setPointerCapture(e.pointerId)
|
|
|
+ lastPointermove = { x: e.clientX, y: e.clientY }
|
|
|
+ })
|
|
|
+ // 绑定 pointermove
|
|
|
+ image.addEventListener('pointermove', function (e) {
|
|
|
+ if (isPointerdown) {
|
|
|
+ const current = { x: e.clientX, y: e.clientY }
|
|
|
+ diff.x = current.x - lastPointermove.x
|
|
|
+ diff.y = current.y - lastPointermove.y
|
|
|
+ lastPointermove = { x: current.x, y: current.y }
|
|
|
+ x += diff.x
|
|
|
+ y += diff.y
|
|
|
+
|
|
|
+ image.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) scale(' + scale + ')'
|
|
|
+ // log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(0)}<br>scale = ${scale.toFixed(5)}`
|
|
|
+ }
|
|
|
+ e.preventDefault()
|
|
|
+ })
|
|
|
+ // 绑定 pointerup
|
|
|
+ image.addEventListener('pointerup', function (e) {
|
|
|
+ if (isPointerdown) {
|
|
|
+ isPointerdown = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // 绑定 pointercancel
|
|
|
+ image.addEventListener('pointercancel', function (e) {
|
|
|
+ if (isPointerdown) {
|
|
|
+ isPointerdown = false
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+const containerRef = ref(null)
|
|
|
+
|
|
|
+const zoomFun = e => {
|
|
|
+ let ratio = 1.1
|
|
|
+ // 缩小
|
|
|
+ if (e.deltaY > 0) {
|
|
|
+ ratio = 1 / 1.1
|
|
|
+ }
|
|
|
+ const _scale = scale * ratio
|
|
|
+ if (_scale > maxScale) {
|
|
|
+ ratio = maxScale / scale
|
|
|
+ scale = maxScale
|
|
|
+ } else if (_scale < minScale) {
|
|
|
+ ratio = minScale / scale
|
|
|
+ scale = minScale
|
|
|
+ } else {
|
|
|
+ scale = _scale
|
|
|
+ }
|
|
|
+ // 目标元素是img说明鼠标在img上,以鼠标位置为缩放中心,否则默认以图片中心点为缩放中心
|
|
|
+ console.log(e.target.tagName)
|
|
|
+ if (e.target.tagName === 'IMG') {
|
|
|
+ const origin = {
|
|
|
+ x: (ratio - 1) * result.width * 0.5,
|
|
|
+ y: (ratio - 1) * result.height * 0.5,
|
|
|
+ }
|
|
|
+ // 计算偏移量
|
|
|
+ x -= (ratio - 1) * (e.clientX - x) - origin.x
|
|
|
+ y -= (ratio - 1) * (e.clientY - y) - origin.y
|
|
|
+ }
|
|
|
+ imgEle.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) scale(' + scale + ')'
|
|
|
+ // log.innerHTML = `x = ${x.toFixed(0)}<br>y = ${y.toFixed(0)}<br>scale = ${scale.toFixed(5)}`
|
|
|
+ e.preventDefault()
|
|
|
+}
|
|
|
+
|
|
|
+// 滚轮缩放
|
|
|
+const initWheelZoom = imgEle => {
|
|
|
+ containerRef.value.addEventListener('wheel', zoomFun)
|
|
|
+}
|
|
|
+const removeWheelZoom = () => {
|
|
|
+ containerRef.value.removeEventListener('wheel', zoomFun)
|
|
|
+}
|
|
|
+
|
|
|
+const resetScale = () => {
|
|
|
+ result = { width: 0, height: 0 }
|
|
|
+ x = null
|
|
|
+ y = null
|
|
|
+ scale = 1
|
|
|
+ minScale = 0.5
|
|
|
+ maxScale = 4
|
|
|
+ isPointerdown = false // 按下标识
|
|
|
+ diff = { x: 0, y: 0 } // 相对于上一次pointermove移动差值
|
|
|
+ lastPointermove = { x: 0, y: 0 } // 用于计算diff
|
|
|
+
|
|
|
+ nextTick(() => {
|
|
|
+ removeWheelZoom()
|
|
|
+ initScale()
|
|
|
+ })
|
|
|
+}
|
|
|
+let imgEle = null
|
|
|
+const initScale = () => {
|
|
|
+ imgEle = document.getElementById(`domImg${imageNum.value}`)
|
|
|
+
|
|
|
+ x = 0
|
|
|
+ y = 0
|
|
|
+ imgEle.style.transform = 'translate3d(' + x + 'px, ' + y + 'px, 0) scale(1)'
|
|
|
+
|
|
|
+ result.width = imgEle.width
|
|
|
+ result.height = imgEle.height
|
|
|
+
|
|
|
+ nextTick(() => {
|
|
|
+ // 拖拽查看
|
|
|
+ drag(imgEle)
|
|
|
+ // 滚轮缩放
|
|
|
+ initWheelZoom(imgEle)
|
|
|
+ })
|
|
|
+}
|
|
|
onMounted(async () => {
|
|
|
const app = await useApp()
|
|
|
isMobile.value = app.config.mobile
|
|
@@ -161,6 +288,13 @@ onMounted(async () => {
|
|
|
let img = new Image()
|
|
|
img.onload = () => {
|
|
|
loading.value = false
|
|
|
+
|
|
|
+ if (props.viewer && !isMobile.value) {
|
|
|
+ //pc端缩放
|
|
|
+ nextTick(() => {
|
|
|
+ initScale()
|
|
|
+ })
|
|
|
+ }
|
|
|
}
|
|
|
img.src = common.changeUrl(imageList.value[0].src)
|
|
|
// if (imageList.value.length > 1) {
|
|
@@ -374,9 +508,12 @@ const openScale = src => {
|
|
|
background-repeat: no-repeat;
|
|
|
background-size: contain;
|
|
|
background-position: center;
|
|
|
+ overflow: hidden;
|
|
|
img {
|
|
|
height: 100%;
|
|
|
- width: auto;
|
|
|
+ width: 100%;
|
|
|
+ object-fit: contain;
|
|
|
+ touch-action: none;
|
|
|
}
|
|
|
}
|
|
|
}
|