Skip to content

Commit edd5095

Browse files
update TransformModifier
1 parent 25f6e72 commit edd5095

File tree

1 file changed

+38
-73
lines changed

1 file changed

+38
-73
lines changed

image/src/main/java/com/smarttoolfactory/image/transform/TransformModifier.kt

Lines changed: 38 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.compose.ui.geometry.Size
1212
import androidx.compose.ui.input.pointer.PointerInputChange
1313
import androidx.compose.ui.input.pointer.positionChange
1414
import com.smarttoolfactory.gesture.pointerMotionEvents
15+
import com.smarttoolfactory.image.util.getDistanceToEdgeFromTouch
1516
import com.smarttoolfactory.image.util.getTouchRegion
1617

1718
internal fun Modifier.transform(
@@ -60,9 +61,9 @@ internal fun Modifier.transform(
6061

6162
// This is the real position of touch in screen, when scaled
6263
// right bottom corner of 1000x1000px Composable is always (1000,1000)
63-
// but we need screen coordinated to set draw rectangle after scaling and translating
64+
// but we need screen coordinates to set draw rectangle after scaling and translating
6465
// rectDraw is drawn based on touch position on screen
65-
var screenPosition: Offset
66+
var touchPositionOnScreen: Offset
6667

6768
// Touch position for edge of the rectangle, used for not jumping to edge of rectangle
6869
// when user moves a handle. We set positionActual as position of selected handle
@@ -93,10 +94,10 @@ internal fun Modifier.transform(
9394
val touchPositionScreenY =
9495
rectDraw.top + position.y * rectDraw.height / rectBounds.height
9596

96-
screenPosition = Offset(touchPositionScreenX, touchPositionScreenY)
97+
touchPositionOnScreen = Offset(touchPositionScreenX, touchPositionScreenY)
9798

9899
touchRegion = getTouchRegion(
99-
position = screenPosition,
100+
position = touchPositionOnScreen,
100101
rect = rectDraw,
101102
handlePlacement = handlePlacement,
102103
threshold = touchRegionRadius * 2
@@ -105,7 +106,7 @@ internal fun Modifier.transform(
105106
// This is the difference between touch position and edge
106107
// This is required for not moving edge of draw rect to touch position on move
107108
distanceToEdgeFromTouch =
108-
getDistanceToEdgeFromTouch(touchRegion, rectTemp, screenPosition)
109+
getDistanceToEdgeFromTouch(touchRegion, rectTemp, touchPositionOnScreen)
109110
}
110111

111112
onDown(currentTransform, rectDraw)
@@ -136,14 +137,14 @@ internal fun Modifier.transform(
136137

137138
// Set position of top left while moving with top left handle and
138139
// limit position to not intersect other handles
139-
screenPosition = Offset(
140+
touchPositionOnScreen = Offset(
140141
screenPositionX.coerceAtMost(rectTemp.right - minDimension),
141142
screenPositionY.coerceAtMost(rectTemp.bottom - minDimension)
142143
)
143144

144145
rectDraw = Rect(
145-
left = screenPosition.x,
146-
top = screenPosition.y,
146+
left = touchPositionOnScreen.x,
147+
top = touchPositionOnScreen.y,
147148
right = rectTemp.right,
148149
bottom = rectTemp.bottom
149150
)
@@ -163,8 +164,8 @@ internal fun Modifier.transform(
163164
// TransformationOrigin of Composable is center
164165
// so need to take center into consideration
165166
// to translate from handle position
166-
val xTranslation = screenPosition.x + horizontalCenter
167-
val yTranslation = screenPosition.y + verticalCenter
167+
val xTranslation = touchPositionOnScreen.x + horizontalCenter
168+
val yTranslation = touchPositionOnScreen.y + verticalCenter
168169

169170
currentTransform = currentTransform.copy(
170171
translationX = xTranslation,
@@ -180,16 +181,16 @@ internal fun Modifier.transform(
180181

181182
// Set position of top left while moving with bottom left handle and
182183
// limit position to not intersect other handles
183-
screenPosition = Offset(
184+
touchPositionOnScreen = Offset(
184185
screenPositionX.coerceAtMost(rectTemp.right - minDimension),
185186
screenPositionY.coerceAtLeast(rectTemp.top + minDimension)
186187
)
187188

188189
rectDraw = Rect(
189-
left = screenPosition.x,
190+
left = touchPositionOnScreen.x,
190191
top = rectTemp.top,
191192
right = rectTemp.right,
192-
bottom = screenPosition.y,
193+
bottom = touchPositionOnScreen.y,
193194
)
194195

195196
// TransformOrion is center of composable, by changing
@@ -207,8 +208,8 @@ internal fun Modifier.transform(
207208
// TransformationOrigin of Composable is center
208209
// so need to take center into consideration
209210
// to translate from handle position
210-
val xTranslation = screenPosition.x + horizontalCenter
211-
val yTranslation = screenPosition.y - rectDraw.height + verticalCenter
211+
val xTranslation = touchPositionOnScreen.x + horizontalCenter
212+
val yTranslation = touchPositionOnScreen.y - rectDraw.height + verticalCenter
212213

213214
currentTransform = currentTransform.copy(
214215
translationX = xTranslation,
@@ -224,15 +225,15 @@ internal fun Modifier.transform(
224225

225226
// Set position of top left while moving with top right handle and
226227
// limit position to not intersect other handles
227-
screenPosition = Offset(
228+
touchPositionOnScreen = Offset(
228229
screenPositionX.coerceAtLeast(rectTemp.left + minDimension),
229230
screenPositionY.coerceAtMost(rectTemp.bottom - minDimension)
230231
)
231232

232233
rectDraw = Rect(
233234
left = rectTemp.left,
234-
top = screenPosition.y,
235-
right = screenPosition.x,
235+
top = touchPositionOnScreen.y,
236+
right = touchPositionOnScreen.x,
236237
bottom = rectTemp.bottom,
237238
)
238239

@@ -251,8 +252,8 @@ internal fun Modifier.transform(
251252
// TransformationOrigin of Composable is center
252253
// so need to take center into consideration
253254
// to translate from handle position
254-
val xTranslation = screenPosition.x - rectDraw.width + horizontalCenter
255-
val yTranslation = screenPosition.y + verticalCenter
255+
val xTranslation = touchPositionOnScreen.x - rectDraw.width + horizontalCenter
256+
val yTranslation = touchPositionOnScreen.y + verticalCenter
256257

257258
currentTransform = currentTransform.copy(
258259
translationX = xTranslation,
@@ -268,16 +269,16 @@ internal fun Modifier.transform(
268269

269270
// Set position of top left while moving with bottom right handle and
270271
// limit position to not intersect other handles
271-
screenPosition = Offset(
272+
touchPositionOnScreen = Offset(
272273
screenPositionX.coerceAtLeast(rectTemp.left + minDimension),
273274
screenPositionY.coerceAtLeast(rectTemp.top + minDimension)
274275
)
275276

276277
rectDraw = Rect(
277278
left = rectTemp.left,
278279
top = rectTemp.top,
279-
right = screenPosition.x,
280-
bottom = screenPosition.y,
280+
right = touchPositionOnScreen.x,
281+
bottom = touchPositionOnScreen.y,
281282
)
282283

283284
// TransformOrion is center of composable, by changing
@@ -295,8 +296,8 @@ internal fun Modifier.transform(
295296
// TransformationOrigin of Composable is center
296297
// so need to take center into consideration
297298
// to translate from handle position
298-
val xTranslation = screenPosition.x - rectDraw.width + horizontalCenter
299-
val yTranslation = screenPosition.y - rectDraw.height + verticalCenter
299+
val xTranslation = touchPositionOnScreen.x - rectDraw.width + horizontalCenter
300+
val yTranslation = touchPositionOnScreen.y - rectDraw.height + verticalCenter
300301

301302
currentTransform = currentTransform.copy(
302303
translationX = xTranslation,
@@ -313,16 +314,16 @@ internal fun Modifier.transform(
313314

314315
// Set position of left while moving with left center handle and
315316
// limit position to not intersect other handles
316-
screenPosition = Offset(
317+
touchPositionOnScreen = Offset(
317318
screenPositionX.coerceAtMost(rectTemp.right - minDimension),
318319
screenPositionY.coerceAtMost(rectTemp.bottom - minDimension)
319320
)
320321

321-
rectDraw = rectDraw.copy(left = screenPosition.x)
322+
rectDraw = rectDraw.copy(left = touchPositionOnScreen.x)
322323

323324
val horizontalCenter = (rectDraw.width - rectBounds.width) / 2
324325
val widthRatio = rectDraw.width / rectBounds.width
325-
val xTranslation = screenPosition.x + horizontalCenter
326+
val xTranslation = touchPositionOnScreen.x + horizontalCenter
326327

327328
currentTransform = currentTransform.copy(
328329
translationX = xTranslation,
@@ -335,12 +336,12 @@ internal fun Modifier.transform(
335336

336337
// Set position of top while moving with top center handle and
337338
// limit position to not intersect other handles
338-
screenPosition = Offset(
339+
touchPositionOnScreen = Offset(
339340
screenPositionX.coerceAtMost(rectTemp.right - minDimension),
340341
screenPositionY.coerceAtMost(rectTemp.bottom - minDimension)
341342
)
342343

343-
rectDraw = rectDraw.copy(top = screenPosition.y)
344+
rectDraw = rectDraw.copy(top = touchPositionOnScreen.y)
344345

345346
// TransformOrion is center of composable, by changing
346347
// it to 0,0 only for translation we move the composable
@@ -355,7 +356,7 @@ internal fun Modifier.transform(
355356
// TransformationOrigin of Composable is center
356357
// so need to take center into consideration
357358
// to translate from handle position
358-
val yTranslation = screenPosition.y + verticalCenter
359+
val yTranslation = touchPositionOnScreen.y + verticalCenter
359360

360361
currentTransform = currentTransform.copy(
361362
translationY = yTranslation,
@@ -369,12 +370,12 @@ internal fun Modifier.transform(
369370

370371
// Set position of right while moving with right center handle and
371372
// limit position to not intersect other handles
372-
screenPosition = Offset(
373+
touchPositionOnScreen = Offset(
373374
screenPositionX.coerceAtLeast(rectTemp.left + minDimension),
374375
screenPositionY.coerceAtLeast(rectTemp.top + minDimension)
375376
)
376377

377-
rectDraw = rectDraw.copy(right = screenPosition.x)
378+
rectDraw = rectDraw.copy(right = touchPositionOnScreen.x)
378379

379380
// TransformOrion is center of composable, by changing
380381
// it to 0,0 only for translation we move the composable
@@ -389,7 +390,7 @@ internal fun Modifier.transform(
389390
// TransformationOrigin of Composable is center
390391
// so need to take center into consideration
391392
// to translate from handle position
392-
val xTranslation = screenPosition.x - rectDraw.width + horizontalCenter
393+
val xTranslation = touchPositionOnScreen.x - rectDraw.width + horizontalCenter
393394

394395
currentTransform = currentTransform.copy(
395396
translationX = xTranslation,
@@ -403,12 +404,12 @@ internal fun Modifier.transform(
403404

404405
// Set position of bottom while moving with bottom center handle and
405406
// limit position to not intersect other handles
406-
screenPosition = Offset(
407+
touchPositionOnScreen = Offset(
407408
screenPositionX.coerceAtLeast(rectTemp.left + minDimension),
408409
screenPositionY.coerceAtLeast(rectTemp.top + minDimension)
409410
)
410411

411-
rectDraw = rectDraw.copy(bottom = screenPosition.y)
412+
rectDraw = rectDraw.copy(bottom = touchPositionOnScreen.y)
412413

413414
// TransformOrion is center of composable, by changing
414415
// it to 0,0 only for translation we move the composable
@@ -423,7 +424,7 @@ internal fun Modifier.transform(
423424
// TransformationOrigin of Composable is center
424425
// so need to take center into consideration
425426
// to translate from handle position
426-
val yTranslation = screenPosition.y - rectDraw.height + verticalCenter
427+
val yTranslation = touchPositionOnScreen.y - rectDraw.height + verticalCenter
427428

428429
currentTransform = currentTransform.copy(
429430
translationY = yTranslation,
@@ -478,39 +479,3 @@ internal fun Modifier.transform(
478479
properties["onUp"] = onUp
479480
}
480481
)
481-
482-
private fun getDistanceToEdgeFromTouch(
483-
touchRegion: TouchRegion,
484-
rectTemp: Rect,
485-
screenPosition: Offset
486-
) = when (touchRegion) {
487-
// Corners
488-
TouchRegion.TopLeft -> {
489-
rectTemp.topLeft - screenPosition
490-
}
491-
TouchRegion.TopRight -> {
492-
rectTemp.topRight - screenPosition
493-
}
494-
TouchRegion.BottomLeft -> {
495-
rectTemp.bottomLeft - screenPosition
496-
}
497-
TouchRegion.BottomRight -> {
498-
rectTemp.bottomRight - screenPosition
499-
}
500-
// Sides
501-
TouchRegion.CenterLeft -> {
502-
rectTemp.centerLeft - screenPosition
503-
}
504-
TouchRegion.TopCenter -> {
505-
rectTemp.topCenter - screenPosition
506-
}
507-
TouchRegion.CenterRight -> {
508-
rectTemp.centerRight - screenPosition
509-
}
510-
TouchRegion.BottomCenter -> {
511-
rectTemp.bottomCenter - screenPosition
512-
}
513-
else -> {
514-
Offset.Zero
515-
}
516-
}

0 commit comments

Comments
 (0)