1- @file:OptIn(ExperimentalMaterial3Api ::class )
2-
31package com.smarttoolfactory.composeprogressindicator
42
5- import android.graphics.ComposePathEffect
6- import android.graphics.CornerPathEffect
7- import android.graphics.DiscretePathEffect
83import android.os.Bundle
94import androidx.activity.ComponentActivity
105import androidx.activity.compose.setContent
11- import androidx.compose.foundation.Canvas
12- import androidx.compose.foundation.background
13- import androidx.compose.foundation.gestures.detectDragGestures
14- import androidx.compose.foundation.layout.Box
15- import androidx.compose.foundation.layout.Column
166import androidx.compose.foundation.layout.fillMaxSize
17- import androidx.compose.foundation.layout.fillMaxWidth
18- import androidx.compose.material3.ExperimentalMaterial3Api
197import androidx.compose.material3.MaterialTheme
208import androidx.compose.material3.Surface
21- import androidx.compose.runtime.*
22- import androidx.compose.ui.Alignment
239import androidx.compose.ui.Modifier
24- import androidx.compose.ui.geometry.*
25- import androidx.compose.ui.graphics.*
26- import androidx.compose.ui.graphics.drawscope.Stroke
27- import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
28- import androidx.compose.ui.graphics.drawscope.translate
29- import androidx.compose.ui.input.pointer.pointerInput
30- import androidx.compose.ui.unit.dp
3110import com.smarttoolfactory.composeprogressindicator.ui.theme.composeprogressindicatorTheme
3211
33-
3412class MainActivity : ComponentActivity () {
3513 override fun onCreate (savedInstanceState : Bundle ? ) {
3614 super .onCreate(savedInstanceState)
3715 setContent {
16+
3817 composeprogressindicatorTheme {
3918 // A surface container using the 'background' color from the theme
4019 Surface (
4120 modifier = Modifier .fillMaxSize(),
4221 color = MaterialTheme .colorScheme.background
4322 ) {
44-
45- Column {
46- Box (
47- modifier = Modifier
48- // .background(Color.Black)
49- .fillMaxWidth()
50- .weight(1f ),
51- contentAlignment = Alignment .Center
52- ) {
53- // SpinningProgressIndicator(show = true)
54- // SpinningCircleProgressIndicator(show = true)
55- // GooeyEffect()
56- GooeyEffectSample2 ()
57- // NeonSample()
58- }
59- }
23+ ProgressIndicatorDemo ()
6024 }
6125 }
6226 }
6327 }
6428}
65-
66- @Composable
67- private fun GooeyEffectSample2 () {
68-
69- val pathDynamic = remember { Path () }
70- val pathStatic = remember { Path () }
71-
72- /* *
73- * Current position of the pointer that is pressed or being moved
74- */
75- var currentPosition by remember { mutableStateOf(Offset .Unspecified ) }
76-
77- val segmentCount = 20
78- val pathMeasure = remember {
79- PathMeasure ()
80- }
81-
82- val modifier = Modifier
83- .pointerInput(Unit ) {
84- detectDragGestures { change, _ ->
85- currentPosition = change.position
86- }
87- }
88- .fillMaxSize()
89-
90- val paint = remember {
91- Paint ()
92- }
93-
94- var isPaintSetUp by remember {
95- mutableStateOf(false )
96- }
97-
98- Canvas (modifier = modifier) {
99- val center = size.center
100-
101- val position = if (currentPosition == Offset .Unspecified ) {
102- center
103- } else currentPosition
104-
105- pathDynamic.reset()
106- pathDynamic.addOval(
107- Rect (
108- center = position,
109- radius = 150f
110- )
111- )
112-
113- pathStatic.reset()
114- pathStatic.addOval(
115- Rect (
116- center = Offset (center.x, center.y),
117- radius = 100f
118- )
119- )
120-
121-
122- pathMeasure.setPath(pathDynamic, true )
123-
124- val discretePathEffect = DiscretePathEffect (pathMeasure.length / segmentCount, 0f )
125- val cornerPathEffect = CornerPathEffect (50f )
126-
127-
128- val chainPathEffect = PathEffect .chainPathEffect(
129- outer = cornerPathEffect.toComposePathEffect(),
130- inner = discretePathEffect.toComposePathEffect()
131- )
132-
133- if (! isPaintSetUp) {
134-
135- paint.shader = LinearGradientShader (
136- from = Offset .Zero ,
137- to = Offset (size.width, size.height),
138- colors = listOf (
139- Color (0xffFFEB3B ),
140- Color (0xffE91E63 )
141- ),
142- tileMode = TileMode .Clamp
143- )
144- isPaintSetUp = true
145- paint.pathEffect = chainPathEffect
146- }
147-
148- val newPath = Path .combine(PathOperation .Union , pathDynamic, pathStatic)
149-
150- with (drawContext.canvas) {
151- this .drawPath(
152- newPath,
153- paint
154- )
155- }
156- }
157- }
158-
159- @Composable
160- private fun GooeyEffect () {
161-
162- val pathLeft = remember { Path () }
163- val pathRight = remember { Path () }
164-
165- val segmentCount = 20
166- val pathMeasure = PathMeasure ()
167- Canvas (modifier = Modifier .fillMaxSize()) {
168- val center = size.center
169-
170- if (pathLeft.isEmpty) {
171- pathLeft.addOval(
172- Rect (
173- center = Offset (center.x - 100f , center.y),
174- radius = 200f
175- )
176- )
177- }
178-
179- if (pathRight.isEmpty) {
180- pathRight.addOval(
181- Rect (
182- center = Offset (center.x + 100f , center.y),
183- radius = 200f
184- )
185- )
186- }
187-
188-
189- val path = Path .combine(PathOperation .Union , pathLeft, pathRight)
190- pathMeasure.setPath(pathLeft, true )
191-
192- val discretePathEffect = DiscretePathEffect (pathMeasure.length / segmentCount, 0f )
193- val cornerPathEffect = CornerPathEffect (50f )
194-
195- val composePathEffect = ComposePathEffect (cornerPathEffect, discretePathEffect)
196-
197-
198- val chainPathEffect = PathEffect .chainPathEffect(
199- outer = cornerPathEffect.toComposePathEffect(),
200- inner = discretePathEffect.toComposePathEffect()
201- )
202- drawPath(path, Color .Blue , style = Stroke (4 .dp.toPx()))
203-
204- translate(top = 50f ) {
205- drawPath(
206- path = path,
207- color = Color .Red ,
208- style = Stroke (
209- 4 .dp.toPx(),
210- pathEffect = chainPathEffect
211- )
212- )
213- }
214-
215- translate(top = 100f ) {
216- drawPath(
217- path = path,
218- color = Color .Cyan ,
219- style = Stroke (
220- 4 .dp.toPx(),
221- pathEffect = composePathEffect.toComposePathEffect()
222- )
223- )
224- }
225- }
226- }
227-
228- @Composable
229- private fun NeonSample () {
230- Column (
231- modifier = Modifier
232- .fillMaxSize()
233- .background(Color .Black )
234- ) {
235-
236- val paint = remember {
237- Paint ().apply {
238- style = PaintingStyle .Stroke
239- strokeWidth = 30f
240- }
241- }
242-
243- val frameworkPaint = remember {
244- paint.asFrameworkPaint()
245- }
246-
247- val color = Color .Red
248-
249-
250- Canvas (modifier = Modifier .fillMaxSize()) {
251- this .drawIntoCanvas {
252-
253- val transparent = color
254- .copy(alpha = 0f )
255- .toArgb()
256-
257- frameworkPaint.color = transparent
258-
259- frameworkPaint.setShadowLayer(
260- 10f ,
261- 0f ,
262- 0f ,
263- color
264- .copy(alpha = .5f )
265- .toArgb()
266- )
267-
268- it.drawRoundRect(
269- left = 100f ,
270- top = 100f ,
271- right = 500f ,
272- bottom = 500f ,
273- radiusX = 5 .dp.toPx(),
274- 5 .dp.toPx(),
275- paint = paint
276- )
277-
278- drawRoundRect(
279- Color .White ,
280- topLeft = Offset (100f , 100f ),
281- size = Size (400f , 400f ),
282- cornerRadius = CornerRadius (5 .dp.toPx(), 5 .dp.toPx()),
283- // style = Stroke(width = 2.dp.toPx())
284- )
285-
286-
287- frameworkPaint.setShadowLayer(
288- 130f ,
289- 0f ,
290- 0f ,
291- color
292- .copy(alpha = .5f )
293- .toArgb()
294- )
295-
296-
297- it.drawRoundRect(
298- left = 600f ,
299- top = 100f ,
300- right = 1000f ,
301- bottom = 500f ,
302- radiusX = 5 .dp.toPx(),
303- 5 .dp.toPx(),
304- paint = paint
305- )
306-
307- drawRoundRect(
308- Color .White ,
309- topLeft = Offset (600f , 100f ),
310- size = Size (400f , 400f ),
311- cornerRadius = CornerRadius (5 .dp.toPx(), 5 .dp.toPx()),
312- style = Stroke (width = 2 .dp.toPx())
313- )
314- }
315- }
316- }
317- }
0 commit comments