Skip to content

Commit

Permalink
feat: implement native auto play for ios
Browse files Browse the repository at this point in the history
  • Loading branch information
matinzd committed Feb 7, 2023
1 parent 8ece214 commit 84e6668
Show file tree
Hide file tree
Showing 10 changed files with 137 additions and 85 deletions.
2 changes: 1 addition & 1 deletion apps/fabric/ios/Podfile.lock
Expand Up @@ -894,7 +894,7 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/yoga"

SPEC CHECKSUMS:
boost: a7c83b31436843459a1961bfd74b96033dc77234
boost: 57d2868c099736d80fcd648bf211b4431e51a558
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
FBLazyVector: 61839cba7a48c570b7ac3e1cd8a4d0948382202f
Expand Down
145 changes: 90 additions & 55 deletions apps/fabric/src/App.tsx
@@ -1,69 +1,104 @@
import React from 'react';
import {StyleSheet, Text, TouchableOpacity, View} from 'react-native';
import AnimatedLottieView from 'lottie-react-native';

const color = {
primary: '#1652f0',
secondary: '#64E9FF',
};

const remoteSource = {
uri: 'https://raw.githubusercontent.com/lottie-react-native/lottie-react-native/master/apps/paper/src/animations/Watermelon.json',
};

const localSource = require('./animations/LottieLogo1.json');

const App = () => {
const [source, setSource] = React.useState<'local' | 'remote'>('local');

return (
<AnimatedLottieView
source={require('./animations/LottieLogo1.json')}
autoPlay
loop
onAnimationFinish={() => {
console.log('finished');
}}
colorFilters={[
{
keypath: 'BG',
color: color.primary,
},
{
keypath: 'O-B',
color: color.secondary,
},
{
keypath: 'L-B',
color: color.secondary,
},
{
keypath: 'T1a-Y 2',
color: color.secondary,
},
{
keypath: 'T1b-Y',
color: color.secondary,
},
{
keypath: 'T2b-B',
color: color.secondary,
},
{
keypath: 'T2a-B',
color: color.secondary,
},
{
keypath: 'I-Y',
color: color.secondary,
},
{
keypath: 'E1-Y',
color: color.secondary,
},
{
keypath: 'E2-Y',
color: color.secondary,
},
{
keypath: 'E3-Y',
color: color.secondary,
},
]}
enableMergePathsAndroidForKitKatAndAbove
/>
<View
style={{
flex: 1,
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 32,
}}>
<AnimatedLottieView
source={source === 'remote' ? remoteSource : localSource}
autoPlay={true}
loop={false}
style={styles.lottie}
colorFilters={source === 'local' ? localColorFilter : undefined}
enableMergePathsAndroidForKitKatAndAbove
onAnimationFinish={() => {
console.log('finished');
}}
/>
<TouchableOpacity
onPress={() => {
setSource(source === 'local' ? 'remote' : 'local');
}}
style={styles.button}>
<Text style={styles.text}>
{source === 'local' ? 'Local animation' : 'Remote animation'}
</Text>
</TouchableOpacity>
</View>
);
};

const styles = StyleSheet.create({
button: {backgroundColor: color.primary, marginTop: 24, padding: 24},
text: {color: 'white'},
lottie: {width: 400, height: 400},
});

const localColorFilter = [
{
keypath: 'BG',
color: color.primary,
},
{
keypath: 'O-B',
color: color.secondary,
},
{
keypath: 'L-B',
color: color.secondary,
},
{
keypath: 'T1a-Y 2',
color: color.secondary,
},
{
keypath: 'T1b-Y',
color: color.secondary,
},
{
keypath: 'T2b-B',
color: color.secondary,
},
{
keypath: 'T2a-B',
color: color.secondary,
},
{
keypath: 'I-Y',
color: color.secondary,
},
{
keypath: 'E1-Y',
color: color.secondary,
},
{
keypath: 'E2-Y',
color: color.secondary,
},
{
keypath: 'E3-Y',
color: color.secondary,
},
];

export default App;
6 changes: 3 additions & 3 deletions apps/paper/ios/Podfile.lock
Expand Up @@ -301,7 +301,7 @@ PODS:
- React-jsinspector (0.71.0)
- React-logger (0.71.0):
- glog
- react-native-slider (4.3.2):
- react-native-slider (4.4.0):
- React-Core
- React-perflogger (0.71.0)
- React-RCTActionSheet (0.71.0):
Expand Down Expand Up @@ -570,7 +570,7 @@ SPEC CHECKSUMS:
hermes-engine: ca3834c67d1729953a2645b89a59f38c47e94ab3
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
lottie-ios: c55158d67d0629a260625cc2ded2052b829e3c3e
lottie-react-native: 8acede38abe26c803d5328f144669475ff15321b
lottie-react-native: 6bcc2ddf085c2d092948978b57de2c7d6a138a0c
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
RCTRequired: dea3e4163184ea57c50288c15c32c1529265c58f
Expand All @@ -586,7 +586,7 @@ SPEC CHECKSUMS:
React-jsiexecutor: 060dd495f1e2af3d87216f7ca8a94c55ec885b4f
React-jsinspector: 5061fcbec93fd672183dfb39cc2f65e55a0835db
React-logger: a6c0b3a807a8e81f6d7fea2e72660766f55daa50
react-native-slider: e540525ea731783850802b7af457d8551edb0711
react-native-slider: d2938a12c4e439a227c70eec65d119136eb4aeb5
React-perflogger: e5fc4149e9bbb972b8520277f3b23141faa47a36
React-RCTActionSheet: 991de88216bf03ab9bb1d213d73c62ecbe64ade7
React-RCTAnimation: b74e3d1bf5280891a573e447b487fa1db0713b5b
Expand Down
14 changes: 11 additions & 3 deletions apps/paper/src/LottieAnimatedExample.js
Expand Up @@ -61,7 +61,7 @@ const EXAMPLES = [
require('./animations/MotionCorpse-Jrcanest.json'),
),
makeExample('Remote load', () => ({
uri: 'https://raw.githubusercontent.com/lottie-react-native/lottie-react-native/master/example/js/animations/Watermelon.json',
uri: 'https://raw.githubusercontent.com/lottie-react-native/lottie-react-native/master/apps/paper/src/animations/Watermelon.json',
})),
];

Expand Down Expand Up @@ -159,8 +159,16 @@ export default class LottieAnimatedExample extends React.Component {
};

render() {
const {duration, isPlaying, isPaused, isInverse, progress, loop, example, renderMode} =
this.state;
const {
duration,
isPlaying,
isPaused,
isInverse,
progress,
loop,
example,
renderMode,
} = this.state;

return (
<View style={{flex: 1}}>
Expand Down
4 changes: 4 additions & 0 deletions packages/core/ios/Fabric/LottieAnimationViewComponentView.mm
Expand Up @@ -85,6 +85,10 @@ - (void)updateProps:(Props::Shared const &)props oldProps:(Props::Shared const &
[_view setRenderMode:RCTNSStringFromString(newLottieProps.renderMode)];
}

if(oldLottieProps.autoPlay != newLottieProps.autoPlay) {
[_view setAutoPlay:newLottieProps.autoPlay];
}

[super updateProps:props oldProps:oldProps];
}

Expand Down
1 change: 1 addition & 0 deletions packages/core/ios/Fabric/LottieContainerView.h
Expand Up @@ -16,6 +16,7 @@
- (void)setProgress:(CGFloat)newProgress;
- (void)reactSetFrame:(CGRect)frame;
- (void)setLoop:(BOOL)isLooping;
- (void)setAutoPlay:(BOOL)isAutoPlay;
- (void)setTextFiltersIOS:(NSArray<NSDictionary *> * _Nonnull)newTextFilters;
- (void)setRenderMode:(NSString * _Nonnull)newRenderMode;
- (void)setSourceURL:(NSString * _Nonnull)newSourceURLString;
Expand Down
37 changes: 24 additions & 13 deletions packages/core/ios/LottieReactNative/ContainerView.swift
Expand Up @@ -9,6 +9,7 @@ import Foundation
class ContainerView: RCTView {
private var speed: CGFloat = 0.0
private var progress: CGFloat = 0.0
private var autoPlay: Bool = false
private var loop: LottieLoopMode = .playOnce
private var sourceJson: String = ""
private var resizeMode: String = ""
Expand Down Expand Up @@ -59,6 +60,13 @@ class ContainerView: RCTView {
animationView?.loopMode = loop
}

@objc func setAutoPlay(_ autoPlay: Bool) {
self.autoPlay = autoPlay
if(autoPlay && animationView?.isAnimationPlaying == false) {
self.play()
}
}

@objc func setTextFiltersIOS(_ newTextFilters: [NSDictionary]) {
textFilters = newTextFilters

Expand All @@ -70,10 +78,10 @@ class ContainerView: RCTView {
filters[key] = value;
}

let starAnimationView = LottieAnimationView()
starAnimationView.textProvider = DictionaryTextProvider(filters)
starAnimationView.animation = animationView?.animation
replaceAnimationView(next: starAnimationView)
let nextAnimationView = LottieAnimationView()
nextAnimationView.textProvider = DictionaryTextProvider(filters)
nextAnimationView.animation = animationView?.animation
replaceAnimationView(next: nextAnimationView)
}
}

Expand Down Expand Up @@ -104,11 +112,11 @@ class ContainerView: RCTView {
renderMode = .automatic
}
if (animationView != nil) {
let starAnimationView = LottieAnimationView(
let nextAnimationView = LottieAnimationView(
animation: animationView?.animation,
configuration: getLottieConfiguration()
)
replaceAnimationView(next: starAnimationView)
replaceAnimationView(next: nextAnimationView)
}
}

Expand All @@ -133,12 +141,11 @@ class ContainerView: RCTView {
}

DispatchQueue.main.async {
let starAnimationView = LottieAnimationView(
let nextAnimationView = LottieAnimationView(
animation: animation,
configuration: self.getLottieConfiguration()
)
self.replaceAnimationView(next: starAnimationView)
self.animationView?.play()
self.replaceAnimationView(next: nextAnimationView)
}
} catch {
if (RCT_DEBUG == 1) {
Expand All @@ -160,11 +167,11 @@ class ContainerView: RCTView {
return
}

let starAnimationView = LottieAnimationView(
let nextAnimationView = LottieAnimationView(
animation: animation,
configuration: getLottieConfiguration()
)
replaceAnimationView(next: starAnimationView)
replaceAnimationView(next: nextAnimationView)
}

@objc func setSourceName(_ newSourceName: String) {
Expand All @@ -173,11 +180,11 @@ class ContainerView: RCTView {
}
sourceName = newSourceName

let starAnimationView = LottieAnimationView(
let nextAnimationView = LottieAnimationView(
name: sourceName,
configuration: getLottieConfiguration()
)
replaceAnimationView(next: starAnimationView)
replaceAnimationView(next: nextAnimationView)
}

@objc func setResizeMode(_ resizeMode: String) {
Expand Down Expand Up @@ -258,6 +265,10 @@ class ContainerView: RCTView {
animationView?.animationSpeed = speed
animationView?.loopMode = loop
applyColorProperties()

if (self.autoPlay) {
self.play()
}
}

func applyColorProperties() {
Expand Down
Expand Up @@ -9,6 +9,7 @@ @interface RCT_EXTERN_MODULE(LottieAnimationView, RCTViewManager)
RCT_EXPORT_VIEW_PROPERTY(sourceURL, NSString);
RCT_EXPORT_VIEW_PROPERTY(progress, CGFloat);
RCT_EXPORT_VIEW_PROPERTY(loop, BOOL);
RCT_EXPORT_VIEW_PROPERTY(autoPlay, BOOL);
RCT_EXPORT_VIEW_PROPERTY(speed, CGFloat);
RCT_EXPORT_VIEW_PROPERTY(onAnimationFinish, RCTBubblingEventBlock);
RCT_EXPORT_VIEW_PROPERTY(colorFilters, LRNColorFilters);
Expand Down
11 changes: 1 addition & 10 deletions packages/core/src/LottieView.tsx
Expand Up @@ -56,16 +56,6 @@ export class AnimatedLottieView extends React.PureComponent<
this._captureRef = this._captureRef.bind(this);
}

componentDidUpdate(prevProps: AnimatedLottieViewProps) {
if (
this.props.autoPlay === true &&
this.props.source !== prevProps.source &&
!!this.props.source
) {
this.play();
}
}

play(startFrame?: number, endFrame?: number): void {
Commands.play(
this._lottieAnimationViewRef,
Expand Down Expand Up @@ -171,6 +161,7 @@ export class AnimatedLottieView extends React.PureComponent<
sourceJson={sourceJson}
sourceURL={sourceURL}
onAnimationFinish={this.onAnimationFinish}
autoPlay={autoPlay}
/>
</View>
);
Expand Down
Expand Up @@ -39,6 +39,7 @@ export interface NativeProps extends ViewProps {
progress?: Float;
speed?: Double;
loop?: boolean;
autoPlay?: boolean;
enableMergePathsAndroidForKitKatAndAbove?: boolean;
hardwareAccelerationAndroid?: boolean;
cacheComposition?: boolean;
Expand Down

0 comments on commit 84e6668

Please sign in to comment.