鸿蒙开发api12及以上支持pag动画步骤

41 阅读2分钟

话不多说: 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)?欢迎和我一起讨论