Skip to content

xAnimate - Library

这是一个非常强大且简单的动画操作类库,性能高,动画平缓。事件回调机制控制,灵活调度,可以方便的让你写交互类动画组件。

演示

在线预览
在线模拟尺寸:

使用

你可以参考demo页面/pages/index/xanimate,来进行参考使用。

ts

//导入参数类型
import { XANIMATE_OPIONS } from "@/uni_modules/tmx-ui/interface.uts"
//导入库
import { xAnimate } from "@/uni_modules/tmx-ui/index.uts"

你需要 new xAnimate(Unielement,options) 创建一个动画操作类,参数options类型为:XANIMATE_OPIONS。

第一个参数你可以通过this.$refs["xx"] as Unielement;来获得赋值给第一个参数

ts

//options类型为:XANIMATE_OPIONS。
export type XANIMATE_OPIONS = {
	/** 时间 */
	duration?:number,
	/** 动画类型 */
	timingFunction?:string,
	/** -1表示无限循环播放,0表示不会播放,大于0表示播放该次数后停止播放 */
	loop?:number,
	/** 表示循环播放时,是否左右来回播放,而不是始终从开始到结束这样的状态播放 */
	tyty?:boolean,
	/** 四位数数组的动画映射值,优先级高于timingFunction */
	bezier?:number[],
	isDescPlay?:booelan,是否顺序执行动画而不是一起调用动画属性
	/** 动画结束后的回调函数 */
	complete?:()=>void,
	/** 动画开始 */
	start?:()=>void,
	/** 动画运行中执行 */
	frame?:(propress:number)=>void
}

xAnimate实例创建

函数参数说明
xAnimate(ele:Unielement,ops:XANIMATE_OPIONS)使用new xAnimate创建并返回一个xAnimate实例

实例属性

属性名类型说明
easingListMap<string,number[]>返回自带的map类的动画映射表
elementUnielement返回元素对象
timingFunctionString动画映射名称,默认为linear
durationNumber动画持续时间,默认为500
runningBoolean当前是否运行中
pauseingBoolean当前是否暂停中
progressNumber当前的播放进度0-1
reverseBoolean当前是否反转了动画
tytyBoolean当前是否是循环播放模式
loopNumber默认播放时,循环的次数,默认为1,-1时为永久循环播放

实例方法

attr函数可以链式调用不断的添加属性动画,达到联合播放动画的效果,isOnley:true时添加相同属性时以最后一次为准,否则允许相同属性动画

函数参数说明
setAniReverse(n:boolean|null=null)设置reverse返转状态
setLoops(n:number|null = null)设置loop,播放时可持续播放的次数
setDurations(n:number|null = null)设置duration,播放时可持续播放的时间
setTytys(n:number|null = null)设置tyty,播放时loop循环时是否左右来回播放的模式
attr(name:string,from : string, to : string,isOnley:boolean)isOnley表示多次添加name时否保留最后一次,默认是ture,name是css合法的值比如left,right,opacity,border-width等,同时也支持颜色的设置比如:border-color,background颜色过渡动画,也支持transform,但需要设置为其属性名称比如:scale,translateX等
play()播放或者继续播放动画
stop()结束动画,并把动画设置到最后一贴的位置
pause()暂停动画
enterFrame(()=>void)刷新回调,回调速率与你的硬件有关系,如果在电脑大概72Hz屏幕上大概是16ms调用一次

以上方法均返回xAnimate实例,即可链式调用比如new xAnimate(ele,{ele:"xx"}).attr("left",'0%','100%').attr("opacity",'1','0').play()

示例

vue

<template>
	<!-- #ifdef APP -->
	<scroll-view style="flex:1">
	<!-- #endif -->

		<view class=" white round-10 overflow pa-24 mx-24 mb-24">
			<text class="text-size-g text-weight-b">xAnimate - Library</text>
			<text class="text-size-m text-grey mt-10  line-8">这是动画核心类库,异常简便,为你开发动画类组件和效果提供了高效流畅性能的动力</text>
			<text class="text-size-m text-grey mt-10  line-8">不管是web还是安卓均采用系统及的刷新回调,使得动画异常流畅。</text>
		</view>
		<view class=" white round-10 overflow pa-24 mx-24 mb-24">
			<text class="text-size-g text-weight-b">刷新回调</text>
			<text class="text-size-m text-grey mt-10  line-8">可以利用此创建吸引视觉强交互动画</text>
		</view>
		
		<x-sheet>
			<view ref="canvas" style="height: 150px;background-color: #f7f7f7;" class="mb-32">
			</view>
			<x-button :block="true" @click="enterFramAni">播放</x-button>
		</x-sheet>
		
		<view ref="vid" style="width:10%;height:100px; background-color: rgb(28, 132, 255);"></view>
		<x-sheet>
		</x-sheet>
		<x-sheet class="flex flex-row">
			<x-button width="160rpx" class="mr-10" size="normal" @click="play">播放/继续</x-button>
			<x-button width="160rpx" class="mr-10" color="success" size="normal" @click="pause">暂停</x-button>
			<x-button width="160rpx" class="mr-10" color="error" size="normal" @click="stop">停止</x-button>
			<x-button width="160rpx" size="normal" color="orange" @click="setReverse">反转播放</x-button>
		</x-sheet>
		<view class=" white round-10 overflow pa-24 mx-24 mb-24">
			<text class="text-size-g text-weight-b">联合动画动画及函数</text>
			<text class="text-size-m text-grey mt-10  line-8">它是支持常见的动画类型比如:ease,linear等内置了24种常见动画,当然也是支持自定义动画函数。</text>
		</view>
		<x-sheet>
			<view class="flex flex-row flex-row-center-center mb-24">
				<view ref="scaleIds"
					style="width:100px;height:100px;background-color: rgb(28, 132, 255);border-style: solid;border-color: rgb(255, 165, 0);border-width: 10px;">
				</view>
			</view>
			<x-button :block="true" @click="palyScale">播放</x-button>
		</x-sheet>

		<view class=" white round-10 overflow pa-24 mx-24 mb-24">
			<text class="text-size-g text-weight-b">动画按顺序执行</text>
			<text class="text-size-m text-grey mt-10  line-8">支持官方所述的所有css动画属性:如border,left,width,opactiy等等</text>
			<text class="text-size-m text-grey mt-10  line-8">如果要播放transfrom属性时,请直接写属性名比如:scale,scaleX等</text>
		</view>
		<x-sheet>
			<view class="flex flex-row flex-row-center-center mb-24">
				<view ref="unionAni" style="width:100px;height:100px;background-color: rgb(28, 132, 255);"></view>
			</view>
			<x-button :block="true" @click="palyunionAni">播放</x-button>
		</x-sheet>




		<view class=" white round-10 overflow pa-24 mx-24 mb-24">
			<text class="text-size-g text-weight-b">其它属性</text>
			<text class="text-size-m text-grey mt-10  line-8">loop:-1时可永久播放及tyty设置为true可来回循环动画衔接</text>
		</view>

		<x-sheet class="flex flex-row flex-row-center-center">
			<view ref="repeatRef" style="width:50px;height:50px;background-color: rgba(28, 132, 255,1);"></view>
		</x-sheet>
		<x-sheet class="flex flex-row flex-row-center-between">
			<x-button width="46%" class="mr-10" size="normal" @click="repeatPlay">播放/继续</x-button>
			<x-button width="46%" class="mr-10" color="success" size="normal" @click="repeatPlayStop">暂停</x-button>
		</x-sheet>

		
	<!-- #ifdef APP -->
	</scroll-view>
	<!-- #endif -->
</template>
ts

<script>
	import { XANIMATE_OPIONS } from "@/uni_modules/interface.uts"
	import { xAnimate } from "@/uni_modules/tmx-ui/index.uts"
	export default {
		data() {
			return {
				xani: null as null | xAnimate,
				repeatAni: null as null | xAnimate,
				xani2: null as null | xAnimate,
				enterAni: null as null | xAnimate,
				isRealCtx: false
			};
		},
		onUnload() {
			this.xani?.stop()
			this.repeatAni?.stop()
			this.xani2?.stop()
			this.enterAni?.stop()
			this.isRealCtx = false;
		},
		methods: {
			enterFramAni() {
				let width = 0
				let height = 0
				let ratio = 1;
				let dom = this.$refs['canvas'] as UniElement;
				let ctx = null as DrawableContext | null

				width = dom.getBoundingClientRect().width!
				height = dom.getBoundingClientRect().height!
				// #ifdef APP
				ctx = dom!.getDrawableContext()!
				// #endif
				// #ifdef WEB
				let canvas = document.createElement("canvas") as HTMLCanvasElement;
				
				if (dom.querySelector('canvas')) {
					canvas = dom.querySelector('canvas')
				} else {
					dom.appendChild(canvas)
					this.isRealCtx=true;
				}
				
				canvas.width = width
				canvas.height = height
				canvas.style = 'width:100%;height:100%'
				ctx = canvas.getContext('2d')!
				ratio = window.devicePixelRatio;
				// #endif
				
				if (this.enterAni == null) {
					this.enterAni = new xAnimate(null, {} as XANIMATE_OPIONS);
				}
				let max = width - 20
				let maxy = height - 20
				let x = 0
				let y = 0
				let fz = 1
				let fzy = 1
				this.enterAni!.enterFrame(function () {
					ctx!.reset()
					ctx!.beginPath()
					ctx!.fillStyle = "red"
					x = x + 1 * fz
					y = y + 3 * fzy

					ctx!.arc(x * ratio, y * ratio, 10 * ratio, 0, Math.PI * 2)
					ctx!.fill()
					ctx!.beginPath()
					// #ifdef APP
					ctx!.update()
					// #endif
					if (x * ratio >= max) {
						fz = -1;
					}
					if (x <= 0) {
						fz = 1;
					}
					if (y * ratio >= maxy) {
						fzy = -1;
					}
					if (y <= 0) {
						fzy = 1;
					}
				})

			},
			palyunionAni() {
				let ele = this.$refs['unionAni'] as UniElement
				if (this.xani2 != null) {
					this.xani2!.stop();
				}
				this.xani2 = new xAnimate(
					ele,
					{
						timingFunction: 'easeInOutBack',
						duration: 1000,
						isDescPlay: true,
						complete() {
							console.log('动画结束')
						}
					} as XANIMATE_OPIONS)
				this.xani2!.attr('background-color', 'orange', 'primary')
					.attr('scale', '1', '0', false)
					.attr('scale', '0', '1', false)
					.attr('left', '0px', '100px', false)
					.attr('left', '100px', '-100px', false)
					.attr('rotate', '0deg', '360deg', false)
					.attr('background-color', 'primary', 'orange', false)
					.attr('background-color', 'orange', 'primary', false)
					.attr('left', '-100px', '0px', false)
					.play()
			},
			palyScale() {
				let ele = this.$refs['scaleIds'] as UniElement
				new xAnimate(
					ele,
					{
						timingFunction: 'easeInOutBack',
						complete() {
							new xAnimate(
								ele,
								{
									timingFunction: 'easeInOutBack',
								} as XANIMATE_OPIONS)
								.attr('border-color', 'yellow', 'red')
								.attr('border-width', '0px', '20px')
								.play()
						}
					} as XANIMATE_OPIONS)
					.attr('border-color', 'red', 'yellow')
					.attr('scale', '0', '1')
					.attr('opacity', '0', '1')
					.play()
			},
			play() {
				if (this.xani == null) {
					let ele = this.$refs['vid'] as UniElement

					this.xani = new xAnimate(
						ele,
						{
							duration: 1500,
							start() {
								console.log("动画开始")
							},
							complete() {
								console.log("动画结束")
							},
							frame(propress : number) {
								// console.log("动画进度", propress)
							}
						} as XANIMATE_OPIONS)
				}
				this.xani!
					.attr('width', '10%', '100%')
					.attr('background-color', 'rgba(28, 132, 255)', 'red')
					.play()
			},
			stop() {

				this.xani?.stop()
			},
			pause() {

				this.xani?.pause()
			},
			setReverse() {

				this.xani?.setAniReverse()
				this.xani?.play()

			},
			repeatPlay() {
				let ele = this.$refs['repeatRef'] as UniElement
				if (this.repeatAni == null) {
					this.repeatAni = new xAnimate(
						ele,
						{
							loop: -1,
							tyty: false,
							duration: 1000
						} as XANIMATE_OPIONS)
				}
				this.repeatAni!.attr('rotate', '0deg', '360deg').play()

			},
			repeatPlayStop() {
				if (this.repeatAni != null) {

					this.repeatAni!.pause();
				}
			}
		}
	}
</script>
css
<style lang="scss">

</style>
最近更新