@@ -10,14 +10,14 @@ import com.smarttoolfactory.cropper.TouchRegion
1010import com.smarttoolfactory.cropper.model.AspectRatio
1111import com.smarttoolfactory.cropper.settings.CropProperties
1212import kotlinx.coroutines.coroutineScope
13+ import kotlin.math.roundToInt
1314
1415/* *
1516 * State for cropper with dynamic overlay. Overlay of this state can be moved or resized
1617 * using handles or touching inner position of overlay. When overlay overflow out of image bounds
1718 * or moves out of bounds it animates back to valid size and position
1819 *
1920 * @param handleSize size of the handle to control, move or scale dynamic overlay
20- * @param minOverlaySize minimum overlay size that can be shrunk to by moving handles
2121 * @param imageSize size of the **Bitmap**
2222 * @param containerSize size of the Composable that draws **Bitmap**
2323 * @param maxZoom maximum zoom value
@@ -29,11 +29,11 @@ import kotlinx.coroutines.coroutineScope
2929 * @param rotatable when set to true rotation is enabled
3030 * @param limitPan limits pan to bounds of parent Composable. Using this flag prevents creating
3131 * @param fixedAspectRatio when set to true aspect ratio of overlay is fixed
32+ * @param minDimension minimum size of the overlay, if null defaults to handleSize * 2
3233 * empty space on sides or edges of parent
3334 */
3435class DynamicCropState internal constructor(
3536 private var handleSize : Float ,
36- private var minOverlaySize : Float ,
3737 imageSize : IntSize ,
3838 containerSize : IntSize ,
3939 drawAreaSize : IntSize ,
@@ -46,6 +46,7 @@ class DynamicCropState internal constructor(
4646 rotatable : Boolean ,
4747 limitPan : Boolean ,
4848 private val fixedAspectRatio : Boolean ,
49+ private val minDimension : IntSize ?
4950) : CropState(
5051 imageSize = imageSize,
5152 containerSize = containerSize,
@@ -87,8 +88,6 @@ class DynamicCropState internal constructor(
8788
8889 override suspend fun updateProperties (cropProperties : CropProperties , forceUpdate : Boolean ) {
8990 handleSize = cropProperties.handleSize
90- minOverlaySize = handleSize * 2
91-
9291 super .updateProperties(cropProperties, forceUpdate)
9392 }
9493
@@ -131,12 +130,17 @@ class DynamicCropState internal constructor(
131130
132131 val change = changes.first()
133132
133+ // Default min dimension is handle size * 2
134+ val doubleHandleSize = handleSize * 2
135+ val defaultMinDimension =
136+ IntSize (doubleHandleSize.roundToInt(), doubleHandleSize.roundToInt())
137+
134138 // update overlay rectangle based on where its touched and touch position to corners
135139 // This function moves and/or scales overlay rectangle
136140 val newRect = updateOverlayRect(
137141 distanceToEdgeFromTouch = distanceToEdgeFromTouch,
138142 touchRegion = touchRegion,
139- minDimension = minOverlaySize ,
143+ minDimension = minDimension ? : defaultMinDimension ,
140144 rectTemp = rectTemp,
141145 overlayRect = overlayRect,
142146 change = change,
@@ -359,7 +363,7 @@ class DynamicCropState internal constructor(
359363 private fun updateOverlayRect (
360364 distanceToEdgeFromTouch : Offset ,
361365 touchRegion : TouchRegion ,
362- minDimension : Float ,
366+ minDimension : IntSize ,
363367 rectTemp : Rect ,
364368 overlayRect : Rect ,
365369 change : PointerInputChange ,
@@ -380,15 +384,15 @@ class DynamicCropState internal constructor(
380384
381385 // Set position of top left while moving with top left handle and
382386 // limit position to not intersect other handles
383- val left = screenPositionX.coerceAtMost(rectTemp.right - minDimension)
387+ val left = screenPositionX.coerceAtMost(rectTemp.right - minDimension.width )
384388 val top = if (fixedAspectRatio) {
385389 // If aspect ratio is fixed we need to calculate top position based on
386390 // left position and aspect ratio
387391 val width = rectTemp.right - left
388392 val height = width / aspectRatio
389393 rectTemp.bottom - height
390394 } else {
391- screenPositionY.coerceAtMost(rectTemp.bottom - minDimension)
395+ screenPositionY.coerceAtMost(rectTemp.bottom - minDimension.height )
392396 }
393397 Rect (
394398 left = left,
@@ -402,15 +406,15 @@ class DynamicCropState internal constructor(
402406
403407 // Set position of top left while moving with bottom left handle and
404408 // limit position to not intersect other handles
405- val left = screenPositionX.coerceAtMost(rectTemp.right - minDimension)
409+ val left = screenPositionX.coerceAtMost(rectTemp.right - minDimension.width )
406410 val bottom = if (fixedAspectRatio) {
407411 // If aspect ratio is fixed we need to calculate bottom position based on
408412 // left position and aspect ratio
409413 val width = rectTemp.right - left
410414 val height = width / aspectRatio
411415 rectTemp.top + height
412416 } else {
413- screenPositionY.coerceAtLeast(rectTemp.top + minDimension)
417+ screenPositionY.coerceAtLeast(rectTemp.top + minDimension.height )
414418 }
415419 Rect (
416420 left = left,
@@ -424,15 +428,15 @@ class DynamicCropState internal constructor(
424428
425429 // Set position of top left while moving with top right handle and
426430 // limit position to not intersect other handles
427- val right = screenPositionX.coerceAtLeast(rectTemp.left + minDimension)
431+ val right = screenPositionX.coerceAtLeast(rectTemp.left + minDimension.width )
428432 val top = if (fixedAspectRatio) {
429433 // If aspect ratio is fixed we need to calculate top position based on
430434 // right position and aspect ratio
431435 val width = right - rectTemp.left
432436 val height = width / aspectRatio
433437 rectTemp.bottom - height
434438 } else {
435- screenPositionY.coerceAtMost(rectTemp.bottom - minDimension)
439+ screenPositionY.coerceAtMost(rectTemp.bottom - minDimension.height )
436440 }
437441
438442 Rect (
@@ -448,15 +452,15 @@ class DynamicCropState internal constructor(
448452
449453 // Set position of top left while moving with bottom right handle and
450454 // limit position to not intersect other handles
451- val right = screenPositionX.coerceAtLeast(rectTemp.left + minDimension)
455+ val right = screenPositionX.coerceAtLeast(rectTemp.left + minDimension.width )
452456 val bottom = if (fixedAspectRatio) {
453457 // If aspect ratio is fixed we need to calculate bottom position based on
454458 // right position and aspect ratio
455459 val width = right - rectTemp.left
456460 val height = width / aspectRatio
457461 rectTemp.top + height
458462 } else {
459- screenPositionY.coerceAtLeast(rectTemp.top + minDimension)
463+ screenPositionY.coerceAtLeast(rectTemp.top + minDimension.height )
460464 }
461465
462466 Rect (
0 commit comments