@@ -26,10 +26,12 @@ import androidx.compose.runtime.setValue
2626import androidx.compose.ui.Alignment
2727import androidx.compose.ui.Modifier
2828import androidx.compose.ui.draw.clip
29- import androidx.compose.ui.geometry.Offset
30- import androidx.compose.ui.geometry.Size
3129import androidx.compose.ui.graphics.Brush
3230import androidx.compose.ui.graphics.Color
31+ import androidx.compose.ui.graphics.ImageBitmap
32+ import androidx.compose.ui.graphics.ImageShader
33+ import androidx.compose.ui.graphics.Paint
34+ import androidx.compose.ui.graphics.ShaderBrush
3335import androidx.compose.ui.graphics.TileMode
3436import androidx.compose.ui.graphics.drawscope.DrawScope
3537import androidx.compose.ui.input.pointer.pointerInput
@@ -252,6 +254,8 @@ fun AlphaSlider(
252254 onAlphaChanged : (Float ) -> Unit ,
253255 hapticEffect : SliderDefaults .SliderHapticEffect = SliderDefaults .DefaultHapticEffect
254256) {
257+ val density = LocalDensity .current
258+
255259 val currentOnAlphaChanged by rememberUpdatedState(onAlphaChanged)
256260 val baseColor = remember(currentHue, currentSaturation, currentValue) {
257261 Color .hsv(currentHue, currentSaturation, currentValue)
@@ -260,35 +264,26 @@ fun AlphaSlider(
260264 val endColor = remember(baseColor) { baseColor.copy(alpha = 1f ) }
261265 val alphaColors = remember(startColor, endColor) { listOf (startColor, endColor) }
262266
263- val checkerBrush = remember {
264- object {
265- val light = Color (0xFFCCCCCC )
266- val dark = Color (0xFFAAAAAA )
267- val checkerSize = 3 .dp
268-
269- fun draw (drawScope : DrawScope , width : Float , height : Float ) {
270- with (drawScope) {
271- val pixelSize = checkerSize.toPx()
272- val horizontalCount = (width / pixelSize).toInt() + 1
273- val verticalCount = (height / pixelSize).toInt() + 1
274-
275- drawRect(light)
276-
277- for (y in 0 until verticalCount) {
278- val isEvenRow = y % 2 == 0
279- val startX = if (isEvenRow) 0 else 1
280-
281- for (x in startX until horizontalCount step 2 ) {
282- drawRect(
283- color = dark,
284- topLeft = Offset (x * pixelSize, y * pixelSize),
285- size = Size (pixelSize, pixelSize)
286- )
287- }
288- }
289- }
290- }
291- }
267+ val actualCheckerBrush = remember(density) {
268+ val lightColor = Color (0xFFCCCCCC )
269+ val darkColor = Color (0xFFAAAAAA )
270+ val checkerSizeDp = 3 .dp
271+
272+ val pixelSize = with (density) { checkerSizeDp.toPx() }
273+ val tileBitmapSideLengthPx = (2 * pixelSize).toInt().coerceAtLeast(1 )
274+
275+ val imageBitmap = ImageBitmap (tileBitmapSideLengthPx, tileBitmapSideLengthPx)
276+ val canvasForBitmap = androidx.compose.ui.graphics.Canvas (imageBitmap)
277+
278+ val lightPaint = Paint ().apply { color = lightColor }
279+ val darkPaint = Paint ().apply { color = darkColor }
280+
281+ canvasForBitmap.drawRect(0f , 0f , tileBitmapSideLengthPx.toFloat(), tileBitmapSideLengthPx.toFloat(), lightPaint)
282+ canvasForBitmap.drawRect(pixelSize, 0f , 2 * pixelSize, pixelSize, darkPaint)
283+ canvasForBitmap.drawRect(0f , pixelSize, pixelSize, 2 * pixelSize, darkPaint)
284+
285+ val shader = ImageShader (imageBitmap, TileMode .Repeated , TileMode .Repeated )
286+ ShaderBrush (shader)
292287 }
293288
294289 ColorSlider (
@@ -297,7 +292,7 @@ fun AlphaSlider(
297292 drawBrushColors = alphaColors,
298293 modifier = Modifier .fillMaxWidth(),
299294 hapticEffect = hapticEffect,
300- drawBackground = checkerBrush::draw
295+ drawBackground = { _, _ -> drawRect(brush = actualCheckerBrush) }
301296 )
302297}
303298
@@ -318,6 +313,7 @@ private fun ColorSlider(
318313 val indicatorSizeDp = 20 .dp
319314 val sliderHeightDp = 26 .dp
320315 val sliderHeightPx = with (density) { remember(sliderHeightDp) { sliderHeightDp.toPx() } }
316+ val sliderWidthPx = with (density) { sliderWidth.toPx() }
321317 val halfSliderHeightPx = remember(sliderHeightPx) { sliderHeightPx / 2f }
322318 val borderShape = remember { SmoothRoundedCornerShape (50 .dp) }
323319 val borderStroke = remember { 0.5 .dp }
@@ -326,6 +322,15 @@ private fun ColorSlider(
326322 val hapticState = remember { SliderHapticState () }
327323 val currentOnValueChanged by rememberUpdatedState(onValueChanged)
328324
325+ val gradientBrush = remember(drawBrushColors, sliderWidthPx, halfSliderHeightPx) {
326+ Brush .horizontalGradient(
327+ colors = drawBrushColors,
328+ startX = halfSliderHeightPx,
329+ endX = sliderWidthPx - halfSliderHeightPx,
330+ tileMode = TileMode .Clamp
331+ )
332+ }
333+
329334 val dragHandler = remember(currentOnValueChanged, sliderHeightPx) {
330335 { posX: Float , width: Float ->
331336 handleSliderInteraction(posX, width, sliderHeightPx).coerceIn(0f , 1f )
@@ -368,15 +373,7 @@ private fun ColorSlider(
368373 modifier = canvasModifier
369374 ) {
370375 drawBackground?.invoke(this , size.width, size.height)
371-
372- Brush .horizontalGradient(
373- colors = drawBrushColors,
374- startX = halfSliderHeightPx,
375- endX = size.width - halfSliderHeightPx,
376- tileMode = TileMode .Clamp
377- ).let {
378- drawRect(it)
379- }
376+ drawRect(gradientBrush)
380377 }
381378
382379 SliderIndicator (
0 commit comments