diff --git a/web/src/components/PreviewImageDialog.tsx b/web/src/components/PreviewImageDialog.tsx index 999af02d..bdbc71f3 100644 --- a/web/src/components/PreviewImageDialog.tsx +++ b/web/src/components/PreviewImageDialog.tsx @@ -1,16 +1,33 @@ -import { useState } from "react"; +import React, { useState } from "react"; import * as utils from "../helpers/utils"; import Icon from "./Icon"; import { generateDialog } from "./Dialog"; import "../less/preview-image-dialog.less"; +const MIN_SCALE = 0.5; +const MAX_SCALE = 5; +const SCALE_UNIT = 0.25; + interface Props extends DialogProps { imgUrls: string[]; initialIndex: number; } +interface State { + angle: number; + scale: number; + originX: number; + originY: number; +} + const PreviewImageDialog: React.FC = ({ destroy, imgUrls, initialIndex }: Props) => { const [currentIndex, setCurrentIndex] = useState(initialIndex); + const [state, setState] = useState({ + angle: 0, + scale: 1, + originX: -1, + originY: -1, + }); const handleCloseBtnClick = () => { destroy(); @@ -39,6 +56,38 @@ const PreviewImageDialog: React.FC = ({ destroy, imgUrls, initialIndex }: } }; + const handleImgRotate = (event: React.MouseEvent, angle: number) => { + const curImgAngle = (state.angle + angle + 360) % 360; + setState({ + ...state, + originX: -1, + originY: -1, + angle: curImgAngle, + }); + }; + + const handleImgContainerScroll = (event: React.WheelEvent) => { + const offsetX = event.nativeEvent.offsetX; + const offsetY = event.nativeEvent.offsetY; + const sign = event.deltaY < 0 ? 1 : -1; + const curAngle = Math.max(MIN_SCALE, Math.min(MAX_SCALE, state.scale + sign * SCALE_UNIT)); + setState({ + ...state, + originX: offsetX, + originY: offsetY, + scale: curAngle, + }); + }; + + const getImageComputedStyle = () => { + return { + transform: `scale(${state.scale}) rotate(${state.angle}deg)`, + transformOrigin: `${state.originX === -1 ? "center" : `${state.originX}px`} ${ + state.originY === -1 ? "center" : `${state.originY}px` + }`, + }; + }; + return ( <>
@@ -48,9 +97,20 @@ const PreviewImageDialog: React.FC = ({ destroy, imgUrls, initialIndex }: + +
- e.stopPropagation()} src={imgUrls[currentIndex]} /> + e.stopPropagation()} + src={imgUrls[currentIndex]} + onWheel={handleImgContainerScroll} + style={getImageComputedStyle()} + />
);