From b3e02bd6fa89db8e1c051ab8623f92ea0f45d4e2 Mon Sep 17 00:00:00 2001 From: viyiviyi Date: Sat, 22 Jun 2024 16:08:53 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E7=A7=BB=E5=8A=A8=E7=AB=AF?= =?UTF-8?q?=E7=BC=A9=E6=94=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- javascript/zoomimage.js | 122 +++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 58 deletions(-) diff --git a/javascript/zoomimage.js b/javascript/zoomimage.js index b0faefe..0738274 100644 --- a/javascript/zoomimage.js +++ b/javascript/zoomimage.js @@ -6,10 +6,12 @@ onUiLoaded(function () { function disableClose(e) { e.stopPropagation(); } + let toolDomHeight = 0; let modalControls = imageContainer.getElementsByClassName("modalControls")[0]; if (modalControls) { modalControls.style.position = "relative"; modalControls.style.zIndex = 1; + toolDomHeight = modalControls.offsetHeight; } let img = imageContainer.querySelector("img"); img.style.width = "auto"; @@ -19,10 +21,13 @@ onUiLoaded(function () { let scale = 1; let lastX = 0; let lastY = 0; + let lastLen = 1; let offsetX = 0; let offsetY = 0; let isDragging = false; let touchStore = {}; + let moveFunTimer = setTimeout(() => {}, 0); + let moveFunLastExecTime = Date.now(); let event = { wheel: function (event) { event.stopPropagation(); @@ -31,23 +36,23 @@ onUiLoaded(function () { let delta = Math.max(-1, Math.min(1, event.wheelDelta || -event.detail)); let zoomStep = 0.1; let zoom = 1 + delta * zoomStep; + let lastScale = scale; scale *= zoom; + scale = Math.max(0.1, scale); // 图片中心坐标 let centerX = imageContainer.offsetWidth / 2; - let centerY = imageContainer.offsetHeight / 2; - // 当前中心坐标 - let deltaCenterX = centerX + offsetX; - let deltaCenterY = centerY + offsetY; - // 鼠标位置与中心坐标的差 - let mouseDistanceX = event.clientX - deltaCenterX; - let mouseDistanceY = event.clientY - deltaCenterY; - // 以当前位置缩放会产生的距离变化 - let dX = mouseDistanceX - mouseDistanceX * zoom; - let dY = mouseDistanceY - mouseDistanceY * zoom; + let centerY = (imageContainer.offsetHeight - toolDomHeight) / 2; + let imgCenterX = offsetX + centerX; + let imgCenterY = offsetY + centerY; + offsetX = + offsetX - + ((event.pageX - (offsetX + centerX)) / lastScale) * (scale - lastScale); + offsetY = + offsetY - + ((event.pageY - (offsetY + centerY)) / lastScale) * (scale - lastScale); // 计算缩放后的图片中心偏移 - offsetX = Math.min(centerX, Math.max(-centerX, offsetX + dX)); - offsetY = Math.min(centerY, Math.max(-centerY, offsetY + dY)); - + offsetX = Math.min(centerX, Math.max(-centerX, offsetX)); + offsetY = Math.min(centerY, Math.max(-centerY, offsetY)); img.style.transform = "translate(" + offsetX + "px, " + offsetY + "px) scale(" + scale + ")"; }, @@ -119,7 +124,6 @@ onUiLoaded(function () { lastX = event.targetTouches[0].pageX - offsetX; lastY = event.targetTouches[0].pageY - offsetY; } - touchStore.tpuchScale = false; if (event.targetTouches[1]) { touchStore.tpuchScale = true; touchStore.last1X = event.targetTouches[0].pageX; @@ -127,6 +131,10 @@ onUiLoaded(function () { touchStore.last2X = event.targetTouches[1].pageX; touchStore.last2Y = event.targetTouches[1].pageY; touchStore.scale = scale; + lastLen = Math.sqrt( + Math.pow(touchStore.last2X - touchStore.last1X, 2) + + Math.pow(touchStore.last2Y - touchStore.last1Y, 2) + ); } }, touchmove: function (event) { @@ -134,50 +142,48 @@ onUiLoaded(function () { event.preventDefault(); img.onclick = disableClose; if (event.targetTouches[1]) { - img.style.transition = "transform 0.3s ease"; - touchStore.delta1X = event.targetTouches[0].pageX; - touchStore.delta1Y = event.targetTouches[0].pageY; - touchStore.delta2X = event.targetTouches[1].pageX; - touchStore.delta2Y = event.targetTouches[1].pageY; - let lastLen = Math.sqrt( - Math.pow(touchStore.last2X - touchStore.last1X, 2) + - Math.pow(touchStore.last2Y - touchStore.last1Y, 2) - ); - let deltaLen = Math.sqrt( - Math.pow(touchStore.delta2X - touchStore.delta1X, 2) + - Math.pow(touchStore.delta2Y - touchStore.delta1Y, 2) - ); - let zoom = deltaLen / lastLen; - scale = touchStore.scale * zoom; - // 图片中心坐标 - let centerX = imageContainer.offsetWidth / 2; - let centerY = imageContainer.offsetHeight / 2; - // 当前中心坐标 - let deltaCenterX = centerX + offsetX; - let deltaCenterY = centerY + offsetY; - // 缩放中心位置与中心坐标的差 - let mouseDistanceX = - touchStore.delta1X + - (touchStore.delta2X - touchStore.delta1X) / 2 - - deltaCenterX; - let mouseDistanceY = - touchStore.delta1Y + - (touchStore.delta2Y - touchStore.delta1Y) / 2 - - deltaCenterY; - // 以当前位置缩放会产生的距离变化 - let dX = mouseDistanceX - mouseDistanceX * zoom; - let dY = mouseDistanceY - mouseDistanceY * zoom; - // 计算缩放后的图片中心偏移 - offsetX = Math.min(centerX, Math.max(-centerX, offsetX + dX)); - offsetY = Math.min(centerY, Math.max(-centerY, offsetY + dY)); - img.style.transform = - "translate(" + - offsetX + - "px, " + - offsetY + - "px) scale(" + - scale + - ")"; + function moveFun() { + if (Date.now() - moveFunLastExecTime < 5) return; + img.style.transition = "transform 0.3s ease"; + touchStore.delta1X = event.targetTouches[0].pageX; + touchStore.delta1Y = event.targetTouches[0].pageY; + touchStore.delta2X = event.targetTouches[1].pageX; + touchStore.delta2Y = event.targetTouches[1].pageY; + let centerX = imageContainer.offsetWidth / 2; + let centerY = (imageContainer.offsetHeight - toolDomHeight) / 2; + let deltaLen = Math.sqrt( + Math.pow(touchStore.delta2X - touchStore.delta1X, 2) + + Math.pow(touchStore.delta2Y - touchStore.delta1Y, 2) + ); + let zoom = deltaLen / lastLen; + scale = touchStore.scale * zoom; + scale = Math.max(0.1, scale); + // 当前缩放中心坐标 + let deltaCenterX = + touchStore.delta1X + (touchStore.delta2X - touchStore.delta1X) / 2; + let deltaCenterY = + touchStore.delta1Y + (touchStore.delta2Y - touchStore.delta1Y) / 2; + // // 计算缩放后的图片中心偏移 + offsetX = Math.min(centerX, Math.max(-centerX, deltaCenterX - lastX)); + offsetY = Math.min(centerY, Math.max(-centerY, deltaCenterY - lastY)); + img.style.transform = + "translate(" + + offsetX + + "px, " + + offsetY + + "px) scale(" + + scale + + ")"; + } + if (Date.now() - moveFunLastExecTime >= 50) { + moveFun(); + moveFunLastExecTime = Date.now(); + } else { + clearTimeout(moveFunTimer); + moveFunTimer = setTimeout(() => { + moveFun(); + }, 50); + } } else if (!touchStore.tpuchScale) { img.style.transition = ""; offsetX = event.targetTouches[0].pageX - lastX;