diff --git a/src/components/image-editor/index.less b/src/components/image-editor/index.less index ca41eea9..a201c70b 100644 --- a/src/components/image-editor/index.less +++ b/src/components/image-editor/index.less @@ -16,4 +16,8 @@ align-items: center; overflow: hidden; } + + .overlay-canvas:hover { + cursor: 'none !important'; + } } diff --git a/src/components/image-editor/index.tsx b/src/components/image-editor/index.tsx index 3abfe350..8769cfa4 100644 --- a/src/components/image-editor/index.tsx +++ b/src/components/image-editor/index.tsx @@ -18,6 +18,7 @@ type Stroke = Point[]; type CanvasImageEditorProps = { imageSrc: string; disabled?: boolean; + imguid: string | number; onSave: (imageData: { mask: string; img: string }) => void; uploadButton: React.ReactNode; imageStatus: { @@ -33,6 +34,7 @@ const CanvasImageEditor: React.FC = ({ disabled, imageStatus, onSave, + imguid, uploadButton }) => { const MIN_SCALE = 0.5; @@ -55,8 +57,8 @@ const CanvasImageEditor: React.FC = ({ const translatePos = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); const contentPos = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); const animationFrameIdRef = useRef(null); - const originRef = useRef<{ x: number; y: number }>({ x: 0, y: 0 }); - const preAutoScale = useRef(1); + const strokeCache = useRef({}); + const preImguid = useRef(''); const getTransformedPoint = (offsetX: number, offsetY: number) => { const { current: scale } = autoScale; @@ -67,13 +69,13 @@ const CanvasImageEditor: React.FC = ({ const transformedY = (offsetY + lineWidth / 2 - translateY) / scale; return { - x: Math.round(transformedX), - y: Math.round(transformedY) + x: _.round(transformedX), + y: _.round(transformedY) }; }; const getTransformLineWidth = (lineWidth: number) => { - return lineWidth / autoScale.current; + return lineWidth; }; const setCanvasTransformOrigin = (e: React.MouseEvent) => { @@ -214,6 +216,7 @@ const CanvasImageEditor: React.FC = ({ stroke.forEach((point, i) => { const { x, y } = getTransformedPoint(point.x, point.y); + console.log('Drawing point:'); ctx.lineWidth = getTransformLineWidth(point.lineWidth); if (i === 0) { ctx.moveTo(x, y); @@ -487,6 +490,15 @@ const CanvasImageEditor: React.FC = ({ await drawImage(); setImgLoaded(true); console.log('Image Loaded:', imageStatus, strokesRef.current); + // if (strokeCache.current[imguid]) { + // strokesRef.current = strokeCache.current[imguid]; + // } else if (preImguid.current !== imguid) { + // strokeCache.current[preImguid.current] = strokesRef.current; + // onReset(); + // resetCanvas(); + // preImguid.current = imguid; + // } + if (imageStatus.isOriginal) { redrawStrokes(strokesRef.current, 'initialize'); } else if (imageStatus.isResetNeeded) { @@ -540,6 +552,7 @@ const CanvasImageEditor: React.FC = ({ const handleOnWheel = (event: any) => { handleZoom(event); updateCursorSize(); + // redrawStrokes(strokesRef.current); }; const handleFitView = () => { @@ -552,6 +565,11 @@ const CanvasImageEditor: React.FC = ({ redrawStrokes(strokesRef.current); }; + const handleBrushSizeChange = (value: number) => { + setLineWidth(value); + cursorRef.current!.style.width = `${value * autoScale.current}px`; + cursorRef.current!.style.height = `${value * autoScale.current}px`; + }; useEffect(() => { initializeImage(); }, [initializeImage]); @@ -607,7 +625,7 @@ const CanvasImageEditor: React.FC = ({ defaultValue={lineWidth} min={10} max={60} - onChange={(value) => setLineWidth(value)} + onChange={handleBrushSizeChange} /> } @@ -680,7 +698,8 @@ const CanvasImageEditor: React.FC = ({ = ({ style={{ display: 'none', position: 'fixed', - width: lineWidth, - height: lineWidth, + width: lineWidth * autoScale.current, + height: lineWidth * autoScale.current, backgroundColor: COLOR, borderRadius: '50%', pointerEvents: 'none', - zIndex: 100 + cursor: 'none', + zIndex: 5 }} /> diff --git a/src/pages/playground/components/image-edit.tsx b/src/pages/playground/components/image-edit.tsx index e44a81e8..a1c33117 100644 --- a/src/pages/playground/components/image-edit.tsx +++ b/src/pages/playground/components/image-edit.tsx @@ -130,8 +130,10 @@ const GroundImages: React.FC = forwardRef((props, ref) => { isOriginal: false, isResetNeeded: false }); + const doneImage = useRef(false); const cacheFormData = useRef({}); const size = Form.useWatch('size', form.current?.form); + const [imguid, setImgUid] = useState(0); const { initialize, updateScrollerPosition } = useOverlayScroller(); const { initialize: innitializeParams } = useOverlayScroller(); @@ -216,6 +218,7 @@ const GroundImages: React.FC = forwardRef((props, ref) => { const imageFile = useMemo(() => { if (!image) return null; + console.log('image>>>>>>>>>>>>>>', image); return base64ToFile(image, 'image'); }, [image]); @@ -306,14 +309,12 @@ const GroundImages: React.FC = forwardRef((props, ref) => { }; if (parameters.preview === 'preview') { stream_options = { - ...stream_options, stream_options_preview: true }; } if (parameters.preview === 'preview_faster') { stream_options = { - ...stream_options, stream_options_preview_faster: true }; } @@ -385,12 +386,8 @@ const GroundImages: React.FC = forwardRef((props, ref) => { } else if (item.b64_json) { imgItem.dataUrl = `data:image/png;base64,${item.b64_json}`; } - console.log( - 'stream_options_chunk_result:', - params.stream_options_chunk_result - ); const progress = _.round(item.progress, 0); - console.log('progress:', item, progress); + newImageList[item.index] = { dataUrl: imgItem.dataUrl, height: imgSize[1], @@ -400,8 +397,8 @@ const GroundImages: React.FC = forwardRef((props, ref) => { uid: imgItem.uid, span: imgItem.span, loading: params.stream_options_chunk_result - ? false - : progress < 100, + ? progress < 100 + : false, preview: false, progress: progress }; @@ -628,6 +625,7 @@ const GroundImages: React.FC = forwardRef((props, ref) => { const img = _.get(base64List, '[0].dataUrl', ''); setUploadList(base64List); setImage(img); + setImgUid(_.get(base64List, '[0].uid', '')); setImageStatus({ isOriginal: false, isResetNeeded: true @@ -648,6 +646,7 @@ const GroundImages: React.FC = forwardRef((props, ref) => { if (image) { return ( = forwardRef((props, ref) => { }, [image, loading, imageStatus, handleOnSave, handleUpdateImageList]); const handleOnImgClick = useCallback((item: any, isOrigin: boolean) => { - console.log('item:', item); + console.log('item:99', item); if (item.progress < 100) { return; } + setImgUid(item.uid); setImage(item.dataUrl); setImageStatus({ isOriginal: isOrigin, @@ -700,6 +700,16 @@ const GroundImages: React.FC = forwardRef((props, ref) => { }); }, []); + useEffect(() => { + if (imageList.length > 0) { + const doneImg = imageList.find((item) => item.progress === 100); + if (doneImg && !doneImage.current) { + doneImage.current = true; + handleOnImgClick(doneImg, false); + } + } + }, [imageList, handleOnImgClick]); + const renderOriginImage = useMemo(() => { if (!uploadList.length) { return null; diff --git a/src/pages/playground/images.tsx b/src/pages/playground/images.tsx index 87a10069..314bb5c6 100644 --- a/src/pages/playground/images.tsx +++ b/src/pages/playground/images.tsx @@ -32,12 +32,12 @@ const TextToImages: React.FC = () => { const optionsList = [ { - label: 'Generate', + label: intl.formatMessage({ id: 'playground.image.generate' }), value: TabsValueMap.Tab1, icon: }, { - label: 'Edit', + label: intl.formatMessage({ id: 'playground.image.edit' }), value: TabsValueMap.Tab2, icon: } diff --git a/src/utils/index.ts b/src/utils/index.ts index 1e5aceea..ed1daa50 100644 --- a/src/utils/index.ts +++ b/src/utils/index.ts @@ -149,7 +149,8 @@ export const generateRandomNumber = () => { }; function base64ToBlob(base64: string, contentType = '', sliceSize = 512) { - const byteCharacters = atob(base64.split(',')[1]); // 去掉 Base64 前缀部分 + const base64Content = base64.replace(/^data:image\/(png|jpg);base64,/, ''); + const byteCharacters = atob(base64Content); const byteArrays = []; for (let offset = 0; offset < byteCharacters.length; offset += sliceSize) {