前情提要:搜索后發(fā)現(xiàn)沒(méi)有移動(dòng)端和PC兼容的符合我要求的現(xiàn)成組件于是想自己寫(xiě)一個(gè)圖片預(yù)覽的功能,寫(xiě)著寫(xiě)著發(fā)現(xiàn)里面門(mén)道有點(diǎn)子多導(dǎo)致越寫(xiě)越亂??于是我!
找到了這篇文章??
https://zhuanlan.zhihu.com/p/579668318
參考了這篇代碼??
https://code.juejin.cn/pen/7158337368355766285
大佬用了原生JS,我是放在VUE3項(xiàng)目中的,可以作一siusiu優(yōu)化??而且我想在這個(gè)基礎(chǔ)上新增一些卡邊界的功能,然后我不自量力地改呀加呀努力地寫(xiě)呀。。
只是想分享一段代碼的優(yōu)化過(guò)程。我真的。。人家一次能寫(xiě)好的東西,我改一百次出來(lái)都不一定是最優(yōu)雅的??雖然我會(huì)努力,可是我想死????
第一次嘗試??
if (scale.value < 1) {
const scale1TranslateDif = imgRef.value.offsetHeight - container.height
resetImage({
y: scale1TranslateDif > 0 ? y : Math.abs(scale1TranslateDif / 2)
})
} else if (scale.value > 2) {
const { top: translateY } = getBoundaryOffset({originO: newOrigin, newScale: 2})
// 放大后非長(zhǎng)圖居中
// console.log(imgRef.value.offsetHeight*2 - container.height)
const scale2isLongPic = imgRef.value.offsetHeight*2 - container.height
resetImage({
x,
y: scale2isLongPic > 0 ? y : translateY + Math.abs(scale2isLongPic/2),
newScale: 2,
newOrigin,
})
}
這次寫(xiě)完發(fā)現(xiàn)功能還不全呢,這個(gè)時(shí)候就應(yīng)該意識(shí)到用if else來(lái)區(qū)分scale值有點(diǎn)不對(duì)勁了,雖然scale<1或>2需要重置,可是不管scale多大,y值長(zhǎng)圖都保持不變,非長(zhǎng)圖都得給它居中。但我腦子那會(huì)兒有點(diǎn)兒木于是在意識(shí)到不對(duì)勁的情況下硬是在不對(duì)勁的代碼基礎(chǔ)上做了第二次嘗試??
let newTranslateY: number = getBoundaryOffset({ originO: newOrigin }).top
if (scale.value < 1) {
const scale1YDif = imgRef.value.offsetHeight - container.height
newTranslateY = scale1YDif > 0 ? y : Math.abs(scale1YDif / 2)
} else if (scale.value > 2) {
const scale2YDif = imgRef.value.offsetHeight * 2 - container.height
newTranslateY =
scale2YDif > 0
? y
: getBoundaryOffset({ originO: newOrigin, newScale: 2 }).top + Math.abs(scale2YDif / 2)
} else {
newTranslateY =
isLongPic.value > 0
? y
: getBoundaryOffset({ originO: newOrigin }).top + Math.abs(isLongPic.value / 2)
}
resetImage({
x: scale.value < 1 ? 0 : x,
y: newTranslateY,
newScale: (scale.value < 1 && 1) || (scale.value > 2 && 2) || scale.value,
newOrigin: scale.value < 1 ? centerOrigin : newOrigin
})
這次寫(xiě)完倒是達(dá)到了我的目的,可是看著這些。。這么多。。。明顯一樣的代碼只是換了個(gè)參數(shù)值我就腦殼疼??于是又給它整合了一下子??
const currentIsLongPic = (scale.value < 1 && imgRef.value.offsetHeight - container.height) || (scale.value > 2 && imgRef.value.offsetHeight*2 - container.height) || isLongPic.value
const currentCenterY = getBoundaryOffset({originO: scale.value < 1 ? centerOrigin : newOrigin, newScale: (scale.value < 1 && 1) || (scale.value > 2 && 2) || scale.value}).top + Math.abs(currentIsLongPic/2)
resetImage({
x: scale.value < 1 ? 0 : x,
y: currentIsLongPic > 0 ? y : currentCenterY,
newScale: (scale.value < 1 && 1) || (scale.value > 2 && 2) || scale.value,
newOrigin: scale.value < 1 ? centerOrigin : newOrigin
})
看著最后這次的代碼,我依然不知道這是不是它們最好的呈現(xiàn)方式,但對(duì)于目前的我來(lái)說(shuō),它真的順眼多了。
其實(shí)應(yīng)該一開(kāi)始別著急上手,先想清楚,reset的目的是什么。
首先,y值計(jì)算。圖片為非長(zhǎng)圖時(shí)設(shè)置y值給它垂直居中,長(zhǎng)圖時(shí)保持值不變;
其次,x軸的偏移量和newScale的計(jì)算。只有scale<1或>2時(shí)才給它固定,其它時(shí)候都是scale值本身;
第三,scale基準(zhǔn)點(diǎn)的傳值。只有scale<1時(shí)需要才回到center位置。
想明白這三點(diǎn)再下手敲。。應(yīng)該就不會(huì)像我這次這么痛苦了吧??