Guía de desarrollo: uso de animación de componentes e interpoladores para implementar la animación de HarmonyOS

1. Animación de componentes

Acceso directo para crear y ejecutar animaciones en componentes. Consulte el método general para un uso específico .

Obtener objeto de animación

El objeto de animación se obtiene llamando al método animate, y el objeto de animación admite propiedades de animación, métodos de animación y eventos de animación.

<!-- 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();  }}

ilustrar

● Se deben pasar los parámetros de fotogramas clave y opciones cuando se utiliza el método de animación.

● Cuando el método animado se llama varias veces, se adopta la estrategia de reemplazo, es decir, los parámetros pasados ​​durante la última llamada entran en vigor.

Establecer parámetros de animación

Después de obtener el objeto de animación, establezca el estilo de la animación en el componente configurando el parámetro Fotogramas clave.

<!-- 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()  }}

ilustrar

● El orden de traducción, escala y rotación afectará el efecto de animación.

● transformOrigin sólo funciona a escala y rtotate.

Después de obtener el objeto de animación, configure las propiedades de la animación configurando el parámetro Opciones.

<!-- 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();  }}

ilustrar

dirección: especifica el modo de reproducción de la animación.

normal: la animación avanza.

inversa: la animación se reproduce en bucle inverso.

alternativo: la animación se reproduce alternativamente en un bucle, avanzando hacia adelante para números impares y hacia atrás para números pares.

alternativo-inverso: la animación se reproduce en un bucle alternativo en direcciones inversas, con reproducciones inversas con números impares y reproducciones hacia adelante con números pares.

2. Animación del interpolador

Efectos de animación

Los efectos de animación se logran configurando interpoladores. (Compatible a partir de la versión 6 de API).

Crear objetos animados

Cree un objeto de animación a través de createAnimator y establezca las propiedades de la animación configurando opciones de parámetros.

<!-- 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();  }}

ilustrar

● Cuando se utiliza createAnimator para crear un objeto de animación, se debe pasar el parámetro de opciones.

● comenzar el punto de inicio de la interpolación; el valor predeterminado es 0 si no se establece.

● end es el punto final de la interpolación. Si no se establece, el valor predeterminado es 1.

Agregar eventos de animación e interfaces de llamadas.

Animator admite eventos e interfaces. Puede personalizar los efectos de animación agregando fotogramas, cancelando, repitiendo y finalizando eventos y llamando a las interfaces de actualización, reproducción, pausa, cancelación, reversión y finalización. Para obtener detalles sobre los eventos e interfaces admitidos por Animator, consulte createAnimator en animación .

<!-- 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(); //调用动画倒放接口  }}

ilustrar

En el proceso de llamar a la interfaz de actualización, puede utilizar esta interfaz para actualizar los parámetros de la animación, de forma coherente con los involucrados en createAnimator.

Cuadros de animación

Solicitar fotogramas de animación

Al solicitar cuadros de animación, vuelva a llamar cuadro por cuadro a través de la función requestAnimationFrame y pase una función de devolución de llamada cuando llame a esta función.

Cuando el runframe llama a requestAnimationFrame, pasa el paso de la función de devolución de llamada con el parámetro de marca de tiempo y asigna la marca de tiempo en el paso al startTime inicial. Cuando la diferencia entre la marca de tiempo y startTime es menor que el tiempo especificado, se llamará nuevamente a requestAnimationFrame y, finalmente, la animación se detendrá.

<!-- 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);    }}

ilustrar

La función requestAnimationFrame pasa la marca de tiempo en la posición del primer parámetro al llamar a la función de devolución de llamada, lo que indica el momento en que requestAnimationFrame comienza a ejecutar la función de devolución de llamada.

Cancelar fotograma de animación

Cancele la devolución de llamada cuadro por cuadro a través de la función cancelAnimationFrame y cancele la función requestAnimationFrame al llamar a la función cancelAnimationFrame.

<!-- 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);  }}

ilustrar

Al llamar a esta función, se debe pasar un parámetro con una identificación de identificación.

Supongo que te gusta

Origin blog.csdn.net/HarmonyOSDev/article/details/132688143
Recomendado
Clasificación