Skip to content

Commit 915a8d9

Browse files
update demos
1 parent 405543c commit 915a8d9

File tree

11 files changed

+237
-10
lines changed

11 files changed

+237
-10
lines changed
Lines changed: 223 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,223 @@
1+
package com.smarttoolfactory.composecropper.demo
2+
3+
import android.graphics.Bitmap
4+
import androidx.compose.foundation.Image
5+
import androidx.compose.foundation.background
6+
import androidx.compose.foundation.border
7+
import androidx.compose.foundation.layout.*
8+
import androidx.compose.runtime.Composable
9+
import androidx.compose.runtime.remember
10+
import androidx.compose.ui.Modifier
11+
import androidx.compose.ui.geometry.Offset
12+
import androidx.compose.ui.graphics.*
13+
import androidx.compose.ui.graphics.drawscope.Stroke
14+
import androidx.compose.ui.graphics.drawscope.translate
15+
import androidx.compose.ui.layout.ContentScale
16+
import androidx.compose.ui.res.imageResource
17+
import androidx.compose.ui.unit.dp
18+
import com.smarttoolfactory.composecropper.R
19+
20+
@Composable
21+
fun CanvasDemo() {
22+
23+
Column(modifier = Modifier.fillMaxSize()) {
24+
25+
NativeCanvasSample1(
26+
modifier = Modifier
27+
.fillMaxWidth()
28+
.aspectRatio(4 / 3f)
29+
)
30+
31+
NativeCanvasMaskSample()
32+
33+
VectorSample()
34+
}
35+
36+
}
37+
38+
39+
@Composable
40+
fun NativeCanvasMaskSample() {
41+
42+
43+
val cropMaskBitmap = ImageBitmap.imageResource(id = R.drawable.squircle)
44+
45+
val imagePaint = remember {
46+
Paint().apply {
47+
blendMode = BlendMode.SrcIn
48+
}
49+
}
50+
51+
val paint = remember {
52+
Paint()
53+
}
54+
55+
val imageBitmap = ImageBitmap
56+
.imageResource(id = R.drawable.cinnamon)
57+
.asAndroidBitmap()
58+
.copy(Bitmap.Config.ARGB_8888, true)!!
59+
.asImageBitmap()
60+
61+
62+
Canvas(image = imageBitmap).apply {
63+
64+
saveLayer(nativeCanvas.clipBounds.toComposeRect(), imagePaint)
65+
// Destination
66+
// drawCircle(center = Offset(400f, 400f), radius = 300f, paint)
67+
// drawImage(cropMaskBitmap, topLeftOffset = Offset.Zero, paint)
68+
69+
val matrix = android.graphics.Matrix()
70+
matrix.postScale(30f, 30f)
71+
favoritePath.asAndroidPath().transform(matrix)
72+
73+
val left = favoritePath.getBounds().left
74+
val top = favoritePath.getBounds().top
75+
76+
77+
drawPath(favoritePath, paint)
78+
79+
// Source
80+
drawImage(imageBitmap, topLeftOffset = Offset.Zero, imagePaint)
81+
82+
restore()
83+
}
84+
85+
Image(
86+
modifier = Modifier
87+
.fillMaxWidth()
88+
.aspectRatio(4 / 3f)
89+
.border(1.dp, Color.Green),
90+
bitmap = imageBitmap,
91+
contentDescription = null
92+
)
93+
}
94+
95+
@Composable
96+
fun NativeCanvasSample1(modifier: Modifier) {
97+
98+
val imageBitmap = ImageBitmap
99+
.imageResource(id = R.drawable.cinnamon)
100+
.asAndroidBitmap()
101+
.copy(Bitmap.Config.ARGB_8888, true)!!
102+
.asImageBitmap()
103+
104+
BoxWithConstraints(modifier) {
105+
106+
107+
val imageWidth = constraints.maxWidth
108+
val imageHeight = constraints.maxHeight
109+
110+
val bitmapWidth = imageBitmap.width
111+
val bitmapHeight = imageBitmap.height
112+
113+
114+
val canvas = Canvas(imageBitmap)
115+
116+
val imagePaint = remember {
117+
Paint().apply {
118+
blendMode = BlendMode.SrcIn
119+
}
120+
}
121+
122+
val paint = remember {
123+
Paint().apply {
124+
color = Color(0xff29B6F6)
125+
}
126+
}
127+
128+
canvas.apply {
129+
val nativeCanvas = this.nativeCanvas
130+
val canvasWidth = nativeCanvas.width.toFloat()
131+
val canvasHeight = nativeCanvas.height.toFloat()
132+
133+
println(
134+
"🔥 Canvas Width: $canvasWidth, canvasHeight: $canvasHeight, " +
135+
"imageWidth: $imageWidth, imageHeight: $imageHeight\n" +
136+
"bitmapWidth: $bitmapWidth, bitmapHeight: $bitmapHeight\n" +
137+
"rect: ${nativeCanvas.clipBounds.toComposeRect()}"
138+
)
139+
saveLayer(nativeCanvas.clipBounds.toComposeRect(), imagePaint)
140+
141+
drawCircle(
142+
center = Offset(canvasWidth / 2, canvasHeight / 2),
143+
radius = canvasHeight / 2,
144+
paint = paint
145+
)
146+
drawImage(image = imageBitmap, topLeftOffset = Offset.Zero, imagePaint)
147+
restore()
148+
149+
150+
}
151+
152+
Image(
153+
modifier = Modifier
154+
.background(Color.LightGray)
155+
.border(2.dp, Color.Red),
156+
bitmap = imageBitmap,
157+
contentDescription = null,
158+
contentScale = ContentScale.FillBounds
159+
)
160+
161+
}
162+
}
163+
164+
@Composable
165+
private fun VectorSample() {
166+
167+
androidx.compose.foundation.Canvas(
168+
modifier = Modifier
169+
.fillMaxWidth()
170+
.aspectRatio(4 / 3f)
171+
.border(3.dp,Color.Cyan)
172+
) {
173+
174+
val matrix = android.graphics.Matrix()
175+
matrix.postScale(30f, 30f)
176+
starPath.asAndroidPath().transform(matrix)
177+
178+
val left = starPath.getBounds().left
179+
val top = starPath.getBounds().top
180+
181+
translate(left = -left, top = -top) {
182+
drawPath(starPath, Color.Red)
183+
}
184+
185+
drawRect(
186+
color = Color.Green,
187+
topLeft = starPath.getBounds().topLeft,
188+
size = starPath.getBounds().size,
189+
style = Stroke(2.dp.toPx())
190+
)
191+
192+
}
193+
}
194+
195+
196+
197+
198+
val favoritePath = Path().apply {
199+
moveTo(12.0f, 21.35f)
200+
relativeLineTo(-1.45f, -1.32f)
201+
cubicTo(5.4f, 15.36f, 2.0f, 12.28f, 2.0f, 8.5f)
202+
cubicTo(2.0f, 5.42f, 4.42f, 3.0f, 7.5f, 3.0f)
203+
relativeCubicTo(1.74f, 0.0f, 3.41f, 0.81f, 4.5f, 2.09f)
204+
cubicTo(13.09f, 3.81f, 14.76f, 3.0f, 16.5f, 3.0f)
205+
cubicTo(19.58f, 3.0f, 22.0f, 5.42f, 22.0f, 8.5f)
206+
relativeCubicTo(0.0f, 3.78f, -3.4f, 6.86f, -8.55f, 11.54f)
207+
lineTo(12.0f, 21.35f)
208+
close()
209+
}
210+
211+
val starPath = Path().apply {
212+
moveTo(12.0f, 17.27f)
213+
lineTo(18.18f, 21.0f)
214+
relativeLineTo(-1.64f, -7.03f)
215+
lineTo(22.0f, 9.24f)
216+
relativeLineTo(-7.19f, -0.61f)
217+
lineTo(12.0f, 2.0f)
218+
lineTo(9.19f, 8.63f)
219+
lineTo(2.0f, 9.24f)
220+
relativeLineTo(5.46f, 4.73f)
221+
lineTo(5.82f, 21.0f)
222+
close()
223+
}

app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemo.kt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ package com.smarttoolfactory.composecropper.demo
44

55
import androidx.compose.foundation.Image
66
import androidx.compose.foundation.background
7-
import androidx.compose.foundation.layout.Box
8-
import androidx.compose.foundation.layout.Column
9-
import androidx.compose.foundation.layout.fillMaxSize
10-
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.*
118
import androidx.compose.foundation.shape.RoundedCornerShape
129
import androidx.compose.material.*
1310
import androidx.compose.material.icons.Icons
@@ -28,6 +25,7 @@ import androidx.compose.ui.layout.ContentScale
2825
import androidx.compose.ui.platform.LocalContext
2926
import androidx.compose.ui.res.imageResource
3027
import androidx.compose.ui.unit.dp
28+
import com.smarttoolfactory.colorpicker.widget.drawChecker
3129
import com.smarttoolfactory.composecropper.ImageSelectionButton
3230
import com.smarttoolfactory.composecropper.R
3331
import com.smarttoolfactory.composecropper.preferences.CropStyleSelectionMenu
@@ -140,7 +138,7 @@ private fun MainContent(
140138

141139
val imageBitmapLarge = ImageBitmap.imageResource(
142140
LocalContext.current.resources,
143-
R.drawable.landscape1
141+
R.drawable.cinnamon
144142
)
145143

146144
var imageBitmap by remember { mutableStateOf(imageBitmapLarge) }
@@ -239,7 +237,10 @@ private fun ShowCroppedImageDialog(imageBitmap: ImageBitmap, onDismissRequest: (
239237
onDismissRequest = onDismissRequest,
240238
text = {
241239
Image(
242-
modifier = Modifier.fillMaxWidth(),
240+
modifier = Modifier
241+
.drawChecker(RoundedCornerShape(8.dp))
242+
.fillMaxWidth()
243+
.aspectRatio(1f),
243244
contentScale = ContentScale.Fit,
244245
bitmap = imageBitmap,
245246
contentDescription = "result"

app/src/main/java/com/smarttoolfactory/composecropper/demo/ImageCropDemoSimple.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ fun ImageCropDemoSimple() {
3939

4040
val imageBitmapLarge = ImageBitmap.imageResource(
4141
LocalContext.current.resources,
42-
R.drawable.landscape1
42+
R.drawable.cinnamon
4343
)
4444

4545
val imageBitmap by remember { mutableStateOf(imageBitmapLarge) }

app/src/main/java/com/smarttoolfactory/composecropper/preferences/CropFrameSelection.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ fun CropFrameSelection(
8989
@Composable
9090
private fun CropFrameSelectionList(
9191
modifier: Modifier = Modifier,
92-
initialSelectedIndex: Int = 2,
92+
initialSelectedIndex: Int = 0,
9393
cropFrames: List<CropFrame>,
9494
onClick: (CropFrame) -> Unit,
9595
onCropFrameChange: (CropFrame) -> Unit
@@ -102,7 +102,7 @@ private fun CropFrameSelectionList(
102102
items = cropFrames,
103103
inactiveItemPercent = 80,
104104
initialFirstVisibleIndex = initialSelectedIndex - 2,
105-
) { animationProgress: AnimationProgress, _, item: CropFrame, width: Dp ->
105+
) { animationProgress: AnimationProgress, index: Int, item: CropFrame, width: Dp ->
106106

107107
val scale = animationProgress.scale
108108
val color = animationProgress.color
1.83 MB
Loading
-25.6 KB
Binary file not shown.
-230 KB
Binary file not shown.
-5.42 MB
Binary file not shown.
-5.88 MB
Binary file not shown.

cropper/src/main/java/com/smarttoolfactory/cropper/ImageCropper.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package com.smarttoolfactory.cropper
44
import androidx.compose.animation.AnimatedVisibility
55
import androidx.compose.animation.ExperimentalAnimationApi
66
import androidx.compose.animation.animateColorAsState
7+
import androidx.compose.animation.core.LinearEasing
78
import androidx.compose.animation.core.tween
89
import androidx.compose.animation.scaleIn
910
import androidx.compose.foundation.background
@@ -119,6 +120,7 @@ fun ImageCropper(
119120
}
120121

121122
val transparentColor by animateColorAsState(
123+
animationSpec = tween(300, easing = LinearEasing),
122124
targetValue = if (isTouched.value) Color(0x77000000) else Color(0xAA000000)
123125
)
124126

0 commit comments

Comments
 (0)