@@ -3,6 +3,7 @@ package com.dotlottiereactnative
33import android.graphics.Color
44import android.widget.FrameLayout
55import androidx.compose.runtime.Composable
6+ import androidx.compose.runtime.mutableStateOf
67import androidx.compose.ui.platform.ComposeView
78import com.dotlottie.dlplayer.Mode
89import com.facebook.react.bridge.Arguments
@@ -12,14 +13,15 @@ import com.facebook.react.uimanager.ThemedReactContext
1213import com.facebook.react.uimanager.events.RCTEventEmitter
1314import com.lottiefiles.dotlottie.core.compose.runtime.DotLottieController
1415import com.lottiefiles.dotlottie.core.compose.ui.DotLottieAnimation
16+ import com.lottiefiles.dotlottie.core.compose.ui.DotLottieGLAnimation
1517import com.lottiefiles.dotlottie.core.util.DotLottieEventListener
1618import com.lottiefiles.dotlottie.core.util.DotLottieSource
1719import com.lottiefiles.dotlottie.core.util.StateMachineEventListener
1820
1921class DotlottieReactNativeView (context : ThemedReactContext ) : FrameLayout(context) {
2022
2123 private var reactContext: ReactContext = context.reactApplicationContext
22- private var animationUrl: String? = null
24+ private var animationUrl = mutableStateOf< String ?>( null )
2325 private var loop: Boolean = false
2426 private var autoplay: Boolean = true
2527 private var speed: Float = 1f
@@ -29,7 +31,10 @@ class DotlottieReactNativeView(context: ThemedReactContext) : FrameLayout(contex
2931 private var segment: Pair <Float , Float >? = null
3032 private var playMode: Mode = Mode .FORWARD
3133 private var stateMachineId: String? = null
34+ private var useOpenGLRenderer: Boolean = false
35+ private var rendererLocked: Boolean = false
3236 var dotLottieController: DotLottieController = DotLottieController ()
37+ private val eventListeners: List <DotLottieEventListener > = createEventListeners()
3338 private val stateMachineEventListener: StateMachineEventListener = createStateMachineEventListener()
3439 private var stateMachineListenerRegistered: Boolean = false
3540 private var hasActiveComposition: Boolean = false
@@ -51,81 +56,112 @@ class DotlottieReactNativeView(context: ThemedReactContext) : FrameLayout(contex
5156 reactContext.getJSModule(RCTEventEmitter ::class .java).receiveEvent(id, eventName, value)
5257 }
5358
59+ private fun createEventListeners (): List <DotLottieEventListener > {
60+ return listOf (
61+ object : DotLottieEventListener {
62+ override fun onLoad () {
63+ onReceiveNativeEvent(" onLoad" , null )
64+ }
65+ override fun onComplete () {
66+ onReceiveNativeEvent(" onComplete" , null )
67+ }
68+ override fun onLoadError () {
69+ onReceiveNativeEvent(" onLoadError" , null )
70+ }
71+ override fun onPlay () {
72+ onReceiveNativeEvent(" onPlay" , null )
73+ }
74+ override fun onStop () {
75+ onReceiveNativeEvent(" onStop" , null )
76+ }
77+ override fun onPause () {
78+ onReceiveNativeEvent(" onPause" , null )
79+ }
80+ override fun onFreeze () {
81+ onReceiveNativeEvent(" onFreeze" , null )
82+ }
83+ override fun onUnFreeze () {
84+ onReceiveNativeEvent(" onUnFreeze" , null )
85+ }
86+ override fun onDestroy () {
87+ onReceiveNativeEvent(" onDestroy" , null )
88+ }
89+ override fun onFrame (frame : Float ) {
90+ val value =
91+ Arguments .createMap().apply {
92+ putDouble(" frameNo" , frame.toDouble())
93+ }
94+ onReceiveNativeEvent(" onFrame" , value)
95+ }
96+ override fun onLoop (loopCount : Int ) {
97+ val value =
98+ Arguments .createMap().apply {
99+ putInt(" loopCount" , loopCount)
100+ }
101+ onReceiveNativeEvent(" onLoop" , value)
102+ }
103+ override fun onRender (frameNo : Float ) {
104+ val value =
105+ Arguments .createMap().apply {
106+ putDouble(" frameNo" , frameNo.toDouble())
107+ }
108+ onReceiveNativeEvent(" onRender" , value)
109+ }
110+ }
111+ )
112+ }
113+
54114 @Composable
55115 fun DotLottieContent () {
56- animationUrl?.let { url ->
57- DotLottieAnimation (
58- source = DotLottieSource .Url (url),
59- autoplay = autoplay,
60- loop = loop,
61- speed = speed,
62- controller = dotLottieController,
63- useFrameInterpolation = useFrameInterpolation,
64- themeId = themeId,
65- stateMachineId = stateMachineId,
66- marker = marker,
67- segment = segment,
68- playMode = playMode,
69- eventListeners =
70- listOf (
71- object : DotLottieEventListener {
72- override fun onLoad () {
73- onReceiveNativeEvent(" onLoad" , null )
74- }
75- override fun onComplete () {
76- onReceiveNativeEvent(" onComplete" , null )
77- }
78- override fun onLoadError () {
79- onReceiveNativeEvent(" onLoadError" , null )
80- }
81- override fun onPlay () {
82- onReceiveNativeEvent(" onPlay" , null )
83- }
84- override fun onStop () {
85- onReceiveNativeEvent(" onStop" , null )
86- }
87- override fun onPause () {
88- onReceiveNativeEvent(" onPause" , null )
89- }
90- override fun onFreeze () {
91- onReceiveNativeEvent(" onFreeze" , null )
92- }
93- override fun onUnFreeze () {
94- onReceiveNativeEvent(" onUnFreeze" , null )
95- }
96- override fun onDestroy () {
97- onReceiveNativeEvent(" onDestroy" , null )
98- }
99- override fun onFrame (frame : Float ) {
100- val value =
101- Arguments .createMap().apply {
102- putDouble(" frameNo" , frame.toDouble())
103- }
104- onReceiveNativeEvent(" onFrame" , value)
105- }
106- override fun onLoop (loopCount : Int ) {
107- val value =
108- Arguments .createMap().apply {
109- putInt(" loopCount" , loopCount)
110- }
111- onReceiveNativeEvent(" onLoop" , value)
112- }
113- override fun onRender (frameNo : Float ) {
114- val value =
115- Arguments .createMap().apply {
116- putDouble(" frameNo" , frameNo.toDouble())
117- }
118- onReceiveNativeEvent(" onRender" , value)
119- }
120- }
121- )
122- )
116+ animationUrl.value?.let { url ->
117+ val source = DotLottieSource .Url (url)
118+
119+ if (useOpenGLRenderer) {
120+ DotLottieGLAnimation (
121+ source = source,
122+ autoplay = autoplay,
123+ loop = loop,
124+ speed = speed,
125+ controller = dotLottieController,
126+ useFrameInterpolation = useFrameInterpolation,
127+ themeId = themeId,
128+ stateMachineId = stateMachineId,
129+ marker = marker,
130+ segment = segment,
131+ playMode = playMode,
132+ eventListeners = eventListeners
133+ )
134+ } else {
135+ DotLottieAnimation (
136+ source = source,
137+ autoplay = autoplay,
138+ loop = loop,
139+ speed = speed,
140+ controller = dotLottieController,
141+ useFrameInterpolation = useFrameInterpolation,
142+ themeId = themeId,
143+ stateMachineId = stateMachineId,
144+ marker = marker,
145+ segment = segment,
146+ playMode = playMode,
147+ eventListeners = eventListeners
148+ )
149+ }
150+ }
151+ }
152+
153+ // Renderer is locked on first set because switching between GL and Canvas
154+ // surfaces at runtime is not supported by the underlying SDK.
155+ fun setUseOpenGLRenderer (value : Boolean ) {
156+ if (! rendererLocked) {
157+ useOpenGLRenderer = value
158+ rendererLocked = true
123159 }
124160 }
125161
126162 fun setSource (url : String? ) {
127- animationUrl = url
128- if (! isReleased) {
163+ animationUrl.value = url
164+ if (! isReleased && ! hasActiveComposition ) {
129165 renderContent()
130166 }
131167 }
0 commit comments