Skip to content

Commit

Permalink
Added Compose APIs and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Gabriel Peal committed Jan 10, 2022
1 parent cbe0e30 commit e9b8cfc
Show file tree
Hide file tree
Showing 9 changed files with 74 additions and 23 deletions.
Expand Up @@ -54,6 +54,12 @@ import kotlin.math.roundToInt
* features so it defaults to off. The only way to know if your animation will work
* well with merge paths or not is to try it. If your animation has merge paths and
* doesn't render correctly, please file an issue.
* @param renderMode Allows you to specify whether you want Lottie to use hardware or software rendering.
* Defaults to AUTOMATIC. Refer to [LottieAnimationView.setRenderMode] for more info.
* @param maintainOriginalImageBounds When true, dynamically set bitmaps will be drawn with the exact bounds of the original animation,
* regardless of the bitmap size.
* When false, dynamically set bitmaps will be drawn at the top left of the original image but with its own bounds.
* Defaults to false.
* @param dynamicProperties Allows you to change the properties of an animation dynamically. To use them, use
* [rememberLottieDynamicProperties]. Refer to its docs for more info.
* @param alignment Define where the animation should be placed within this composable if it has a different
Expand All @@ -69,6 +75,7 @@ fun LottieAnimation(
applyOpacityToLayers: Boolean = false,
enableMergePaths: Boolean = false,
renderMode: RenderMode = RenderMode.AUTOMATIC,
maintainOriginalImageBounds: Boolean = false,
dynamicProperties: LottieDynamicProperties? = null,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
Expand Down Expand Up @@ -106,6 +113,7 @@ fun LottieAnimation(
drawable.isApplyingOpacityToLayersEnabled = applyOpacityToLayers
drawable.enableMergePathsForKitKatAndAbove(enableMergePaths)
drawable.useSoftwareRendering(useSoftwareRendering)
drawable.maintainOriginalImageBounds = maintainOriginalImageBounds
drawable.progress = progress
drawable.setBounds(0, 0, composition.bounds.width(), composition.bounds.height())
drawable.draw(canvas.nativeCanvas, matrix)
Expand Down Expand Up @@ -133,6 +141,7 @@ fun LottieAnimation(
applyOpacityToLayers: Boolean = false,
enableMergePaths: Boolean = false,
renderMode: RenderMode = RenderMode.AUTOMATIC,
maintainOriginalImageBounds: Boolean = false,
dynamicProperties: LottieDynamicProperties? = null,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
Expand All @@ -153,6 +162,7 @@ fun LottieAnimation(
applyOpacityToLayers,
enableMergePaths,
renderMode,
maintainOriginalImageBounds,
dynamicProperties,
alignment,
contentScale,
Expand Down
Expand Up @@ -19,15 +19,14 @@ import com.airbnb.lottie.value.ScaleXY
* This takes a vararg of individual dynamic properties which should be created with [rememberLottieDynamicProperty].
*
* @see rememberLottieDynamicProperty
* @see LottieDrawable.setRescaleBitmaps
* @see LottieDrawable.setMaintainOriginalImageBounds
*/
@Composable
fun rememberLottieDynamicProperties(
rescaleBitmaps: Boolean = false,
vararg properties: LottieDynamicProperty<*>,
): LottieDynamicProperties {
return remember(rescaleBitmaps, properties) {
LottieDynamicProperties(rescaleBitmaps, properties.toList())
return remember(properties) {
LottieDynamicProperties(properties.toList())
}
}

Expand Down Expand Up @@ -93,7 +92,6 @@ class LottieDynamicProperty<T> internal constructor(
* @see rememberLottieDynamicProperties
*/
class LottieDynamicProperties internal constructor(
private val rescaleBitmaps: Boolean,
private val intProperties: List<LottieDynamicProperty<Int>>,
private val pointFProperties: List<LottieDynamicProperty<PointF>>,
private val floatProperties: List<LottieDynamicProperty<Float>>,
Expand All @@ -105,8 +103,7 @@ class LottieDynamicProperties internal constructor(
private val bitmapProperties: List<LottieDynamicProperty<Bitmap>>,
) {
@Suppress("UNCHECKED_CAST")
constructor(rescaleBitmaps: Boolean, properties: List<LottieDynamicProperty<*>>) : this(
rescaleBitmaps,
constructor(properties: List<LottieDynamicProperty<*>>) : this(
properties.filter { it.property is Int } as List<LottieDynamicProperty<Int>>,
properties.filter { it.property is PointF } as List<LottieDynamicProperty<PointF>>,
properties.filter { it.property is Float } as List<LottieDynamicProperty<Float>>,
Expand All @@ -118,7 +115,6 @@ class LottieDynamicProperties internal constructor(
)

internal fun addTo(drawable: LottieDrawable) {
drawable.rescaleBitmaps = rescaleBitmaps
intProperties.forEach { p ->
drawable.addValueCallback(p.keyPath, p.property, p.callback.toValueCallback())
}
Expand Down
Expand Up @@ -900,7 +900,7 @@ public String getImageAssetsFolder() {
* Defaults to false.
*/
public void setRescaleBitmaps(boolean rescaleBitmaps) {
lottieDrawable.setRescaleBitmaps(rescaleBitmaps);
lottieDrawable.setMaintainOriginalImageBounds(rescaleBitmaps);
}

/**
Expand All @@ -910,7 +910,7 @@ public void setRescaleBitmaps(boolean rescaleBitmaps) {
* Defaults to false.
*/
public boolean getRescaleBitmaps() {
return lottieDrawable.getRescaleBitmaps();
return lottieDrawable.getMaintainOriginalImageBounds();
}

/**
Expand Down
22 changes: 11 additions & 11 deletions lottie/src/main/java/com/airbnb/lottie/LottieDrawable.java
Expand Up @@ -99,7 +99,7 @@ public void onAnimationUpdate(ValueAnimator animation) {
@Nullable
TextDelegate textDelegate;
private boolean enableMergePaths;
private boolean rescaleBitmaps = true;
private boolean maintainOriginalImageBounds = false;
@Nullable
private CompositionLayer compositionLayer;
private int alpha = 255;
Expand Down Expand Up @@ -221,23 +221,23 @@ public String getImageAssetsFolder() {
}

/**
* When true, dynamically set bitmaps will be drawn at the size of the original bitmap.
* When false, dynamically set bitmaps will be drawn at 0,0 at the original bitmap but at whatever size the dynamic bitmap is.
* When true, dynamically set bitmaps will be drawn with the exact bounds of the original animation, regardless of the bitmap size.
* When false, dynamically set bitmaps will be drawn at the top left of the original image but with its own bounds.
*
* Defaults to true.
* Defaults to false.
*/
public void setRescaleBitmaps(boolean rescaleBitmaps) {
this.rescaleBitmaps = rescaleBitmaps;
public void setMaintainOriginalImageBounds(boolean maintainOriginalImageBounds) {
this.maintainOriginalImageBounds = maintainOriginalImageBounds;
}

/**
* When true, dynamically set bitmaps will be drawn at the size of the original bitmap.
* When false, dynamically set bitmaps will be drawn at 0,0 at the original bitmap but at whatever size the dynamic bitmap is.
* When true, dynamically set bitmaps will be drawn with the exact bounds of the original animation, regardless of the bitmap size.
* When false, dynamically set bitmaps will be drawn at the top left of the original image but with its own bounds.
*
* Defaults to true.
* Defaults to false.
*/
public boolean getRescaleBitmaps() {
return rescaleBitmaps;
public boolean getMaintainOriginalImageBounds() {
return maintainOriginalImageBounds;
}

/**
Expand Down
Expand Up @@ -48,7 +48,7 @@ public class ImageLayer extends BaseLayer {
canvas.save();
canvas.concat(parentMatrix);
src.set(0, 0, bitmap.getWidth(), bitmap.getHeight());
if (lottieDrawable.getRescaleBitmaps()) {
if (lottieDrawable.getMaintainOriginalImageBounds()) {
dst.set(0, 0, (int) (lottieImageAsset.getWidth() * density), (int) (lottieImageAsset.getHeight() * density));
} else {
dst.set(0, 0, (int) (bitmap.getWidth() * density), (int) (bitmap.getHeight() * density));
Expand Down
@@ -1,10 +1,13 @@
package com.airbnb.lottie.snapshots.tests

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Color
import androidx.compose.ui.platform.ComposeView
import com.airbnb.lottie.LottieCompositionFactory
import com.airbnb.lottie.LottieProperty
import com.airbnb.lottie.compose.LottieAnimation
import com.airbnb.lottie.compose.LottieDynamicProperty
import com.airbnb.lottie.compose.rememberLottieDynamicProperties
import com.airbnb.lottie.compose.rememberLottieDynamicProperty
import com.airbnb.lottie.snapshots.SnapshotTestCase
Expand All @@ -14,8 +17,8 @@ import com.airbnb.lottie.snapshots.snapshotComposition

class ComposeDynamicPropertiesTestCase : SnapshotTestCase {
override suspend fun SnapshotTestCaseContext.run() {
val composition = LottieCompositionFactory.fromAssetSync(context, "Tests/DynamicGradient.json").value!!
snapshotComposable("Compose Dynamic Gradient") {
val composition = LottieCompositionFactory.fromAssetSync(context, "Tests/DynamicGradient.json").value!!
val dynamicProperties = rememberLottieDynamicProperties(
rememberLottieDynamicProperty(
LottieProperty.GRADIENT_COLOR,
Expand All @@ -34,5 +37,46 @@ class ComposeDynamicPropertiesTestCase : SnapshotTestCase {
)
LottieAnimation(composition, 0f, dynamicProperties = dynamicProperties)
}

val heartComposition = LottieCompositionFactory.fromAssetSync(context, "Tests/Heart.json").value!!
snapshotComposable("Compose Dynamic Image", "Default") {
LottieAnimation(heartComposition, 0f)
}
snapshotComposable("Compose Dynamic Image", "Default - Maintain Original Bounds") {
LottieAnimation(heartComposition, 0f, maintainOriginalImageBounds = true)
}
snapshotComposable("Compose Dynamic Image", "Smaller") {
val bitmap = getBitmapFromAssets("Images/Heart-80.png")
val dynamicProperties = rememberLottieDynamicProperties(
rememberLottieDynamicProperty(LottieProperty.IMAGE, bitmap, "Heart"),
)
LottieAnimation(heartComposition, 0f, dynamicProperties = dynamicProperties)
}
snapshotComposable("Compose Dynamic Image", "Smaller - Maintain Original Bounds") {
val bitmap = getBitmapFromAssets("Images/Heart-80.png")
val dynamicProperties = rememberLottieDynamicProperties(
rememberLottieDynamicProperty(LottieProperty.IMAGE, bitmap, "Heart"),
)
LottieAnimation(heartComposition, 0f, dynamicProperties = dynamicProperties, maintainOriginalImageBounds = true)
}
snapshotComposable("Compose Dynamic Image", "Larger") {
val bitmap = getBitmapFromAssets("Images/Heart-1200.png")
val dynamicProperties = rememberLottieDynamicProperties(
rememberLottieDynamicProperty(LottieProperty.IMAGE, bitmap, "Heart"),
)
LottieAnimation(heartComposition, 0f, dynamicProperties = dynamicProperties)
}
snapshotComposable("Compose Dynamic Image", "Larger - Maintain Original Bounds") {
val bitmap = getBitmapFromAssets("Images/Heart-1200.png")
val dynamicProperties = rememberLottieDynamicProperties(
rememberLottieDynamicProperty(LottieProperty.IMAGE, bitmap, "Heart"),
)
LottieAnimation(heartComposition, 0f, dynamicProperties = dynamicProperties, maintainOriginalImageBounds = true)
}
}

private fun SnapshotTestCaseContext.getBitmapFromAssets(name: String): Bitmap {
@Suppress("BlockingMethodInNonBlockingContext")
return BitmapFactory.decodeStream(context.assets.open(name), null, BitmapFactory.Options())!!
}
}
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit e9b8cfc

Please sign in to comment.