@react-native-ohos/lottie-react-native 6.4.2-rc.1
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/LICENSE +201 -0
- package/README.en.md +36 -0
- package/README.md +13 -0
- package/harmony/lottie/BuildProfile.ets +17 -0
- package/harmony/lottie/LICENSE +15 -0
- package/harmony/lottie/NOTICE +244 -0
- package/harmony/lottie/OAT.xml +54 -0
- package/harmony/lottie/README.OpenSource +20 -0
- package/harmony/lottie/build-profile.json5 +8 -0
- package/harmony/lottie/hvigorfile.ts +1 -0
- package/harmony/lottie/index.ets +8 -0
- package/harmony/lottie/oh-package.json5 +14 -0
- package/harmony/lottie/src/main/cpp/CMakeLists.txt +9 -0
- package/harmony/lottie/src/main/cpp/LottieAnimationViewPackage.h +15 -0
- package/harmony/lottie/src/main/cpp/generated/RNOH/generated/BaseLottieReactNativePackage.h +78 -0
- package/harmony/lottie/src/main/cpp/generated/RNOH/generated/components/LottieAnimationViewJSIBinder.h +46 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/ComponentDescriptors.h +22 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/EventEmitters.cpp +46 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/EventEmitters.h +39 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/Props.cpp +43 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/Props.h +43 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/ShadowNodes.cpp +19 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/ShadowNodes.h +33 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/States.cpp +16 -0
- package/harmony/lottie/src/main/cpp/generated/react/renderer/components/lottie_react_native/States.h +20 -0
- package/harmony/lottie/src/main/ets/LottieAnimationTools.ets +21 -0
- package/harmony/lottie/src/main/ets/LottieAnimationView.ets +393 -0
- package/harmony/lottie/src/main/ets/LottieAnimationViewPackage.ets +26 -0
- package/harmony/lottie/src/main/ets/LottieCompositionCache.ets +30 -0
- package/harmony/lottie/src/main/ets/common/Animation.ts +43 -0
- package/harmony/lottie/src/main/ets/common/AnimationType.ets +50 -0
- package/harmony/lottie/src/main/ets/common/TextUtils.ets +18 -0
- package/harmony/lottie/src/main/ets/generated/components/LottieAnimationView.ts +181 -0
- package/harmony/lottie/src/main/ets/generated/components/ts.ts +5 -0
- package/harmony/lottie/src/main/ets/generated/index.ets +5 -0
- package/harmony/lottie/src/main/ets/generated/ts.ts +6 -0
- package/harmony/lottie/src/main/ets/generated/turboModules/ts.ts +5 -0
- package/harmony/lottie/src/main/module.json5 +9 -0
- package/harmony/lottie/src/main/resources/base/element/string.json +8 -0
- package/harmony/lottie/src/main/resources/en_US/element/string.json +8 -0
- package/harmony/lottie/src/main/resources/zh_CN/element/string.json +8 -0
- package/harmony/lottie/ts.ets +5 -0
- package/harmony/lottie.har +0 -0
- package/lib/commonjs/LottieAnimationViewNativeComponent.js +18 -0
- package/lib/commonjs/LottieAnimationViewNativeComponent.js.map +1 -0
- package/lib/commonjs/codegenUtils.js +2 -0
- package/lib/commonjs/codegenUtils.js.map +1 -0
- package/lib/commonjs/index.js +22 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/LottieAnimationViewNativeComponent.js +11 -0
- package/lib/module/LottieAnimationViewNativeComponent.js.map +1 -0
- package/lib/module/codegenUtils.js +2 -0
- package/lib/module/codegenUtils.js.map +1 -0
- package/lib/module/index.js +4 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/LottieAnimationViewNativeComponent.d.ts +44 -0
- package/lib/typescript/LottieAnimationViewNativeComponent.d.ts.map +1 -0
- package/lib/typescript/codegenUtils.d.ts +3 -0
- package/lib/typescript/codegenUtils.d.ts.map +1 -0
- package/lib/typescript/index.d.ts +4 -0
- package/lib/typescript/index.d.ts.map +1 -0
- package/package.json +138 -0
- package/src/LottieAnimationViewNativeComponent.ts +78 -0
- package/src/codegenUtils.ts +9 -0
- package/src/index.tsx +3 -0
|
@@ -0,0 +1,393 @@
|
|
|
1
|
+
// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
2
|
+
// Use of this source code is governed by a Apache-2.0 license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import { RNOHContext, RNViewBase } from '@rnoh/react-native-openharmony';
|
|
6
|
+
import lottie from '@ohos/lottie';
|
|
7
|
+
import { AnimationItem } from '@ohos/lottie';
|
|
8
|
+
import http from '@ohos.net.http';
|
|
9
|
+
import { colorFiltersItem, LOTTLE_STRING } from './common/AnimationType';
|
|
10
|
+
import { AnimationObject, layersItem } from './common/Animation';
|
|
11
|
+
import { LottieCompositionCache } from './LottieCompositionCache';
|
|
12
|
+
import { convertImageFolder } from './LottieAnimationTools';
|
|
13
|
+
import { getHashCode } from './common/TextUtils';
|
|
14
|
+
import { RNOHLogger } from "@rnoh/react-native-openharmony/ts";
|
|
15
|
+
import { RNC } from './generated';
|
|
16
|
+
/**
|
|
17
|
+
* @deprecated Use LottieAnimationView.NAME instead
|
|
18
|
+
*/
|
|
19
|
+
export const LOTTIE_TYPE: string = RNC.LottieAnimationView.NAME
|
|
20
|
+
|
|
21
|
+
@Component
|
|
22
|
+
export struct LottieAnimationView {
|
|
23
|
+
public static readonly NAME = RNC.LottieAnimationView.NAME
|
|
24
|
+
ctx!: RNOHContext;
|
|
25
|
+
tag: number = 0;
|
|
26
|
+
private logger!: RNOHLogger
|
|
27
|
+
@State descriptorWrapper: RNC.LottieAnimationView.DescriptorWrapper = {} as RNC.LottieAnimationView.DescriptorWrapper;
|
|
28
|
+
private unregisterDescriptorChangesListener?: () => void = undefined;
|
|
29
|
+
@State @Watch('onStateChanged') progress: number = 0;
|
|
30
|
+
@State @Watch('onStateChanged') speed: number = 1;
|
|
31
|
+
@State @Watch('onStateChanged') loop: boolean = true;
|
|
32
|
+
@State @Watch('onStateChanged') autoPlay: boolean = false;
|
|
33
|
+
@State @Watch('onStateChanged') cacheComposition: boolean = true;
|
|
34
|
+
private jsonData: AnimationObject | null = {} as AnimationObject;
|
|
35
|
+
private jsonDataHashCode: string = '';
|
|
36
|
+
private cleanupCommandCallback?: () => void = undefined;
|
|
37
|
+
private renderingSettings: RenderingContextSettings = new RenderingContextSettings(true);
|
|
38
|
+
private canvasRenderingContext: CanvasRenderingContext2D = new CanvasRenderingContext2D(this.renderingSettings);
|
|
39
|
+
private animateItem: AnimationItem | null = null;
|
|
40
|
+
private lottieCache = LottieCompositionCache.getInstance();
|
|
41
|
+
private animateKey: string | null = null;
|
|
42
|
+
private eventEmitter: RNC.LottieAnimationView.EventEmitter | undefined = undefined
|
|
43
|
+
|
|
44
|
+
aboutToAppear() {
|
|
45
|
+
// 创建EventEmitter实例,用于处理事件的订阅和触发
|
|
46
|
+
this.eventEmitter = new RNC.LottieAnimationView.EventEmitter(this.ctx.rnInstance, this.tag)
|
|
47
|
+
this.logger = this.ctx!.logger.clone(RNC.LottieAnimationView.NAME)
|
|
48
|
+
this.onDescriptorWrapperChange(this.ctx.descriptorRegistry.findDescriptorWrapperByTag<RNC.LottieAnimationView.DescriptorWrapper>(this.tag)!)
|
|
49
|
+
this.commandCallback();
|
|
50
|
+
this.subscribeToDescriptorChanges();
|
|
51
|
+
lottie.bindContext2dToCoordinator(this.canvasRenderingContext)
|
|
52
|
+
this.logger.info(`testlottie:${JSON.stringify(this.descriptorWrapper.props)}`)
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
private onDescriptorWrapperChange(descriptorWrapper: RNC.LottieAnimationView.DescriptorWrapper) {
|
|
56
|
+
this.descriptorWrapper = descriptorWrapper
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
aboutToDisappear() {
|
|
60
|
+
this.cleanupCommandCallback?.();
|
|
61
|
+
this.unregisterDescriptorChangesListener?.();
|
|
62
|
+
this.destroyAnimation();
|
|
63
|
+
if (this.animateKey) {
|
|
64
|
+
lottie.destroy(this.animateKey);
|
|
65
|
+
}
|
|
66
|
+
this.animateKey = null;
|
|
67
|
+
lottie.unbindContext2dFromCoordinator(this.canvasRenderingContext)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
subscribeToDescriptorChanges(): void {
|
|
71
|
+
this.unregisterDescriptorChangesListener = this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag,
|
|
72
|
+
(newDescriptor: object) => {
|
|
73
|
+
this.descriptorWrapper = (newDescriptor as RNC.LottieAnimationView.DescriptorWrapper);
|
|
74
|
+
this.onDescriptorChanged(true);
|
|
75
|
+
}
|
|
76
|
+
)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
onDescriptorChanged(change?: boolean): void {
|
|
80
|
+
if (this.descriptorWrapper.props) {
|
|
81
|
+
this.handleColorFilters();
|
|
82
|
+
this.updateWatchData();
|
|
83
|
+
change && this.parseSourceURL();
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onStateChanged(propName: string): void {
|
|
88
|
+
if (this.animateItem == null) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
switch (propName) {
|
|
92
|
+
case LOTTLE_STRING.progress:
|
|
93
|
+
this.setProgress();
|
|
94
|
+
break;
|
|
95
|
+
case LOTTLE_STRING.speed:
|
|
96
|
+
this.setSpeed();
|
|
97
|
+
break;
|
|
98
|
+
case LOTTLE_STRING.loop: {
|
|
99
|
+
this.animateItem.loop = this.loop;
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
case LOTTLE_STRING.autoPlay:
|
|
103
|
+
this.setAutoPlay();
|
|
104
|
+
break;
|
|
105
|
+
default:
|
|
106
|
+
break;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
onAnimationFinish(isCancelled: boolean): void {
|
|
111
|
+
this.eventEmitter!.emit("animationFinish", {isCancelled: isCancelled});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
onAnimationCancel(): void {
|
|
115
|
+
this.onAnimationFinish(true);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
onAnimationEnd(): void {
|
|
119
|
+
this.onAnimationFinish(false);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
cacheProcessing(data: string, isURL?: boolean): void {
|
|
123
|
+
const hashCode = getHashCode(data);
|
|
124
|
+
if (hashCode === this.jsonDataHashCode) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
if (this.descriptorWrapper.props.cacheComposition) {
|
|
128
|
+
const tempJsonObj = this.getCacheData(hashCode);
|
|
129
|
+
if (tempJsonObj) {
|
|
130
|
+
this.jsonData = tempJsonObj;
|
|
131
|
+
this.jsonDataHashCode = hashCode;
|
|
132
|
+
this.initAnimation();
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (isURL) {
|
|
137
|
+
this.request(data, hashCode);
|
|
138
|
+
} else {
|
|
139
|
+
this.updateJsonData(data, hashCode);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
parseSourceURL(): void {
|
|
144
|
+
if (!this.descriptorWrapper?.props) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
if (this.descriptorWrapper.props.sourceURL &&
|
|
148
|
+
this.descriptorWrapper.props.sourceURL.startsWith(LOTTLE_STRING.http)) {
|
|
149
|
+
this.cacheProcessing(this.descriptorWrapper.props.sourceURL, true);
|
|
150
|
+
} else {
|
|
151
|
+
this.descriptorWrapper.props.sourceJson && this.cacheProcessing(this.descriptorWrapper.props.sourceJson);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
request(url: string, hashCode?: string): void {
|
|
156
|
+
this.logger.debug('httpRequest.request url:', url);
|
|
157
|
+
const httpRequest = http.createHttp();
|
|
158
|
+
httpRequest.request(url, { header: { [LOTTLE_STRING.contentType]: LOTTLE_STRING.json } }, (err, data) => {
|
|
159
|
+
if (err == undefined && data != undefined) {
|
|
160
|
+
this.logger.debug('httpRequest.request success:', JSON.stringify(data));
|
|
161
|
+
const result: Object = data.result;
|
|
162
|
+
if (result) {
|
|
163
|
+
this.updateJsonData(result as string, hashCode);
|
|
164
|
+
}
|
|
165
|
+
} else {
|
|
166
|
+
this.logger.error('httpRequest.request error:', `errorCode: ${err?.code}`);
|
|
167
|
+
}
|
|
168
|
+
})
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
updateWatchData(): void {
|
|
172
|
+
this.progress = this.descriptorWrapper.props.progress;
|
|
173
|
+
this.speed = this.descriptorWrapper.props.speed;
|
|
174
|
+
this.loop = Boolean(this.descriptorWrapper.props.loop);
|
|
175
|
+
this.autoPlay = Boolean(this.descriptorWrapper.props.autoPlay);
|
|
176
|
+
this.cacheComposition = Boolean(this.descriptorWrapper.props.cacheComposition);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
updateJsonData(data: string, hashCode?: string): void {
|
|
180
|
+
try {
|
|
181
|
+
this.jsonData =
|
|
182
|
+
convertImageFolder(JSON.parse(data) as AnimationObject,
|
|
183
|
+
this.descriptorWrapper.props.imageAssetsFolder as string);
|
|
184
|
+
this.initAnimation();
|
|
185
|
+
this.setCacheData(this.jsonData as AnimationObject, hashCode);
|
|
186
|
+
} catch (e) {
|
|
187
|
+
this.logger.error('updateJsonData,source parse error');
|
|
188
|
+
this.jsonData = null;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
setCacheData(jsonObj: AnimationObject, key?: string): void {
|
|
193
|
+
if (key) {
|
|
194
|
+
this.lottieCache.set(key, jsonObj);
|
|
195
|
+
this.jsonDataHashCode = key;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
getCacheData(key: string): AnimationObject | null {
|
|
200
|
+
return this.lottieCache.get(key);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
initAnimation(): void {
|
|
204
|
+
if (this.jsonData == null) {
|
|
205
|
+
return;
|
|
206
|
+
}
|
|
207
|
+
this.loadAnimation();
|
|
208
|
+
this.setSpeed();
|
|
209
|
+
this.addEventFrameListener();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
destroyAnimation(): void {
|
|
213
|
+
if (this.animateItem == null) {
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
if (this.animateItem.isPaused === false) {
|
|
217
|
+
this.onAnimationEnd();
|
|
218
|
+
}
|
|
219
|
+
lottie.destroy(this.animateKey);
|
|
220
|
+
this.animateItem = null;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
loadAnimation(): void {
|
|
224
|
+
this.destroyAnimation();
|
|
225
|
+
this.animateKey = `${this.tag}${new Date().getTime()}`;
|
|
226
|
+
this.animateItem = lottie.loadAnimation({
|
|
227
|
+
container: this.canvasRenderingContext,
|
|
228
|
+
renderer: LOTTLE_STRING.canvas,
|
|
229
|
+
name: this.animateKey,
|
|
230
|
+
loop: Boolean(this.descriptorWrapper.props.loop),
|
|
231
|
+
autoplay: Boolean(this.descriptorWrapper.props.autoPlay),
|
|
232
|
+
animationData: this.jsonData
|
|
233
|
+
});
|
|
234
|
+
this.animateItem?.addEventListener(LOTTLE_STRING.DOMLoaded, () => {
|
|
235
|
+
try{
|
|
236
|
+
let upperResizeMode =
|
|
237
|
+
this.descriptorWrapper.props?.resizeMode?.replace(this.descriptorWrapper.props.resizeMode[0],
|
|
238
|
+
this.descriptorWrapper.props.resizeMode[0].toUpperCase())
|
|
239
|
+
this.eventEmitter!.emit("animationLoaded", {});
|
|
240
|
+
this.animateItem?.setContentMode(upperResizeMode);
|
|
241
|
+
this.onDescriptorChanged();
|
|
242
|
+
}catch(e) {
|
|
243
|
+
this.logger.error('DOMLoaded catch error:', e);
|
|
244
|
+
}
|
|
245
|
+
})
|
|
246
|
+
this.animateItem?.addEventListener(LOTTLE_STRING.data_failed, () => {
|
|
247
|
+
this.eventEmitter!.emit("animationFailure", {error: 'data_failed'});
|
|
248
|
+
})
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
handleColorFilters(): void {
|
|
252
|
+
const layersData: Array<layersItem> = this.jsonData?.layers ?? [];
|
|
253
|
+
const colorFiltersData: Array<colorFiltersItem> =
|
|
254
|
+
(this.descriptorWrapper.props.colorFilters ?? []) as Array<colorFiltersItem>;
|
|
255
|
+
for (const item of colorFiltersData) {
|
|
256
|
+
const index: number = layersData.findIndex((layersItem: layersItem) => layersItem?.nm === item?.keypath);
|
|
257
|
+
const color: Array<number> = this.getColorByColorFilters(item);
|
|
258
|
+
const isIndex: boolean = index !== (-1);
|
|
259
|
+
const isColor: boolean = color.length === 3;
|
|
260
|
+
if (isIndex && isColor) {
|
|
261
|
+
this.animateItem?.changeColor(color, index + 1);
|
|
262
|
+
this.logger.debug('colorFilters success:', item?.keypath);
|
|
263
|
+
} else {
|
|
264
|
+
this.logger.error('colorFilters fail:not find keyPath', item?.keypath);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
getColorByColorFilters(colorFiltersItem: colorFiltersItem): Array<number> {
|
|
270
|
+
const color: string = colorFiltersItem?.color;
|
|
271
|
+
if (color) {
|
|
272
|
+
const processColor: number = Number(color);
|
|
273
|
+
const r: number = (processColor >> 16) & 0xff;
|
|
274
|
+
const g: number = (processColor >> 8) & 0xff;
|
|
275
|
+
const b: number = processColor & 0xff;
|
|
276
|
+
this.logger.debug(`getColorByColorFilters, r=${r}, g=${g}, b=${b}`);
|
|
277
|
+
return [r, g, b];
|
|
278
|
+
}
|
|
279
|
+
this.logger.error('colorFilters fail:not find color', colorFiltersItem?.keypath);
|
|
280
|
+
return [];
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
setProgress(): void {
|
|
284
|
+
const frame = this.getAnimateFrame();
|
|
285
|
+
this.animateItem?.goToAndStop(frame, true);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
setSpeed(): void {
|
|
289
|
+
this.animateItem?.setSpeed(this.descriptorWrapper.props.speed);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
setAutoPlay(): void {
|
|
293
|
+
this.animateItem?.goToAndPlay(this.getAnimateFrame(), true);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
getAnimateFrame(): number {
|
|
297
|
+
const firstFrame: number = this.animateItem?.firstFrame ?? 0;
|
|
298
|
+
const totalFrames: number = this.animateItem?.totalFrames ?? 0;
|
|
299
|
+
return Math.ceil(firstFrame + this.descriptorWrapper.props.progress * totalFrames);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
addEventFrameListener(): void {
|
|
303
|
+
this.completeEvent();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
completeEvent(): void {
|
|
307
|
+
//动画播放结束且不再播放动画触发
|
|
308
|
+
this.animateItem?.addEventListener(LOTTLE_STRING.complete, () => {
|
|
309
|
+
this.onAnimationFinish(false);
|
|
310
|
+
})
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
commandCallback(): void {
|
|
314
|
+
this.cleanupCommandCallback = this.ctx.componentCommandReceiver.registerCommandCallback(
|
|
315
|
+
this.tag,
|
|
316
|
+
(command: string, args: object) => {
|
|
317
|
+
if (this.animateItem == null) {
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
switch (command) {
|
|
321
|
+
case LOTTLE_STRING.play:
|
|
322
|
+
this.play(args as number[]);
|
|
323
|
+
break;
|
|
324
|
+
case LOTTLE_STRING.reset:
|
|
325
|
+
this.reset();
|
|
326
|
+
break;
|
|
327
|
+
case LOTTLE_STRING.pause:
|
|
328
|
+
this.pause();
|
|
329
|
+
break;
|
|
330
|
+
case LOTTLE_STRING.resume:
|
|
331
|
+
this.resume();
|
|
332
|
+
break;
|
|
333
|
+
default:
|
|
334
|
+
this.logger.warn('not find command');
|
|
335
|
+
break;
|
|
336
|
+
}
|
|
337
|
+
})
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
play(args: number[]): void {
|
|
341
|
+
const startFrame = args[0];
|
|
342
|
+
const endFrame = args[1];
|
|
343
|
+
this.animateItem?.stop();
|
|
344
|
+
if (this.progress !== 0) {
|
|
345
|
+
this.progress = 0;
|
|
346
|
+
this.animateItem?.goToAndPlay(this.getAnimateFrame(), true);
|
|
347
|
+
return;
|
|
348
|
+
}
|
|
349
|
+
if (args.length > 1 && startFrame != -1 && endFrame != -1) {
|
|
350
|
+
if (startFrame > endFrame) {
|
|
351
|
+
this.animateItem?.setSegment(endFrame, startFrame);
|
|
352
|
+
if (this.descriptorWrapper.props.speed > 0) {
|
|
353
|
+
this.animateItem?.setDirection(-1);
|
|
354
|
+
}
|
|
355
|
+
} else {
|
|
356
|
+
this.animateItem?.setSegment(startFrame, endFrame);
|
|
357
|
+
if (this.descriptorWrapper.props.speed < 0) {
|
|
358
|
+
this.animateItem?.setDirection(-1);
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
this.animateItem?.play();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
reset(): void {
|
|
366
|
+
this.animateItem?.stop();
|
|
367
|
+
this.onAnimationEnd();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
pause(): void {
|
|
371
|
+
this.animateItem?.pause();
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
resume(): void {
|
|
375
|
+
if (this.animateItem?.isPaused) {
|
|
376
|
+
this.animateItem?.togglePause();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
resize(): void {
|
|
381
|
+
this.animateItem?.resize();
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
build() {
|
|
385
|
+
RNViewBase({ ctx: this.ctx, tag: this.tag }) {
|
|
386
|
+
Canvas(this.canvasRenderingContext)
|
|
387
|
+
.width('100%')
|
|
388
|
+
.height('100%')
|
|
389
|
+
.onReady(() => this.parseSourceURL())
|
|
390
|
+
.onAreaChange(() => this.resize())
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
2
|
+
// Use of this source code is governed by a Apache-2.0 license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import { RNOHPackage, ComponentBuilderContext } from '@rnoh/react-native-openharmony';
|
|
6
|
+
import type {DescriptorWrapperFactoryByDescriptorTypeCtx, DescriptorWrapperFactoryByDescriptorType} from '@rnoh/react-native-openharmony/ts';
|
|
7
|
+
import { RNC } from './generated/ts';
|
|
8
|
+
import { LottieAnimationView } from './LottieAnimationView'
|
|
9
|
+
|
|
10
|
+
@Builder
|
|
11
|
+
function buildLottieAnimationView(ctx: ComponentBuilderContext) {
|
|
12
|
+
LottieAnimationView({ ctx: ctx.rnComponentContext, tag: ctx.tag, })
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export class LottieAnimationViewPackage extends RNOHPackage {
|
|
16
|
+
createDescriptorWrapperFactoryByDescriptorType(ctx:
|
|
17
|
+
DescriptorWrapperFactoryByDescriptorTypeCtx):
|
|
18
|
+
DescriptorWrapperFactoryByDescriptorType {
|
|
19
|
+
return {
|
|
20
|
+
LottieAnimationView: (ctx) => new RNC.LottieAnimationView.DescriptorWrapper(ctx.descriptor)
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
createWrappedCustomRNComponentBuilderByComponentNameMap(): Map<string, WrappedBuilder<[ComponentBuilderContext]>> {
|
|
24
|
+
return new Map().set(LottieAnimationView.NAME, wrapBuilder(buildLottieAnimationView))
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
2
|
+
// Use of this source code is governed by a Apache-2.0 license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import HashMap from '@ohos.util.HashMap'
|
|
6
|
+
import { AnimationObject } from './common/Animation'
|
|
7
|
+
|
|
8
|
+
export class LottieCompositionCache {
|
|
9
|
+
private static readonly sInstance: LottieCompositionCache = new LottieCompositionCache()
|
|
10
|
+
private cache: HashMap<String, AnimationObject> = new HashMap()
|
|
11
|
+
|
|
12
|
+
public static getInstance(): LottieCompositionCache {
|
|
13
|
+
return LottieCompositionCache.sInstance
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
get(cacheKey: string): AnimationObject | null {
|
|
17
|
+
return cacheKey ? this.cache.get(cacheKey) : null
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
set(cacheKey: string, composition: AnimationObject): void {
|
|
21
|
+
if (cacheKey.length === 0) {
|
|
22
|
+
return
|
|
23
|
+
}
|
|
24
|
+
this.cache.set(cacheKey, composition)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
clear(): void {
|
|
28
|
+
this.cache.clear()
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
2
|
+
// Use of this source code is governed by a Apache-2.0 license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
export interface layersItem {
|
|
6
|
+
"ddd"?: number;
|
|
7
|
+
"ind"?: number;
|
|
8
|
+
"ty"?: number;
|
|
9
|
+
"nm"?: string;
|
|
10
|
+
"sr"?: number;
|
|
11
|
+
"ks": object;
|
|
12
|
+
"ao"?: number;
|
|
13
|
+
"shapes": Array<{ [key: string]: string | number }>
|
|
14
|
+
"ip"?: number;
|
|
15
|
+
"op"?: number;
|
|
16
|
+
"st"?: number;
|
|
17
|
+
"bm"?: number;
|
|
18
|
+
|
|
19
|
+
[key: string]: string | number | object | [];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export type AnimationObject = {
|
|
23
|
+
v: string
|
|
24
|
+
fr: number
|
|
25
|
+
ip: number
|
|
26
|
+
op: number
|
|
27
|
+
w: number
|
|
28
|
+
h: number
|
|
29
|
+
nm?: string
|
|
30
|
+
ddd?: number
|
|
31
|
+
assets: AnimationAssets[]
|
|
32
|
+
layers: layersItem[]
|
|
33
|
+
markers?: Object[]
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export type AnimationAssets = {
|
|
37
|
+
id: string
|
|
38
|
+
w: number
|
|
39
|
+
h: number
|
|
40
|
+
u: string
|
|
41
|
+
p: string
|
|
42
|
+
e: number
|
|
43
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
2
|
+
// Use of this source code is governed by a Apache-2.0 license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
import { ViewRawProps } from '@rnoh/react-native-openharmony'
|
|
6
|
+
|
|
7
|
+
export interface LottieViewState {}
|
|
8
|
+
|
|
9
|
+
export interface colorFiltersItem {
|
|
10
|
+
keypath: string;
|
|
11
|
+
color: string
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface LottieViewProps extends ViewRawProps {
|
|
15
|
+
resizeMode: string
|
|
16
|
+
renderMode: string
|
|
17
|
+
sourceName: string
|
|
18
|
+
sourceJson: string
|
|
19
|
+
sourceURL: string
|
|
20
|
+
imageAssetsFolder: string
|
|
21
|
+
progress: number
|
|
22
|
+
speed: number
|
|
23
|
+
loop: boolean
|
|
24
|
+
autoPlay: boolean
|
|
25
|
+
enableMergePathsAndroidForKitKatAndAbove: boolean
|
|
26
|
+
hardwareAccelerationAndroid: boolean
|
|
27
|
+
cacheComposition: boolean
|
|
28
|
+
colorFilters: Array<colorFiltersItem>
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export enum LOTTLE_STRING {
|
|
32
|
+
onStateChanged = 'onStateChanged',
|
|
33
|
+
progress = 'progress',
|
|
34
|
+
speed = 'speed',
|
|
35
|
+
loop = 'loop',
|
|
36
|
+
autoPlay = 'autoPlay',
|
|
37
|
+
onAnimationFinish = 'onAnimationFinish',
|
|
38
|
+
http = 'http',
|
|
39
|
+
contentType = 'Content-Type',
|
|
40
|
+
json = 'application/json',
|
|
41
|
+
canvas = 'canvas',
|
|
42
|
+
DOMLoaded = 'DOMLoaded',
|
|
43
|
+
colorFilters = 'colorFilters',
|
|
44
|
+
complete = 'complete',
|
|
45
|
+
play = 'play',
|
|
46
|
+
reset = 'reset',
|
|
47
|
+
pause = 'pause',
|
|
48
|
+
resume = 'resume',
|
|
49
|
+
data_failed = 'data_failed'
|
|
50
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
// Copyright (c) 2024 Huawei Device Co., Ltd. All rights reserved
|
|
2
|
+
// Use of this source code is governed by a Apache-2.0 license that can be
|
|
3
|
+
// found in the LICENSE file.
|
|
4
|
+
|
|
5
|
+
export function isEmpty(str: string | null | undefined): boolean {
|
|
6
|
+
return str == null || typeof str == 'undefined' || str.length == 0
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getHashCode(str: string): string {
|
|
10
|
+
let hash: number = 1315423911
|
|
11
|
+
let i: number
|
|
12
|
+
let ch: number
|
|
13
|
+
for (i = str.length - 1; i >= 0; i--) {
|
|
14
|
+
ch = str.charCodeAt(i)
|
|
15
|
+
hash ^= ((hash << 5) + ch + (hash >> 2))
|
|
16
|
+
}
|
|
17
|
+
return (hash & 0x7FFFFFFF).toString()
|
|
18
|
+
}
|