diff --git a/debug/comprehensive_test.js b/debug/comprehensive_test.js deleted file mode 100644 index 50b63fa..0000000 --- a/debug/comprehensive_test.js +++ /dev/null @@ -1,199 +0,0 @@ -// 全面测试修复效果 -async function comprehensiveTest() { - console.log('=== 全面测试修复效果 ==='); - - // 模拟React状态和refs - let canvasImageState = null; - let imageState = null; - let canvasZoomState = 1; - let canvasPanState = { x: 0, y: 0 }; - let stageSizeState = { width: 800, height: 600 }; - - // 模拟stageRef - const stageRefMock = { - current: { - scaleX: () => canvasZoomState, - scaleY: () => canvasZoomState, - x: () => canvasPanState.x * canvasZoomState, - y: () => canvasPanState.y * canvasZoomState, - scale: (scale) => { - if (scale) { - canvasZoomState = scale.x; - console.log('Stage缩放已设置为:', scale.x); - } - }, - position: (pos) => { - if (pos) { - canvasPanState = { x: pos.x / canvasZoomState, y: pos.y / canvasZoomState }; - console.log('Stage位置已设置为:', pos); - } - }, - batchDraw: () => { - console.log('Stage已重新绘制'); - } - } - }; - - // 模拟setter函数 - const setCanvasImage = (url) => { - console.log('setCanvasImage被调用:', url); - canvasImageState = url; - }; - - const setImage = (img) => { - console.log('setImage被调用'); - imageState = img; - }; - - const setCanvasZoom = (zoom) => { - console.log('setCanvasZoom被调用:', zoom); - canvasZoomState = zoom; - }; - - const setCanvasPan = (pan) => { - console.log('setCanvasPan被调用:', pan); - canvasPanState = pan; - }; - - console.log('\n1. 测试图像加载useEffect...'); - - // 模拟canvasImage变化 - const testImageUrl = 'https://cdn.pandorastudio.cn/upload/886ab948b.png'; - console.log('设置canvasImage为:', testImageUrl); - setCanvasImage(testImageUrl); - - // 模拟图像加载useEffect执行 - function simulateImageLoadingEffect() { - console.log('执行图像加载useEffect...'); - - if (canvasImageState) { - console.log('开始加载图像:', canvasImageState); - - // 模拟图像加载完成 - const mockImage = { - width: 1024, - height: 1024, - src: canvasImageState - }; - - console.log('图像加载完成,尺寸:', mockImage.width, 'x', mockImage.height); - setImage(mockImage); - - // 模拟自动适应画布(使用setTimeout模拟) - console.log('模拟自动适应画布...'); - - // 计算最优缩放 - const isMobile = window.innerWidth < 768; - const padding = isMobile ? 0.9 : 0.8; - - const scaleX = (stageSizeState.width * padding) / mockImage.width; - const scaleY = (stageSizeState.height * padding) / mockImage.height; - - const maxZoom = isMobile ? 0.3 : 0.8; - const optimalZoom = Math.min(scaleX, scaleY, maxZoom); - - // 直接通过stage控制,不依赖状态更新 - console.log('直接设置Stage缩放:', optimalZoom); - stageRefMock.current.scale({ x: optimalZoom, y: optimalZoom }); - stageRefMock.current.position({ x: 0, y: 0 }); - stageRefMock.current.batchDraw(); - - // 同时更新React状态以保持同步 - setCanvasZoom(optimalZoom); - setCanvasPan({ x: 0, y: 0 }); - - console.log('图像自动适应画布完成'); - } - } - - simulateImageLoadingEffect(); - - console.log('\n2. 测试多次执行useEffect...'); - - // 模拟多次执行useEffect,确保不会引起无限循环 - for (let i = 0; i < 3; i++) { - console.log(`\n第${i + 1}次执行useEffect:`); - simulateImageLoadingEffect(); - - // 检查状态是否稳定 - console.log(' 当前canvasZoom:', canvasZoomState); - console.log(' 当前canvasPan:', canvasPanState); - } - - console.log('\n3. 测试handleZoom函数...'); - - // 模拟handleZoom函数 - function handleZoom(delta) { - const stage = stageRefMock.current; - if (stage) { - const currentZoom = stage.scaleX(); - const newZoom = Math.max(0.1, Math.min(3, currentZoom + delta)); - - // 直接通过stage控制 - console.log('handleZoom: 设置新缩放:', newZoom); - stage.scale({ x: newZoom, y: newZoom }); - stage.batchDraw(); - - // 同时更新React状态以保持同步 - setCanvasZoom(newZoom); - } - } - - console.log('调用handleZoom(0.1)...'); - handleZoom(0.1); - - console.log('调用handleZoom(-0.1)...'); - handleZoom(-0.1); - - console.log('\n4. 测试handleReset函数...'); - - // 模拟handleReset函数 - function handleReset() { - if (imageState) { - const isMobile = window.innerWidth < 768; - const padding = isMobile ? 0.9 : 0.8; - const scaleX = (stageSizeState.width * padding) / imageState.width; - const scaleY = (stageSizeState.height * padding) / imageState.height; - const maxZoom = isMobile ? 0.3 : 0.8; - const optimalZoom = Math.min(scaleX, scaleY, maxZoom); - - // 直接通过stage控制 - console.log('handleReset: 设置最优缩放:', optimalZoom); - stageRefMock.current.scale({ x: optimalZoom, y: optimalZoom }); - stageRefMock.current.position({ x: 0, y: 0 }); - stageRefMock.current.batchDraw(); - - // 同时更新React状态以保持同步 - setCanvasZoom(optimalZoom); - setCanvasPan({ x: 0, y: 0 }); - } - } - - console.log('调用handleReset()...'); - handleReset(); - - console.log('\n5. 测试新图像加载...'); - - // 模拟加载新图像 - const newImageUrl = 'https://cdn.pandorastudio.cn/upload/new-image.png'; - console.log('加载新图像:', newImageUrl); - - setCanvasImage(newImageUrl); - simulateImageLoadingEffect(); - - console.log('\n=== 测试完成 ==='); - console.log('\n最终状态:'); - console.log('canvasImage:', canvasImageState); - console.log('canvasZoom:', canvasZoomState); - console.log('canvasPan:', canvasPanState); - - console.log('\n修复效果验证:'); - console.log('✓ 图像加载useEffect只依赖于canvasImage'); - console.log('✓ 通过stageRef直接控制Stage,避免状态循环更新'); - console.log('✓ React状态与Stage状态保持同步'); - console.log('✓ handleZoom和handleReset函数正确工作'); - console.log('✓ 多次执行不会引起无限循环'); -} - -// 运行测试 -comprehensiveTest(); \ No newline at end of file diff --git a/debug/test_centering_fix.js b/debug/test_centering_fix.js deleted file mode 100644 index 4bf8d95..0000000 --- a/debug/test_centering_fix.js +++ /dev/null @@ -1,218 +0,0 @@ -// 测试居中显示修复效果 -async function testCenteringFix() { - console.log('=== 测试居中显示修复效果 ==='); - - // 模拟React状态和refs - let canvasImageState = null; - let imageState = null; - let canvasZoomState = 1; - let canvasPanState = { x: 0, y: 0 }; - let stageSizeState = { width: 800, height: 600 }; - - // 模拟stageRef - const stageRefMock = { - current: { - scaleX: () => canvasZoomState, - scaleY: () => canvasZoomState, - x: () => canvasPanState.x * canvasZoomState, - y: () => canvasPanState.y * canvasZoomState, - scale: (scale) => { - if (scale) { - canvasZoomState = scale.x; - console.log('Stage缩放已设置为:', scale.x); - } - }, - position: (pos) => { - if (pos) { - canvasPanState = { x: pos.x / canvasZoomState, y: pos.y / canvasZoomState }; - console.log('Stage位置已设置为:', pos); - } - }, - batchDraw: () => { - console.log('Stage已重新绘制'); - } - } - }; - - // 模拟setter函数 - const setCanvasImage = (url) => { - console.log('setCanvasImage被调用:', url); - canvasImageState = url; - }; - - const setImage = (img) => { - console.log('setImage被调用'); - imageState = img; - }; - - const setCanvasZoom = (zoom) => { - console.log('setCanvasZoom被调用,新值:', zoom); - canvasZoomState = zoom; - }; - - const setCanvasPan = (pan) => { - console.log('setCanvasPan被调用,新值:', pan); - canvasPanState = pan; - }; - - console.log('\n1. 测试图像加载时的居中计算...'); - - // 模拟canvasImage变化 - const testImageUrl = 'https://cdn.pandorastudio.cn/upload/886ab948b.png'; - console.log('设置canvasImage为:', testImageUrl); - setCanvasImage(testImageUrl); - - // 模拟图像加载完成 - const mockImage = { - width: 1024, - height: 1024, - src: testImageUrl - }; - - console.log('图像加载完成,尺寸:', mockImage.width, 'x', mockImage.height); - setImage(mockImage); - - console.log('\n2. 测试图像居中逻辑...'); - - // 模拟图像加载完成后的居中逻辑 - function simulateImageCentering() { - console.log('开始图像居中计算...'); - - const isMobile = window.innerWidth < 768; - const padding = isMobile ? 0.9 : 0.8; - - const scaleX = (stageSizeState.width * padding) / mockImage.width; - const scaleY = (stageSizeState.height * padding) / mockImage.height; - - const maxZoom = isMobile ? 0.3 : 0.8; - const optimalZoom = Math.min(scaleX, scaleY, maxZoom); - - console.log('计算得到的最优缩放:', optimalZoom); - - // 立即更新React状态以确保Konva Image组件使用正确的缩放值 - console.log('立即更新React状态...'); - setCanvasZoom(optimalZoom); - setCanvasPan({ x: 0, y: 0 }); - - // 模拟setTimeout中的Stage设置 - console.log('模拟setTimeout中的Stage设置...'); - - // 直接设置缩放,但保持Stage居中 - stageRefMock.current.scale({ x: optimalZoom, y: optimalZoom }); - // 重置Stage位置以确保居中 - stageRefMock.current.position({ x: 0, y: 0 }); - stageRefMock.current.batchDraw(); - - console.log('图像居中设置完成'); - } - - simulateImageCentering(); - - console.log('\n3. 测试Konva Image组件的坐标计算...'); - - // 模拟Konva Image组件的坐标计算 - function calculateImagePosition() { - console.log('使用当前状态计算图像位置...'); - console.log('stageSize.width:', stageSizeState.width); - console.log('stageSize.height:', stageSizeState.height); - console.log('canvasZoom:', canvasZoomState); - console.log('image.width:', mockImage.width); - console.log('image.height:', mockImage.height); - - const x = (stageSizeState.width / canvasZoomState - mockImage.width) / 2; - const y = (stageSizeState.height / canvasZoomState - mockImage.height) / 2; - - console.log('计算得到的图像坐标: x=', x, 'y=', y); - - // 验证是否居中 - const stageCenterX = stageSizeState.width / 2; - const stageCenterY = stageSizeState.height / 2; - const imageCenterX = x + mockImage.width / 2; - const imageCenterY = y + mockImage.height / 2; - - console.log('Stage中心点:', stageCenterX, 'x', stageCenterY); - console.log('图像中心点:', imageCenterX, 'x', imageCenterY); - - const isCentered = Math.abs(stageCenterX - imageCenterX) < 1 && Math.abs(stageCenterY - imageCenterY) < 1; - console.log('图像是否居中:', isCentered ? '是' : '否'); - - return { x, y, isCentered }; - } - - const position = calculateImagePosition(); - - console.log('\n4. 测试handleReset函数...'); - - // 模拟handleReset函数 - function handleReset() { - console.log('执行handleReset...'); - - if (imageState) { - const isMobile = window.innerWidth < 768; - const padding = isMobile ? 0.9 : 0.8; - const scaleX = (stageSizeState.width * padding) / imageState.width; - const scaleY = (stageSizeState.height * padding) / imageState.height; - const maxZoom = isMobile ? 0.3 : 0.8; - const optimalZoom = Math.min(scaleX, scaleY, maxZoom); - - console.log('计算得到的最优缩放:', optimalZoom); - - // 先更新React状态 - setCanvasZoom(optimalZoom); - setCanvasPan({ x: 0, y: 0 }); - - // 模拟setTimeout中的Stage设置 - console.log('模拟setTimeout中的Stage设置...'); - - // 直接控制Stage - stageRefMock.current.scale({ x: optimalZoom, y: optimalZoom }); - stageRefMock.current.position({ x: 0, y: 0 }); - stageRefMock.current.batchDraw(); - - console.log('handleReset执行完成'); - } - } - - handleReset(); - - console.log('\n5. 测试handleZoom函数...'); - - // 模拟handleZoom函数 - function handleZoom(delta) { - console.log('执行handleZoom,delta:', delta); - - const currentZoom = stageRefMock.current.scaleX(); - const newZoom = Math.max(0.1, Math.min(3, currentZoom + delta)); - - console.log('当前缩放:', currentZoom, '新缩放:', newZoom); - - // 先更新React状态 - setCanvasZoom(newZoom); - - // 模拟setTimeout中的Stage设置 - console.log('模拟setTimeout中的Stage设置...'); - - // 直接控制Stage - stageRefMock.current.scale({ x: newZoom, y: newZoom }); - stageRefMock.current.batchDraw(); - - console.log('handleZoom执行完成'); - } - - handleZoom(0.1); - - console.log('\n=== 测试完成 ==='); - console.log('\n最终状态:'); - console.log('canvasZoom:', canvasZoomState); - console.log('canvasPan:', canvasPanState); - console.log('图像位置:', position); - - console.log('\n修复效果验证:'); - console.log('✓ 图像加载时正确计算并设置居中位置'); - console.log('✓ React状态与Stage状态保持同步'); - console.log('✓ Konva Image组件使用正确的坐标计算'); - console.log('✓ handleReset和handleZoom函数正确处理居中'); -} - -// 运行测试 -testCenteringFix(); \ No newline at end of file diff --git a/debug/test_fix_effect.js b/debug/test_fix_effect.js deleted file mode 100644 index c5d6252..0000000 --- a/debug/test_fix_effect.js +++ /dev/null @@ -1,136 +0,0 @@ -// 测试修复效果 -async function testFixEffect() { - console.log('=== 测试修复效果 ==='); - - // 模拟React状态和setter函数 - let canvasImageState = null; - let imageState = null; - let canvasZoomState = 1; - let canvasPanState = { x: 0, y: 0 }; - let stageSizeState = { width: 800, height: 600 }; - - // 模拟setter函数 - const setCanvasImage = (url) => { - console.log('setCanvasImage被调用:', url); - canvasImageState = url; - }; - - const setImage = (img) => { - console.log('setImage被调用'); - imageState = img; - }; - - const setCanvasZoom = (zoom) => { - console.log('setCanvasZoom被调用:', zoom); - canvasZoomState = zoom; - }; - - const setCanvasPan = (pan) => { - console.log('setCanvasPan被调用:', pan); - canvasPanState = pan; - }; - - // 模拟useEffect行为 - console.log('\n1. 测试图像加载useEffect...'); - - // 模拟canvasImage变化 - const testImageUrl = 'https://cdn.pandorastudio.cn/upload/886ab948b.png'; - setCanvasImage(testImageUrl); - - // 模拟第一个useEffect(图像加载) - function simulateImageLoadingEffect() { - console.log('执行图像加载useEffect...'); - - if (canvasImageState) { - console.log('开始加载图像:', canvasImageState); - - // 模拟图像加载完成 - const mockImage = { - width: 1024, - height: 1024, - src: canvasImageState - }; - - console.log('图像加载完成,尺寸:', mockImage.width, 'x', mockImage.height); - setImage(mockImage); - } - } - - simulateImageLoadingEffect(); - - console.log('\n2. 测试画布适应useEffect...'); - - // 模拟第二个useEffect(画布适应) - function simulateCanvasAdaptEffect() { - console.log('执行画布适应useEffect...'); - - if (imageState && canvasImageState) { - console.log('图像已加载,开始计算最优缩放...'); - - // 模拟计算 - const isMobile = window.innerWidth < 768; - const padding = isMobile ? 0.9 : 0.8; - - const scaleX = (stageSizeState.width * padding) / imageState.width; - const scaleY = (stageSizeState.height * padding) / imageState.height; - - const maxZoom = isMobile ? 0.3 : 0.8; - const optimalZoom = Math.min(scaleX, scaleY, maxZoom); - - // 检查是否需要更新缩放 - if (Math.abs(canvasZoomState - optimalZoom) > 0.01) { - console.log('缩放级别变化较大,更新缩放:', optimalZoom); - setCanvasZoom(optimalZoom); - } else { - console.log('缩放级别变化较小,跳过更新'); - } - - // 居中图像 - setCanvasPan({ x: 0, y: 0 }); - console.log('图像居中完成'); - } - } - - simulateCanvasAdaptEffect(); - - console.log('\n3. 测试避免无限循环...'); - - // 模拟多次执行useEffect - console.log('模拟多次执行useEffect...'); - - for (let i = 0; i < 3; i++) { - console.log(`\n第${i + 1}次执行:`); - - // 执行画布适应effect - const oldZoom = canvasZoomState; - simulateCanvasAdaptEffect(); - - if (oldZoom === canvasZoomState) { - console.log('缩放级别未变化,避免了不必要的重渲染'); - } - } - - console.log('\n4. 测试新图像加载...'); - - // 模拟加载新图像 - const newImageUrl = 'https://cdn.pandorastudio.cn/upload/new-image.png'; - console.log('加载新图像:', newImageUrl); - - setCanvasImage(newImageUrl); - - // 重新执行图像加载effect - simulateImageLoadingEffect(); - - // 重新执行画布适应effect - simulateCanvasAdaptEffect(); - - console.log('\n=== 测试完成 ==='); - console.log('\n修复效果验证:'); - console.log('✓ 图像加载和画布适应逻辑已分离'); - console.log('✓ 避免了setCanvasZoom引起的无限循环'); - console.log('✓ 通过缩放级别差异检查避免了不必要的更新'); - console.log('✓ 新图像加载时能正确适应画布'); -} - -// 运行测试 -testFixEffect(); \ No newline at end of file diff --git a/src/components/HistoryPanel.tsx b/src/components/HistoryPanel.tsx index 3ab8d42..37ef7bd 100644 --- a/src/components/HistoryPanel.tsx +++ b/src/components/HistoryPanel.tsx @@ -1178,75 +1178,7 @@ export const HistoryPanel: React.FC = () => { })()} - {/* 操作 */} -