rn-newarch-svga-player 1.1.4 → 1.1.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +108 -0
- package/SvgaPlayer.tsx +52 -13
- package/android/build.gradle +1 -2
- package/android/gradle.properties +5 -5
- package/android/src/main/java/com/svgaplayer/RNSvgaPlayer.kt +13 -0
- package/android/src/main/java/com/svgaplayer/RNSvgaPlayerManager.kt +77 -26
- package/android/src/main/java/com/svgaplayer/events/TopFrameEvent.kt +19 -0
- package/android/src/main/java/com/svgaplayer/events/TopPercentageEvent.kt +19 -0
- package/ios/RCTSvgaPlayer.h +1 -5
- package/ios/RCTSvgaPlayer.mm +99 -27
- package/package.json +3 -3
- package/src/specs/SvgaPlayerNativeComponent.ts +35 -10
- package/readme.md +0 -184
package/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
## **这是一款使用 ReactNative 新架构 加载`Android/iOS` Svga 动画的开源插件**[三端 Svga 动画统一使用点击这里](https://github.com/yrjwcharm/react-native-ohos/tree/feature/rnoh/svgaplayer)
|
2
|
+
|
3
|
+
> ### 版本:latest
|
4
|
+
|
5
|
+
<p align="center">
|
6
|
+
<h1 align="center"> <code>rn-newarch-svga-player</code> </h1>
|
7
|
+
</p>
|
8
|
+
<p align="center">
|
9
|
+
<a href="https://github.com/wonday/react-native-pdf/blob/master/LICENSE">
|
10
|
+
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License" />
|
11
|
+
</a>
|
12
|
+
</p>
|
13
|
+
|
14
|
+
> [!TIP] [Github 地址](https://github.com/yrjwcharm/rn-newarch-svga-player)
|
15
|
+
|
16
|
+
## 安装与使用
|
17
|
+
|
18
|
+
> [!TIP] 注意 ⚠️ 本库 android/ios 仅给予 Fabric 新架构 支持,旧架构不在跟进,若需旧架构支持请移步<https://github.com/yrjwcharm/react-native-svga-player>
|
19
|
+
|
20
|
+
#### **npm**
|
21
|
+
|
22
|
+
```bash
|
23
|
+
npm install rn-newarch-svga-player
|
24
|
+
```
|
25
|
+
|
26
|
+
#### **yarn**
|
27
|
+
|
28
|
+
```bash
|
29
|
+
yarn add rn-newarch-svga-player
|
30
|
+
```
|
31
|
+
|
32
|
+
## API 参考
|
33
|
+
|
34
|
+
### Props
|
35
|
+
|
36
|
+
| 属性 | 类型 | 默认值 | 描述 |
|
37
|
+
| ----------------- | ------------------------- | ----------- | ----------------------------------------------------- |
|
38
|
+
| `source` | `SvgaSource` | - | SVGA 文件源 |
|
39
|
+
| `autoPlay` | `boolean` | `true` | 是否自动播放 |
|
40
|
+
| `loops` | `number` | `0` | 循环播放次数,默认值:0 表示无限循环 |
|
41
|
+
| `clearsAfterStop` | `boolean` | `true` | 动画停止后是否清空画布 |
|
42
|
+
| `fillMode` | `'Forward' \| 'Backward'` | `'Forward'` | 填充模式:Forward 停留在最后一帧,Backward 回到第一帧 |
|
43
|
+
| `onFinished` | `function` | - | 播放完成时的回调函数 |
|
44
|
+
| `onFrame` | `function` | - | 帧变化时的回调函数 |
|
45
|
+
| `onPercentage` | `function` | - | 播放进度变化时的回调函数 |
|
46
|
+
|
47
|
+
### Ref 方法
|
48
|
+
|
49
|
+
| 方法 | 描述 |
|
50
|
+
| ---------------------------------------------------- | ----------------------------------------------- |
|
51
|
+
| `startAnimation()` | 从第 0 帧开始播放动画 |
|
52
|
+
| `startAnimationWithRange(location, length, reverse)` | 在指定范围内播放动画,可选择反向播放 |
|
53
|
+
| `pauseAnimation()` | 暂停动画,停留在当前帧 |
|
54
|
+
| `stopAnimation()` | 停止动画,根据 clearsAfterStop 决定是否清空画布 |
|
55
|
+
| `stepToFrame(frame, andPlay)` | 跳转到指定帧,可选择是否从该帧开始播放 |
|
56
|
+
| `stepToPercentage(percentage, andPlay)` | 跳转到指定百分比位置 (0.0-1.0),可选择是否播放 |
|
57
|
+
|
58
|
+
> 若想更改库的别名 react-native-svga-player 来导入。你则需要把 rn-newarch-svga-player 库修改下,重新 yarn 执行
|
59
|
+
|
60
|
+
```diff
|
61
|
+
+ "dependencies": {
|
62
|
+
"@react-native-oh/react-native-harmony": "0.72.48",
|
63
|
+
"patch-package": "^8.0.0",
|
64
|
+
"postinstall-postinstall": "^2.1.0",
|
65
|
+
"react": "18.2.0",
|
66
|
+
"react-native": "0.72.5",
|
67
|
+
- "rn-newarch-svga-player":"^1.1.6"
|
68
|
+
+ "react-native-svga-player":"npm:rn-newarch-svga-player@1.1.6"
|
69
|
+
},
|
70
|
+
```
|
71
|
+
|
72
|
+
下面的代码展示了这个库的基本使用场景:
|
73
|
+
|
74
|
+
```js
|
75
|
+
import React from "react";
|
76
|
+
import { View, Dimensions, StyleSheet } from "react-native";
|
77
|
+
import { RNSvgaPlayer } from "react-native-svga-player";
|
78
|
+
|
79
|
+
export function App() {
|
80
|
+
return (
|
81
|
+
<RNSvgaPlayer
|
82
|
+
source="https://raw.githubusercontent.com/yyued/SVGAPlayer-iOS/master/SVGAPlayer/Samples/Goddess.svga"
|
83
|
+
style={{
|
84
|
+
width: 300,
|
85
|
+
height: 150,
|
86
|
+
}}
|
87
|
+
/>
|
88
|
+
);
|
89
|
+
}
|
90
|
+
|
91
|
+
const styles = StyleSheet.create({
|
92
|
+
container: {
|
93
|
+
flex: 1,
|
94
|
+
justifyContent: "flex-start",
|
95
|
+
alignItems: "center",
|
96
|
+
},
|
97
|
+
});
|
98
|
+
```
|
99
|
+
|
100
|
+
更多详情用法参考 [三端 Svga 动画统一使用点击这里](https://github.com/yrjwcharm/react-native-ohos/tree/feature/rnoh/svgaplayer)
|
101
|
+
|
102
|
+
#### 开源不易,希望您可以动一动小手点点小 ⭐⭐
|
103
|
+
|
104
|
+
#### 👴 希望大家如有好的需求踊跃提交,如有问题请提交 issue,空闲时间会扩充与修复优化
|
105
|
+
|
106
|
+
## 开源协议
|
107
|
+
|
108
|
+
本项目基于 [The MIT License (MIT)](https://github.com/yrjwcharm/react-native-ohos-svgaplayer/blob/master/LICENSE) ,请自由地享受和参与开源。
|
package/SvgaPlayer.tsx
CHANGED
@@ -1,22 +1,21 @@
|
|
1
1
|
import React, { forwardRef, useImperativeHandle, useRef } from 'react';
|
2
2
|
import type { ViewProps } from 'react-native';
|
3
|
-
import
|
3
|
+
import SvgaPlayerView, {
|
4
4
|
Commands,
|
5
5
|
type ComponentType,
|
6
6
|
} from './src/specs/SvgaPlayerNativeComponent';
|
7
|
-
|
8
7
|
export interface SvgaErrorEvent {
|
9
8
|
error: string;
|
10
9
|
}
|
11
10
|
|
12
11
|
export interface SvgaPlayerProps extends ViewProps {
|
13
|
-
source
|
12
|
+
source: string;
|
14
13
|
/**
|
15
14
|
* 是否自动播放,默认 true
|
16
15
|
*/
|
17
16
|
autoPlay?: boolean;
|
18
17
|
/**
|
19
|
-
* 循环播放次数,默认 0
|
18
|
+
* 循环播放次数,默认 0(无限循环播放)
|
20
19
|
*/
|
21
20
|
loops?: number;
|
22
21
|
/**
|
@@ -28,10 +27,14 @@ export interface SvgaPlayerProps extends ViewProps {
|
|
28
27
|
*/
|
29
28
|
align?: 'top' | 'bottom' | 'center';
|
30
29
|
|
30
|
+
fillMode?: 'Forward' | 'Backward';
|
31
|
+
|
31
32
|
// 事件回调
|
32
33
|
onError?: (event: SvgaErrorEvent) => void;
|
33
34
|
onFinished?: () => void;
|
34
35
|
onLoaded?: () => void;
|
36
|
+
onFrame?: (event: { value: number }) => void;
|
37
|
+
onPercentage?: (event: { value: number }) => void;
|
35
38
|
}
|
36
39
|
|
37
40
|
export interface SvgaPlayerRef {
|
@@ -43,6 +46,14 @@ export interface SvgaPlayerRef {
|
|
43
46
|
* 停止动画,如果 clearsAfterStop 为 true 则清空画布
|
44
47
|
*/
|
45
48
|
stopAnimation: () => void;
|
49
|
+
pauseAnimation: () => void;
|
50
|
+
stepToFrame: (frame: number, andPlay: boolean) => void;
|
51
|
+
stepToPercentage: (percentage: number, andPlay: boolean) => void;
|
52
|
+
startAnimationWithRange: (
|
53
|
+
location: number,
|
54
|
+
length: number,
|
55
|
+
reverse: boolean
|
56
|
+
) => void;
|
46
57
|
}
|
47
58
|
|
48
59
|
const RNSvgaPlayer = forwardRef<SvgaPlayerRef, SvgaPlayerProps>(
|
@@ -50,11 +61,13 @@ const RNSvgaPlayer = forwardRef<SvgaPlayerRef, SvgaPlayerProps>(
|
|
50
61
|
{
|
51
62
|
autoPlay = true,
|
52
63
|
loops = 0,
|
53
|
-
clearsAfterStop =
|
54
|
-
source,
|
64
|
+
clearsAfterStop = true,
|
65
|
+
source = '',
|
55
66
|
onError,
|
56
67
|
onFinished,
|
57
68
|
onLoaded,
|
69
|
+
onFrame,
|
70
|
+
onPercentage,
|
58
71
|
...restProps
|
59
72
|
},
|
60
73
|
ref
|
@@ -72,22 +85,48 @@ const RNSvgaPlayer = forwardRef<SvgaPlayerRef, SvgaPlayerProps>(
|
|
72
85
|
Commands.stopAnimation(nativeRef.current);
|
73
86
|
}
|
74
87
|
},
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
88
|
+
pauseAnimation: () => {
|
89
|
+
if (nativeRef.current) {
|
90
|
+
Commands.pauseAnimation(nativeRef.current);
|
91
|
+
}
|
92
|
+
},
|
93
|
+
stepToFrame: (frame: number, andPlay: boolean) => {
|
94
|
+
if (nativeRef.current) {
|
95
|
+
Commands.stepToFrame(nativeRef.current, frame, andPlay);
|
96
|
+
}
|
97
|
+
},
|
98
|
+
stepToPercentage: (frame: number, andPlay: boolean) => {
|
99
|
+
if (nativeRef.current) {
|
100
|
+
Commands.stepToPercentage(nativeRef.current, frame, andPlay);
|
101
|
+
}
|
102
|
+
},
|
103
|
+
startAnimationWithRange: (
|
104
|
+
location: number,
|
105
|
+
length: number,
|
106
|
+
reverse: boolean
|
107
|
+
) => {
|
108
|
+
if (nativeRef.current) {
|
109
|
+
Commands.startAnimationWithRange(
|
110
|
+
nativeRef.current,
|
111
|
+
location,
|
112
|
+
length,
|
113
|
+
reverse
|
114
|
+
);
|
115
|
+
}
|
116
|
+
},
|
80
117
|
}));
|
81
118
|
|
82
119
|
return (
|
83
|
-
<
|
120
|
+
<SvgaPlayerView
|
84
121
|
ref={nativeRef}
|
85
122
|
source={source}
|
86
123
|
autoPlay={autoPlay}
|
87
124
|
loops={loops}
|
88
125
|
clearsAfterStop={clearsAfterStop}
|
89
|
-
onError={(
|
126
|
+
onError={(event) => onError?.(event.nativeEvent)}
|
90
127
|
onFinished={onFinished}
|
128
|
+
onFrameChanged={(event) => onFrame?.(event.nativeEvent)}
|
129
|
+
onPercentageChanged={(event) => onPercentage?.(event.nativeEvent)}
|
91
130
|
onLoaded={onLoaded}
|
92
131
|
{...restProps}
|
93
132
|
/>
|
package/android/build.gradle
CHANGED
@@ -15,7 +15,7 @@ buildscript {
|
|
15
15
|
}
|
16
16
|
|
17
17
|
dependencies {
|
18
|
-
classpath "com.android.tools.build:gradle:
|
18
|
+
classpath "com.android.tools.build:gradle:7.3.1"
|
19
19
|
// noinspection DifferentKotlinGradleVersion
|
20
20
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${getExtOrDefault('kotlinVersion')}"
|
21
21
|
}
|
@@ -24,7 +24,6 @@ buildscript {
|
|
24
24
|
|
25
25
|
apply plugin: "com.android.library"
|
26
26
|
apply plugin: "kotlin-android"
|
27
|
-
|
28
27
|
apply plugin: "com.facebook.react"
|
29
28
|
|
30
29
|
def getExtOrIntegerDefault(name) {
|
@@ -1,5 +1,5 @@
|
|
1
|
-
SvgaPlayer_kotlinVersion=2.0.21
|
2
|
-
SvgaPlayer_minSdkVersion=24
|
3
|
-
SvgaPlayer_targetSdkVersion=34
|
4
|
-
SvgaPlayer_compileSdkVersion=35
|
5
|
-
SvgaPlayer_ndkVersion=27.1.12297006
|
1
|
+
# SvgaPlayer_kotlinVersion=2.0.21
|
2
|
+
# SvgaPlayer_minSdkVersion=24
|
3
|
+
# SvgaPlayer_targetSdkVersion=34
|
4
|
+
# SvgaPlayer_compileSdkVersion=35
|
5
|
+
# SvgaPlayer_ndkVersion=27.1.12297006
|
@@ -11,6 +11,9 @@ import com.facebook.react.uimanager.events.EventDispatcher
|
|
11
11
|
import com.opensource.svgaplayer.SVGACallback
|
12
12
|
import com.opensource.svgaplayer.SVGAImageView
|
13
13
|
import com.svgaplayer.events.TopFinishedEvent
|
14
|
+
import com.svgaplayer.events.TopFrameEvent
|
15
|
+
import com.svgaplayer.events.TopLoadedEvent
|
16
|
+
import com.svgaplayer.events.TopPercentageEvent
|
14
17
|
|
15
18
|
class RNSvgaPlayer(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : SVGAImageView(context, attrs, defStyleAttr) {
|
16
19
|
|
@@ -23,6 +26,16 @@ class RNSvgaPlayer(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
|
|
23
26
|
override fun onStep(frame: Int, percentage: Double) {
|
24
27
|
// 动画开始播放,清除启动标记
|
25
28
|
isStarting = false
|
29
|
+
val frameArguments = Arguments.createMap()
|
30
|
+
val percentageArguments = Arguments.createMap()
|
31
|
+
frameArguments.putDouble("value",frame.toDouble());
|
32
|
+
percentageArguments.putDouble("value", percentage);
|
33
|
+
val surfaceId = UIManagerHelper.getSurfaceId(context)
|
34
|
+
val framedEvent = TopFrameEvent(surfaceId, id, frameArguments)
|
35
|
+
var percentageEvent = TopPercentageEvent(surfaceId,id,percentageArguments);
|
36
|
+
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context as ThemedReactContext, id)
|
37
|
+
dispatcher?.dispatchEvent(framedEvent)
|
38
|
+
dispatcher?.dispatchEvent(percentageEvent);
|
26
39
|
}
|
27
40
|
|
28
41
|
override fun onRepeat() {
|
@@ -1,48 +1,45 @@
|
|
1
1
|
package com.svgaplayer
|
2
2
|
|
3
|
-
import android.content.Context
|
4
3
|
import android.util.Log
|
5
|
-
import
|
4
|
+
import android.widget.ImageView
|
6
5
|
import com.facebook.react.bridge.Arguments
|
7
|
-
import com.facebook.react.bridge.ReactApplicationContext
|
8
6
|
import com.facebook.react.bridge.ReadableArray
|
7
|
+
import com.facebook.react.common.MapBuilder
|
9
8
|
import com.facebook.react.module.annotations.ReactModule
|
10
9
|
import com.facebook.react.uimanager.SimpleViewManager
|
11
10
|
import com.facebook.react.uimanager.ThemedReactContext
|
12
11
|
import com.facebook.react.uimanager.UIManagerHelper
|
13
12
|
import com.facebook.react.uimanager.ViewManagerDelegate
|
14
13
|
import com.facebook.react.uimanager.annotations.ReactProp
|
15
|
-
import android.widget.ImageView
|
16
14
|
import com.facebook.react.viewmanagers.RNSvgaPlayerManagerDelegate
|
17
15
|
import com.facebook.react.viewmanagers.RNSvgaPlayerManagerInterface
|
16
|
+
import com.opensource.svgaplayer.SVGACache
|
18
17
|
import com.opensource.svgaplayer.SVGAParser
|
19
18
|
import com.opensource.svgaplayer.SVGAVideoEntity
|
20
|
-
import com.opensource.svgaplayer.
|
19
|
+
import com.opensource.svgaplayer.utils.SVGARange
|
21
20
|
import com.svgaplayer.events.TopErrorEvent
|
22
|
-
import com.svgaplayer.events.TopFinishedEvent
|
23
21
|
import com.svgaplayer.events.TopLoadedEvent
|
24
22
|
import java.io.File
|
25
23
|
import java.io.FileInputStream
|
26
|
-
import java.io.IOException
|
27
24
|
import java.net.URL
|
28
25
|
|
29
|
-
|
30
|
-
|
26
|
+
|
27
|
+
@ReactModule(name = RNSvgaPlayerManager.REACT_CLASS)
|
28
|
+
class RNSvgaPlayerManager() : SimpleViewManager<RNSvgaPlayer>(), RNSvgaPlayerManagerInterface<RNSvgaPlayer> {
|
31
29
|
|
32
30
|
companion object {
|
33
|
-
const val
|
31
|
+
const val REACT_CLASS = "RNSvgaPlayer"
|
34
32
|
}
|
35
|
-
|
36
33
|
private val mDelegate: ViewManagerDelegate<RNSvgaPlayer> = RNSvgaPlayerManagerDelegate(this)
|
37
34
|
|
38
|
-
override fun getName(): String =
|
35
|
+
override fun getName(): String = REACT_CLASS
|
39
36
|
|
40
37
|
override fun getDelegate(): ViewManagerDelegate<RNSvgaPlayer>? = mDelegate
|
41
38
|
|
42
39
|
override fun createViewInstance(c: ThemedReactContext): RNSvgaPlayer {
|
43
40
|
return RNSvgaPlayer(c, null, 0)
|
44
41
|
}
|
45
|
-
|
42
|
+
@ReactProp(name = "source")
|
46
43
|
override fun setSource(view: RNSvgaPlayer, source: String?) {
|
47
44
|
val context = view.context
|
48
45
|
source?.let {
|
@@ -67,7 +64,7 @@ class RNSvgaPlayerManager : SimpleViewManager<RNSvgaPlayer>(), RNSvgaPlayerManag
|
|
67
64
|
val surfaceId = UIManagerHelper.getSurfaceId(context)
|
68
65
|
val loadedEvent = TopLoadedEvent(surfaceId, view.id, loadedData)
|
69
66
|
val dispatcher = UIManagerHelper.getEventDispatcherForReactTag(context as ThemedReactContext, view.id)
|
70
|
-
|
67
|
+
dispatcher?.dispatchEvent(loadedEvent)
|
71
68
|
|
72
69
|
if(view.autoPlay){
|
73
70
|
view.startAnimationSafely()
|
@@ -99,20 +96,20 @@ class RNSvgaPlayerManager : SimpleViewManager<RNSvgaPlayer>(), RNSvgaPlayerManag
|
|
99
96
|
}
|
100
97
|
}
|
101
98
|
}
|
102
|
-
|
99
|
+
@ReactProp(name = "loops", defaultInt = 0)
|
103
100
|
override fun setLoops(view: RNSvgaPlayer, loops: Int) {
|
104
101
|
view.loops = loops
|
105
102
|
}
|
106
|
-
|
103
|
+
@ReactProp(name = "clearsAfterStop", defaultBoolean = true)
|
107
104
|
override fun setClearsAfterStop(view: RNSvgaPlayer, clearsAfterStop: Boolean) {
|
108
105
|
view.clearsAfterDetached = clearsAfterStop
|
109
106
|
view.clearsAfterStop = clearsAfterStop
|
110
107
|
}
|
111
|
-
|
108
|
+
@ReactProp(name = "autoPlay", defaultBoolean = true)
|
112
109
|
override fun setAutoPlay(view: RNSvgaPlayer, autoPlay: Boolean) {
|
113
110
|
view.autoPlay = autoPlay
|
114
111
|
}
|
115
|
-
|
112
|
+
@ReactProp(name = "align")
|
116
113
|
override fun setAlign(view: RNSvgaPlayer, align: String?) {
|
117
114
|
val scaleType = when (align) {
|
118
115
|
"bottom" -> ImageView.ScaleType.FIT_END
|
@@ -130,6 +127,26 @@ class RNSvgaPlayerManager : SimpleViewManager<RNSvgaPlayer>(), RNSvgaPlayerManag
|
|
130
127
|
when (commandId) {
|
131
128
|
"startAnimation" -> startAnimation(root)
|
132
129
|
"stopAnimation" -> stopAnimation(root)
|
130
|
+
"pauseAnimation" -> pauseAnimation(root)
|
131
|
+
"stepToFrame" -> {
|
132
|
+
val frame = args?.getInt(0) ?: 0
|
133
|
+
val andPlay = args?.getBoolean(1) ?: false
|
134
|
+
stepToFrame(root, frame, andPlay)
|
135
|
+
}
|
136
|
+
"stepToPercentage" -> {
|
137
|
+
val percentage = args?.getInt(0) ?: 0
|
138
|
+
val andPlay = args?.getBoolean(1) ?: false
|
139
|
+
stepToPercentage(root, percentage, andPlay)
|
140
|
+
}
|
141
|
+
"startAnimationWithRange" -> {
|
142
|
+
val location = args?.getInt(0) ?: 0
|
143
|
+
val length = args?.getInt(1) ?: 0
|
144
|
+
val reverse = args?.getBoolean(2) ?: false
|
145
|
+
startAnimationWithRange(root, location, length, reverse)
|
146
|
+
}
|
147
|
+
else -> {
|
148
|
+
Log.w(REACT_CLASS, "Unknown command: $commandId")
|
149
|
+
}
|
133
150
|
}
|
134
151
|
}
|
135
152
|
|
@@ -138,17 +155,51 @@ class RNSvgaPlayerManager : SimpleViewManager<RNSvgaPlayer>(), RNSvgaPlayerManag
|
|
138
155
|
}
|
139
156
|
|
140
157
|
override fun stopAnimation(view: RNSvgaPlayer) {
|
141
|
-
view.stopAnimation(
|
158
|
+
view.stopAnimation(view.clearsAfterStop)
|
159
|
+
}
|
160
|
+
|
161
|
+
// override fun getExportedCustomBubblingEventTypeConstants(): Map<String, Any>? {
|
162
|
+
// val export = super.getExportedCustomDirectEventTypeConstants()?.toMutableMap()
|
163
|
+
// ?: mutableMapOf<String, Any>()
|
164
|
+
//
|
165
|
+
// export[TopErrorEvent.EVENT_NAME] = mapOf("registrationName" to "onError")
|
166
|
+
// export[TopFinishedEvent.EVENT_NAME] = mapOf("registrationName" to "onFinished")
|
167
|
+
// export[TopLoadedEvent.EVENT_NAME] = mapOf("registrationName" to "onLoaded")
|
168
|
+
// export[TopFrameEvent.EVENT_NAME] = mapOf("registrationName" to "onFrameChanged")
|
169
|
+
// export[TopPercentageEvent.EVENT_NAME] = mapOf("registrationName" to "onPercentageChanged")
|
170
|
+
//
|
171
|
+
// return export
|
172
|
+
// }
|
173
|
+
override fun getExportedCustomBubblingEventTypeConstants(): MutableMap<String, Any>? {
|
174
|
+
val map = MapBuilder.builder<String, Any>()
|
175
|
+
.put("topError", MapBuilder.of("registrationName", "onError"))
|
176
|
+
.put("topFinished", MapBuilder.of("registrationName", "onFinished"))
|
177
|
+
.put("topLoaded", MapBuilder.of("registrationName", "onLoaded"))
|
178
|
+
.put("topFrameChanged", MapBuilder.of("registrationName", "onFrameChanged"))
|
179
|
+
.put("topPercentageChanged", MapBuilder.of("registrationName", "onPercentageChanged"))
|
180
|
+
.build()
|
181
|
+
return map
|
142
182
|
}
|
143
183
|
|
144
|
-
override fun
|
145
|
-
|
146
|
-
|
184
|
+
override fun pauseAnimation(view: RNSvgaPlayer?) {
|
185
|
+
view?.pauseAnimation()
|
186
|
+
}
|
147
187
|
|
148
|
-
|
149
|
-
|
150
|
-
|
188
|
+
override fun stepToFrame(view: RNSvgaPlayer?, frame: Int, andPlay: Boolean) {
|
189
|
+
view?.stepToFrame(frame, andPlay);
|
190
|
+
}
|
191
|
+
|
192
|
+
override fun stepToPercentage(view: RNSvgaPlayer?, percentage: Int, andPlay: Boolean) {
|
193
|
+
view?.stepToFrame(percentage, andPlay);
|
194
|
+
}
|
151
195
|
|
152
|
-
|
196
|
+
override fun startAnimationWithRange(
|
197
|
+
view: RNSvgaPlayer?,
|
198
|
+
location: Int,
|
199
|
+
length: Int,
|
200
|
+
reverse: Boolean
|
201
|
+
) {
|
202
|
+
var range = SVGARange(location, length)
|
203
|
+
view?.startAnimation(range,reverse)
|
153
204
|
}
|
154
205
|
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
package com.svgaplayer.events
|
2
|
+
|
3
|
+
import com.facebook.react.bridge.WritableMap
|
4
|
+
import com.facebook.react.uimanager.events.Event
|
5
|
+
|
6
|
+
class TopFrameEvent(
|
7
|
+
surfaceId: Int,
|
8
|
+
viewTag: Int,
|
9
|
+
private val eventData: WritableMap
|
10
|
+
) : Event<TopFrameEvent>(surfaceId, viewTag) {
|
11
|
+
|
12
|
+
companion object {
|
13
|
+
const val EVENT_NAME = "onFrameChanged"
|
14
|
+
}
|
15
|
+
|
16
|
+
override fun getEventName(): String = EVENT_NAME
|
17
|
+
|
18
|
+
override fun getEventData(): WritableMap? = eventData
|
19
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
package com.svgaplayer.events
|
2
|
+
|
3
|
+
import com.facebook.react.bridge.WritableMap
|
4
|
+
import com.facebook.react.uimanager.events.Event
|
5
|
+
|
6
|
+
class TopPercentageEvent(
|
7
|
+
surfaceId: Int,
|
8
|
+
viewTag: Int,
|
9
|
+
private val eventData: WritableMap
|
10
|
+
) : Event<TopPercentageEvent>(surfaceId, viewTag) {
|
11
|
+
|
12
|
+
companion object {
|
13
|
+
const val EVENT_NAME = "onPercentageChanged"
|
14
|
+
}
|
15
|
+
|
16
|
+
override fun getEventName(): String = EVENT_NAME
|
17
|
+
|
18
|
+
override fun getEventData(): WritableMap? = eventData
|
19
|
+
}
|
package/ios/RCTSvgaPlayer.h
CHANGED
package/ios/RCTSvgaPlayer.mm
CHANGED
@@ -25,11 +25,22 @@ using namespace facebook::react;
|
|
25
25
|
SVGAVideoEntity * _currentVideoItem;
|
26
26
|
}
|
27
27
|
|
28
|
+
// Event emitter convenience method
|
29
|
+
- (const RNSvgaPlayerEventEmitter &)eventEmitter
|
30
|
+
{
|
31
|
+
return static_cast<const RNSvgaPlayerEventEmitter &>(*_eventEmitter);
|
32
|
+
}
|
33
|
+
|
28
34
|
+ (ComponentDescriptorProvider)componentDescriptorProvider
|
29
35
|
{
|
30
36
|
return concreteComponentDescriptorProvider<RNSvgaPlayerComponentDescriptor>();
|
31
37
|
}
|
32
38
|
|
39
|
+
|
40
|
+
Class<RCTComponentViewProtocol> RNSvgaPlayerCls(void)
|
41
|
+
{
|
42
|
+
return RCTSvgaPlayer.class;
|
43
|
+
}
|
33
44
|
- (instancetype)initWithFrame:(CGRect)frame
|
34
45
|
{
|
35
46
|
if (self = [super initWithFrame:frame]) {
|
@@ -104,12 +115,6 @@ using namespace facebook::react;
|
|
104
115
|
|
105
116
|
[super updateProps:props oldProps:oldProps];
|
106
117
|
}
|
107
|
-
|
108
|
-
Class<RCTComponentViewProtocol> SvgaPlayerViewCls(void)
|
109
|
-
{
|
110
|
-
return RCTSvgaPlayer.class;
|
111
|
-
}
|
112
|
-
|
113
118
|
// 辅助方法:根据 align 属性设置 contentMode
|
114
119
|
- (void)updateContentModeWithAlign:(RNSvgaPlayerAlign)align
|
115
120
|
{
|
@@ -135,21 +140,27 @@ Class<RCTComponentViewProtocol> SvgaPlayerViewCls(void)
|
|
135
140
|
[_svgaPlayer setVideoItem:nil];
|
136
141
|
[_svgaPlayer clear];
|
137
142
|
_currentVideoItem = nil;
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
143
|
+
|
144
|
+
RNSvgaPlayerEventEmitter::OnError result = RNSvgaPlayerEventEmitter::OnError{RNSvgaPlayerEventEmitter::OnError( [errorMessage UTF8String] )};
|
145
|
+
self.eventEmitter.onError(result);
|
146
|
+
|
147
|
+
// if (_eventEmitter != nullptr) {
|
148
|
+
// std::dynamic_pointer_cast<const facebook::react::RNSvgaPlayerEventEmitter>(_eventEmitter)
|
149
|
+
// ->onError(facebook::react::RNSvgaPlayerEventEmitter::OnError{
|
150
|
+
// .error = std::string([errorMessage UTF8String])
|
151
|
+
// });
|
152
|
+
// }
|
145
153
|
}
|
146
154
|
|
147
155
|
- (void)sendLoadedEvent
|
148
156
|
{
|
149
|
-
if (_eventEmitter != nullptr) {
|
150
|
-
std::dynamic_pointer_cast<const facebook::react::RNSvgaPlayerEventEmitter>(_eventEmitter)
|
151
|
-
->onLoaded(facebook::react::RNSvgaPlayerEventEmitter::OnLoaded{});
|
152
|
-
|
157
|
+
// if (_eventEmitter != nullptr) {
|
158
|
+
// std::dynamic_pointer_cast<const facebook::react::RNSvgaPlayerEventEmitter>(_eventEmitter)
|
159
|
+
// ->onLoaded(facebook::react::RNSvgaPlayerEventEmitter::OnLoaded{});
|
160
|
+
//
|
161
|
+
// }
|
162
|
+
RNSvgaPlayerEventEmitter::OnLoaded result = RNSvgaPlayerEventEmitter::OnLoaded{RNSvgaPlayerEventEmitter::OnLoaded( {} )};
|
163
|
+
self.eventEmitter.onLoaded(result);
|
153
164
|
}
|
154
165
|
|
155
166
|
// 辅助方法:处理文件路径
|
@@ -372,7 +383,34 @@ Class<RCTComponentViewProtocol> SvgaPlayerViewCls(void)
|
|
372
383
|
{
|
373
384
|
[_svgaPlayer stopAnimation];
|
374
385
|
}
|
375
|
-
|
386
|
+
- (void)pauseAnimation {
|
387
|
+
[_svgaPlayer pauseAnimation];
|
388
|
+
}
|
389
|
+
-(void)stepToFrame:(NSInteger)frame andPlay:(BOOL)play {
|
390
|
+
if (frame < 0 || !_svgaPlayer || _svgaPlayer.delegate != self) {
|
391
|
+
return;
|
392
|
+
}
|
393
|
+
[_svgaPlayer stepToFrame:frame andPlay:play];
|
394
|
+
}
|
395
|
+
-(void)stepToPercentage:(NSInteger)percentage andPlay:(BOOL)play {
|
396
|
+
if (percentage < 0 || !_svgaPlayer || _svgaPlayer.delegate != self) {
|
397
|
+
return;
|
398
|
+
}
|
399
|
+
[_svgaPlayer stepToPercentage:percentage andPlay:play];
|
400
|
+
}
|
401
|
+
-(void)startAnimationWithRange:(NSInteger)location length:(NSInteger)length reverse:(BOOL)reverse{
|
402
|
+
if (!_svgaPlayer || _svgaPlayer.delegate != self) {
|
403
|
+
return;
|
404
|
+
}
|
405
|
+
|
406
|
+
// 检查 location 和 length 的有效性
|
407
|
+
if (location < 0 || length <= 0) {
|
408
|
+
return;
|
409
|
+
}
|
410
|
+
// 设置动画范围
|
411
|
+
[_svgaPlayer startAnimationWithRange:NSMakeRange(location, length) reverse:reverse];
|
412
|
+
}
|
413
|
+
|
376
414
|
// 处理来自 JavaScript 的命令调用
|
377
415
|
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args
|
378
416
|
{
|
@@ -380,7 +418,43 @@ Class<RCTComponentViewProtocol> SvgaPlayerViewCls(void)
|
|
380
418
|
[self startAnimation];
|
381
419
|
} else if ([commandName isEqualToString:@"stopAnimation"]) {
|
382
420
|
[self stopAnimation];
|
421
|
+
}else if ([commandName isEqualToString:@"pauseAnimation"]) {
|
422
|
+
[self pauseAnimation];
|
423
|
+
}else if([commandName isEqualToString:@"stepToFrame"]){
|
424
|
+
[self stepToFrame:[args[0] integerValue] andPlay:[args[1] boolValue]];
|
425
|
+
|
426
|
+
}else if([commandName isEqualToString:@"stepToPercentage"]){
|
427
|
+
[self stepToPercentage:[args[0] integerValue] andPlay:[args[1] boolValue]];
|
428
|
+
|
429
|
+
}else if([commandName isEqualToString:@"startAnimationWithRange"]){
|
430
|
+
// 处理 startAnimationWithRange 命令
|
431
|
+
[self startAnimationWithRange:[args[0] integerValue]
|
432
|
+
length:[args[1] integerValue]
|
433
|
+
reverse:[args[2] boolValue]];
|
383
434
|
}
|
435
|
+
|
436
|
+
}
|
437
|
+
-(void) svgaPlayerDidAnimatedToFrame:(NSInteger)frame{
|
438
|
+
if (!_svgaPlayer || _svgaPlayer.delegate != self) {
|
439
|
+
return;
|
440
|
+
}
|
441
|
+
RNSvgaPlayerEventEmitter::OnFrameChanged result = RNSvgaPlayerEventEmitter::OnFrameChanged{RNSvgaPlayerEventEmitter::OnFrameChanged( frame )};
|
442
|
+
self.eventEmitter.onFrameChanged(result);
|
443
|
+
// std::dynamic_pointer_cast<const RNSvgaPlayerEventEmitter>(_eventEmitter)
|
444
|
+
// ->onFrameChanged(RNSvgaPlayerEventEmitter::OnFrameChanged{.value=(float)frame});
|
445
|
+
|
446
|
+
}
|
447
|
+
-(void) svgaPlayerDidAnimatedToPercentage:(CGFloat)percentage{
|
448
|
+
// 检查播放器是否还有效
|
449
|
+
if (!_svgaPlayer || _svgaPlayer.delegate != self) {
|
450
|
+
return;
|
451
|
+
}
|
452
|
+
|
453
|
+
RNSvgaPlayerEventEmitter::OnPercentageChanged result = RNSvgaPlayerEventEmitter::OnPercentageChanged{RNSvgaPlayerEventEmitter::OnPercentageChanged( percentage )};
|
454
|
+
self.eventEmitter.onPercentageChanged(result);
|
455
|
+
//直接事件
|
456
|
+
// std::dynamic_pointer_cast<const RNSvgaPlayerEventEmitter>(_eventEmitter)
|
457
|
+
// ->onFrameChanged(RNSvgaPlayerEventEmitter::OnFrameChanged{.value=(float)percentage});
|
384
458
|
}
|
385
459
|
|
386
460
|
// SVGAPlayerDelegate methods
|
@@ -390,16 +464,13 @@ Class<RCTComponentViewProtocol> SvgaPlayerViewCls(void)
|
|
390
464
|
if (!_svgaPlayer || player != _svgaPlayer) {
|
391
465
|
return;
|
392
466
|
}
|
393
|
-
|
394
467
|
// 检查事件发送器是否还有效
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
.finished = true
|
402
|
-
});
|
468
|
+
RNSvgaPlayerEventEmitter::OnFinished result = RNSvgaPlayerEventEmitter::OnFinished{RNSvgaPlayerEventEmitter::OnFinished( true )};
|
469
|
+
self.eventEmitter.onFinished(result);
|
470
|
+
// std::dynamic_pointer_cast<const facebook::react::RNSvgaPlayerEventEmitter>(_eventEmitter)
|
471
|
+
// ->onFinished(facebook::react::RNSvgaPlayerEventEmitter::OnFinished{
|
472
|
+
// .finished = true
|
473
|
+
// });
|
403
474
|
}
|
404
475
|
|
405
476
|
// React Native Fabric 生命周期方法
|
@@ -482,3 +553,4 @@ Class<RCTComponentViewProtocol> SvgaPlayerViewCls(void)
|
|
482
553
|
}
|
483
554
|
|
484
555
|
@end
|
556
|
+
|
package/package.json
CHANGED
@@ -26,10 +26,10 @@
|
|
26
26
|
"files": [
|
27
27
|
"android",
|
28
28
|
"ios",
|
29
|
-
"
|
29
|
+
"lib",
|
30
30
|
"src",
|
31
31
|
"SvgaPlayer.tsx",
|
32
|
-
"
|
32
|
+
"rn-newarch-svga-player.podspec"
|
33
33
|
],
|
34
34
|
"homepage": "https://github.com/yrjwcharm/rn-newarch-svga-player#readme",
|
35
35
|
"keywords": [
|
@@ -53,5 +53,5 @@
|
|
53
53
|
"scripts": {
|
54
54
|
"codegen-lib": "react-native codegen-lib-harmony --no-safety-check --npm-package-name react-native-ohos-svgaplayer --cpp-output-path ../../harmony/svgaplayer/src/main/cpp/generated --ets-output-path ../../harmony/svgaplayer/src/main/ets/generated --turbo-modules-spec-paths ./src --arkts-components-spec-paths ./src"
|
55
55
|
},
|
56
|
-
"version": "1.1.
|
56
|
+
"version": "1.1.6"
|
57
57
|
}
|
@@ -1,35 +1,60 @@
|
|
1
|
-
import type {HostComponent, ViewProps} from 'react-native';
|
1
|
+
import type { HostComponent, ViewProps } from 'react-native';
|
2
2
|
import type {
|
3
3
|
BubblingEventHandler,
|
4
|
+
Double,
|
4
5
|
Int32,
|
5
6
|
WithDefault,
|
6
7
|
} from 'react-native/Libraries/Types/CodegenTypes';
|
7
8
|
import codegenNativeCommands from 'react-native/Libraries/Utilities/codegenNativeCommands';
|
8
9
|
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
|
9
10
|
|
10
|
-
interface
|
11
|
-
source
|
11
|
+
interface SvgaPlayerProps extends ViewProps {
|
12
|
+
source: string;
|
12
13
|
autoPlay?: boolean;
|
13
14
|
loops?: Int32;
|
14
15
|
clearsAfterStop?: boolean;
|
15
16
|
align?: WithDefault<'top' | 'bottom' | 'center', 'center'>;
|
16
|
-
|
17
17
|
// 事件回调
|
18
|
-
onError?: BubblingEventHandler<{error: string}>;
|
19
|
-
onFinished?: BubblingEventHandler<{finished: boolean}>;
|
18
|
+
onError?: BubblingEventHandler<{ error: string }>;
|
19
|
+
onFinished?: BubblingEventHandler<{ finished: boolean }>;
|
20
20
|
onLoaded?: BubblingEventHandler<{}>;
|
21
|
+
onFrameChanged?: BubblingEventHandler<{ value: Double }>;
|
22
|
+
onPercentageChanged?: BubblingEventHandler<{ value: Double }>;
|
21
23
|
}
|
22
24
|
|
23
|
-
export type ComponentType = HostComponent<
|
25
|
+
export type ComponentType = HostComponent<SvgaPlayerProps>;
|
24
26
|
|
25
27
|
interface NativeCommands {
|
26
28
|
startAnimation: (viewRef: React.ElementRef<ComponentType>) => void;
|
27
|
-
// pauseAnimation: (viewRef: React.ElementRef<ComponentType>) => void;
|
28
29
|
stopAnimation: (viewRef: React.ElementRef<ComponentType>) => void;
|
30
|
+
pauseAnimation: (viewRef: React.ElementRef<ComponentType>) => void;
|
31
|
+
stepToFrame: (
|
32
|
+
viewRef: React.ElementRef<ComponentType>,
|
33
|
+
frame: Int32,
|
34
|
+
andPlay: boolean
|
35
|
+
) => void;
|
36
|
+
stepToPercentage: (
|
37
|
+
viewRef: React.ElementRef<ComponentType>,
|
38
|
+
percentage: Int32,
|
39
|
+
andPlay: boolean
|
40
|
+
) => void;
|
41
|
+
startAnimationWithRange: (
|
42
|
+
viewRef: React.ElementRef<ComponentType>,
|
43
|
+
location: Int32,
|
44
|
+
length: Int32,
|
45
|
+
reverse: boolean
|
46
|
+
) => void;
|
29
47
|
}
|
30
48
|
|
31
49
|
export const Commands: NativeCommands = codegenNativeCommands<NativeCommands>({
|
32
|
-
supportedCommands: [
|
50
|
+
supportedCommands: [
|
51
|
+
'startAnimation',
|
52
|
+
'pauseAnimation',
|
53
|
+
'stopAnimation',
|
54
|
+
'stepToFrame',
|
55
|
+
'stepToPercentage',
|
56
|
+
'startAnimationWithRange',
|
57
|
+
],
|
33
58
|
});
|
34
59
|
|
35
|
-
export default codegenNativeComponent<
|
60
|
+
export default codegenNativeComponent<SvgaPlayerProps>('RNSvgaPlayer');
|
package/readme.md
DELETED
@@ -1,184 +0,0 @@
|
|
1
|
-
## **_这是一款使用 ReactNative 加载`Android/iOS` Svga 动画的播放器插件_** [三端 Svga 动画统一使用点击这里](https://github.com/yrjwcharm/react-native-ohos/tree/feature/rnoh/svgaplayer)
|
2
|
-
|
3
|
-
> ### 版本:latest
|
4
|
-
|
5
|
-
<p align="center">
|
6
|
-
<h1 align="center"> <code>rn-newarch-svga-player</code> </h1>
|
7
|
-
</p>
|
8
|
-
<p align="center">
|
9
|
-
<a href="https://github.com/wonday/react-native-pdf/blob/master/LICENSE">
|
10
|
-
<img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License" />
|
11
|
-
</a>
|
12
|
-
</p>
|
13
|
-
|
14
|
-
> [!TIP] [Github 地址](https://github.com/yrjwcharm/rn-newarch-svga-player)
|
15
|
-
|
16
|
-
## 安装与使用
|
17
|
-
|
18
|
-
> [!TIP] 注意 ⚠️ 本库 android/ios 仅给予 Fabric 新架构支持,旧架构不在跟进,若需旧架构支持请移步<https://github.com/yrjwcharm/react-native-svga-player>
|
19
|
-
|
20
|
-
**确保你的 Android/iOS 已经开启了新架构支持 <https://reactnative.cn/docs/0.72/the-new-architecture/use-app-template>**
|
21
|
-
|
22
|
-
#### **npm**
|
23
|
-
|
24
|
-
```bash
|
25
|
-
npm install rn-newarch-svga-player
|
26
|
-
```
|
27
|
-
|
28
|
-
#### **yarn**
|
29
|
-
|
30
|
-
```bash
|
31
|
-
yarn add rn-newarch-svga-player
|
32
|
-
```
|
33
|
-
|
34
|
-
> 若想更改库的别名 react-native-svga-player 来导入。你则需要把 rn-newarch-svga-player 库修改下,重新 yarn 执行
|
35
|
-
|
36
|
-
```diff
|
37
|
-
+ "dependencies": {
|
38
|
-
"@react-native-oh/react-native-harmony": "0.72.48",
|
39
|
-
"patch-package": "^8.0.0",
|
40
|
-
"postinstall-postinstall": "^2.1.0",
|
41
|
-
"react": "18.2.0",
|
42
|
-
"react-native": "0.72.5",
|
43
|
-
- "rn-newarch-svga-player":"^1.1.2"
|
44
|
-
+ "react-native-svga-player":"npm:rn-newarch-svga-player@1.1.2"
|
45
|
-
},
|
46
|
-
```
|
47
|
-
android 需要
|
48
|
-
|
49
|
-
```bash
|
50
|
-
./gradlew generateCodegenArtifactsFromSchema
|
51
|
-
```
|
52
|
-
|
53
|
-
ios 需要
|
54
|
-
|
55
|
-
```bash
|
56
|
-
cd ios
|
57
|
-
bundle install && bundle exec pod install
|
58
|
-
```
|
59
|
-
|
60
|
-
下面的代码展示了这个库的基本使用场景:
|
61
|
-
|
62
|
-
```js
|
63
|
-
import React, { useRef, useState } from "react";
|
64
|
-
import {
|
65
|
-
Button,
|
66
|
-
SafeAreaView,
|
67
|
-
ScrollView,
|
68
|
-
StatusBar,
|
69
|
-
StyleSheet,
|
70
|
-
Text,
|
71
|
-
View,
|
72
|
-
} from "react-native";
|
73
|
-
import { RNSvgaPlayer, SvgaPlayerRef } from "react-native-svga-player";
|
74
|
-
const App = () => {
|
75
|
-
const svgaPlayerRef = useRef < SvgaPlayerRef > null;
|
76
|
-
//播放网络资源
|
77
|
-
const [source, setSource] = useState(
|
78
|
-
"https://raw.githubusercontent.com/yyued/SVGAPlayer-iOS/master/SVGAPlayer/Samples/Goddess.svga"
|
79
|
-
);
|
80
|
-
//播放本地资源
|
81
|
-
// const [source, setSource] = useState(
|
82
|
-
// 'homePage_studyPlanner_computer_welcome.svga',
|
83
|
-
// );
|
84
|
-
return (
|
85
|
-
<SafeAreaView style={styles.container}>
|
86
|
-
<StatusBar barStyle={"dark-content"} />
|
87
|
-
<ScrollView showsVerticalScrollIndicator={false}>
|
88
|
-
<Text style={styles.welcome}>Svga</Text>
|
89
|
-
<RNSvgaPlayer
|
90
|
-
ref={svgaPlayerRef}
|
91
|
-
source={source}
|
92
|
-
autoPlay={true}
|
93
|
-
loops={1} // 循环次数,默认 0无限循环
|
94
|
-
clearsAfterStop={false} // 停止后清空画布,默认 true
|
95
|
-
style={styles.svgaStyle}
|
96
|
-
onFinished={() => {
|
97
|
-
console.log("播放完成");
|
98
|
-
}} // 播放完成回调
|
99
|
-
onLoaded={() => {
|
100
|
-
console.log("动画加载完成");
|
101
|
-
}}
|
102
|
-
/>
|
103
|
-
<View style={styles.flexAround}>
|
104
|
-
<Button
|
105
|
-
title="开始动画"
|
106
|
-
onPress={() => {
|
107
|
-
svgaPlayerRef.current?.startAnimation();
|
108
|
-
}}
|
109
|
-
/>
|
110
|
-
<Button
|
111
|
-
title="暂停动画"
|
112
|
-
onPress={() => {
|
113
|
-
// svgaPlayerRef.current?.pauseAnimation();
|
114
|
-
}}
|
115
|
-
/>
|
116
|
-
<Button
|
117
|
-
title="停止动画"
|
118
|
-
onPress={() => {
|
119
|
-
svgaPlayerRef.current?.stopAnimation();
|
120
|
-
}}
|
121
|
-
/>
|
122
|
-
</View>
|
123
|
-
<View style={[styles.flexAround, { marginTop: 20 }]}>
|
124
|
-
<Button
|
125
|
-
title="手动加载动画"
|
126
|
-
onPress={() => {
|
127
|
-
setSource(
|
128
|
-
"https://raw.githubusercontent.com/yyued/SVGAPlayer-iOS/master/SVGAPlayer/Samples/matteBitmap.svga"
|
129
|
-
);
|
130
|
-
}}
|
131
|
-
/>
|
132
|
-
<Button
|
133
|
-
title="指定帧开始"
|
134
|
-
onPress={() => {
|
135
|
-
// svgaPlayerRef.current?.stepToFrame(20, true);
|
136
|
-
}}
|
137
|
-
/>
|
138
|
-
<Button
|
139
|
-
title="指定百分比开始"
|
140
|
-
onPress={() => {
|
141
|
-
// svgaPlayerRef.current?.stepToPercentage(1, true);
|
142
|
-
}}
|
143
|
-
/>
|
144
|
-
</View>
|
145
|
-
</ScrollView>
|
146
|
-
</SafeAreaView>
|
147
|
-
);
|
148
|
-
};
|
149
|
-
export default App;
|
150
|
-
const styles = StyleSheet.create({
|
151
|
-
flexAround: { flexDirection: "row", justifyContent: "space-around" },
|
152
|
-
container: {
|
153
|
-
flex: 1,
|
154
|
-
},
|
155
|
-
svgaStyle: {
|
156
|
-
width: 150,
|
157
|
-
height: 150,
|
158
|
-
marginTop: 30,
|
159
|
-
},
|
160
|
-
welcome: {
|
161
|
-
fontSize: 20,
|
162
|
-
textAlign: "center",
|
163
|
-
margin: 10,
|
164
|
-
marginTop: 80,
|
165
|
-
},
|
166
|
-
instructions: {
|
167
|
-
textAlign: "center",
|
168
|
-
color: "#333333",
|
169
|
-
marginBottom: 5,
|
170
|
-
},
|
171
|
-
});
|
172
|
-
```
|
173
|
-
|
174
|
-
#### 新架构[Android/iOS]demo 请参考 <https://github.com/yrjwcharm/react-native-ohos/tree/feature/newarch/svgaplayer>
|
175
|
-
|
176
|
-
更多详情用法参考 [三端 Svga 动画统一使用点击这里](https://github.com/yrjwcharm/react-native-ohos/tree/feature/rnoh/svgaplayer)
|
177
|
-
|
178
|
-
#### 开源不易,希望您可以动一动小手点点小 ⭐⭐
|
179
|
-
|
180
|
-
#### 👴 希望大家如有好的需求踊跃提交,如有问题请提交 issue,空闲时间会扩充与修复优化
|
181
|
-
|
182
|
-
## 开源协议
|
183
|
-
|
184
|
-
本项目基于 [The MIT License (MIT)](https://github.com/yrjwcharm/react-native-ohos-svgaplayer/blob/master/LICENSE) ,请自由地享受和参与开源。
|