日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > vue >内容正文

vue

pc 图片预览放大 端vue_移动端Vue.js的图片预览组件,支持放缩、滑动功能!

發(fā)布時間:2024/9/18 vue 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pc 图片预览放大 端vue_移动端Vue.js的图片预览组件,支持放缩、滑动功能! 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

功能:圖片預(yù)覽組件,支持雙手指放大/縮小,雙擊放大/縮小,單擊消失隱藏。

注:touch事件請手機(jī)預(yù)覽

源碼分享

組件參數(shù)

data() {

return {

loading: 2, // 1成功 2正在加載 3error失敗

dragObject: {},

starLine: 0, // 初始倆個點(diǎn)第1次距離

zoom: 1, // 放縮比

compress: null, // 最大壓縮比

elWidth: null, // 外層寬度

elHeight: null, // 外層高度

imgWidth: null, // 當(dāng)前圖片寬度

imgHeight: null, // 當(dāng)前圖片高度

mTop: 0, // margin-top 值

mLeft: 0, // margin-left 值

isTouch: false, // 是否touch

scrolling: false, // 是否放縮

animating: false, // 是否動畫中

isTwoClick: false, // 是否雙擊

startTime: null, // 第一次時間

timeFunc: null, // 定時器

}

},

組件初始化init(),dom綁定事件,區(qū)分滑動事件、單擊、雙擊事件

/**

* 初始化事件

* @param {Object} $el 當(dāng)前DOM

*/

init($el) {

this.elWidth = document.documentElement.clientWidth

this.elHeight = document.documentElement.clientHeight

$el.addEventListener('touchstart', (e) => {

if (this.animating) return

// 記錄點(diǎn)擊時間和第二次點(diǎn)擊的時差

if (this.startTime) this.dragObject.duration = new Date() - this.startTime

if (!this.startTime) this.startTime = new Date()

if (this.dragObject.duration) this.startTime = null

this.dragObject.startTime = new Date()

this.touchStart(e)

if (!this.isTouch) this.isTouch = e.touches.length > 1

})

$el.addEventListener('touchmove', (e) => {

....

})

$el.addEventListener('touchend', (e) => {

....

}

})

圖片加載完后執(zhí)行imgLoad()事件,設(shè)置圖片初始顯示的寬imgWidth高imgHeight以及放縮比compress

/**

* 圖片加載成功事件

*/

imgLoad(e) {

const compress = e.target.width / this.elWidth

const scale = this.scale > 3 ? this.scale : 3

this.imgWidth = compress > 1 ? this.elWidth : e.target.width

this.imgHeight = compress > 1 ? e.target.height / compress : e.target.height

this.compress = compress > scale ? compress : scale

this.loading = 1

},

滑動開始,區(qū)分放縮事件or滑動事件

$el.addEventListener('touchmove', (e) => {

e.preventDefault()

if (this.animating) return

this.isTouch = true

if (e.touches.length === 2) this.touchTwoMove(e)

if (e.touches.length === 1) this.touchMove(e)

})

touchStart()滑動開始事件

/**

* 觸發(fā)開發(fā)

*/

touchStart(e) {

const touch = e.touches[0]

if (e.touches.length > 1) {

// 放縮初始倆點(diǎn)的距離

const touch2 = e.touches[1]

const diffX = touch.pageX - touch2.pageX

const diffY = touch.pageY - touch2.pageY

this.starLine = Math.pow((diffX * diffX + diffY * diffY), 0.5)

}

// 緩存初始的margin-left和margin-top的比值

this.dragObject.topThan = this.mTop !== 0 ? this.mTop / this.reckonHeight(this.zoom) : 0

this.dragObject.leftThan = this.mLeft !== 0 ? this.mLeft / this.reckonWidth(this.zoom) : 0

this.dragObject.startLeft = touch.pageX

this.dragObject.startTop = touch.pageY

this.dragObject.zoom = this.zoom

}

touchMove()觸發(fā)滑動事件

/**

* 觸發(fā)移動

*/

touchMove(e) {

if (this.scrolling) return

const dragObject = this.dragObject

const touch = e.touches[0]

let xx = touch.pageX - (dragObject.oldLeft || dragObject.startLeft)

let yy = touch.pageY - (dragObject.oldTop || dragObject.startTop)

dragObject.oldLeft = touch.pageX

dragObject.oldTop = touch.pageY

if (this.imgWidth * dragObject.zoom > this.elWidth) {

if (Math.abs(this.mLeft) > this.reckonWidth(dragObject.zoom)) xx *= 0.3

this.mLeft += xx

}

if (this.imgHeight * dragObject.zoom > this.elHeight) {

if (Math.abs(this.mTop) > this.reckonHeight(dragObject.zoom)) yy *= 0.3

this.mTop += yy

}

},

touchEnd()觸發(fā)結(jié)束事件,計算滑動后的位置,并執(zhí)行動畫事件continueTranslate()

/**

* 解發(fā)結(jié)束

* @param {Number} dragDuration 間隔

*/

touchEnd(dragDuration) {

....

this.continueTranslate(top, left, this.mLeft, this.mTop)

},

continueTranslate()動畫事件,借助requestAnimationFrame()方法

/**

* 繼續(xù)執(zhí)行一段距離滑行

* @param {Number} top 將要到達(dá)的top值

* @param {Number} left 將要到達(dá)的left值

* @param {Number} oldX 動畫執(zhí)行前l(fā)eft值

* @param {Number} oldY 動畫執(zhí)行前top值

*/

continueTranslate(top, left, oldX, oldY) {

this.animating = true

const xx = left - oldX

const yy = top - oldY

let diffX = 0

let diffY = 0

let ALPHA = 0.88

const animationLoop = () => {

ALPHA *= 0.95

const resultX = Math.abs(diffX - xx) < 1

const resultY = Math.abs(diffY - yy) < 1

if (resultX && resultY) {

this.animating = false

this.mLeft = left

this.mTop = top

} else {

diffX = diffX * ALPHA + (1 - ALPHA) * xx

diffY = diffY * ALPHA + (1 - ALPHA) * yy

if (!resultX) this.mLeft = oldX + diffX

if (!resultY) this.mTop = oldY + diffY

animationFrame(animationLoop)

}

}

animationLoop()

},

touchTwoMove()放縮滑動事件

/**

* 放縮移動

*/

touchTwoMove(e) {

this.scrolling = true

const dragObject = this.dragObject

const touch = e.touches[0]

const touch2 = e.touches[1]

const diffX = touch.pageX - touch2.pageX

const diffY = touch.pageY - touch2.pageY

const line = Math.pow((diffX * diffX + diffY * diffY), 0.5) - this.starLine

let zoom = Number(dragObject.zoom + (line / 2 / 75))

if (zoom < 1) zoom = 1 - (1 - zoom) * 0.15

if (zoom > this.compress) zoom = this.compress + (zoom - 3) * 0.2

this.zoom = zoom

this.mLeft = dragObject.leftThan * this.reckonWidth(zoom)

this.mTop = dragObject.topThan * this.reckonHeight(zoom)

},

touchEnd()事件,當(dāng)touches.length===0才執(zhí)行事件,區(qū)分滑動事件、單擊、雙擊事件。

$el.addEventListener('touchend', (e) => {

if (this.animating || e.touches.length > 0) return

const dragObject = this.dragObject

// 單次間隔時長

const duration = new Date() - this.dragObject.startTime

let zoom = this.zoom

if (this.isTouch) {

// 滑動事件

clearTimeout(this.timeFunc)

this.timeFunc = null

// 滑動執(zhí)行事件

if (!this.scrolling) this.touchEnd(duration)

// 放縮執(zhí)行事件

if (this.scrolling) {

if (zoom > this.compress) zoom = this.compress

if (zoom < 1) zoom = 1

if (dragObject.leftThan) this.mLeft = dragObject.leftThan * this.reckonWidth(zoom)

if (dragObject.topThan) this.mTop = dragObject.topThan * this.reckonHeight(zoom)

}

this.isTouch = false

this.zoom = zoom

this.scrolling = false

this.starLine = 0

this.dragObject = {}

} else {

// 倆次點(diǎn)擊時長<250雙擊

if (dragObject.duration && dragObject.duration < 250) {

// 雙擊事件

clearTimeout(this.timeFunc)

this.timeFunc = null

this.zoom = zoom > 1 ? 1 : 2

this.mLeft = this.mTop = 0

this.dragObject = {}

} else {

// 單擊事件

if (this.timeFunc) return

this.timeFunc = setTimeout(() => {

this.timeFunc = null

this.dragObject = {}

this.startTime = null

this.zoom = 1

this.mLeft = this.mTop = 0

this.$emit('input', false)

}, 250)

}

}

})

結(jié)束...

效果圖

掃碼預(yù)覽

歡迎buging

總結(jié)

以上是生活随笔為你收集整理的pc 图片预览放大 端vue_移动端Vue.js的图片预览组件,支持放缩、滑动功能!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。