From ec01735424bc379eea607780e478ac7132cdd689 Mon Sep 17 00:00:00 2001 From: Yukai Huang Date: Sun, 19 Apr 2020 23:31:27 +0800 Subject: [PATCH] Zoom/drag image Signed-off-by: Yukai Huang --- public/js/lib/renderer/lightbox/index.js | 78 +++++++++++++++++++- public/js/lib/renderer/lightbox/lightbox.css | 10 ++- 2 files changed, 83 insertions(+), 5 deletions(-) diff --git a/public/js/lib/renderer/lightbox/index.js b/public/js/lib/renderer/lightbox/index.js index 55c78042..ab263eaf 100644 --- a/public/js/lib/renderer/lightbox/index.js +++ b/public/js/lib/renderer/lightbox/index.js @@ -1,6 +1,7 @@ import './lightbox.css' let images = [] +/** @type {HTMLImageElement} */ let currentImage = null let currentIndexIndex = 0 @@ -21,10 +22,13 @@ function findOrCreateLightboxContainer () { ` + addImageZoomListener(lightBoxContainer) + const hideContainer = (e) => { e.stopPropagation() lightBoxContainer.classList.remove('show') document.body.classList.remove('no-scroll') + currentImage = null } lightBoxContainer.querySelector('.lightbox-control-previous').addEventListener('click', (e) => { @@ -36,7 +40,7 @@ function findOrCreateLightboxContainer () { switchImage(1) }) lightBoxContainer.querySelector('.lightbox-control-close').addEventListener('click', hideContainer) - lightBoxContainer.addEventListener('click', hideContainer) + // lightBoxContainer.addEventListener('click', hideContainer) document.body.appendChild(lightBoxContainer) } @@ -63,7 +67,8 @@ function setImageInner (img, lightBoxContainer) { const src = img.getAttribute('src') const alt = img.getAttribute('alt') - lightBoxContainer.querySelector('.lightbox-inner').innerHTML = `${alt}` + lightBoxContainer.querySelector('.lightbox-inner').innerHTML = `${alt}` + addImageDragListener(lightBoxContainer.querySelector('.lightbox-inner img')) } function onClickImage (img) { @@ -86,6 +91,70 @@ function updateLightboxImages () { } } +function addImageZoomListener (container) { + container.addEventListener('wheel', function (e) { + // normalize scroll position as percentage + e.preventDefault() + + /** @type {HTMLImageElement} */ + const image = container.querySelector('img') + + if (!image) { + return + } + + let scale = image.getBoundingClientRect().width / image.offsetWidth + scale += e.deltaY * -0.01 + + // Restrict scale + scale = Math.min(Math.max(0.125, scale), 4) + + var transformValue = `scale(${scale})` + + image.style.WebkitTransform = transformValue + image.style.MozTransform = transformValue + image.style.OTransform = transformValue + image.style.transform = transformValue + }) +} + +/** + * @param {HTMLImageElement} image + */ +function addImageDragListener (image) { + let moved = false + let pos = [] + image.addEventListener('mousedown', (evt) => { + moved = true + + const { left, top } = image.getBoundingClientRect() + + pos = [ + evt.pageX - left, + evt.pageY - top + ] + }, true) + + image.addEventListener('mousemove', (evt) => { + if (!moved) { + return + } + + image.style.left = `${evt.pageX - pos[0]}px` + image.style.top = `${evt.pageY - pos[1]}px` + image.style.position = 'absolute' + }, true) + + image.addEventListener('mouseup', () => { + moved = false + pos = [] + }, true) + + image.addEventListener('mouseout', () => { + moved = false + }) +} + const init = () => { const markdownBody = document.querySelector('.markdown-body') if (!markdownBody) { @@ -93,8 +162,9 @@ const init = () => { } markdownBody.addEventListener('click', function (e) { - if (e.target.nodeName === 'IMG' && e.target.classList.contains('md-image')) { - onClickImage(e.target) + const img = e.target + if (img.nodeName === 'IMG' && img.classList.contains('md-image')) { + onClickImage(img) e.stopPropagation() } }) diff --git a/public/js/lib/renderer/lightbox/lightbox.css b/public/js/lib/renderer/lightbox/lightbox.css index 14f29d01..bc5bca5b 100644 --- a/public/js/lib/renderer/lightbox/lightbox.css +++ b/public/js/lib/renderer/lightbox/lightbox.css @@ -29,12 +29,13 @@ cursor: pointer; user-select: none; font-size: 25px; + z-index: 1; } .lightbox-container .lightbox-control-previous:hover, .lightbox-container .lightbox-control-next:hover, .lightbox-container .lightbox-control-close:hover { - cursor: rgba(130, 130, 130, 0.78); + color: rgba(130, 130, 130, 0.78); } .lightbox-container .lightbox-control-next, @@ -57,6 +58,13 @@ .lightbox-container .lightbox-inner img { max-width: 100%; + cursor: move; + + transform-origin: 0 0; + -moz-transform-origin: 0 0; + -webkit-transform-origin: 0 0; + -ms-transform-origin: 0 0; + -o-transform-origin: 0 0; } .markdown-body img.md-image {