import fallbackImg from '@/assets/images/img_fallback.png'; import { DownloadOutlined, EyeOutlined, RotateLeftOutlined, RotateRightOutlined, SwapOutlined, UndoOutlined, ZoomInOutlined, ZoomOutOutlined } from '@ant-design/icons'; import { Image as AntImage, ImageProps, Space } from 'antd'; import { round } from 'lodash'; import React, { useCallback, useEffect, useState } from 'react'; import './index.less'; const AutoImage: React.FC< ImageProps & { height: number | string; width?: number | string; autoSize?: boolean; preview?: boolean; onLoad?: () => void; } > = (props) => { const { height = 100, width: w, autoSize, preview = true, ...rest } = props; const [width, setWidth] = useState(w || 0); const [isError, setIsError] = useState(false); const getImgRatio = useCallback((url: string): Promise<{ ratio: number }> => { return new Promise((resolve) => { const img = new Image(); img.onload = () => { resolve({ ratio: round(img.width / img.height, 2) }); }; img.onerror = () => { resolve({ ratio: 1 }); }; img.src = url; }); }, []); const handleOnLoad = useCallback(async () => { if (autoSize) { return; } const { ratio } = await getImgRatio(props.src || ''); if (typeof height === 'number') { setWidth(height * ratio); } else { throw new Error('Height must be a number'); } }, [getImgRatio, height, props.src]); const onDownload = () => { const url = props.src || ''; const filename = Date.now() + ''; const link = document.createElement('a'); link.href = url; link.download = filename; document.body.appendChild(link); link.click(); link.remove(); }; const handleImgLoad = useCallback(() => { props.onLoad?.(); }, [props.onLoad]); const handleOnError = () => { setIsError(true); }; useEffect(() => { handleOnLoad(); }, [handleOnLoad]); useEffect(() => { setWidth(w || 0); }, [w]); return ( , toolbarRender: ( _, { transform: { scale }, actions: { onFlipY, onFlipX, onRotateLeft, onRotateRight, onZoomOut, onZoomIn, onReset } } ) => ( ) } } /> ); }; export default AutoImage;