diff --git a/src/components/image-editor/index.tsx b/src/components/image-editor/index.tsx index 667a8df5..f23cab8a 100644 --- a/src/components/image-editor/index.tsx +++ b/src/components/image-editor/index.tsx @@ -34,9 +34,6 @@ const CanvasImageEditor: React.FC = ({ onSave, uploadButton }) => { - const MIN_SCALE = 0.4; - const MAX_SCALE = 10; - const zoomFactor = 1.1; const intl = useIntl(); const canvasRef = useRef(null); const overlayCanvasRef = useRef(null); @@ -50,20 +47,25 @@ const CanvasImageEditor: React.FC = ({ const autoScale = useRef(1); const cursorRef = useRef(null); const [imgLoaded, setImgLoaded] = useState(false); - const offsetRef = useRef({ x: 0, y: 0 }); - const originPosition = useRef({ x: 0, y: 0 }); + + let scale = 1; + let offsetX = 0; + let offsetY = 0; + + const MIN_SCALE = 0.5; + const MAX_SCALE = 5; const getTransformedPoint = (event: React.MouseEvent) => { const overlayCanvas = overlayCanvasRef.current!; const rect = overlayCanvas.getBoundingClientRect(); - // 获取鼠标在画布上的原始坐标 const x = event.clientX - rect.left; const y = event.clientY - rect.top; - // 考虑缩放比例和偏移量 - const transformedX = (x - offsetRef.current.x) / autoScale.current; - const transformedY = (y - offsetRef.current.y) / autoScale.current; + const transformedX = x - overlayCanvas.width / 2; + const transformedY = y - overlayCanvas.height / 2; + + console.log('Mouse Coordinates (Transformed):', transformedX, transformedY); return { x: transformedX, y: transformedY }; }; @@ -111,10 +113,6 @@ const CanvasImageEditor: React.FC = ({ overlayCtx!.translate(ctx!.canvas.width / 2, ctx!.canvas.height / 2); ctx!.translate(ctx!.canvas.width / 2, ctx!.canvas.height / 2); offscreenCtx!.translate(ctx!.canvas.width / 2, ctx!.canvas.height / 2); - originPosition.current = { - x: ctx!.canvas.width / 2, - y: ctx!.canvas.height / 2 - }; }, [canvasRef.current, overlayCanvasRef.current]); const scaleCanvasSize = useCallback(() => { @@ -441,8 +439,8 @@ const CanvasImageEditor: React.FC = ({ 1 ); - canvas!.width = img.width; - canvas!.height = img.height; + canvas!.width = img.width * scale; + canvas!.height = img.height * scale; autoScale.current = scale / autoScale.current; @@ -459,7 +457,6 @@ const CanvasImageEditor: React.FC = ({ canvas!.width, canvas!.height ); - canvas!.style.transform = `scale(${scale})`; resolve(); }; }); @@ -505,102 +502,61 @@ const CanvasImageEditor: React.FC = ({ const y = event.clientY - rect.top; // 考虑缩放比例和偏移量 - const transformedX = (x - offsetRef.current.x) / autoScale.current; - const transformedY = (y - offsetRef.current.y) / autoScale.current; + const transformedX = (x - offsetX) / scale; + const transformedY = (y - offsetY) / scale; return { x: transformedX, y: transformedY }; }; - const getMousePosition = (event: any) => { - const canvas = overlayCanvasRef.current!; - const rect = canvas.getBoundingClientRect(); - const mouseX = event.clientX - rect.left; - const mouseY = event.clientY - rect.top; - - const { x: originX, y: originY } = originPosition.current; - const canvasX = (mouseX - originX) / autoScale.current; - const canvasY = (mouseY - originY) / autoScale.current; - - return { x: canvasX, y: canvasY }; - }; - - const updateCavasTransform = (event: any) => { - const canvas = overlayCanvasRef.current!; - const rect = canvas.getBoundingClientRect(); - const mouseX = event.clientX - rect.left; - const mouseY = event.clientY - rect.top; - - // 鼠标在中心坐标系中的位置 - const { x: originX, y: originY } = originPosition.current; - const canvasX = (mouseX - originX) / autoScale.current; - const canvasY = (mouseY - originY) / autoScale.current; - - // 更新缩放比例 - // max scale: 2, min scale: 0.3 - const zoomIn = event.deltaY < 0; - let newScale = autoScale.current; - if (zoomIn) { - newScale = Math.min(MAX_SCALE, autoScale.current * zoomFactor); - } else { - newScale = Math.max(MIN_SCALE, autoScale.current / zoomFactor); - } - - console.log('New Scale:', newScale); - - autoScale.current = newScale; - // 更新原点 - const neworiginX = mouseX - canvasX * newScale; - const neworiginY = mouseY - canvasY * newScale; - originPosition.current = { x: neworiginX, y: neworiginY }; - - const overlayCtx = overlayCanvasRef.current!.getContext('2d')!; - const canvasCtx = canvasRef.current!.getContext('2d')!; - // 更新 Canvas 的变换 - overlayCtx.setTransform( - autoScale.current, - 0, - 0, - autoScale.current, - neworiginX, - neworiginY - ); - canvasCtx.setTransform( - autoScale.current, - 0, - 0, - autoScale.current, - neworiginX, - neworiginY - ); - }; - const handleOnWheel = (event: WheelEvent) => { event.preventDefault(); - updateCavasTransform(event); + const zoomFactor = event.deltaY < 0 ? 1.1 : 0.9; + const newScale = Math.min( + MAX_SCALE, + Math.max(MIN_SCALE, scale * zoomFactor) + ); - overlayCanvasRef.current!.style.transform = `scale(${autoScale.current})`; - canvasRef.current!.style.transform = `scale(${autoScale.current})`; + const rect = canvasRef.current!.getBoundingClientRect(); + const mouseX = event.clientX - rect.left; + const mouseY = event.clientY - rect.top; + + // 计算新的偏移量 + offsetX = mouseX - (mouseX - offsetX) * (newScale / scale); + offsetY = mouseY - (mouseY - offsetY) * (newScale / scale); + + // 更新缩放比例 + scale = newScale; + + // 设置画布的变换 + const overlayCtx = overlayCanvasRef.current!.getContext('2d')!; + overlayCtx.setTransform(scale, 0, 0, scale, offsetX, offsetY); + const canvasCtx = canvasRef.current!.getContext('2d')!; + canvasCtx.setTransform(scale, 0, 0, scale, offsetX, offsetY); + overlayCanvasRef.current!.style.transform = `scale(${scale})`; + canvasRef.current!.style.transform = `scale(${scale})`; + + console.log('Zoom:', scale, offsetX, offsetY); }; useEffect(() => { initializeImage(); }, [initializeImage]); - useEffect(() => { - const container = containerRef.current; - if (!container) return; - if (container) { - resizeObserver.current = new ResizeObserver( - _.throttle(handleResize, 100) - ); - resizeObserver.current.observe(container); - } + // useEffect(() => { + // const container = containerRef.current; + // if (!container) return; + // if (container) { + // resizeObserver.current = new ResizeObserver( + // _.throttle(handleResize, 100) + // ); + // resizeObserver.current.observe(container); + // } - return () => { - resizeObserver.current?.disconnect(); - }; - }, [handleResize, containerRef.current]); + // return () => { + // resizeObserver.current?.disconnect(); + // }; + // }, [handleResize, containerRef.current]); useEffect(() => { createOffscreenCanvas(); diff --git a/src/global.less b/src/global.less index 7710942c..4d20d6a8 100644 --- a/src/global.less +++ b/src/global.less @@ -184,7 +184,6 @@ body { font-family: 'noto sans', sans-serif; -moz-osx-font-smoothing: grayscale; -webkit-font-smoothing: antialiased; - overflow-y: initial !important; &::-webkit-scrollbar { width: 0; diff --git a/src/hooks/use-overlay-scroller.ts b/src/hooks/use-overlay-scroller.ts index 1a1d44a2..bb4bb9d1 100644 --- a/src/hooks/use-overlay-scroller.ts +++ b/src/hooks/use-overlay-scroller.ts @@ -42,6 +42,7 @@ export default function useOverlayScroller(options?: any) { clickScroll: 'instant' } }, + defer: true }); diff --git a/src/pages/llmodels/components/column-wrapper.tsx b/src/pages/llmodels/components/column-wrapper.tsx index ce080028..2745de16 100644 --- a/src/pages/llmodels/components/column-wrapper.tsx +++ b/src/pages/llmodels/components/column-wrapper.tsx @@ -4,29 +4,36 @@ import 'simplebar-react/dist/simplebar.min.css'; import '../style/column-wrapper.less'; const ColumnWrapper: React.FC = ({ children, footer, height }) => { - if (footer) { - return ( -
+ const handleOnWheel = (e: React.WheelEvent) => { + console.log('handleOnWheel', e); + e.preventDefault(); + e.stopPropagation(); + }; + + return ( + <> + {footer ? ( +
+
+ + {children} + +
+ {
{footer}
} +
+ ) : (
- + {children}
- {
{footer}
} -
- ); - } - return ( -
- - {children} - -
+ )} + ); }; diff --git a/src/pages/llmodels/components/deploy-builtin-modal.tsx b/src/pages/llmodels/components/deploy-builtin-modal.tsx index 4bd4d1b1..8a567e26 100644 --- a/src/pages/llmodels/components/deploy-builtin-modal.tsx +++ b/src/pages/llmodels/components/deploy-builtin-modal.tsx @@ -189,8 +189,9 @@ const AddModal: React.FC = (props) => { value: item.quantization }; }); - setQuantizationOptions(quantizationList); - return quantizationList; + const result = _.uniqBy(quantizationList, 'value'); + setQuantizationOptions(result); + return result; }; const handleSetBackendOptions = () => {