效果如下:
具体代码
先封装一个组件,名字FadeInOut.vue
<template>
<view>
<view
ref="ani"
:animation="animationData"
class="message"
:style="{ top: top + 'px', left: left + 'px' }"
v-if="show"
>
<view class="round bg-gradual-orange flex justify-start shadow" style="padding: 3px;">
<view class="cu-avatar cu-a-sm round" :style="{ backgroundImage: `url(${info.img})` }">
<!-- #ifdef APP-NVUE -->
<image :src="info.img" class="avatarimg"></image>
<!-- #endif -->
</view>
<view class="padding-lr-sm flex align-center">
<text class="text-sm">{{ info.title }}</text>
</view>
</view>
</view>
</view>
</template>
<script>
// #ifdef APP-NVUE
const animation = uni.requireNativePlugin('animation');
// #endif
export default {
name: 'Pengpai-FadeInOut',
props: {
//持续时间
duration: {
type: Number,
default: 2600
},
//停留时间
wait: {
type: Number,
default: 3000
},
//顶部距离px
top: {
type: Number,
default: 350
},
//左边距离px
left: {
type: Number,
default: 10
},
//动画半径
radius: {
type: Number,
default: 30
},
//数据
info: {
type: [Array,Object],
default: () => {
return []
}
}
},
data() {
return {
animationData: {},
animationNumber:{},
show: true
};
},
mounted(){
this.donghua();
},
watch:{
},
methods: {
donghua() {
//进入
// #ifndef APP-NVUE
this.animationData = uni
.createAnimation({
duration: this.duration / 2,
timingFunction: 'ease'
})
.top(this.top - this.radius)
.opacity(0.9)
.step()
.export();
// #endif
// #ifdef APP-NVUE
if (!this.$refs['ani']) return;
animation.transition(
this.$refs['ani'].ref,
{
styles: {
transform: `translateY(-${this.radius/2}px)`,
opacity: 1
},
duration: this.duration/2,
timingFunction: 'linear',
needLayout: false,
delay: 0
}
);
// #endif
//停留
setTimeout(() => {
//消失
// #ifndef APP-NVUE
this.animationData = uni
.createAnimation({
duration: this.duration / 2,
timingFunction: 'ease'
})
.top(this.top - this.radius * 2)
.opacity(0)
.step()
.export();
// #endif
// #ifdef APP-NVUE
if (!this.$refs['ani']) return;
animation.transition(
this.$refs['ani'].ref,
{
styles: {
transform: `translateY(-${this.radius}px)`,
opacity: 0
},
duration: this.duration/2,
timingFunction: 'linear',
needLayout: false,
delay: 0
}
);
// #endif
}, this.wait);
}
}
};
</script>
<style scoped>
.message {
position: fixed;
z-index: 99999;
opacity: 0;
}
.round {
border-radius: 5000px;
}
.bg-gradual-orange {
background-image: linear-gradient(45deg, #ff9700, #ed1c24);
background-image: linear-gradient(to bottom right, #ff9700, #ed1c24);
color: #ffffff;
}
.shadow {
box-shadow: 4px 4px 5px rgba(217, 109, 26, 0.2);
}
.flex {
display: flex;
flex-direction: row;
}
.justify-start {
justify-content: flex-start;
}
.cu-avatar {
font-variant: small-caps;
display: inline-flex;
white-space: nowrap;
background-size: cover;
background-position: center;
vertical-align: middle;
margin: 0;
padding: 0;
text-align: center;
justify-content: center;
align-items: center;
background-color: #ccc;
color: #ffffff;
position: relative;
width: 30px;
height: 30px;
font-size: 1.5em;
}
.avatarimg {
width: 30px;
height: 30px;
border-radius: 50px;
}
.cu-a-sm {
width: 30px;
height: 30px;
font-size: 1em;
}
.padding-lr-sm {
padding-left: 20upx;
padding-right: 20upx;
}
.align-center {
align-items: center;
}
.margin-left-xs {
margin-left: 10upx;
}
.text-bold {
font-weight: bold;
}
.margin-lr-sm {
margin-left: 20upx;
margin-right: 20upx;
}
.text-sm {
font-size: 15px;
color: #ffffff;
}
</style>
然后引入这个组件
<template>
<view>
<Pengpai-FadeInOut
:duration="2000"
:wait="1000"
:top="150"
:left="10"
:radius="60"
:loop="true"
:info="item"
v-for="(item, index) in list"
:key="index"
></Pengpai-FadeInOut>
</view>
</template>
<script>
import PengpaiFadeInOut from '../../components/Pengpai-FadeInOut/Pengpai-FadeInOut.vue'
export default {
components:{
PengpaiFadeInOut
},
data() {
return {
list: [
],
//演示数据
demo_data: [
{
title: '踮起脚尖走向阳光 刚刚浏览本店',
img: 'https://wx.qlogo.cn/mmopen/vi_32/DYAIOgq83er0aq5WuQhWxXcQoQbSnSPywUheQrot5biaFxV47nF2OB0aegkH12q2A6VkGUBDfUVqiaqgzVCJJicDg/132'
},
{
title: '幸福的小女人 刚刚浏览本店',
img: 'https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTIOeUhleCNwcOoTtk9Y1zwmpw76FsmAr1bYcKia2AVPiapbtl34jac7SQgjMaibKDJCqjYaHwvmUh3IQ/132'
},
{
title: '快乐天使 刚刚浏览本店',
img: 'https://wx.qlogo.cn/mmopen/vi_32/OaXz0rjMsrHkZlfxeEqRhhUCKyaXyVSbCQZWFUeZQuUetKhbQRZiclqNQhFfv3yiclOzTl1FgZdjDpwAFG5gDhBg/132'
},
{
title: '握不住的沙 刚刚浏览本店',
img: 'https://wx.qlogo.cn/mmopen/vi_32/bVfMeCPxSQsfBRc1XFHiaAiaZvvdrXC9hMTWAHoqDZKk7HD2By7km1dc55eSEibibKwDaW3ZQ2Zcbccr4KzwILVquQ/132'
},
{
title: '顺其自然 刚刚浏览本店',
img: 'https://thirdwx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJghoO6zuibOUG6AMubJJIUicbbWjyOyljFr4QVZecvRqEhHfkIribPfEyfxiaKY5MpiaAeVjvokLLATDw/132'
}
]
};
},
methods: {
add() {
//随机获取演示数据
let randomItem = this.demo_data[Math.floor(Math.random() * this.demo_data.length)];
//追加一条数据
this.list = this.list.concat(randomItem);
}
},
onLoad() {
setInterval(()=>{
this.add()
},3000)
}
};
</script>
<style></style>
OK,完事