【关键词】
动画样式、透明度、image、stack
【问题背景】
快应用中想在图片切换时加入一些动画效果,使用stack组件下使用两个image组件堆叠,一个image组件通过动画样式设置透明度从1-0隐藏起来,另一张显示出来,从而来实现图片切换效果,但是,前一张图片会概率性地闪现,然后消失。问题代码如下:
<template><div class="page-wrapper"><input type="button" class="button" onclick="onCallAnimationClick" value="Animation 动画" /><stack style="width: 400px; height: 400px"><image class="img" id="img1" src="{{imgUrl}}" oncomplete="imgcomplete"></image><image class="img" id="img2" if="{{ximg}}" src="{{preUrl}}" oncomplete="imgcomplete2" style="{{'opacity:' + preop + ';'}}"></image></stack></div></template><script>export default {data: {imgsrc: ["../Common/logo.png","../Common/b.jpg","../Common/logo.png","../Common/b.jpg","../Common/logo.png",],imgUrl: '',preUrl: '',ximg: true,preop: 0,i: 0},onInit: function () {this.imgUrl = this.imgsrc[0]},onCallAnimationClick() {if (this.i > 3) {this.i = 0;this.imgUrl = this.imgsrc[this.i]} else {this.i++this.imgUrl = this.imgsrc[this.i]}console.log('imgcomplete=', this.i)},imgcomplete() {console.log('imgcomplete 1')this.preop = 1var options = {duration: 500,easing: 'linear',delay: 0,fill: 'forwards',iterations: 1}var frames = [{opacity: 1},{opacity: 0}];var animation = this.$element('img2').animate(frames, options);animation.play();var self = thisanimation.onfinish = function () {console.log("imgcomplete animation onfinish");self.ximg = falseself.preop = 0setTimeout(() => {self.ximg = trueself.preUrl = self.$element("img1").attr.src}, 30);}},imgcomplete2() {console.log('imgcomplete 2')setTimeout(() => {this.preop = 1}, 50);},}</script><style>.page-wrapper {flex-direction: column;justify-content: center;align-items: center;}.img {width: 100%;height: 100%;}.button {color: #20a0ff;background-color: #ffffff;padding: 10px 20px;border: 1px solid #20a0ff;border-radius: 40px;}</style>
【问题分析】
上述代码用两个image组件实现了图片切换时淡入淡出的动画效果,主要是通过透明度实现的。第二个image的css中设置了透明度,但是imgcomplete()方法中又对该image组件做了透明度动画,透明度值从1到0,同时代码中又将css中绑定的透明度变量preop设置为1。
当动画方法完成时间早于css实现的时间,就会出现这个情况。
【解决方案】
1、 将template中第二个image组件的style="{{'opacity:' + preop + ';'}}"去掉。
<image class="img" id="img2" if="{{ximg}}" src="{{preUrl}}" oncomplete="imgcomplete2" ></image>
2、 改为通过动画样式来调用,从0-1变化。
imgcomplete2() {console.log('imgcomplete 2')var options = {duration: 10,easing: 'linear',delay: 0,fill: 'forwards',iterations: 1}var frames = [{opacity: 0},{opacity: 1}];var animation = this.$element('img2').animate(frames, options);animation.play();},