@@ -56,9 +56,9 @@ class DynamicCropState internal constructor(
5656) {
5757
5858 /* *
59- * Rectangle that covers Image composable
60- */
61-
59+ * Rectangle that covers bounds of Composable. This is a rectangle uses [containerSize] as
60+ * size and [Offset.Zero] as top left corner
61+ */
6262 private val rectBounds = Rect (
6363 offset = Offset .Zero ,
6464 size = Size (containerSize.width.toFloat(), containerSize.height.toFloat())
@@ -139,15 +139,23 @@ class DynamicCropState internal constructor(
139139
140140 override suspend fun onUp (change : PointerInputChange ) = coroutineScope {
141141 if (touchRegion != TouchRegion .None ) {
142- // Update overlay if it's out of Container bounds
143- rectTemp = calculateOverlayRectInBounds(rectBounds, overlayRect)
144- animateOverlayRectTo(rectTemp)
142+
143+ val isInContainerBounds = isRectInContainerBounds(overlayRect)
144+ if (! isInContainerBounds) {
145+
146+ // Calculate new overlay since it's out of Container bounds
147+ rectTemp = calculateOverlayRectInBounds(rectBounds, overlayRect)
148+
149+ // Animate overlay to new bounds inside container
150+ animateOverlayRectTo(rectTemp)
151+ }
145152
146153 // Update and animate pan, zoom and image draw area after overlay position is updated
147- animateTransformationToOverlayBounds()
154+ animateTransformationToOverlayBounds(overlayRect, true )
148155
149156 // Update image draw area after animating pan, zoom or rotation is completed
150157 drawAreaRect = updateImageDrawRectFromTransformation()
158+
151159 touchRegion = TouchRegion .None
152160 }
153161
@@ -208,15 +216,14 @@ class DynamicCropState internal constructor(
208216 onBoundsCalculated()
209217 }
210218
211- animateTransformationToOverlayBounds()
219+ animateTransformationToOverlayBounds(overlayRect, animate = true )
212220 }
213221 }
214222 }
215223
216224 override suspend fun onDoubleTap (
217- pan : Offset ,
225+ offset : Offset ,
218226 zoom : Float ,
219- rotation : Float ,
220227 onAnimationEnd : () -> Unit
221228 ) {
222229 doubleTapped = true
@@ -226,10 +233,26 @@ class DynamicCropState internal constructor(
226233 }
227234 resetWithAnimation(pan = pan, zoom = zoom, rotation = rotation)
228235
229- animateOverlayRectTo(
230- calculateOverlayRectInBounds(rectBounds, overlayRect)
231- )
232- animateTransformationToOverlayBounds()
236+ // We get target value on start instead of updating bounds after
237+ // gesture has finished
238+ drawAreaRect = updateImageDrawRectFromTransformation()
239+
240+
241+ if (! isOverlayInImageDrawBounds()) {
242+ // Moves rectangle to bounds inside drawArea Rect while keeping aspect ratio
243+ // of current overlay rect
244+ animateOverlayRectTo(
245+ getOverlayFromAspectRatio(
246+ containerSize.width.toFloat(),
247+ containerSize.height.toFloat(),
248+ drawAreaSize.width.toFloat(),
249+ drawAreaSize.height.toFloat(),
250+ aspectRatio
251+ )
252+ )
253+
254+ animateTransformationToOverlayBounds(overlayRect,false )
255+ }
233256 onAnimationEnd()
234257 }
235258
0 commit comments