前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(七) -> JS动画(二)

【HarmonyOS之旅】基于ArkTS开发(三) -> 兼容JS的类Web开发(七) -> JS动画(二)

作者头像
枫叶丹
发布于 2025-03-04 00:51:23
发布于 2025-03-04 00:51:23
6300
代码可运行
举报
文章被收录于专栏:C++C++
运行总次数:0
代码可运行

1 -> 动画动效

通过设置插值器来实现动画效果。

说明

API Version 6 开始支持。

1.1 -> 创建动画对象

通过createAnimator创建一个动画对象,通过设置参数options来设置动画的属性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- test.hml -->
<div class="container">
  <div style="width: 300px;height: 300px;margin-top: 100px;background: linear-gradient(pink, purple);transform: translate({{translateVal}});">
  </div>
  <div class="row">
    <button type="capsule" value="play" onclick="playAnimation"></button>
  </div>
</div>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.css */
.container {
  width:100%;
  height:100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
button{
  width: 200px;
}
.row{
  width: 65%;
  height: 100px;
  align-items: center;
  justify-content: space-between;
  margin-top: 50px;
  margin-left: 260px;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.js */
import animator from '@ohos.animator';
export default {
  data: {
    translateVal: 0,
    animation: null
  },
  onInit() {},
  onShow(){
    var options = {
      duration: 3000,
      easing:"friction",
      delay:"1000",
      fill: 'forwards',
      direction:'alternate',
      iterations: 2,
      begin: 0,
      end: 180
    };//设置参数
    this.animation = animator.createAnimator(options)//创建动画
  },
  playAnimation() {
    var _this = this;
    this.animation.onframe = function(value) {
      _this.translateVal= value
    };
    this.animation.play();
  }
}

说明

  • 使用createAnimator创建动画对象时必须传入options参数。
  • begin插值起点,不设置时默认为0。
  • end插值终点,不设置时默认为1。

1.2 -> 添加动画事件和调用接口

animator支持事件和接口,可以通过添加frame、cancel、repeat、finish事件和调用update、play、pause、cancel、reverse、finish接口自定义动画效果。animator支持的事件和接口具体见动画中的createAnimator。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- test.hml -->
<div style="flex-direction: column;align-items: center;width: 100%;height: 100%;">
  <div style="width:200px;height: 200px;margin-top: 100px;background: linear-gradient(#b30d29, #dcac1b);
  transform: scale({{scaleVal}});"></div>
  <div style="width: {{DivWidth}};height: {{DivHeight}};margin-top: 200px;
  background: linear-gradient(pink, purple);margin-top: 200px;transform:translateY({{translateVal}});">
  </div>
  <div class="row">
    <button type="capsule" value="play" onclick="playAnimation"></button>
    <button type="capsule" value="update" onclick="updateAnimation"></button>
  </div>
  <div class="row1">
    <button type="capsule" value="pause" onclick="pauseAnimation"></button>
    <button type="capsule" value="finish" onclick="finishAnimation"></button>
  </div>
  <div class="row2">
    <button type="capsule" value="cancel" onclick="cancelAnimation"></button>
    <button type="capsule" value="reverse" onclick="reverseAnimation"></button>
  </div>
</div>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.css */
button{
  width: 200px;
}
.row{
  width: 65%;
  height: 100px;
  align-items: center;
  justify-content: space-between;
  margin-top: 150px;
  position: fixed;
  top: 52%;
  left: 120px;
}
.row1{
  width: 65%;
  height: 100px;
  align-items: center;
  justify-content: space-between;
  margin-top: 120px;
  position: fixed;
  top: 65%;
  left: 120px;
}
.row2{
  width: 65%;
  height: 100px;
  align-items: center;
  justify-content: space-between;
  margin-top: 100px;
  position: fixed;
  top: 75%;
  left: 120px;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.js */
import animator from '@ohos.animator';
import prompt from '@system.prompt';
export default {
  data: {
    scaleVal:1,
    DivWidth:200,
    DivHeight:200,
    translateVal:0,
    animation: null
  },
  onInit() {
    var options = {
      duration: 3000,
      fill: 'forwards',
      begin: 200,
      end: 270
    };
    this.animation = animator.createAnimator(options);
  },
  onShow() {
    var _this= this;
    //添加动画重放事件
    this.animation.onrepeat = function() {
      prompt.showToast({
        message: 'repeat'
      });
      var repeatoptions = {
        duration: 2000,
        iterations: 1,
         direction: 'alternate',
         begin: 180,
         end: 240
       };
        _this.animation.update(repeatoptions);
        _this.animation.play();
      };
  },
  playAnimation() {
    var _this= this;
    //添加动画逐帧插值回调事件
    this.animation.onframe = function(value) {
      _this. scaleVal= value/150,
      _this.DivWidth = value,
      _this.DivHeight = value,
      _this.translateVal = value-180
    };
    this.animation.play();
  },
  updateAnimation() {
    var newoptions = {
      duration: 5000,
      iterations: 2,
      begin: 120,
      end: 180
    };
    this.animation.update(newoptions);
    this.animation.play();//调用动画播放接口
  },
  pauseAnimation() {
    this.animation.pause();//调用动画暂停接口
  },
  finishAnimation() {
    var _this= this;
   //添加动画完成事件
    this.animation.onfinish = function() {
      prompt.showToast({
        message: 'finish'
      })
    };
    this.animation.finish(); //调用动画完成接口
  },
  cancelAnimation() {
    this.animation.cancel(); //调用动画取消接口
  },
  reverseAnimation() {
    this.animation.reverse(); //调用动画倒放接口
  }
}

说明

在调用update接口的过程中可以使用这个接口更新动画参数,入参与createAnimator一致。

2 -> 动画帧

2.1 -> 请求动画帧

请求动画帧时通过requestAnimationFrame函数逐帧回调,在调用该函数时传入一个回调函数。

runframe在调用requestAnimationFrame时传入带有timestamp参数的回调函数step,将step中的timestamp赋予起始的startTime。当timestamp与startTime的差值小于规定的时间时将再次调用requestAnimationFrame,最终动画将会停止。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- test.hml -->
<div class="container">
  <tabs onchange="changecontent">
    <tab-content>
      <div class="container">
        <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;">
          <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;">
          </canvas>
          <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};">
          </div>
        </stack>
        <button type="capsule" value="play" onclick="runframe"></button>
      </div>
    </tab-content>
  </tabs>
</div>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.css */
.container {
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}
button{
  width: 300px;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.js */
export default {
  data: {
    timer: null,
    left: 0,
    top: 0,
    flag: true,
    animation: null,
    startTime: 0,
  },
  onShow() {
    var test = this.$element("mycanvas");
    var ctx = test.getContext("2d");
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(300, 300);
    ctx.lineWidth = 5;
    ctx.strokeStyle = "red";
    ctx.stroke();
  },
  runframe() {
    this.left = 0;
    this.top = 0;
    this.flag = true;
    this.animation = requestAnimationFrame(this.step);
  },
  step(timestamp) {
    if (this.flag) {
      this.left += 5;
      this.top += 5;
      if (this.startTime == 0) {
        this.startTime = timestamp;
      }
      var elapsed = timestamp - this.startTime;
        if (elapsed < 500) {
          console.log('callback step timestamp: ' + timestamp);
          this.animation = requestAnimationFrame(this.step);
        }
      } else {
        this.left -= 5;
        this.top -= 5;
        this.animation = requestAnimationFrame(this.step);
      }
      if (this.left == 250 || this.left == 0) {
        this.flag = !this.flag
     }
    },
    onDestroy() {
      cancelAnimationFrame(this.animation);
    }
}

说明

requestAnimationFrame函数在调用回调函数时在第一个参数位置传入timestamp时间戳,表示requestAnimationFrame开始去执行回调函数的时刻。

2.2 -> 取消动画帧

通过cancelAnimationFrame函数取消逐帧回调,在调用cancelAnimationFrame函数时取消requestAnimationFrame函数的请求。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!-- test.hml -->
<div class="container">
  <tabs onchange="changecontent">
    <tab-content>
      <div class="container">
        <stack style="width: 300px;height: 300px;margin-top: 100px;margin-bottom: 100px;">
          <canvas id="mycanvas" style="width: 100%;height: 100%;background-color: coral;">
          </canvas>
          <div style="width: 50px;height: 50px;border-radius: 25px;background-color: indigo;position: absolute;left: {{left}};top: {{top}};">
          </div>
        </stack>
        <button type="capsule" value="play" onclick="runframe"></button>
      </div>
    </tab-content>
  </tabs>
</div>
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.css */
.container {
  flex-direction: column;
  justify-content: center;
  align-items: center;
  width: 100%;
  height: 100%;
}
button{
  width: 300px;
}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
/* test.js */
export default {
  data: {
    timer: null,
    left: 0,
    top: 0,
    flag: true,
    animation: null
  },
  onShow() {
    var test = this.$element("mycanvas");
    var ctx = test.getContext("2d");
    ctx.beginPath();
    ctx.moveTo(0, 0);
    ctx.lineTo(300, 300);
    ctx.lineWidth = 5;
    ctx.strokeStyle = "red";
    ctx.stroke();
  },
  runframe() {
    this.left = 0;
    this.top = 0;
    this.flag = true;
    this.animation = requestAnimationFrame(this.step);
  },
  step(timestamp) {
    if (this.flag) {
      this.left += 5;
      this.top += 5;
      this.animation = requestAnimationFrame(this.step);
    } else {
      this.left -= 5;
      this.top -= 5;
      this.animation = requestAnimationFrame(this.step);
    }
    if (this.left == 250 || this.left == 0) {
      this.flag = !this.flag
    }
  },
  onDestroy() {
    cancelAnimationFrame(this.animation);
  }
}

说明

在调用该函数时需传入一个具有标识id的参数。

感谢各位大佬支持!!!

互三啦!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
.NET性能优化-使用ValueStringBuilder拼接字符串
这一次要和大家分享的一个Tips是在字符串拼接场景使用的,我们经常会遇到有很多短小的字符串需要拼接的场景,在这种场景下及其的不推荐使用String.Concat也就是使用+=运算符。 目前来说官方最推荐的方案就是使用StringBuilder来构建这些字符串,那么有什么更快内存占用更低的方式吗?那就是今天要和大家介绍的ValueStringBuilder。
用户9127601
2022/06/09
5370
.NET性能优化-使用ValueStringBuilder拼接字符串
教妹学 Java 第 37 讲:字符串拼接
“哥,你让我看的《Java 开发手册》上有这么一段内容:循环体内,拼接字符串最好使用 StringBuilder 的 append() 方法,而不是 + 号操作符。这是为什么呀?”三妹疑惑地问。
沉默王二
2021/07/16
3170
C#中的字符串拼接技巧大汇总!
string.Format 是一种更传统的字符串格式化方法,适用于需要更复杂的格式化规则的场景。
郑子铭
2025/04/28
1190
C#中的字符串拼接技巧大汇总!
聊聊字符串拼接的哪一些事儿
​ 字符串对我编程人员来说是字符串时每天见面的常客,你不认识不熟悉他都不得行,字符串的拼接更是家常便饭,那么在实际开发过程中实现字符串的拼接有哪一些方式呢?咱们一起来聊聊,来交流沟通,学习一波。也许你会说,那也太简单了嘛,谁不会啊,哈哈,使用起来确实简单,但是不一定我们都使用的方式还有优秀的方式吗?
小小许
2020/01/15
5690
聊聊字符串拼接的哪一些事儿
Java 中拼接 String 的 N 种方式
Java 提供了拼接 String 字符串的多种方式,不过有时候如果我们不注意 null 字符串的话,可能会把 null 拼接到结果当中,很明显这不是我们想要的。
未读代码
2022/03/22
9900
Java 中拼接 String 的 N 种方式
没使用加号拼接字符串,面试官竟然问我为什么
小小白:主要是为了确保String对象中存储的值不会被改变,充分利用字符串常量池的优化策略,同时字符串对象的hashCode也不会被改变。如果String设计成可变的,那么自定义的类就可以通过集成String,重写其中的方法将其存储的值改变。如果String是可变的,将String类型变量作为参数传递的过程中,存储的将有可能会被改变,这样会导致安全隐患。
JavaQ
2020/03/31
1.1K0
在 for 循环中使用 "+" 进行字符串拼接,合适吗?
字符串,是 Java 中最常用的一个数据类型了。本文主要来介绍一下字符串拼接相关的知识。本文基于jdk1.8.0_181。
逆锋起笔
2020/03/12
3.1K0
在 for 循环中使用 "+" 进行字符串拼接,合适吗?
羞,Java 字符串拼接竟然有这么多姿势
我当时看到这条微信的第一感觉是:小菜你也太菜了吧,这都不知道为啥啊!我估计正在读这篇文章的你也会有同样的感觉。
沉默王二
2019/10/28
9020
Java字符串之性能优化
在程序中你可能时常会需要将别的类型转化成String,有时候可能是一些基础类型的值。在拼接字符串的时候,如果你有两个或者多个基础类型的值需要放到前面,你需要显式的将第一个值转化成String(不然的话像System.out.println(1+’a')会输出98,而不是”1a”)。当然了,有一组String.valueOf方法可以完成这个(或者是基础类型对应的包装类的方法),不过如果有更好的方法能少敲点代码的话,谁还会愿意这么写呢?
哲洛不闹
2018/09/18
4370
Java 字符串拼接方法及使用场景
訾博ZiBo
2025/01/06
850
不能用 + 拼接字符串? 这次我要吊打面试官!
好久没维护《吊打面试官》系列了,今天再来一篇,这次真的要吊打了,哈哈!(看往期吊打系列请在后台回复:吊打,我会陆续更新……)
Java技术栈
2019/12/23
7020
不能用 + 拼接字符串? 这次我要吊打面试官!
为什么 IDEA 建议去掉 StringBuilder,而要使用 “+” 拼接字符串?
虽然有差异,但是差异极小,考虑到执行了100000次,每次耗时的差异就更小了,而且程序执行有各种因素影响执行效率,可以认为耗时差不多。也可以多次执行对比耗时差异,也可以发现基本一致。
Spark学习技巧
2024/03/27
1720
为什么 IDEA 建议去掉 StringBuilder,而要使用 “+” 拼接字符串?
高效拼接字符串,你会用 “+” 还是StringBuilder.append?
在《阿里java开发手册(泰山版)》(提取码:hb6i)中,对于Java字符串的拼接有一条规则如下:
陈哈哈
2020/07/03
4.8K0
Java细节:字符串的拼接
工作日忙于项目的逻辑实现,周六有点时间,从书柜里拿出厚厚的英文版Thinking In Java,读到了字符串对象的拼接。参考着这本书做个翻译,加上自己思考的东西,写上这篇文章记录一下。
技术小黑屋
2018/09/04
1.1K0
关于Java里面的字符串拼接,你了解多少?
字符串拼接是我们日常开发中很常见的操作,虽然常见,但要是使用不当的的话,很有可能让你的程序处理效率降低一大半,所以我们有必要来重新了解一下Java里面的字符串操作。
我是攻城师
2018/07/23
5560
关于Java里面的字符串拼接,你了解多少?
Java String + 拼接字符串原理
很明确,上述代码输出的结果是:"111111222222",但是它工作原理是怎样的呢?
用户7886150
2021/04/27
8760
还在用StringBuilder进行字符串拼接?那你就OUT了
大部分人会这么做,但是我们发现里面有太重复的"," 和"+"了。感觉拼接不是很灵活。
Lvshen
2022/05/05
3470
还在用StringBuilder进行字符串拼接?那你就OUT了
java字符连接字符串数组_Java中连接字符串的最佳方法
这让我开始思考Java中连接字符串的不同方法,以及它们如何相互对抗。 这些是我要研究的方法:
用户7886150
2021/02/01
3.8K0
Go语言如何高效的进行字符串拼接(6种方式进行对比分析)
string是一个8位字节的集合,通常但不一定代表UTF-8编码的文本。string可以为空,但是不能为nil。string的值是不能改变的。
Golang梦工厂
2022/07/11
7200
Go语言如何高效的进行字符串拼接(6种方式进行对比分析)
.NET性能优化-复用StringBuilder
在之前的文章中,我们介绍了 dotnet 在字符串拼接时可以使用的一些性能优化技巧。比如:
InCerry
2022/11/14
3090
推荐阅读
相关推荐
.NET性能优化-使用ValueStringBuilder拼接字符串
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档