|
|
@@ -28,10 +28,18 @@ export async function DownloadStreamSaver(blob, fileName) {
|
|
|
ws.close()
|
|
|
}
|
|
|
|
|
|
+// 在 AutoFit.js 初始化后,获取容器的实际变换矩阵
|
|
|
+export function getContainerTransform(container) {
|
|
|
+ const style = window.getComputedStyle(container)
|
|
|
+ const transform = style.transform
|
|
|
+ if (transform === 'none') return { scaleX: 1, scaleY: 1 }
|
|
|
+
|
|
|
+ const matrix = new DOMMatrix(transform)
|
|
|
+ return { scaleX: matrix.a, scaleY: matrix.d }
|
|
|
+}
|
|
|
+
|
|
|
// 滚轮缩放、放大逻辑
|
|
|
export function enableImageManipulation(container, image, options = {}) {
|
|
|
- // const container = document.querySelector(containerId);
|
|
|
- // const image = document.querySelector(imageId);
|
|
|
let isDragging = false
|
|
|
let startX,
|
|
|
startY,
|
|
|
@@ -43,28 +51,44 @@ export function enableImageManipulation(container, image, options = {}) {
|
|
|
targetX = 0,
|
|
|
targetY = 0
|
|
|
|
|
|
- // 配置选项: 最小和最大缩放比例,是否启用缩放和拖动功能
|
|
|
+ image && (image.style.transformOrigin = 'top left')
|
|
|
+
|
|
|
+ // 配置选项
|
|
|
const minScale = options.minScale || container.offsetWidth / image.offsetWidth
|
|
|
const maxScale = options.maxScale || 3
|
|
|
const dragSpeed = options.dragSpeed || 0.2
|
|
|
- const enableZoom = options.enableZoom !== false // 默认启用缩放
|
|
|
- const enableDrag = options.enableDrag !== false // 默认启用拖动
|
|
|
+ const enableZoom = options.enableZoom !== false
|
|
|
+ const enableDrag = options.enableDrag !== false
|
|
|
+
|
|
|
function reset() {
|
|
|
isDragging = false
|
|
|
}
|
|
|
|
|
|
+ // 获取正确的鼠标位置(考虑容器缩放)
|
|
|
+ function getCorrectMousePosition(event, container) {
|
|
|
+ const containerRect = container.getBoundingClientRect()
|
|
|
+ const transform = getContainerTransform(container)
|
|
|
+
|
|
|
+ return {
|
|
|
+ x: (event.clientX - containerRect.left) * transform.scaleX,
|
|
|
+ y: (event.clientY - containerRect.top) * transform.scaleY
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
// 处理缩放功能
|
|
|
if (enableZoom) {
|
|
|
container.addEventListener('wheel', function (event) {
|
|
|
event.preventDefault()
|
|
|
|
|
|
- const { offsetX, offsetY } = event
|
|
|
+ // 使用修正后的鼠标位置
|
|
|
+ const mousePos = getCorrectMousePosition(event, container)
|
|
|
const delta = Math.sign(event.deltaY) * -0.1
|
|
|
|
|
|
const newScale = Math.min(Math.max(scale + delta, minScale), maxScale)
|
|
|
|
|
|
- const dx = (offsetX - currentX) * (newScale / scale - 1)
|
|
|
- const dy = (offsetY - currentY) * (newScale / scale - 1)
|
|
|
+ // 计算缩放中心偏移
|
|
|
+ const dx = (mousePos.x - currentX) * (newScale / scale - 1)
|
|
|
+ const dy = (mousePos.y - currentY) * (newScale / scale - 1)
|
|
|
|
|
|
scale = newScale
|
|
|
currentX -= dx
|
|
|
@@ -74,12 +98,16 @@ export function enableImageManipulation(container, image, options = {}) {
|
|
|
adjustPosition()
|
|
|
})
|
|
|
}
|
|
|
+
|
|
|
// 处理拖动功能
|
|
|
if (enableDrag) {
|
|
|
image.addEventListener('mousedown', function (event) {
|
|
|
isDragging = true
|
|
|
- startX = event.clientX
|
|
|
- startY = event.clientY
|
|
|
+
|
|
|
+ // 使用修正后的鼠标位置
|
|
|
+ const mousePos = getCorrectMousePosition(event, container)
|
|
|
+ startX = mousePos.x
|
|
|
+ startY = mousePos.y
|
|
|
|
|
|
const transform = image.style.transform.match(/translate\(([^)]+)\)/)
|
|
|
;[initialX, initialY] = transform ? transform[1].split(',').map(parseFloat) : [0, 0]
|
|
|
@@ -87,8 +115,10 @@ export function enableImageManipulation(container, image, options = {}) {
|
|
|
|
|
|
document.addEventListener('mousemove', function (event) {
|
|
|
if (isDragging) {
|
|
|
- const dx = (event.clientX - startX) * dragSpeed
|
|
|
- const dy = (event.clientY - startY) * dragSpeed
|
|
|
+ // 使用修正后的鼠标位置
|
|
|
+ const mousePos = getCorrectMousePosition(event, container)
|
|
|
+ const dx = (mousePos.x - startX) * dragSpeed
|
|
|
+ const dy = (mousePos.y - startY) * dragSpeed
|
|
|
|
|
|
targetX = initialX + dx
|
|
|
targetY = initialY + dy
|
|
|
@@ -121,21 +151,32 @@ export function enableImageManipulation(container, image, options = {}) {
|
|
|
const rect = image.getBoundingClientRect()
|
|
|
const containerRect = container.getBoundingClientRect()
|
|
|
|
|
|
- let newX = rect.left - containerRect.left
|
|
|
- let newY = rect.top - containerRect.top
|
|
|
+ // 考虑容器缩放的比例
|
|
|
+ const containerScaleX = container.offsetWidth / containerRect.width
|
|
|
+ const containerScaleY = container.offsetHeight / containerRect.height
|
|
|
|
|
|
- if (rect.width < containerRect.width) {
|
|
|
- newX = (containerRect.width - rect.width) / 2
|
|
|
+ let newX = (rect.left - containerRect.left) * containerScaleX
|
|
|
+ let newY = (rect.top - containerRect.top) * containerScaleY
|
|
|
+
|
|
|
+ const scaledImageWidth = rect.width * containerScaleX
|
|
|
+ const scaledImageHeight = rect.height * containerScaleY
|
|
|
+ const scaledContainerWidth = container.offsetWidth
|
|
|
+ const scaledContainerHeight = container.offsetHeight
|
|
|
+
|
|
|
+ if (scaledImageWidth < scaledContainerWidth) {
|
|
|
+ newX = (scaledContainerWidth - scaledImageWidth) / 2
|
|
|
} else {
|
|
|
if (newX > 0) newX = 0
|
|
|
- if (newX + rect.width < containerRect.width) newX = containerRect.width - rect.width
|
|
|
+ if (newX + scaledImageWidth < scaledContainerWidth)
|
|
|
+ newX = scaledContainerWidth - scaledImageWidth
|
|
|
}
|
|
|
|
|
|
- if (rect.height < containerRect.height) {
|
|
|
- newY = (containerRect.height - rect.height) / 2
|
|
|
+ if (scaledImageHeight < scaledContainerHeight) {
|
|
|
+ newY = (scaledContainerHeight - scaledImageHeight) / 2
|
|
|
} else {
|
|
|
if (newY > 0) newY = 0
|
|
|
- if (newY + rect.height < containerRect.height) newY = containerRect.height - rect.height
|
|
|
+ if (newY + scaledImageHeight < scaledContainerHeight)
|
|
|
+ newY = scaledContainerHeight - scaledImageHeight
|
|
|
}
|
|
|
|
|
|
currentX = newX
|
|
|
@@ -143,6 +184,7 @@ export function enableImageManipulation(container, image, options = {}) {
|
|
|
|
|
|
updateImageTransform()
|
|
|
}
|
|
|
+
|
|
|
return () => {
|
|
|
isDragging = false
|
|
|
startX = 0
|