Skip to content

Animation动画

Animation动画,采用链式调用创建动态的视觉效果,使页面更加流畅和自然、 增强用户体验,让页面更加有趣更加吸引力。

  • 支持动画队列
  • 支持动画循环

支持平台

安卓iosweb微信小程序支付宝小程序QQ小程序
xxx

创建Animation类

js
this.animation = new TuvueUiAnimation(domEle, {
	transformOrigin: "50% 50%",
	duration: 500,
	timingFunction: "linear",
	delay: 0
})

Animation 动画队列完成回调

js
this.animation.onTranSitionEnd(() => {
	uni.showToast({
		title: '动画队列执行完成'
	})

})

option

参数类型必填默认值说明
durationInteger400动画持续时间,单位ms
timingFunctionString"linear"定义动画的效果
delayInteger0动画延迟时间,单位 ms
transformOriginString"50% 50% 0"设置transform-origin

timingFunction 有效值:

  • "linear":匀速动画。
  • "ease":先慢后快然后慢。
  • "ease-in":先慢后快。
  • "ease-out":先快后慢。
  • "ease-in-out":先慢后快然后再慢。
  • "cubic-bezier(n,n,n,n)":自定义贝塞尔动画,四个值分别表示首段、首点、中点和尾点的曲率,值在0到1之间。

动画实例可以调用以下方法来描述动画,调用结束后会返回自身,支持链式调用的写法。

Methods

方法参数说明
opacityvalue透明度,参数范围 0~1
backgroundColorcolor颜色值
widthlength长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
heightlength长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
toplength长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
leftlength长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
bottomlength长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值
rightlength长度值,如果传入 Number 则默认使用 px,可传入其他自定义单位的长度值

旋转:

方法参数说明
rotatedegdeg的范围-180~180,从原点顺时针旋转一个deg角度
rotateXdegdeg的范围-180~180,在X轴旋转一个deg角度
rotateYdegdeg的范围-180~180,在Y轴旋转一个deg角度
rotateZdegdeg的范围-180~180,在Z轴旋转一个deg角度

缩放:

方法参数说明
scalesx,[sy]一个参数时,表示在X轴、Y轴同时缩放sx倍数;两个参数时表示在X轴缩放sx倍数,在Y轴缩放sy倍数
scaleXsx在X轴缩放sx倍数
scaleYsy在Y轴缩放sy倍数
scaleZsz在Z轴缩放sz倍数

偏移:

方法参数说明
translatetx,[ty]一个参数时,表示在X轴偏移tx,单位px;两个参数时,表示在X轴偏移tx,在Y轴偏移ty,单位px。
translateXtx在X轴偏移tx,单位px
translateYty在Y轴偏移ty,单位px
translateZtz在Z轴偏移tz,单位px

调用动画操作方法后要调用 step() 来表示一组动画完成,可以在一组动画中调用任意多个动画方法,一组动画中的所有动画会同时开始,一组动画完成后才会进行下一组动画。

示例

html
<template>
	<t-page title='过渡动画' @initFinished="loading" class="p.30">
		<t-col class="df-di.0-ope.n-z.999">
			<t-col ref="testdom" class="twhr.120-tdb.p-fc-dt.150-dl.30">
				<t-avatar src="/static/image/65275c9ac3b1d.jpg"></t-avatar>
			</t-col>
			<t-col ref="testdom1" class="twhr.150-tdb.s-fc-dr.30-da-dt.150">
				<t-text class="c.#fff">队列循环</t-text>
			</t-col>
		</t-col>
		<t-card title="Animation" sub-title="采用链式调用,支持动画队列、支持循环播放!" class="mb.30"></t-card>
		<t-col>
			<t-card title="宽高随机设置" class="mb.30"
				sub-title="this.animation!.width('500rpx').height('400rpx').step().export()">
				<t-button @click="whAni1" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="margin随机设置" class="mb.30"
				sub-title="this.animation!.margin(this.getRandRpx()).step().export()">
				<t-button @click="whAni2" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="left,top,bottom,right测试" class="mb.30"
				sub-title="this.animation?.left(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni3" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="padding测试" class="mb.30"
				sub-title="this.animation?.left(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni4" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="opacity过渡效果" class="mb.30"
				sub-title="this.animation?.opacity(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni5" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="background-color过渡效果" class="mb.30"
				sub-title="this.animation?.backgroundColor(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni6" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="border-color过渡效果" class="mb.30"
				sub-title="this.animation?.borderColor(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni7" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="rotate过渡效果" class="mb.30"
				sub-title="this.animation?.borderColor(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni8" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="scale过渡效果" class="mb.30"
				sub-title="this.animation?.borderColor(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni9" :border="false">展示效果</t-button>
			</t-card>
			<t-card title="translate过渡效果" class="mb.30"
				sub-title="this.animation?.borderColor(this.getRandRpx())?.step()?.export()">
				<t-button @click="whAni10" :border="false">展示效果</t-button>
			</t-card>
		</t-col>
	</t-page>
</template>

<script>
	import { getRandomInt, TuiAnimation, TuiRefToElement } from '@/uni_modules/t-ui'
	export default {
		data() {
			return {
				animation: null as TuiAnimation | null,
				animation1: null as TuiAnimation | null
			};
		},
		methods: {
			loading() {
				const domEle = TuiRefToElement('testdom', this)
				const domEle1 = TuiRefToElement('testdom1', this)
				this.animation1 = new TuiAnimation(domEle1, {
					transformOrigin: "50% 50%",
					duration: 3000,
					timingFunction: "ease-out",
					delay: 0
				} as UTSJSONObject)
				this.animation = new TuiAnimation(domEle, {
					transformOrigin: "50% 50%",
					duration: 1000,
					timingFunction: "linear",
					delay: 0
				} as UTSJSONObject)
				this.animation?.onTranSitionEnd(() => {
					console.log('动画执行完成')
				})
				this.$nextTick(() => {
					this.whAni()
					this.animation1?.onTranSitionEnd(() => {
						this.whAni()
					})
				})
			},
			whAni10() {
				this.animation?.translate('150rpx')?.step()?.export()
				this.animation?.translate('0')?.step()?.export()
				this.animation?.translateX('150rpx')?.step()?.export()
				this.animation?.translateX('0')?.step()?.export()
				this.animation?.translateY('150rpx')?.step()?.export()
				this.animation?.translateY('0px')?.step()?.export()
			},
			whAni9() {
				this.animation?.scale('1.5')?.step()?.export()
				this.animation?.scale('0.5')?.step()?.export()
				this.animation?.scale('1')?.step()?.export()
				this.animation?.scaleX('1.5')?.step()?.export()
				this.animation?.scaleX('0.5')?.step()?.export()
				this.animation?.scaleX('1')?.step()?.export()
				this.animation?.scaleY('1.5')?.step()?.export()
				this.animation?.scaleY('0.5')?.step()?.export()
				this.animation?.scaleY('1')?.step()?.export()

			},
			whAni8() {
				this.animation?.rotate('360deg')?.step()?.export()
				this.animation?.rotate('0deg')?.step()?.export()
				this.animation?.rotateX('360deg')?.step()?.export()
				this.animation?.rotateX('0deg')?.step()?.export()
				this.animation?.rotateY('360deg')?.step()?.export()
				this.animation?.rotateY('0deg')?.step()?.export()
				this.animation?.rotateZ('360deg')?.step()?.export()
				this.animation?.rotateZ('0deg')?.step()?.export()
			},
			whAni7() {
				this.animation?.borderColor('#000')?.step()?.export()
				this.animation?.borderColor('#fff')?.step()?.export()
			},
			whAni5() {
				this.animation?.opacity(0.5)?.step()?.export()
				this.animation?.opacity(1)?.step()?.export()
				// const testdom = this.$refs['testdom'] as Element

				// this.animation?.opacity('0')?.step()?.export()

			},
			whAni6() {
				this.animation?.backgroundColor('#000')?.step()?.export()
				this.animation?.backgroundColor('#f56c6c')?.step()?.export()
				// const testdom = this.$refs['testdom'] as Element
				// testdom.style.setProperty('background-color', '#f56c6c')
			},
			whAni4() {
				this.animation?.padding(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.padding('0')?.step()?.export()
			},
			whAni1() {
				this.animation?.width(this.getRandRpx() + 'rpx')?.height(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.width(100 + 'rpx')?.height(100 + 'rpx')?.step()?.export()
				this.animation?.width(this.getRandRpx() + 'rpx')?.height(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.width(100 + 'rpx')?.height(100 + 'rpx')?.step()?.export()
			},
			whAni3() {
				this.animation?.left(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.left('50px')?.step()?.export()
				// this.animation?.right(this.getRandRpx() + 'rpx')?.step()?.export()
				// this.animation?.bottom(this.getRandRpx() + 'rpx')?.step()?.export()
				// this.animation?.top(this.getRandRpx() + 'rpx')?.step()?.export()
			},
			whAni2() {
				this.animation?.margin(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.margin('0')?.step()?.export()
				this.animation?.marginTop(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.marginTop('0')?.step()?.export()
				this.animation?.marginBottom(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.marginBottom('0')?.step()?.export()
				this.animation?.marginLeft(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.marginLeft('0')?.step()?.export()
				this.animation?.marginRight(this.getRandRpx() + 'rpx')?.step()?.export()
				this.animation?.marginRight('0')?.step()?.export()
			},
			whAni() {
				this.animation1!.translateY('50rpx').duration(3000).step().export()
				this.animation1!.translateY('0rpx').duration(3000).step().export()
				this.animation1!.rotateX('360deg').translateY('150rpx').step().export()
				this.animation1?.rotateX('0deg')?.step()?.export()
				this.animation1?.rotateY('360deg')?.step()?.export()
				this.animation1?.rotateY('0deg')?.step()?.export()
				this.animation1?.rotateZ('360deg')?.step()?.export()
				this.animation1?.rotateZ('0deg')?.step()?.export()
				this.animation1?.scale('1')?.translate('-150rpx')?.step()?.export()
				this.animation1?.scale('0.5')?.translate('0')?.step()?.export()
				this.animation1?.scale('0.8')?.translateY('-150rpx')?.step()?.export()
				this.animation1?.scale('1')?.translateY('0')?.step()?.export()
			},
			getRandRpx() : string {
				return `${getRandomInt(100, 200)}`
			}
		},
		onUnload() {
			this.animation = null
		}
	}
</script>