话不多说:
1、准备工作
(1)导库:"@ohos/libpag": "1.0.2"
(2)在资源目录放pag动画文件
2、组件直接拿去吧,注意!!SizeUtils、XLogUtil删掉就可以,对项目没影响
import { common } from '@kit.AbilityKit';
import { newPAGFile, newPAGView, newPAGComposition } from '@ohos/libpag';
import { PAGScaleMode } from '@ohos/libpag';
import prompt from '@ohos.prompt';
import { SizeUtils } from '../../common/Utils/SizeUtils'
import { XLogUtil } from "../Utils/XLogUtil"
const Tag = "PagComponentView"
enum EnumPagPlayState {
ePagPlayNull,
ePagPlayPlaying,
ePagPlayPause,
ePagPlayComplete,
ePagPlayStop
};
@Component
export struct PagComponentView {
private PAGFile = new newPAGFile();
private PAGView = new newPAGView();
private xComponentContext: PagComponentContext | undefined = undefined;
@State currentStatus: string = "init";
@State isPause: boolean = true;
@State repeateCount: string = ''
@State currentFrame: string = " "
@State isPlaying: string = " "
private componentIndex: number = 0
private pagPath: Array<string> = []
@State startFrame: string = '';
private xcomponentId: string = 'xcomponentId' + (Math.random() * 10000);
private pagCompoition: newPAGComposition | undefined = undefined;
@State scaleMode: string = " "
private dTime: number = 0;
private delDuration: number = 0;
@State showScaleMode: boolean = true;
@State showComposition: boolean = true;
@State random: number = 0;
@State maxFrameRate: string = " "
@State getPath: string = " "
@State getProgress: string = " "
@State getRepeatCount: string = " "
@State playCount: number = 1;
@State pauseCount: number = 1;
@Prop @Watch('closePlayer') closePlay: boolean = false;
buildComposition(): void {
let context = getContext(this) as common.UIAbilityContext;
let filePath = context.resourceDir;
if (this.pagPath.length > 1) {
this.showScaleMode = false;
this.pagCompoition!.init(0, 0);
this.pagPath.forEach(item => {
this.PAGFile.loadFromPath(filePath + '/' + item);
this.PAGFile.setStartTime(this.dTime);
let duration = this.PAGFile.duration();
this.dTime += duration;
this.pagCompoition!.addLayerAt(0);
this.PAGView.setComposition();
})
} else {
this.showComposition = false;
this.PAGView.setPath(filePath + '/' + this.pagPath[0]);
}
this.PAGView.setSurface();
this.PAGView.freeCache();
if (this.pagPath.length > 1) {
this.PAGView.setMatrix(0.8, 0, 100, 0, 0.8, 20);
let pagMatrix = this.PAGView.matrix();
pagMatrix.getScaleX();
pagMatrix.getScaleY();
pagMatrix.getSkewX();
pagMatrix.getSkewY();
pagMatrix.getTranslateX();
pagMatrix.getTranslateY();
XLogUtil.debug(Tag, 'getScaleX ' + JSON.stringify(pagMatrix.getScaleX()));
XLogUtil.debug(Tag, 'getSkewX ' + JSON.stringify(pagMatrix.getSkewX()));
XLogUtil.debug(Tag, 'getTranslateX ' + JSON.stringify(pagMatrix.getTranslateX()));
XLogUtil.debug(Tag, 'getSkewY ' + JSON.stringify(pagMatrix.getSkewY()));
XLogUtil.debug(Tag, 'getScaleY ' + JSON.stringify(pagMatrix.getScaleY()));
XLogUtil.debug(Tag, 'getTranslateY ' + JSON.stringify(pagMatrix.getTranslateY()));
}
}
aboutToAppear(): void {
this.pagCompoition = new newPAGComposition(this.xcomponentId);
console.info('aboutToAppear');
// this.isPause = true;
// const state = this.PAGView.getState();
// if (state === EnumPagPlayState.ePagPlayPause) {
// this.PAGView.resume();
// } else {
// this.PAGView.setRepeatCount(Number(this.repeateCount));
// this.PAGView.setProgress(Number(this.startFrame));
// this.PAGView.play();
// this.PAGView.flush();
// }
}
closePlayer() {
this.PAGView.stop();
}
removeLayerFuc(index = 0, isWhole = false): void {
if (isWhole) {
this.dTime = 0;
} else {
const num: number = this.pagCompoition?.numChildren() as number;
this.dTime = 0;
for (let i = num - 1; i >= 0; i--) {
if (i === index) {
continue;
}
this.pagCompoition?.getLayerAt(i);
this.PAGFile.setStartTime(this.dTime);
this.dTime += this.PAGFile.duration();
this.pagCompoition?.removeLayerAt(i);
this.pagCompoition?.addLayerAt(i);
}
this.pagCompoition?.removeLayerAt(index);
}
}
/**
* 页面销毁时释放动画资源
*/
aboutToDisappear(): void {
this.PAGView.stop();
console.info('aboutToDisappear');
}
@Builder
scaleModeBuilder() {
Row() {
Button("$r('app.string.Zoom_mode_None')")
.onClick(() => {
this.PAGView.setScaleMode(PAGScaleMode.None);
})
Button("$r('app.string.Zoom_mode_Stretch')")
.onClick(() => {
this.PAGView.setScaleMode(PAGScaleMode.Stretch);
})
}.margin({ top: 5 })
Row() {
Button("$r('app.string.Zoom_mode_LetterBox')")
.onClick(() => {
this.PAGView.setScaleMode(PAGScaleMode.LetterBox);
})
Button("$r('app.string.Zoom_mode_Zoom')")
.onClick(() => {
this.PAGView.setScaleMode(PAGScaleMode.Zoom);
})
}.margin({ top: 5 })
Row() {
Button(this.scaleMode)
.onClick(() => {
this.scaleMode = " "
this.scaleMode = this.scaleMode + ': ' + this.PAGView.scaleMode();
})
Button(this.getRepeatCount)
.onClick(() => {
this.getRepeatCount = " "
this.getRepeatCount = this.getRepeatCount + ' : ' + this.PAGView.repeatCount();
})
}.margin({ top: 5 })
Row() {
Button(this.getPath)
.onClick(() => {
this.getPath = " "
this.getPath = this.getPath + ': ' + this.PAGView.getPath()
})
}.margin({ top: 5 })
}
@Builder
compositionBuilder() {
Row() {
Button("$r('app.string.Clear_layer')")
.onClick(() => {
if (this.pagCompoition!.numChildren() > 0) {
this.pagCompoition!.numChildren();
this.pagCompoition!.getLayerAt(0);
this.pagCompoition!.removeLayer();
this.delDuration = this.PAGFile.duration();
this.pagCompoition!.numChildren();
this.PAGView.stop();
this.PAGView.setComposition();
}
})
Button("$r('app.string.Add_layer')")
.onClick(() => {
this.PAGView.stop();
let context = getContext(this) as common.UIAbilityContext;
let filePath = context.resourceDir;
if (this.random % 2 == 0) {
this.PAGFile.loadFromPath(filePath + '/18.pag');
} else {
this.PAGFile.loadFromPath(filePath + '/13.pag');
}
this.random++;
const duration = this.PAGFile.duration();
this.dTime -= this.delDuration;
this.PAGFile.setStartTime(this.dTime);
this.dTime += duration;
this.pagCompoition!.addLayerAt(0);
let num = this.pagCompoition!.numChildren();
this.PAGView.setComposition();
this.delDuration = 0;
})
}.margin({ top: 5 })
Row() {
Button("$r('app.string.Clear_specified_layer')")
.onClick(() => {
this.PAGView.stop();
const num: number = this.pagCompoition?.numChildren() as number;
const index = Math.floor(num / 2);
this.removeLayerFuc(index);
this.PAGView.setComposition();
})
Button("$r('app.string.Clear_all_layers')")
.onClick(() => {
this.pagCompoition!.removeAllLayers();
this.PAGView.stop();
this.PAGView.setComposition();
this.dTime = 0;
})
}.margin({ top: 5 })
Row() {
if (this.playCount === 1) {
Button("$r('app.string.Add_playback_and_repeat_monitoring')")
.onClick(() => {
this.playCount++;
// 添加动画播放监听
let playFuc = (state: number) => {
XLogUtil.debug(Tag, `PAGView.play state=====${state}`)
prompt.showToast({
message: " ",
duration: 1000,
bottom: 100
})
}
this.PAGView.addPlayStateListener(playFuc);
// 添加重复监听
let RepeatCountFuc = (RepeatCount: number) => {
XLogUtil.debug(Tag, `PAGView.RepeatCount state=====${RepeatCount}`)
prompt.showToast({
message: " ",
duration: 1000,
bottom: 100
})
}
this.PAGView.addRepeatCountListener(RepeatCountFuc);
})
} else {
Button("$r('app.string.Add_playback_and_repeat_monitoring')", { stateEffect: false })
}
if (this.pauseCount === 1) {
Button("$r('app.string.Add_pause_listening')")
.onClick(() => {
this.pauseCount++;
// 添加动画更新监听
let CurrentFrame = (CurrentFrame: number) => {
XLogUtil.debug(Tag, `PAGView.CurrentFrame state=====${CurrentFrame}`)
}
this.PAGView.addCurrentFrameListener(CurrentFrame);
// 添加动画暂停监听
let pauseFuc = (state: number) => {
XLogUtil.debug(Tag, `PAGView.pauseFuc state=====${state}`)
prompt.showToast({
message: " ",
duration: 1000,
bottom: 100
})
}
this.PAGView.addPlayStateListener(pauseFuc);
})
} else {
Button("$r('app.string.Add_pause_listening')", { stateEffect: false })
}
}.margin({ top: 5 })
Row() {
Button("$r('app.string.Add_pause_listening')").onClick(() => {
// 添加动画停止监听
let stopFuc = (state: number) => {
XLogUtil.debug(Tag, `PAGView.stop state=====${state}`)
prompt.showToast({
message: " ",
duration: 1000,
bottom: 100
})
}
this.PAGView.addPlayStateListener(stopFuc);
})
Button("$r('app.string.Remove_listening')")
.onClick(() => {
// 移除重复监听
this.PAGView.removeRepeatCountListener();
// 移除动画更新监听
this.PAGView.removeCurrentFrameListener();
// 移除动画播放监听
this.PAGView.removePlayStateListener();
// 移除动画暂停监听
let pauseFuc = (state: number) => {
XLogUtil.debug(Tag, `PAGView.pauseFuc state=====${state}`)
}
this.PAGView.addPlayStateListener(pauseFuc);
// 移除动画停止监听
let stopFuc = (state: number) => {
XLogUtil.debug(Tag, `PAGView.stop state=====${state}`)
}
this.PAGView.addPlayStateListener(stopFuc);
this.playCount = 1;
this.pauseCount = 1;
})
}.margin({ top: 5 })
}
build() {
Column() {
Column({ space: 10 }) {
XComponent({
id: `${this.xcomponentId}`,
type: XComponentType.SURFACE,
libraryname: 'native_libpag'
})
.onLoad((xComponentContext) => {
this.PAGView.init(this.xcomponentId);
this.xComponentContext = xComponentContext as PagComponentContext;
this.currentStatus = "index";
this.buildComposition();
})
.onDestroy(() => {
XLogUtil.debug(Tag, 'onDestroy');
})
.id("xcomponent" + this.componentIndex)
.backgroundColor('white')
}
.onClick(() => {
})
.width(SizeUtils.realSize(130))
.height(SizeUtils.realSize(130))
.onAppear(() => {
this.isPause = true;
const state = this.PAGView.getState();
if (state === EnumPagPlayState.ePagPlayPause) {
this.PAGView.resume();
} else {
this.PAGView.setRepeatCount(Number(this.repeateCount));
this.PAGView.setProgress(Number(this.startFrame));
this.PAGView.play();
this.PAGView.flush();
}
})
}
}
getResourceString(resourceName:string) {
return getContext().resourceManager.getStringByNameSync(resourceName)
}
}
export default interface PagComponentContext {
drawPattern(): void;
getStatus(): PagComponentContextStatus;
};
interface PagComponentContextStatus {
hasDraw: boolean,
hasChangeColor: boolean,
};
3、使用步骤:
PagComponentView({
closePlay: false,
componentIndex: 1,
pagPath: ['boll_bmp.pag']
})
4、这都不支持一下作者v(llvy077)?欢迎和我一起讨论