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"> <div class="zoom-in-image-mask">
<img src=""> <img class="zoom-in-image">
</div> </div>

View File

@ -13,7 +13,11 @@ hexo.extend.filter.register(
function (match, attrBegin, src, attrEnd) { function (match, attrBegin, src, attrEnd) {
let hasAlt = false let hasAlt = false
if (!src) return match 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} return `<img ${attrBegin}
lazyload lazyload
${hasAlt ? '' : 'alt="image"'} ${hasAlt ? '' : 'alt="image"'}

View File

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

View File

@ -197,12 +197,17 @@
img { img {
position relative
display block display block
box-sizing border-box box-sizing border-box
max-width 100% max-width 100%
box-shadow 0 0 0.2rem var(--shadow-color) box-shadow 0 0 0.2rem var(--shadow-color)
cursor zoom-in 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') { if (hexo-config('post.img_align') == 'center' || hexo-config('style.article_img_align') == 'center') {
margin 0.8rem auto 0.2rem margin 0.8rem auto 0.2rem

View File

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

View File

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

View File

@ -221,39 +221,69 @@ KEEP.initUtils = () => {
} }
}, },
// big image viewer // zoom in image
imageViewer() { zoomInImage() {
let isBigImage = false 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) => { const zoomOut = () => {
document.body.style.overflow = isShow ? 'hidden' : 'auto' if (isZoomIn) {
if (isShow) { isZoomIn = false
maskDom.classList.add('active') zoomInImg && (zoomInImg.style.transform = `scale(1)`)
} else { zoomInImgMask && zoomInImgMask.classList.remove('show')
maskDom.classList.remove('active') const timer = setTimeout(() => {
clearTimeout(timer)
selectedImgDom && selectedImgDom.classList.remove('hide')
}, 300)
} }
} }
const imageViewerDom = document.querySelector('.image-viewer-container') const zoomOutHandle = () => {
const targetImg = document.querySelector('.image-viewer-container img') zoomInImgMask &&
imageViewerDom && zoomInImgMask.addEventListener('click', () => {
imageViewerDom.addEventListener('click', () => { zoomOut()
isBigImage = false
showHandle(imageViewerDom, isBigImage)
}) })
const imgDoms = document.querySelectorAll('.markdown-body img') document.addEventListener('scroll', () => {
zoomOut()
})
}
if (imgDoms.length) { if (imgDomList.length) {
imgDoms.forEach((img) => { zoomOutHandle()
imgDomList.forEach((img) => {
img.addEventListener('click', () => { img.addEventListener('click', () => {
isBigImage = true isZoomIn = !isZoomIn
showHandle(imageViewerDom, isBigImage) zoomInImg.setAttribute('src', img.getAttribute('src'))
targetImg.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() KEEP.utils.initFirstScreenHeight()
// big image viewer handle // big image viewer handle
KEEP.utils.imageViewer() KEEP.utils.zoomInImage()
// set how long age in home article block // set how long age in home article block
KEEP.utils.setHowLongAgoInHome() KEEP.utils.setHowLongAgoInHome()