HarmonyOS 用什么方式可以实现直播点赞的效果

HarmonyOS
1天前
浏览
收藏 0
回答 1
待解决
回答 1
按赞同
/
按时间
shlp

参考示例:

/**
 * 点赞动画效果组件
 */
const NUMBER_OF_ITEMS = 20;

/**
 * 动画相关参数
 */
const MIN_ANM_DURATION = 120;
const MAX_ANM_DURATION = 180;

/**
 * 表情图片左右偏移距离
 */
const MIN_OFFSET_X = -1;
const MAX_OFFSET_X = 5;

@Entry
@Component
struct Index {
  @State num: number = 0

  build() {
    Column() {
      Image($r('app.media.icon'))
        .width(36)
        .height(36)
        .onClick(() => {
          this.num++
        })
      FloatLikeView({ clickSum: this.num })
    }.margin({
      top: 500,
      left: 200,
      bottom: 0,
      right: 0
    })
  }
}

@Component
export struct FloatLikeView {
  uiContext: UIContext | undefined = undefined;
  /**
   * 动态图片资源
   */
  private images: Array<Resource> = [$r('app.media.icon'), $r('app.media.icon'), $r('app.media.icon'),
    $r('app.media.icon'), $r('app.media.icon'), $r('app.media.icon'), $r('app.media.icon'),
    $r('app.media.icon'), $r('app.media.icon'), $r('app.media.icon'), $r('app.media.icon'),
    $r('app.media.icon'), $r('app.media.icon'), $r('app.media.icon')];
  @State scaleArray: Array<number> = [];
  @State offXArray: Array<number> = [];
  @State offYArray: Array<number> = [];
  @State opacityArray: Array<number> = [];
  @State imageViews: Array<number> = [];
  @State flag: Array<boolean> = [];
  @Prop @Watch('startAnimation') clickSum: number = 0;

  aboutToAppear(): void {
    this.uiContext = this.getUIContext?.();
    for (let i = 0; i < NUMBER_OF_ITEMS; i++) {
      this.imageViews.push(i);
      this.opacityArray.push(0)
      this.offXArray.push(0)
      this.offYArray.push(0)
      this.scaleArray.push(0)
      this.flag.push(false)
    }
  }

  build() {

    Stack() {
      ForEach(this.imageViews, (image: number, index: number) => {
        Image(this.images[image % this.images.length])
          .objectFit(ImageFit.Cover)
          .width(36)
          .height(36)
          .opacity(this.opacityArray[index])
          .scale({ x: this.scaleArray[index], y: this.scaleArray[index] })
          .offset({
            x: this.offXArray[index],
            y: this.offYArray[index]
          })
      }, (image: Resource) => `${image.id}`)
    }
  }

  startAnimation() {
    this.clickAnimation()
  }

  /**
   * 点赞动画
   * 0, 1.18, 0.86, 1
   */
  clickAnimation() {
    if (!this.uiContext) {
      return;
    }
    let index = getRandomInt(0, NUMBER_OF_ITEMS);
    index = index >= NUMBER_OF_ITEMS ? 0 : index;
    while (this.flag[index] === true) {
      index = getRandomInt(0, NUMBER_OF_ITEMS);
      index = index >= NUMBER_OF_ITEMS ? 0 : index;
    }
    this.flag[index] = true;
    this.uiContext.keyframeAnimateTo({
      iterations: 1, onFinish: () => {
        this.flag[index] = false;
      }
    }, [
      {
        duration: 1,
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 0;
          this.opacityArray[index] = 0;
          this.offYArray[index] = 0;
          this.offXArray[index] = 0;
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 0.3;
          this.opacityArray[index] = 0.5;
          this.offYArray[index] = -15;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 0.5;
          this.opacityArray[index] = 0.8;
          this.offYArray[index] = -30;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 0.6;
          this.opacityArray[index] = 0.9;
          this.offYArray[index] = -45;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 0.86;
          this.opacityArray[index] = 1.0;
          this.offYArray[index] = -60;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1.0;
          this.opacityArray[index] = 0.9;
          this.offYArray[index] = -75;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1.0;
          this.opacityArray[index] = 0.8;
          this.offYArray[index] = -90;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1.0;
          this.opacityArray[index] = 0.75;
          this.offYArray[index] = -105;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1.0;
          this.opacityArray[index] = 0.7;
          this.offYArray[index] = -120;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1;
          this.opacityArray[index] = 0.6;
          this.offYArray[index] = -135;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1;
          this.opacityArray[index] = 0.5;
          this.offYArray[index] = -150;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1;
          this.opacityArray[index] = 0.3;
          this.offYArray[index] = -165;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1;
          this.opacityArray[index] = 0.2;
          this.offYArray[index] = -180;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1;
          this.opacityArray[index] = 0.1;
          this.offYArray[index] = -195;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
      {
        duration: getRandomInt(MIN_ANM_DURATION, MAX_ANM_DURATION),
        curve: Curve.Smooth,
        event: () => {
          this.scaleArray[index] = 1;
          this.opacityArray[index] = 0;
          this.offYArray[index] = -210;
          this.offXArray[index] = getRandomInt(MIN_OFFSET_X, MAX_OFFSET_X);
        }
      },
    ])

  }
}

function getRandomInt(min: number, max: number): number {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}
分享
微博
QQ
微信
回复
1天前
相关问题
HarmonyOS 动画实现方案
81浏览 • 1回复 待解决
关于实现图文混排几种方式优劣
536浏览 • 1回复 待解决
arkts 什么时候可以实现模糊效果
3145浏览 • 1回复 待解决
请问什么接口可以实现定时任务?
1731浏览 • 0回复 待解决
HarmonyOS 如何实现直播功能?
44浏览 • 1回复 待解决
HarmonyOS 帧动画什么实现
28浏览 • 1回复 待解决
是否可以实现滚动锚定效果
862浏览 • 1回复 待解决
HarmonyOS 有没有提供可以直播sdk
89浏览 • 1回复 待解决
hdc hilog 可以抓取日志命令是什么
3672浏览 • 1回复 待解决
在应用内埋采集数据方式
538浏览 • 1回复 待解决