perf(post): optimize zoom in image function (#148)
This commit is contained in:
parent
002374b304
commit
e931ea8f4f
|
@ -1,3 +1,3 @@
|
||||||
<div class="image-viewer-container">
|
<div class="zoom-in-image-mask">
|
||||||
<img src="">
|
<img class="zoom-in-image">
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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"'}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
// ==============================================================================================
|
// ==============================================================================================
|
||||||
|
|
|
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue