diff --git a/docs/docs/components/cropzoom.md b/docs/docs/components/cropzoom.md index 8f8935a..82fc4b6 100644 --- a/docs/docs/components/cropzoom.md +++ b/docs/docs/components/cropzoom.md @@ -258,6 +258,18 @@ Rotate the component 90 degrees clockwise in a range from 0 to 360 degrees. - Returns `void` +### rotateWithDirection +Rotate the component 90 degrees (or -90 degrees) clockwise or counterclockwise in a range from 0 to 360 degrees (or 0 to -360 degrees). +- Arguments + +| Name | Type | Default |Description | +|------|------|-----|--------------| +| animate | `boolean \| undefined` | `true` | Whether to animate the transition or not. | +| clockwise | `boolean \| undefined` | `true` | Whether to rotate clockwise (90 degrees) or counterclockwise (-90 degrees) | +| cb | `function \| undefined` | `undefined` | Callback to trigger at the beginning of the transition, as its only argument receives the angle your component will transition to, this angle ranges from 0 to 360 degrees (or -360 degrees) (at 360 or -360 degrees it's clamped to 0). | + +- Returns `void` + ### flipHorizontal Flip the component horizontally. - Arguments diff --git a/src/components/crop/CropZoom.tsx b/src/components/crop/CropZoom.tsx index e008638..3bfed25 100644 --- a/src/components/crop/CropZoom.tsx +++ b/src/components/crop/CropZoom.tsx @@ -26,6 +26,7 @@ import { type CropContextResult, type CropZoomType, type RotateTransitionCallback, + type DirectionRotationCallback, type CropZoomState, type CropZoomAssignableState, } from './types'; @@ -227,10 +228,16 @@ const CropZoom: React.FC = (props) => { // Reference handling section const canRotate = useSharedValue(true); - const handleRotate: RotateTransitionCallback = (animate = true, cb) => { + const handleRotate: DirectionRotationCallback = ( + animate = true, + clockwise = true, + cb + ) => { if (!canRotate.value) return; - const toAngle = rotation.value + Math.PI / 2; + // Determine the direction multiplier based on clockwise or counterclockwise rotation + const direction = clockwise ? 1 : -1; + const toAngle = rotation.value + (Math.PI / 2) * direction; sizeAngle.value = toAngle; if (cb !== undefined) cb(toAngle % (Math.PI * 2)); @@ -246,7 +253,7 @@ const CropZoom: React.FC = (props) => { rotation.value = withTiming(toAngle, undefined, (_) => { canRotate.value = true; - if (rotation.value === Math.PI * 2) rotation.value = 0; + if (Math.abs(rotation.value) === Math.PI * 2) rotation.value = 0; }); return; @@ -364,7 +371,8 @@ const CropZoom: React.FC = (props) => { }; useImperativeHandle(ref, () => ({ - rotate: handleRotate, + rotate: (animate, cb) => handleRotate(animate, true, cb), + rotateWithDirection: handleRotate, flipHorizontal: flipHorizontal, flipVertical: flipVertical, reset: handleReset, diff --git a/src/components/crop/types.ts b/src/components/crop/types.ts index d0ccfa6..89f4d8e 100644 --- a/src/components/crop/types.ts +++ b/src/components/crop/types.ts @@ -46,6 +46,12 @@ export type RotateTransitionCallback = ( cb?: (value: number) => void ) => void; +export type DirectionRotationCallback = ( + animate?: boolean, + clockwise?: boolean, + cb?: (value: number) => void +) => void; + export type CropZoomType = { /** * @description Request internal transformation values of this component at the moment of the calling. @@ -69,6 +75,15 @@ export type CropZoomType = { */ rotate: RotateTransitionCallback; + /** + * @description Rotates in steps of 90 degrees at a time, either in the positive or negative direction, within a range from 0 to 360 degrees (or 0 to -360 degrees). + * @param animate Whether to animate the transition or not. + * @param clockwise Whether to rotate clockwise (90 degrees) or counterclockwise (-90 degrees). + * @param cb Callback to trigger at the beginning of the transition, as its only argument receives + * the angle your component will transition to, this angle ranges from 0 to 360 degrees (or 0 to -360 degrees) and at 360 degrees (or -360 degrees) it is clamped back to 0. + */ + rotateWithDirection: DirectionRotationCallback; + /** * @description Rotates the Y axis from 0 to 180 degrees and vice versa * @param animate Whether to animate the transition or not.