From a6da4138b1cf0ed201fa96760e82b7caff1f0d27 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 1 Sep 2024 06:23:04 +0900 Subject: [PATCH 1/6] :wastebasket: The process of displaying the border has been removed. --- .../confsched/profilecard/component/CaptureableCardBack.kt | 5 ----- .../confsched/profilecard/component/CaptureableCardFront.kt | 5 ----- 2 files changed, 10 deletions(-) diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt index 5b9b5f81b..b51e57f55 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt @@ -63,11 +63,6 @@ internal fun BackgroundCapturableCardBack( qrCodeImagePainter, modifier = Modifier .size(width = 300.dp, height = 380.dp) - .border( - 3.dp, - Color.Black, - RoundedCornerShape(8.dp), - ) .graphicsLayer { rotationY = 180f }, diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt index 57a290bfa..bb3c6ca45 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt @@ -61,11 +61,6 @@ internal fun BackgroundCapturableCardFront( profileImagePainter, modifier = Modifier .size(width = 300.dp, height = 380.dp) - .border( - 3.dp, - Color.Black, - RoundedCornerShape(8.dp), - ), ) } } From c0b750eb18b8544d4592a774070e5c4b0f14a68f Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 1 Sep 2024 06:24:25 +0900 Subject: [PATCH 2/6] :recycle: We have implemented a process to ensure that the profile card images have the correct shadows. --- .../profilecard/component/ShareableCard.kt | 122 ++++++++++++++---- 1 file changed, 94 insertions(+), 28 deletions(-) diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt index e3889cfe2..86648d9c6 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt @@ -18,8 +18,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.draw.rotate +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.drawscope.ContentDrawScope +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.layer.GraphicsLayer import androidx.compose.ui.graphics.layer.drawLayer import androidx.compose.ui.platform.LocalDensity @@ -109,42 +113,104 @@ private fun ShareableCardContent( .background(LocalProfileCardTheme.current.primaryColor), ) { Box(modifier = Modifier.padding(vertical = 30.dp)) { - backImage?.let { - Image( - bitmap = it, - contentDescription = null, - modifier = Modifier - .offset( - x = with(density) { offsetXBackPx.toDp() }, - y = with(density) { offsetYBackPx.toDp() }, - ) - .rotate(10f) - .size( - width = with(density) { cardWidthPx.toDp() }, - height = with(density) { cardHeightPx.toDp() }, - ), + backImage?.let { backBitmap -> + ShadowedImage( + imageBitmap = backBitmap, + offsetX = offsetXBackPx, + offsetY = offsetYBackPx, + rotation = 10f, + cardWidthPx = cardWidthPx, + cardHeightPx = cardHeightPx ) } - frontImage?.let { - Image( - bitmap = it, - contentDescription = null, - modifier = Modifier - .offset( - x = with(density) { offsetXFrontPx.toDp() }, - y = with(density) { offsetYFrontPx.toDp() }, - ) - .rotate(-12.2f) - .size( - width = with(density) { cardWidthPx.toDp() }, - height = with(density) { cardHeightPx.toDp() }, - ), + frontImage?.let { frontBitmap -> + ShadowedImage( + imageBitmap = frontBitmap, + offsetX = offsetXFrontPx, + offsetY = offsetYFrontPx, + rotation = -12.2f, + cardWidthPx = cardWidthPx, + cardHeightPx = cardHeightPx ) } } } } +@Composable +private fun ShadowedImage( + imageBitmap: ImageBitmap, + offsetX: Float, + offsetY: Float, + rotation: Float, + cardWidthPx: Int, + cardHeightPx: Int, + modifier: Modifier = Modifier, +) { + val density = LocalDensity.current + Box( + modifier = modifier + .offset( + x = with(density) { offsetX.toDp() }, + y = with(density) { offsetY.toDp() }, + ) + .rotate(rotation) + .size( + width = with(density) { cardWidthPx.toDp() }, + height = with(density) { cardHeightPx.toDp() }, + ) + .drawWithContent { + // Draw the blurred shadow behind the actual content. + // This function first draws a shadow by calling drawBlurredShadow(), + // then draws the actual content (the image) with drawContent(). + // By doing this, we ensure the shadow appears behind the image, + // creating a layered effect with the shadow in the background. + drawBlurredShadow(size, Color.Black.copy(alpha = 0.2f)) + // The child element Image is drawn by calling drawContent. + drawContent() + } + ) { + Image( + bitmap = imageBitmap, + contentDescription = null, + modifier = Modifier.graphicsLayer() + ) + } +} + +/** + * Draws a blurred shadow effect on the canvas. + * + * This function creates a blurred shadow by drawing multiple layers of rectangles with varying offsets + * and transparency. The shadow effect is created by gradually increasing the offset and reducing the + * opacity of each rectangle, simulating the natural fading of a shadow. + * + * @param size The size of the base rectangle to draw the shadow around. + * @param color The base color of the shadow. The alpha channel will be adjusted for the blur effect. + */ +private fun ContentDrawScope.drawBlurredShadow(size: Size, color: Color) { + // The number of shadow layers determines the smoothness of the shadow. + // Fewer layers result in a less smooth shadow. + val shadowLayers = 30 + + // Controls how much the shadow spreads out. + // A larger number results in a more diffused and smoother shadow. + val maxOffset = 20f + + for (i in 1..shadowLayers) { + val offset = i * (maxOffset / shadowLayers) + drawRect( + // The shadow is darkest at its base, and becomes lighter as it extends further away. + color = color.copy(alpha = 0.05f / i), + // The shadow extends diagonally from the upper left to the lower right. + topLeft = Offset(offset, offset), + // Increasing the size of the rectangles with each iteration creates the effect of a shadow + // that gets thinner and more diffused the further it is from the base. + size = Size(size.width + offset, size.height + offset) + ) + } +} + @Composable @Preview fun ShareableCardPreview() { From 54230f937b92efc6cd886ff07105efd0282f1d8b Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Sun, 1 Sep 2024 06:26:59 +0900 Subject: [PATCH 3/6] :wrench: ./gradlew detekt --auto-correct --- .../profilecard/component/CaptureableCardBack.kt | 3 --- .../profilecard/component/CaptureableCardFront.kt | 6 +----- .../confsched/profilecard/component/ShareableCard.kt | 10 +++++----- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt index b51e57f55..4ee75559f 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardBack.kt @@ -1,9 +1,7 @@ package io.github.droidkaigi.confsched.profilecard.component -import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -12,7 +10,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithCache -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.graphics.layer.GraphicsLayer diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt index bb3c6ca45..e4492603b 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt @@ -1,9 +1,7 @@ package io.github.droidkaigi.confsched.profilecard.component -import androidx.compose.foundation.border import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -12,7 +10,6 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithCache -import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap import androidx.compose.ui.graphics.layer.drawLayer import androidx.compose.ui.graphics.rememberGraphicsLayer @@ -59,8 +56,7 @@ internal fun BackgroundCapturableCardFront( FlipCardFront( uiState, profileImagePainter, - modifier = Modifier - .size(width = 300.dp, height = 380.dp) + modifier = Modifier.size(width = 300.dp, height = 380.dp), ) } } diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt index 86648d9c6..5df24cfe3 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt @@ -120,7 +120,7 @@ private fun ShareableCardContent( offsetY = offsetYBackPx, rotation = 10f, cardWidthPx = cardWidthPx, - cardHeightPx = cardHeightPx + cardHeightPx = cardHeightPx, ) } frontImage?.let { frontBitmap -> @@ -130,7 +130,7 @@ private fun ShareableCardContent( offsetY = offsetYFrontPx, rotation = -12.2f, cardWidthPx = cardWidthPx, - cardHeightPx = cardHeightPx + cardHeightPx = cardHeightPx, ) } } @@ -168,12 +168,12 @@ private fun ShadowedImage( drawBlurredShadow(size, Color.Black.copy(alpha = 0.2f)) // The child element Image is drawn by calling drawContent. drawContent() - } + }, ) { Image( bitmap = imageBitmap, contentDescription = null, - modifier = Modifier.graphicsLayer() + modifier = Modifier.graphicsLayer(), ) } } @@ -206,7 +206,7 @@ private fun ContentDrawScope.drawBlurredShadow(size: Size, color: Color) { topLeft = Offset(offset, offset), // Increasing the size of the rectangles with each iteration creates the effect of a shadow // that gets thinner and more diffused the further it is from the base. - size = Size(size.width + offset, size.height + offset) + size = Size(size.width + offset, size.height + offset), ) } } From a386dc2a4dfc9e47de4aaced5fbc2e9ffa6315ae Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Wed, 4 Sep 2024 13:55:56 +0900 Subject: [PATCH 4/6] :wrench: ./gradlew detekt --auto-correct --- .../confsched/profilecard/component/CaptureableCardFront.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt index 4c96bbc71..0860f68ae 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/CaptureableCardFront.kt @@ -65,7 +65,7 @@ internal fun BackgroundCapturableCardFront( FlipCardFront( uiState, profileImagePainter, - modifier = Modifier.size(width = 300.dp, height = 380.dp) + modifier = Modifier.size(width = 300.dp, height = 380.dp), ) } } From 588db370f5fb5d638e3b3ee32ea15236899f4616 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:27:34 +0900 Subject: [PATCH 5/6] :wrench: The processing has been simplified. --- .../profilecard/component/ShareableCard.kt | 75 ++++++------------- 1 file changed, 23 insertions(+), 52 deletions(-) diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt index b959c7789..b3677817c 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt @@ -1,6 +1,6 @@ package io.github.droidkaigi.confsched.profilecard.component -import androidx.compose.foundation.Image +import androidx.compose.foundation.Canvas import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.offset @@ -18,12 +18,13 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.drawWithContent import androidx.compose.ui.draw.rotate +import androidx.compose.ui.geometry.CornerRadius import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ImageBitmap -import androidx.compose.ui.graphics.drawscope.ContentDrawScope -import androidx.compose.ui.graphics.graphicsLayer +import androidx.compose.ui.graphics.drawscope.rotate import androidx.compose.ui.graphics.layer.GraphicsLayer import androidx.compose.ui.graphics.layer.drawLayer import androidx.compose.ui.platform.LocalDensity @@ -147,8 +148,15 @@ private fun ShadowedImage( cardHeightPx: Int, modifier: Modifier = Modifier, ) { + val sweepGradient = Brush.sweepGradient( + colors = listOf( + Color.Black.copy(alpha = 0.1f), + Color.Transparent, + ) + ) val density = LocalDensity.current - Box( + + Canvas( modifier = modifier .offset( x = with(density) { offsetX.toDp() }, @@ -159,55 +167,18 @@ private fun ShadowedImage( width = with(density) { cardWidthPx.toDp() }, height = with(density) { cardHeightPx.toDp() }, ) - .drawWithContent { - // Draw the blurred shadow behind the actual content. - // This function first draws a shadow by calling drawBlurredShadow(), - // then draws the actual content (the image) with drawContent(). - // By doing this, we ensure the shadow appears behind the image, - // creating a layered effect with the shadow in the background. - drawBlurredShadow(size, Color.Black.copy(alpha = 0.2f)) - // The child element Image is drawn by calling drawContent. - drawContent() - }, ) { - Image( - bitmap = imageBitmap, - contentDescription = null, - modifier = Modifier.graphicsLayer(), - ) - } -} - -/** - * Draws a blurred shadow effect on the canvas. - * - * This function creates a blurred shadow by drawing multiple layers of rectangles with varying offsets - * and transparency. The shadow effect is created by gradually increasing the offset and reducing the - * opacity of each rectangle, simulating the natural fading of a shadow. - * - * @param size The size of the base rectangle to draw the shadow around. - * @param color The base color of the shadow. The alpha channel will be adjusted for the blur effect. - */ -private fun ContentDrawScope.drawBlurredShadow(size: Size, color: Color) { - // The number of shadow layers determines the smoothness of the shadow. - // Fewer layers result in a less smooth shadow. - val shadowLayers = 30 - - // Controls how much the shadow spreads out. - // A larger number results in a more diffused and smoother shadow. - val maxOffset = 20f - - for (i in 1..shadowLayers) { - val offset = i * (maxOffset / shadowLayers) - drawRect( - // The shadow is darkest at its base, and becomes lighter as it extends further away. - color = color.copy(alpha = 0.05f / i), - // The shadow extends diagonally from the upper left to the lower right. - topLeft = Offset(offset, offset), - // Increasing the size of the rectangles with each iteration creates the effect of a shadow - // that gets thinner and more diffused the further it is from the base. - size = Size(size.width + offset, size.height + offset), - ) + rotate(degrees = 180f) { + for (i in 1..15) { + drawRoundRect( + brush = sweepGradient, + size = Size(cardWidthPx.toFloat(), cardHeightPx.toFloat()), + topLeft = Offset(-i.toFloat(), -i.toFloat()), + cornerRadius = CornerRadius(with(density) { 16.toDp().toPx() }) + ) + } + } + drawImage(imageBitmap) } } From d0f8deb07c91e4ad814d14a68e51c7d9805e7346 Mon Sep 17 00:00:00 2001 From: todayama_r <13657682+Corvus400@users.noreply.github.com> Date: Thu, 5 Sep 2024 16:27:56 +0900 Subject: [PATCH 6/6] :wrench: ./gradlew detekt --auto-correct --- .../confsched/profilecard/component/ShareableCard.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt index b3677817c..3ad2bfc16 100644 --- a/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt +++ b/feature/profilecard/src/commonMain/kotlin/io/github/droidkaigi/confsched/profilecard/component/ShareableCard.kt @@ -152,7 +152,7 @@ private fun ShadowedImage( colors = listOf( Color.Black.copy(alpha = 0.1f), Color.Transparent, - ) + ), ) val density = LocalDensity.current @@ -166,7 +166,7 @@ private fun ShadowedImage( .size( width = with(density) { cardWidthPx.toDp() }, height = with(density) { cardHeightPx.toDp() }, - ) + ), ) { rotate(degrees = 180f) { for (i in 1..15) { @@ -174,7 +174,7 @@ private fun ShadowedImage( brush = sweepGradient, size = Size(cardWidthPx.toFloat(), cardHeightPx.toFloat()), topLeft = Offset(-i.toFloat(), -i.toFloat()), - cornerRadius = CornerRadius(with(density) { 16.toDp().toPx() }) + cornerRadius = CornerRadius(with(density) { 16.toDp().toPx() }), ) } }