Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Compose] Add merge paths flag #1744

Merged
merged 7 commits into from
Feb 24, 2021
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG_COMPOSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
#### Note: For the time being, we won't provide numbered releases for every new Jetpack Compose
version. Check out our [snapshot builds](https://github.com/airbnb/lottie/blob/master/android-compose.md#getting-started) instead.

# 1.0.0-alpha07-SNAPSHOT
* Add flag for merge paths to LottieAnimationState

# 1.0.0-alpha06
* Compatible with Jetpack Compose Alpha 12

Expand Down
2 changes: 1 addition & 1 deletion build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ buildscript {
}
dependencies {
classpath 'org.ajoberstar:grgit:1.9.3'
classpath 'com.android.tools.build:gradle:7.0.0-alpha06'
classpath 'com.android.tools.build:gradle:7.0.0-alpha07'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlinVersion"
classpath 'org.ajoberstar:grgit:1.9.3'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.drawscope.withTransform
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.platform.AmbientContext
import androidx.compose.ui.platform.LocalContext
import com.airbnb.lottie.LottieComposition
import com.airbnb.lottie.LottieCompositionFactory
Expand Down Expand Up @@ -80,11 +79,7 @@ fun LottieAnimation(
state: LottieAnimationState,
modifier: Modifier = Modifier,
) {
val drawable = remember {
LottieDrawable().apply {
enableMergePathsForKitKatAndAbove(true)
}
}
val drawable = remember { LottieDrawable() }

SideEffect {
drawable.composition = composition
Expand Down Expand Up @@ -118,17 +113,19 @@ fun LottieAnimation(
}

if (composition == null || composition.duration == 0f) return
SideEffect {}

Canvas(
modifier = Modifier
.maintainAspectRatio(composition)
.then(modifier)
) {
drawIntoCanvas { canvas ->
drawable.progress = state.progress
drawable.setOutlineMasksAndMattes(state.outlineMasksAndMattes)
drawable.isApplyingOpacityToLayersEnabled = state.applyOpacityToLayers
drawable.apply {
jossiwolf marked this conversation as resolved.
Show resolved Hide resolved
progress = state.progress
setOutlineMasksAndMattes(state.outlineMasksAndMattes)
isApplyingOpacityToLayersEnabled = state.applyOpacityToLayers
enableMergePathsForKitKatAndAbove(state.enableMergePaths)
}
withTransform({
scale(size.width / composition.bounds.width().toFloat(), size.height / composition.bounds.height().toFloat(), Offset.Zero)
}) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,64 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue

/**
* Create a [LottieAnimationState] and remember it
*
* @param autoPlay Whether the animation will auto play
* @param repeatCount How many times the animation will be played. Use [Int.MAX_VALUE] for
* infinite repetitions.
* @param initialProgress The progress the animation starts with
* @param enableMergePaths Whether merge paths are enabled
jossiwolf marked this conversation as resolved.
Show resolved Hide resolved
*/
@Composable
fun rememberLottieAnimationState(
autoPlay: Boolean = true,
repeatCount: Int = 0,
initialProgress: Float = 0f,
enableMergePaths: Boolean = true
): LottieAnimationState {
// Use rememberSavedInstanceState so you can pause/resume animations
return remember(repeatCount, autoPlay) {
LottieAnimationState(isPlaying = autoPlay, repeatCount, initialProgress)
LottieAnimationState(
isPlaying = autoPlay,
repeatCount = repeatCount,
initialProgress = initialProgress,
enableMergePaths = enableMergePaths
)
}
}

/**
* State of the [LottieAnimation] composable
*
* @param isPlaying Initial value for [isPlaying]
* @param repeatCount Initial value for [repeatCount]
* @param initialProgress Initial value for [progress]
* @param enableMergePaths Initial value for [enableMergePaths]
*
* @see rememberLottieAnimationState()
*/
class LottieAnimationState(
isPlaying: Boolean,
repeatCount: Int = 0,
initialProgress: Float = 0f,
enableMergePaths: Boolean = true
) {
var progress by mutableStateOf(initialProgress)

// TODO: make this public
private var _frame = mutableStateOf(0)
val frame: Int by _frame

/**
* Whether the animation is currently playing
jossiwolf marked this conversation as resolved.
Show resolved Hide resolved
*/
var isPlaying by mutableStateOf(isPlaying)

/**
* How many times the animation will be played. Use [Int.MAX_VALUE] for
* infinite repetitions.
*/
var repeatCount by mutableStateOf(repeatCount)

var speed by mutableStateOf(1f)
Expand All @@ -58,6 +89,18 @@ class LottieAnimationState(
*/
var applyOpacityToLayers by mutableStateOf(false)

/**
* Enable this to get merge path support.
* <p>
* Merge paths currently don't work if the the operand shape is entirely contained within the
* first shape. If you need to cut out one shape from another shape, use an even-odd fill type
* instead of using merge paths.
* <p>
* If your animation contains merge paths and you are encountering rendering issues, disabling
* merge paths might help.
*/
var enableMergePaths by mutableStateOf(enableMergePaths)

internal fun updateFrame(frame: Int) {
_frame.value = frame
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,8 @@ fun LottieFilesSearchPage(
value = state.query,
onValueChange = onQueryChanged,
label = { Text(stringResource(R.string.query)) },
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp)
modifier = Modifier.fillMaxWidth().padding(horizontal = 16.dp),
singleLine = true
)
LazyColumn(
modifier = Modifier.weight(1f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.res.colorResource
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.style.TextAlign
Expand Down Expand Up @@ -50,6 +52,7 @@ fun PlayerPage(
val scaffoldState = rememberScaffoldState()
val outlineMasksAndMattes = remember { mutableStateOf(false) }
val applyOpacityToLayers = remember { mutableStateOf(false) }
val enableMergePaths = remember { mutableStateOf(animationState.enableMergePaths) }
var focusMode by remember { mutableStateOf(false) }
var backgroundColor by remember { mutableStateOf(animationBackgroundColor) }
var showWarningsDialog by remember { mutableStateOf(false) }
Expand All @@ -72,6 +75,7 @@ fun PlayerPage(

animationState.outlineMasksAndMattes = outlineMasksAndMattes.value
animationState.applyOpacityToLayers = applyOpacityToLayers.value
animationState.enableMergePaths = enableMergePaths.value

Scaffold(
scaffoldState = scaffoldState,
Expand Down Expand Up @@ -164,6 +168,7 @@ fun PlayerPage(
backgroundColor = backgroundColorToolbar,
outlineMasksAndMattes = outlineMasksAndMattes,
applyOpacityToLayers = applyOpacityToLayers,
enableMergePaths = enableMergePaths
)
}
}
Expand Down Expand Up @@ -344,6 +349,7 @@ private fun Toolbar(
backgroundColor: MutableState<Boolean>,
outlineMasksAndMattes: MutableState<Boolean>,
applyOpacityToLayers: MutableState<Boolean>,
enableMergePaths: MutableState<Boolean>,
) {
Row(
modifier = Modifier
Expand All @@ -352,40 +358,47 @@ private fun Toolbar(
.padding(bottom = 8.dp)
) {
ToolbarChip(
iconRes = R.drawable.ic_masks_and_mattes,
iconPainter = painterResource(R.drawable.ic_masks_and_mattes),
label = stringResource(R.string.toolbar_item_masks),
isActivated = outlineMasksAndMattes.value,
onClick = { outlineMasksAndMattes.value = it },
modifier = Modifier.padding(end = 8.dp)
)
ToolbarChip(
iconRes = R.drawable.ic_layers,
iconPainter = painterResource(R.drawable.ic_layers),
label = stringResource(R.string.toolbar_item_opacity_layers),
isActivated = applyOpacityToLayers.value,
onClick = { applyOpacityToLayers.value = it },
modifier = Modifier.padding(end = 8.dp)
)
ToolbarChip(
iconRes = R.drawable.ic_color,
iconPainter = painterResource(R.drawable.ic_color),
label = stringResource(R.string.toolbar_item_color),
isActivated = backgroundColor.value,
onClick = { backgroundColor.value = it },
modifier = Modifier.padding(end = 8.dp)
)
ToolbarChip(
iconRes = R.drawable.ic_speed,
iconPainter = painterResource(R.drawable.ic_speed),
label = stringResource(R.string.toolbar_item_speed),
isActivated = speed.value,
onClick = { speed.value = it },
modifier = Modifier.padding(end = 8.dp)
)
ToolbarChip(
iconRes = R.drawable.ic_border,
iconPainter = painterResource(R.drawable.ic_border),
label = stringResource(R.string.toolbar_item_border),
isActivated = border.value,
onClick = { border.value = it },
modifier = Modifier.padding(end = 8.dp)
)
ToolbarChip(
iconPainter = rememberVectorPainter(Icons.Default.MergeType),
label = stringResource(R.string.toolbar_item_merge_paths),
isActivated = enableMergePaths.value,
onClick = { enableMergePaths.value = it },
modifier = Modifier.padding(end = 8.dp)
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.TextStyle
Expand All @@ -28,7 +29,7 @@ fun ToolbarChip(
isActivated: Boolean,
onClick: (isActivated: Boolean) -> Unit,
modifier: Modifier = Modifier,
@DrawableRes iconRes: Int = 0,
iconPainter: Painter? = null,
) {
val unActivatedColor = remember { Color(0xFF444444) }
Surface(
Expand All @@ -44,9 +45,9 @@ fun ToolbarChip(
modifier = Modifier
.padding(horizontal = 8.dp, vertical = 4.dp)
) {
if (iconRes != 0) {
if (iconPainter != null) {
Icon(
painterResource(iconRes),
iconPainter,
tint = if (isActivated) Color.White else unActivatedColor,
modifier = Modifier
.preferredSize(12.dp),
Expand All @@ -67,7 +68,7 @@ fun ToolbarChip(
@Composable
fun PreviewToolbarChip() {
ToolbarChip(
iconRes = R.drawable.ic_border,
iconPainter = painterResource(R.drawable.ic_border),
label = stringResource(R.string.toolbar_item_border),
isActivated = false,
onClick = {}
Expand Down
1 change: 1 addition & 0 deletions sample-compose/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<string name="toolbar_item_speed">Speed</string>
<string name="toolbar_item_color">Background</string>
<string name="toolbar_item_opacity_layers">Apply Opacity To Layers</string>
<string name="toolbar_item_merge_paths">Enable Merge Paths</string>

<string name="failed_to_load">Failed to load composition</string>
<string name="ok">OK</string>
Expand Down