当前位置: 首页 > news >正文

开发指导—利用组件插值器动画实现 HarmonyOS 动效

一. 组件动画

在组件上创建和运行动画的快捷方式。具体用法请参考通用方法。

获取动画对象

通过调用 animate 方法获得 animation 对象,animation 对象支持动画属性、动画方法和动画事件。

<!-- xxx.hml --><div class="container">  <div id="content" class="box" onclick="Show"></div></div>
/* xxx.css */.container {  flex-direction: column;  justify-content: center;  align-items: center;  width: 100%;}.box{  width: 200px;  height: 200px;  background-color: #ff0000;  margin-top: 30px;}
/* xxx.js */export default {  data: {    animation: '',  },  onInit() {  },  onShow() {    var options = {      duration: 1500,    };    var frames = [      {        width:200,height:200,      },      {        width:300,height:300,      }    ];    this.animation = this.$element('content').animate(frames, options);  //获取动画对象  },  Show() {       this.animation.play();  }}

说明

● 使用 animate 方法时必须传入 Keyframes 和 Options 参数。

● 多次调用 animate 方法时,采用 replace 策略,即最后一次调用时传入的参数生效。

设置动画参数

在获取动画对象后,通过设置参数 Keyframes 设置动画在组件上的样式。

<!-- xxx.hml --><div class="container">   <div id="content" class="box" onclick="Show"></div></div>
/* xxx.css */.container {  flex-direction: column;  justify-content: center;  align-items: center;  width: 100%;  height: 100%;}.box{  width: 200px;  height: 200px;  background-color: #ff0000;  margin-top: 30px;}
/* xxx.js */export default {  data: {    animation: '',    keyframes:{},    options:{}  },  onInit() {    this.options = {      duration: 4000,    }    this.keyframes = [    {      transform: {        translate: '-120px -0px',           scale: 1,                rotate: 0        },           transformOrigin: '100px 100px',          offset: 0.0,         width: 200,          height: 200         },       {        transform: {                translate: '120px 0px',               scale: 1.5,               rotate: 90             },          transformOrigin: '100px 100px',          offset: 1.0,          width: 300,          height: 300         }        ]  },  Show() {    this.animation = this.$element('content').animate(this.keyframes, this.options)    this.animation.play()  }}

说明

● translate、scale 和 rtotate 的先后顺序会影响动画效果。

● transformOrigin 只对 scale 和 rtotate 起作用。

在获取动画对象后,通过设置参数 Options 来设置动画的属性。

<!-- xxx.hml --><div class="container">   <div id="content" class="box" onclick="Show"></div></div>
/* xxx.css */.container {  flex-direction: column;  justify-content: center;  align-items: center;  width: 100%;}.box{  width: 200px;  height: 200px;  background-color: #ff0000;  margin-top: 30px;}
/* xxx.js */export default {  data: {    animation: '',  },  onInit() {  },  onShow() {    var options = {              duration: 1500,              easing: 'ease-in',              delay: 5,              iterations: 2,              direction: 'normal',        };    var frames = [      {        transform: {          translate: '-150px -0px'        }      },      {        transform: {          translate: '150px 0px'        }      }    ];    this.animation = this.$element('content').animate(frames, options);  },  Show() {    this.animation.play();  }}

说明

direction:指定动画的播放模式。

normal: 动画正向循环播放。

reverse: 动画反向循环播放。

alternate:动画交替循环播放,奇数次正向播放,偶数次反向播放。

alternate-reverse:动画反向交替循环播放,奇数次反向播放,偶数次正向播放。

二.  插值器动画

动画动效

通过设置插值器来实现动画效果。(从 API Version 6 开始支持。)

创建动画对象

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

<!-- xxx.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>
/* xxx.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;}

// xxx.jsimport 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。

添加动画事件和调用接口

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

<!-- xxx.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>
/* xxx.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;}
// xxx.jsimport animator from '@ohos.animator';import promptAction from '@ohos.promptAction';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() {      promptAction.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() {      promptAction.showToast({        message: 'finish'      })    };    this.animation.finish(); //调用动画完成接口  },  cancelAnimation() {    this.animation.cancel(); //调用动画取消接口  },  reverseAnimation() {    this.animation.reverse(); //调用动画倒放接口  }}

说明

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

动画帧

请求动画帧

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

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

<!-- xxx.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>
/* xxx.css */.container {  flex-direction: column;  justify-content: center;  align-items: center;  width: 100%;  height: 100%;}button{  width: 300px;}
// xxx.jsexport 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 开始去执行回调函数的时刻。

取消动画帧

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

<!-- xxx.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>
/* xxx.css */.container {  flex-direction: column;  justify-content: center;  align-items: center;  width: 100%;  height: 100%;}button{  width: 300px;}
// xxx.jsexport 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 的参数。

相关文章:

开发指导—利用组件插值器动画实现 HarmonyOS 动效

一. 组件动画 在组件上创建和运行动画的快捷方式。具体用法请参考通用方法。 获取动画对象 通过调用 animate 方法获得 animation 对象&#xff0c;animation 对象支持动画属性、动画方法和动画事件。 <!-- xxx.hml --><div class"container"> <di…...

树莓派入门

目录 前言系统烧录使用官方烧录工具选择操作系统选择存储卡配置 Win32DiskImager 有屏幕树莓派开机树莓派关机无屏幕树莓派开机获取树莓派IP地址通过路由器获取共享网络方式获取给树莓派配置静态IP地址查找默认网关分盘给树莓派的IP地址修改树莓派DHCP配置文件 ssh登录 让树莓派…...

算法模型嵌入式 Mendix应用的开发示例

一、前言 根据埃森哲最新一项调查&#xff0c;2023年67%的企业持续加大在技术方面的投入&#xff0c;其中数据和AI应用是重中之重。AI在企业内部应用这个话题已经保持了十多年的热度&#xff0c;随着ChatGPT为代表的生成式AI技术的出现&#xff0c;这一话题迎来又一波的高潮。…...

如何使用Cygwin编译最新版的Redis源码,生成适用于Windows的Redis

文章目录 一、准备Cygwin环境二、下载Redis源码三、编译redis-7.2.01. 执行make命令2. 重新执行make命令3. 再次执行make命令4. 将编译后的可执行文件及依赖放到同一个文件夹5. 测试编译生成的可执行程序 四、换其他redis版本重新编译1. 编译redis-7.0.122. 编译redis-6.2.133.…...

Linux 修改SSH端口

如果防火墙&#xff0c;或防火墙已经开启&#xff0c;需要先开放2222端口 firewall-cmd --add-port2222/tcp --permanent --zonepublic firewall-cmd --reload编辑文件 vim /etc/ssh/sshd_config&#xff1a; #Port 22 Port 2222 # 打开注释&#xff0c;并修改为以下值 Clien…...

Redis经典问题:缓存穿透

&#xff08;笔记总结自《黑马点评》项目&#xff09; 一、产生原因 用户请求的数据在缓存中和数据库中都不存在&#xff0c;不断发起这样的请求&#xff0c;给数据库带来巨大压力。 常见的解决方式有缓存空对象和布隆过滤器。 二、缓存空对象 思路&#xff1a;当我们客户…...

DEFORMABLE DETR: DEFORMABLE TRANSFORMERS FOR END-TO-END OBJECT DETECTION (论文解析)

DEFORMABLE DETR: DEFORMABLE TRANSFORMERS FOR END-TO-END OBJECT DETECTION 摘要1 介绍2 相关工作3 重新审视 Transformers 和 DETR4 方法4.1 用于端到端目标检测的可变形transformer4.2 Deformable Detr的其他改进和变型5 实验5.1 和DETR 比较5.2 消融实验5.3 与最先进方法的…...

网络连接评分机制之NetworkFactory

在开机时,各个提供网络连接的对象需要向ConnectivityService注册自己,并把自己所提供的网络的分值告诉ConnectivityService。 为了ConnectivityService便于统一管理,每一个具备提供网络服务的对象都需要创建一个NetworkFactory的子类对象,并利用该对象注册自己,以及提供自…...

极致精细的jmeter+ant+jenkins 搭建接口自动化测试

一、jmeter 相信大家对jmeter并不陌生哈&#xff0c;如果没有安装和配置环境的小伙伴&#xff0c;可以直接找到我哈&#xff0c;我发给你。 二、ant 安装ant 第一步&#xff1a;下载ant http://ant.apache.org/ 第二步&#xff1a;配置ant window中设置ant环境变量&…...

Unity物体查找方式

参考资料 cUnity中使用GameObject.Find、Transform.Find查找GameObject_思月行云的博客-CSDN博客 GameObject.Find 通过名字或路径查找游戏对象。 GameObject.Find("GameObject"); GameObject.Find("GameObject/ChildGameObject); 使用规范: 1.无法查找隐藏…...

【Spring容器的启动流程】

Spring容器的启动流程主要分为以下几个步骤&#xff1a; 加载配置文件&#xff1a;Spring容器会从指定的配置文件中读取配置信息&#xff0c;包括bean的定义、依赖关系、AOP切面等。 创建容器&#xff1a;Spring容器启动后会创建一个容器实例&#xff0c;容器负责管理bean的生…...

Python---字符串

字符串特点 1. 只可以存储字符串 2. 长度任意 (取决于内存大小) 3. 支持下标索引 4. 允许重复字符串存在 5. 不可以修改 (增加或删除元素等) 6. 支持for和while循环 字符串的下标索引 # 字符串的下标索引 从前向后&#xff0c;下标从0开始 从后向前&#xff0c;下标从-1开始…...

MySQL数据 - 索引

MySQL数据库 - 索引 1:什么是数据库索引?2:都有哪些类型的索引呢?3:MySQL数据库每种索引的底层实现原理,每种索引为什么这么实现?4:上面索引实现基本上是B+树,为什么不用别的数据结构呢?4-1:那为什么不是二叉树呢?4-2:为什么不是红黑树呢?4-3:为什么不是哈希索引…...

长安链BaaS服务平台调研

目录 一、菜单功能二、其他说明2.1、服务平台的部署方式2.2、链本身2.3、建链流程2.4、支持连接已部署的链2.5、链治理投票2.6、支持动态节点操作2.7、支持应用 长安链ChainMaker管理平台文档地址&#xff1a;https://docs.chainmaker.org.cn 一、菜单功能 菜单子菜单/功能点…...

怎么关闭php错误提示?两者方法分享

PHP程序员在开发过程中经常会遇到各种错误。为了方便查错&#xff0c;PHP默认会输出错误提示。但在生产环境中&#xff0c;这些错误提示信息不仅可能暴露你的代码结构&#xff0c;还会影响网站的性能和安全性。因此&#xff0c;关闭 PHP 的错误提示信息是一个很有必要并且很简单…...

Android Aidl跨进程通讯(三)--进阶使用

学更好的别人&#xff0c; 做更好的自己。 ——《微卡智享》 本文长度为2478字&#xff0c;预计阅读6分钟 前言 Android的AIDL使用和异常报错都已经介绍过了&#xff0c;今天这篇还是在原来的Demo基础上加入几个AIDL的进阶使用方法。 】 AIDL进阶使用 微卡智享 in,out,inout的使…...

vue.js+nodejs家庭个人理财收支管理系统5x6nf

本收支管理系统以vue.js作为框架&#xff0c;nodejs语言&#xff0c;B/S模式以及MySql作为后台运行的数据库。本系统主要包括以下功能模块&#xff1a;用户管理、收入分类、支出分类、每日收入、每日支出等模块。 本文的组织结构如下&#xff1a; 1、绪论。综述了本文的研究背景…...

怎样去掉win11快捷方式的小箭头

前有创造注册表新值的方法,现在有了注册表加文件的方法 开始 先下载这个文件,里面有要用到的信息 下载 保存文件到电脑,并解压 有两个文件, 一个是 Remove_shortcut_arrow_icon.reg 一个是blank.ico 把第二个文件移动到 C:\Windows 文件夹, 然后点击打开文件, 如果提示是…...

Django项目如何配置日志文件信息

1、以dict的方式配置在settings.py中 # 日志文件简单配置LOGGING {"version": 1,"disable_existing_loggers": False,"handlers": {"file": {"level": "DEBUG","class": "logging.FileHandler&…...

遇到一个异步任务后是否会直接加入到异步队列当中

在javascript中&#xff0c;异步任务不会立即加入到异步队列&#xff08;任务队列&#xff09;中&#xff0c;而是根据不同的异步操作类型和执行环境&#xff0c;将对应的回调函数函数或事件加入到不同的队列中 javascript中常见的异步操作包括&#xff1a; 定时器&#xff1…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

项目部署到Linux上时遇到的错误(Redis,MySQL,无法正确连接,地址占用问题)

Redis无法正确连接 在运行jar包时出现了这样的错误 查询得知问题核心在于Redis连接失败&#xff0c;具体原因是客户端发送了密码认证请求&#xff0c;但Redis服务器未设置密码 1.为Redis设置密码&#xff08;匹配客户端配置&#xff09; 步骤&#xff1a; 1&#xff09;.修…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)

macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 &#x1f37a; 最新版brew安装慢到怀疑人生&#xff1f;别怕&#xff0c;教你轻松起飞&#xff01; 最近Homebrew更新至最新版&#xff0c;每次执行 brew 命令时都会自动从官方地址 https://formulae.…...

淘宝扭蛋机小程序系统开发:打造互动性强的购物平台

淘宝扭蛋机小程序系统的开发&#xff0c;旨在打造一个互动性强的购物平台&#xff0c;让用户在购物的同时&#xff0c;能够享受到更多的乐趣和惊喜。 淘宝扭蛋机小程序系统拥有丰富的互动功能。用户可以通过虚拟摇杆操作扭蛋机&#xff0c;实现旋转、抽拉等动作&#xff0c;增…...