-
Notifications
You must be signed in to change notification settings - Fork 52
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' of github.com:bumble-tech/puzzyx
- Loading branch information
Showing
193 changed files
with
591 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 1 addition & 2 deletions
3
...mble/appyx/puzzyx/android/MainActivity.kt → .../kotlin/com/bumble/puzzyx/MainActivity.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# This is a script to slice an image into a specified number of pieces | ||
# and save them to a specified directory. | ||
|
||
import os | ||
import argparse | ||
import numpy as np | ||
from PIL import Image | ||
|
||
def main(): | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument('-i', '--image', type=str, required=True, help='Path to image to slice') | ||
parser.add_argument('-o', '--output', type=str, help='Path to output directory') | ||
parser.add_argument('-c', '--columns', type=int, required=True, help='Number of columns to slice image into') | ||
parser.add_argument('-r', '--rows', type=int, required=True, help='Number of rows to slice image into') | ||
args = parser.parse_args() | ||
|
||
# If output directory is not provided, create one named after the image in the working directory | ||
if not args.output: | ||
image_name = os.path.splitext(os.path.basename(args.image))[0] | ||
args.output = os.path.join(os.getcwd(), image_name) | ||
|
||
# Create directory if it does not exist | ||
if not os.path.exists(args.output): | ||
os.makedirs(args.output) | ||
|
||
# Load image | ||
img = Image.open(args.image) | ||
img = np.array(img) | ||
|
||
# Get image dimensions | ||
height, width, channels = img.shape | ||
|
||
# Get slice dimensions | ||
slice_height = height // args.rows | ||
slice_width = width // args.columns | ||
|
||
# Slice image | ||
for y in range(args.rows): | ||
for x in range(args.columns): | ||
start_height = y * slice_height | ||
end_height = start_height + slice_height | ||
start_width = x * slice_width | ||
end_width = start_width + slice_width | ||
slice = img[start_height:end_height, start_width:end_width, :] | ||
slice = Image.fromarray(slice) | ||
slice.save(os.path.join(args.output, 'slice_{}_{}.png'.format(y, x))) | ||
|
||
if __name__ == '__main__': | ||
main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
shared/src/androidMain/kotlin/com/bumble/puzzyx/imageloader/ImageBitmap.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.bumble.puzzyx.imageloader | ||
|
||
import android.graphics.Bitmap | ||
import android.graphics.BitmapFactory | ||
import androidx.compose.ui.graphics.ImageBitmap | ||
import androidx.compose.ui.graphics.asImageBitmap | ||
|
||
actual fun ByteArray.toImageBitmap(): ImageBitmap = toAndroidBitmap().asImageBitmap() | ||
|
||
fun ByteArray.toAndroidBitmap(): Bitmap = BitmapFactory.decodeByteArray(this, 0, size) |
59 changes: 59 additions & 0 deletions
59
...ed/src/commonMain/kotlin/com/bumble/puzzyx/component/backstackclipper/BackStackClipper.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.bumble.puzzyx.component.backstackclipper | ||
|
||
import androidx.compose.animation.core.SpringSpec | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.graphics.Shape | ||
import com.bumble.appyx.components.backstack.BackStackModel | ||
import com.bumble.appyx.interactions.core.ui.context.UiContext | ||
import com.bumble.appyx.interactions.core.ui.helper.DefaultAnimationSpec | ||
import com.bumble.appyx.interactions.core.ui.property.impl.ZIndex | ||
import com.bumble.appyx.interactions.core.ui.state.MatchedTargetUiState | ||
import com.bumble.appyx.transitionmodel.BaseMotionController | ||
|
||
|
||
/** | ||
* With Appyx, we usually map model states (like a back stack element's state) to visual end | ||
* states. | ||
* | ||
* To achieve the canvas clipping effect, instead of usual Alpha, Scale, Rotation etc. properties | ||
* we'll animate the progress value related to a shape, and apply it as a clip mask on the outgoing | ||
* element. | ||
* | ||
* @param shape Should return a Shape given a progress value in the range of 0..1f. The shape will | ||
* be applied as a clip mask on the outgoing back stack element. | ||
*/ | ||
class BackStackClipper<InteractionTarget : Any>( | ||
uiContext: UiContext, | ||
private val shape: @Composable (progress: Float) -> Shape, | ||
defaultAnimationSpec: SpringSpec<Float> = DefaultAnimationSpec | ||
) : BaseMotionController<InteractionTarget, BackStackModel.State<InteractionTarget>, MutableUiState, TargetUiState>( | ||
uiContext = uiContext, | ||
defaultAnimationSpec = defaultAnimationSpec, | ||
) { | ||
|
||
private val incoming = TargetUiState( | ||
clipShapeProgress = ClipShapeProgress.Target(0f), | ||
zIndex = ZIndex.Target(0f), | ||
) | ||
|
||
/** | ||
* The Shape is animated towards 100% progress. | ||
* zIndex ensures the outgoing element stays on top. As the clipping is applied to it, | ||
* any elements behind it should start showing through. | ||
*/ | ||
private val outgoing = TargetUiState( | ||
clipShapeProgress = ClipShapeProgress.Target(1f), | ||
zIndex = ZIndex.Target(1f), | ||
) | ||
|
||
override fun BackStackModel.State<InteractionTarget>.toUiTargets(): | ||
List<MatchedTargetUiState<InteractionTarget, TargetUiState>> = | ||
(created + listOf(active)).map { | ||
MatchedTargetUiState(it, incoming) | ||
} + (stashed + destroyed).map { | ||
MatchedTargetUiState(it, outgoing) | ||
} | ||
|
||
override fun mutableUiStateFor(uiContext: UiContext, targetUiState: TargetUiState): MutableUiState = | ||
targetUiState.toMutableUiState(uiContext, shape) | ||
} |
63 changes: 63 additions & 0 deletions
63
...d/src/commonMain/kotlin/com/bumble/puzzyx/component/backstackclipper/ClipShapeProgress.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.bumble.puzzyx.component.backstackclipper | ||
|
||
import androidx.compose.animation.core.Animatable | ||
import androidx.compose.animation.core.AnimationVector1D | ||
import androidx.compose.animation.core.Easing | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.runtime.collectAsState | ||
import androidx.compose.ui.Modifier | ||
import androidx.compose.ui.composed | ||
import androidx.compose.ui.draw.clip | ||
import androidx.compose.ui.graphics.RectangleShape | ||
import androidx.compose.ui.graphics.Shape | ||
import com.bumble.appyx.interactions.core.ui.math.lerpFloat | ||
import com.bumble.appyx.interactions.core.ui.property.Interpolatable | ||
import com.bumble.appyx.interactions.core.ui.property.MotionProperty | ||
import kotlinx.coroutines.CoroutineScope | ||
import kotlinx.coroutines.flow.MutableStateFlow | ||
import kotlinx.coroutines.flow.StateFlow | ||
|
||
/** | ||
* With Appyx, we usually animate actual UI-related properties like Alpha, Rotation, etc. | ||
* | ||
* This class wraps an animatable Float that should represent an animation progress value | ||
* in the 0..1f range. Using this animated value, a [Shape] is fetched as a function of progress | ||
* and applied as clip mask with Modifier.clip(shape). | ||
*/ | ||
class ClipShapeProgress( | ||
coroutineScope: CoroutineScope, | ||
target: Target, | ||
displacement: StateFlow<Float> = MutableStateFlow(0f), | ||
private val shape: @Composable (progress: Float) -> Shape = { RectangleShape }, | ||
) : MotionProperty<Float, AnimationVector1D>( | ||
coroutineScope = coroutineScope, | ||
animatable = Animatable(target.value), | ||
displacement = displacement | ||
), Interpolatable<ClipShapeProgress.Target> { | ||
|
||
class Target( | ||
val value: Float, | ||
val easing: Easing? = null, | ||
) : MotionProperty.Target | ||
|
||
override fun calculateRenderValue(base: Float, displacement: Float): Float = | ||
base - displacement | ||
|
||
override val modifier: Modifier | ||
get() = Modifier.composed { | ||
val progress = renderValueFlow.collectAsState().value | ||
if (progress == 0f) this | ||
else this.clip(shape.invoke(progress)) | ||
} | ||
|
||
|
||
override suspend fun lerpTo(start: Target, end: Target, fraction: Float) { | ||
snapTo( | ||
lerpFloat( | ||
start = start.value, | ||
end = end.value, | ||
progress = easingTransform(end.easing, fraction) | ||
) | ||
) | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
shared/src/commonMain/kotlin/com/bumble/puzzyx/component/backstackclipper/TargetUiState.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.bumble.puzzyx.component.backstackclipper | ||
|
||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.graphics.Shape | ||
import com.bumble.appyx.interactions.core.ui.context.UiContext | ||
import com.bumble.appyx.interactions.core.ui.property.impl.ZIndex | ||
import com.bumble.appyx.interactions.core.ui.state.MutableUiStateSpecs | ||
|
||
@Suppress("unused") | ||
@MutableUiStateSpecs | ||
class TargetUiState( | ||
val clipShapeProgress: ClipShapeProgress.Target, | ||
val zIndex: ZIndex.Target, | ||
) { | ||
fun toMutableUiState(uiContext: UiContext, shape: @Composable (progress: Float) -> Shape): MutableUiState = | ||
MutableUiState( | ||
uiContext = uiContext, | ||
clipShapeProgress = ClipShapeProgress( | ||
coroutineScope = uiContext.coroutineScope, | ||
target = clipShapeProgress, | ||
shape = shape | ||
), | ||
zIndex = ZIndex( | ||
coroutineScope = uiContext.coroutineScope, | ||
target = zIndex | ||
) | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
26 changes: 26 additions & 0 deletions
26
shared/src/commonMain/kotlin/com/bumble/puzzyx/composable/CallToActionScreen.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package com.bumble.puzzyx.composable | ||
|
||
import androidx.compose.foundation.background | ||
import androidx.compose.foundation.layout.Box | ||
import androidx.compose.foundation.layout.fillMaxSize | ||
import androidx.compose.material3.Text | ||
import androidx.compose.runtime.Composable | ||
import androidx.compose.ui.Alignment | ||
import androidx.compose.ui.Modifier | ||
import com.bumble.puzzyx.ui.appyx_dark | ||
import com.bumble.puzzyx.ui.appyx_yellow1 | ||
|
||
@Composable | ||
fun CallToActionScreen(modifier: Modifier) { | ||
Box( | ||
modifier = modifier | ||
.fillMaxSize() | ||
.background(appyx_dark) | ||
) { | ||
Text( | ||
text = "Join the challenge", | ||
color = appyx_yellow1, | ||
modifier = Modifier.align(Alignment.Center) | ||
) | ||
} | ||
} |
Oops, something went wrong.