@@ -2,12 +2,19 @@ package com.smarttoolfactory.composeimage.demo
22
33import androidx.compose.foundation.background
44import androidx.compose.foundation.layout.*
5+ import androidx.compose.foundation.rememberScrollState
6+ import androidx.compose.foundation.verticalScroll
7+ import androidx.compose.material.Slider
58import androidx.compose.material3.MaterialTheme
69import androidx.compose.material3.Text
710import androidx.compose.runtime.*
811import androidx.compose.ui.Modifier
12+ import androidx.compose.ui.draw.shadow
913import androidx.compose.ui.graphics.Color
1014import androidx.compose.ui.graphics.ImageBitmap
15+ import androidx.compose.ui.graphics.Path
16+ import androidx.compose.ui.graphics.PathEffect
17+ import androidx.compose.ui.graphics.drawscope.Stroke
1118import androidx.compose.ui.layout.ContentScale
1219import androidx.compose.ui.platform.LocalContext
1320import androidx.compose.ui.res.imageResource
@@ -17,56 +24,176 @@ import androidx.compose.ui.unit.sp
1724import com.smarttoolfactory.composeimage.ContentScaleSelectionMenu
1825import com.smarttoolfactory.composeimage.R
1926import com.smarttoolfactory.image.zoom.ZoomableImage
27+ import com.smarttoolfactory.image.zoom.zoom
28+ import kotlin.math.cos
29+ import kotlin.math.roundToInt
30+ import kotlin.math.sin
2031
2132@Composable
22- fun ZoomableImageDemo () {
33+ fun ZoomDemo () {
2334
24- Column (modifier = Modifier .fillMaxSize()) {
25- val imageBitmapLarge = ImageBitmap .imageResource(
26- LocalContext .current.resources,
27- R .drawable.landscape4
28- )
35+ Column (
36+ modifier = Modifier
37+ .fillMaxSize()
38+ .verticalScroll(rememberScrollState())
39+ .background(Color (0xffECEFF1 ))
40+ ) {
41+ ZoomableImageDemo ()
42+ ZoomModifierDemo ()
43+ }
44+ }
2945
30- var contentScale by remember { mutableStateOf(ContentScale .Fit ) }
46+ @Composable
47+ private fun ZoomableImageDemo () {
48+ val imageBitmapLarge = ImageBitmap .imageResource(
49+ LocalContext .current.resources,
50+ R .drawable.landscape4
51+ )
3152
32- ContentScaleSelectionMenu (contentScale = contentScale) {
33- contentScale = it
34- }
53+ var contentScale by remember { mutableStateOf(ContentScale .Fit ) }
54+
55+ ContentScaleSelectionMenu (contentScale = contentScale) {
56+ contentScale = it
57+ }
58+
59+ Text (
60+ text = " clipTransformToContentScale false" ,
61+ fontSize = 16 .sp,
62+ fontWeight = FontWeight .Bold ,
63+ color = MaterialTheme .colorScheme.primary,
64+ modifier = Modifier .padding(8 .dp)
65+ )
66+ ZoomableImage (
67+ modifier = Modifier
68+ .background(Color .LightGray )
69+ .fillMaxWidth()
70+ .aspectRatio(4 / 3f ),
71+ imageBitmap = imageBitmapLarge,
72+ contentScale = contentScale,
73+ clipTransformToContentScale = false
74+ )
75+
76+ Spacer (modifier = Modifier .height(20 .dp))
3577
78+ Text (
79+ text = " clipTransformToContentScale true" ,
80+ fontSize = 16 .sp,
81+ fontWeight = FontWeight .Bold ,
82+ color = MaterialTheme .colorScheme.primary,
83+ modifier = Modifier .padding(8 .dp)
84+ )
85+ ZoomableImage (
86+ modifier = Modifier
87+ .background(Color .LightGray )
88+ .fillMaxWidth()
89+ .aspectRatio(4 / 3f ),
90+ imageBitmap = imageBitmapLarge,
91+ contentScale = contentScale,
92+ clipTransformToContentScale = true
93+ )
94+ }
95+
96+ @Composable
97+ private fun ZoomModifierDemo () {
98+ Column (
99+ modifier = Modifier
100+ ) {
36101 Text (
37- text = " clipTransformToContentScale false " ,
102+ text = " Modifier.zoom(clip=true) " ,
38103 fontSize = 16 .sp,
39104 fontWeight = FontWeight .Bold ,
40105 color = MaterialTheme .colorScheme.primary,
41106 modifier = Modifier .padding(8 .dp)
42107 )
43- ZoomableImage (
108+ DrawPolygonPath (
44109 modifier = Modifier
45- .background(Color .LightGray )
110+ .padding(8 .dp)
111+ .shadow(1 .dp)
112+ .background(Color .White )
46113 .fillMaxWidth()
47- .aspectRatio(4 / 3f ),
48- imageBitmap = imageBitmapLarge,
49- contentScale = contentScale,
50- clipTransformToContentScale = false
114+ .height(200 .dp)
115+ .zoom(Unit , clip = true )
51116 )
52117
53118 Spacer (modifier = Modifier .height(20 .dp))
54119
55120 Text (
56- text = " clipTransformToContentScale true " ,
121+ text = " Modifier.zoom(clip=false) " ,
57122 fontSize = 16 .sp,
58123 fontWeight = FontWeight .Bold ,
59124 color = MaterialTheme .colorScheme.primary,
60125 modifier = Modifier .padding(8 .dp)
61126 )
62- ZoomableImage (
127+ DrawPolygonPath (
63128 modifier = Modifier
64- .background(Color .LightGray )
129+ .padding(8 .dp)
130+ .shadow(1 .dp, clip = false )
131+ .background(Color .White )
65132 .fillMaxWidth()
66- .aspectRatio(4 / 3f ),
67- imageBitmap = imageBitmapLarge,
68- contentScale = contentScale,
69- clipTransformToContentScale = true
133+ .height(200 .dp)
134+ .zoom(Unit , clip = false )
70135 )
71136 }
72- }
137+ }
138+
139+
140+ @Composable
141+ private fun DrawPolygonPath (modifier : Modifier ) {
142+ var sides by remember { mutableStateOf(3f ) }
143+ var cornerRadius by remember { mutableStateOf(1f ) }
144+
145+ androidx.compose.foundation.Canvas (modifier = modifier) {
146+ val canvasWidth = size.width
147+ val canvasHeight = size.height
148+ val cx = canvasWidth / 2
149+ val cy = canvasHeight / 2
150+ val radius = (canvasHeight - 20 .dp.toPx()) / 2
151+ val path = createPolygonPath(cx, cy, sides.roundToInt(), radius)
152+
153+ drawPath(
154+ color = Color .Red ,
155+ path = path,
156+ style = Stroke (
157+ width = 4 .dp.toPx(),
158+ pathEffect = PathEffect .cornerPathEffect(cornerRadius)
159+ )
160+ )
161+ }
162+
163+ Column (modifier = Modifier .padding(horizontal = 20 .dp)) {
164+ androidx.compose.material.Text (text = " Sides ${sides.roundToInt()} " )
165+ Slider (
166+ value = sides,
167+ onValueChange = { sides = it },
168+ valueRange = 3f .. 12f ,
169+ steps = 10
170+ )
171+
172+ androidx.compose.material.Text (text = " CornerRadius ${cornerRadius.roundToInt()} " )
173+
174+ Slider (
175+ value = cornerRadius,
176+ onValueChange = { cornerRadius = it },
177+ valueRange = 0f .. 50f ,
178+ )
179+ }
180+ }
181+
182+
183+ fun createPolygonPath (cx : Float , cy : Float , sides : Int , radius : Float ): Path {
184+ val angle = 2.0 * Math .PI / sides
185+
186+ return Path ().apply {
187+ moveTo(
188+ cx + (radius * cos(0.0 )).toFloat(),
189+ cy + (radius * sin(0.0 )).toFloat()
190+ )
191+ for (i in 1 until sides) {
192+ lineTo(
193+ cx + (radius * cos(angle * i)).toFloat(),
194+ cy + (radius * sin(angle * i)).toFloat()
195+ )
196+ }
197+ close()
198+ }
199+ }
0 commit comments