日韩性视频-久久久蜜桃-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)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 亚洲91网 | 亚洲精品乱码久久久久久蜜桃图片 | 无码人妻aⅴ一区二区三区有奶水 | 成人毛片在线观看 | 欧洲美熟女乱又伦 | 乱精品一区字幕二区 | 久久av色 | 1024国产视频 | 欧美一区亚洲二区 | 九久久久久 | 欧美久久激情 | 成人永久免费视频 | 亚洲精品免费电影 | 操少妇视频 | 日韩免费电影一区 | 日韩精品一区二区亚洲av性色 | 亚洲色图导航 | 成人一二三四区 | 日韩无码精品一区二区 | 午夜秋霞 | 欧美大片在线看免费观看 | 好吊日免费视频 | 亚洲无码精品在线观看 | 国产一区欧美日韩 | 福利精品视频 | 日韩一区免费 | 亚洲综合色小说 | 91精品国产91综合久久蜜臀 | 亚洲男人天堂电影 | 国产精品人八做人人女人a级刘 | 色呦呦官网 | 久久成年网 | 久久综合亚洲色hezyo国产 | 美女扒开尿口给男人捅 | 午夜影院在线 | 99操 | 亚洲av成人片色在线观看高潮 | 国产精品99久久久久久人 | 欧美福利视频在线观看 | 欧美成人一区二区三区片免费 | 美女网站av | 天天插天天爱 | 精品乱码一区二区三四区视频 | 日韩av一区二区三区在线观看 | 久久视频这里只有精品 | 丰满护士巨好爽好大乳 | www色| 成人av男人的天堂 | 91亚洲欧美激情 | 波多野结衣之潜藏淫欲 | 国产叼嘿视频在线观看 | a天堂中文字幕 | 亚洲视频中文字幕 | 日本h在线 | 国产精品成人一区 | 97国产资源 | 日日夜夜爱| 免费成年人视频 | 日本 片 成人 在线 九色麻豆 | 在线观看视频一区 | 亚洲精品国产欧美在线观看 | 久久综合色婷婷 | 99视频国产精品免费观看a | 国产精品久久久久毛片 | 国产区精品在线观看 | 高潮在线视频 | 欧亚av| 亚洲va久久久噜噜噜久久天堂 | 欧美熟妇交换久久久久久分类 | 成人性视频在线 | 日本精品视频一区 | 少妇高潮喷水在线观看 | 欧美黄色a级 | 久久一级电影 | 久久久久久久久久久久久久 | 国产精品久久9 | 糖心vlog精品一区二区 | 亚洲自拍偷拍网站 | 中文字幕成人av | 国产女主播喷水高潮网红在线 | 国产资源av| 成人毛片一区二区三区 | 91入囗| 污视频在线免费观看 | 日本成人在线不卡 | 欧美做爰xxxⅹ性欧美大片 | 免费99精品国产自在在线 | 五月天久久久久久 | 欧美放荡办公室videos4k | 捆绑无遮挡打光屁股调教女仆 | 荫蒂被男人添免费视频 | 丁香婷婷深情五月亚洲 | 毛片aaa | 男人久久久 | 日韩国产成人无码av毛片 | av网址免费 | 国产伦精品一区二区三区高清 | 黑丝少妇喷水 | av片免费|