perf(post): optimize zoom in image function (#148)

This commit is contained in:
XPoet 2022-10-08 20:56:08 +08:00
parent 002374b304
commit e931ea8f4f
7 changed files with 83 additions and 48 deletions

View File

@ -1,3 +1,3 @@
<div class="image-viewer-container">
<img src="">
<div class="zoom-in-image-mask">
<img class="zoom-in-image">
</div>

View File

@ -13,7 +13,11 @@ hexo.extend.filter.register(
function (match, attrBegin, src, attrEnd) {
let hasAlt = false
if (!src) return match
;[attrBegin, attrEnd].forEach(x => { if (x.includes('alt="')) { hasAlt = true } })
if (attrBegin.includes('alt="')) {
hasAlt = true
} else if (attrBegin.includes('alt="')) {
hasAlt = true
}
return `<img ${attrBegin}
lazyload
${hasAlt ? '' : 'alt="image"'}

View File

@ -51,8 +51,8 @@ body {
background var(--background-color)
&::-webkit-scrollbar {
width 0.4rem
height 0.4rem
width 0.6rem
height 0.6rem
}
+keep-tablet() {

View File

@ -197,12 +197,17 @@
img {
position relative
display block
box-sizing border-box
max-width 100%
box-shadow 0 0 0.2rem var(--shadow-color)
cursor zoom-in
transition-t("padding, margin", "0, 0", "0.2, 0.2", "linear, linear")
opacity 1
&.hide {
opacity 0
}
if (hexo-config('post.img_align') == 'center' || hexo-config('style.article_img_align') == 'center') {
margin 0.8rem auto 0.2rem

View File

@ -51,6 +51,7 @@ $z-index-6 = 1006
$z-index-7 = 1007
$z-index-8 = 1008
$z-index-9 = 1009
$z-index-10 = 1010
// ==============================================================================================

View File

@ -1,37 +1,32 @@
.image-viewer-container {
.zoom-in-image-mask {
position fixed
top 0
right 0
bottom 0
left 0
z-index $z-index-8
display flex
align-items center
justify-content center
box-sizing border-box
width 100%
height 100%
padding 6%
background rgba(0, 0, 0, 0)
visibility hidden
transition-t("visibility, background", "0, 0", "0.3, 0.3", "ease, ease")
transition-t("visibility, background", "0, 0", "0.3, 0.3", "linear, linear")
&.active {
&.show {
background rgba(0, 0, 0, 0.5)
visibility visible
img {
padding 0.2rem
background var(--background-color)
transform scale(1)
.zoom-in-image {
cursor zoom-out
}
}
img {
max-width 100%
max-height 100%
transform scale(0)
transition-t("transform", "0", "0.3", "ease")
.zoom-in-image {
position absolute
z-index $z-index-9
transform-origin center center
will-change transform
transition-t("transform", "0", "0.3", "linear")
}
}

View File

@ -221,39 +221,69 @@ KEEP.initUtils = () => {
}
},
// big image viewer
imageViewer() {
let isBigImage = false
// zoom in image
zoomInImage() {
const SIDE_GAP = 30
let isZoomIn = false
let selectedImgDom = null
const imgDomList = document.querySelectorAll('.markdown-body img')
const zoomInImgMask = document.querySelector('.zoom-in-image-mask')
const zoomInImg = zoomInImgMask.querySelector('.zoom-in-image')
const showHandle = (maskDom, isShow) => {
document.body.style.overflow = isShow ? 'hidden' : 'auto'
if (isShow) {
maskDom.classList.add('active')
} else {
maskDom.classList.remove('active')
const zoomOut = () => {
if (isZoomIn) {
isZoomIn = false
zoomInImg && (zoomInImg.style.transform = `scale(1)`)
zoomInImgMask && zoomInImgMask.classList.remove('show')
const timer = setTimeout(() => {
clearTimeout(timer)
selectedImgDom && selectedImgDom.classList.remove('hide')
}, 300)
}
}
const imageViewerDom = document.querySelector('.image-viewer-container')
const targetImg = document.querySelector('.image-viewer-container img')
imageViewerDom &&
imageViewerDom.addEventListener('click', () => {
isBigImage = false
showHandle(imageViewerDom, isBigImage)
const zoomOutHandle = () => {
zoomInImgMask &&
zoomInImgMask.addEventListener('click', () => {
zoomOut()
})
document.addEventListener('scroll', () => {
zoomOut()
})
}
const imgDoms = document.querySelectorAll('.markdown-body img')
if (imgDoms.length) {
imgDoms.forEach((img) => {
if (imgDomList.length) {
zoomOutHandle()
imgDomList.forEach((img) => {
img.addEventListener('click', () => {
isBigImage = true
showHandle(imageViewerDom, isBigImage)
targetImg.setAttribute('src', img.getAttribute('src'))
isZoomIn = !isZoomIn
zoomInImg.setAttribute('src', img.getAttribute('src'))
selectedImgDom = img
if (isZoomIn) {
const imgRect = selectedImgDom.getBoundingClientRect()
const imgW = imgRect.width
const imgH = imgRect.height
const imgL = imgRect.left
const imgT = imgRect.top
const winW = document.body.offsetWidth - SIDE_GAP * 2
const winH = document.body.offsetHeight - SIDE_GAP * 2
const scaleX = winW / imgW
const scaleY = winH / imgH
const scale = (scaleX < scaleY ? scaleX : scaleY) || 1
const translateX = winW / 2 - (imgRect.x + imgW / 2) + SIDE_GAP
const translateY = winH / 2 - (imgRect.y + imgH / 2) + SIDE_GAP
selectedImgDom.classList.add('hide')
zoomInImgMask.classList.add('show')
zoomInImg.style.top = imgT + 'px'
zoomInImg.style.left = imgL + 'px'
zoomInImg.style.width = imgW + 'px'
zoomInImg.style.height = imgH + 'px'
zoomInImg.style.transform = `translateX(${translateX}px) translateY(${translateY}px) scale(${scale}) `
}
})
})
} else {
this.pageContainer_dom.removeChild(imageViewerDom)
}
},
@ -441,7 +471,7 @@ KEEP.initUtils = () => {
KEEP.utils.initFirstScreenHeight()
// big image viewer handle
KEEP.utils.imageViewer()
KEEP.utils.zoomInImage()
// set how long age in home article block
KEEP.utils.setHowLongAgoInHome()