| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- import { Tween } from "cc";
- import { Component, Enum, EventHandler, Node, quat, Quat, tween, v3, Vec3, _decorator } from "cc";
- import { TweenEasing } from "./TweenEasing";
- const { ccclass, property } = _decorator;
- /**
- * 缓动数据
- * @author 袁浩
- */
- @ccclass("PropsData")
- export class PropsData {
- @property({ tooltip: "坐标", type: Vec3 })
- public position: Vec3 = new Vec3();
- @property({ tooltip: "旋转", type: Vec3 })
- public eulerAngles: Vec3 = new Vec3();
- @property({ tooltip: "缩放", type: Vec3 })
- public scale: Vec3 = new Vec3(1, 1, 1);
- }
- /**
- * 缓动数据
- * @author 袁浩
- */
- @ccclass("TweenData")
- export class TweenData {
- @property({ tooltip: "属性数据", type: PropsData })
- public propsData: PropsData;
- @property({ tooltip: "持续时间,单位为秒" })
- public duration: number = 0.3;
- @property({ tooltip: "延迟时间,单位为秒" })
- public delay: number = 0;
- @property({ tooltip: "是否为差值" })
- public isOffset: boolean = false;
- @property({ tooltip: "当缓动动作完成时触发", type: EventHandler })
- public onComplete: EventHandler;
- @property({ tooltip: "当缓动动作启动时触发", type: EventHandler })
- public onStart: EventHandler;
- @property({ tooltip: "当缓动动作更新时触发", type: EventHandler })
- public onUpdate: EventHandler;
- }
- /**
- * 缓动组件,目前只支持节点的三个基础属性
- * @author 袁浩
- */
- @ccclass('UITween')
- export class UITween extends Component {
- @property({ tooltip: "节点初始属性", type: PropsData })
- public fromData: PropsData;
- @property({ tooltip: "节点目标属性", type: [TweenData] })
- public targetData: TweenData[] = [];
- @property({ tooltip: "要播放缓动动画的目标,不填则是当前节点", type: Node })
- public target: Node;
- @property({ tooltip: "是否在缓动组件运行时自动播放缓动动画" })
- public playOnLoad: boolean = false;
- @property({ tooltip: "缓动效果", type: Enum(TweenEasing) })
- public tweenEasing: TweenEasing = TweenEasing.linear;
- @property({ tooltip: "执行次数,为0则一直重复执行" })
- public repeat: number = 1;
- @property({ tooltip: "单次缓动序列执行完毕时触", type: EventHandler })
- public onOneRepeatComplete: EventHandler;
- start() {
- !this.target && (this.target = this.node);
- this.target = this.target || this.node;
- this.currentRepeat = this.repeat;
- this.playOnLoad && this.play();
- }
- private t: Tween<any>;
- private currentRepeat: number;
- public play() {
- if (this.repeat == 0) {
- this.t = tween(this.target);
- this.readyPlay();
- this.t = this.t.call(this.play.bind(this));
- this.t.start();
- }
- else if (this.currentRepeat) {
- this.t = tween(this.target);
- this.readyPlay();
- this.t = this.t.call(this.play.bind(this));
- this.currentRepeat--;
- this.t.start();
- }
- else {
- this.t = null;
- this.currentRepeat = this.repeat;
- }
- }
- public readyPlay() {
- let self = this;
- if (this.fromData) {
- this.node.position = this.fromData.position.clone();
- this.node.scale = this.fromData.scale.clone();
- this.node.eulerAngles = this.fromData.eulerAngles.clone();
- }
- if (this.targetData.length) {
- for (let i = 0; i < this.targetData.length; i++) {
- const targetData = this.targetData[i];
- if (targetData.delay != 0) {
- this.t = this.t.delay(targetData.delay);
- }
- let toData = {
- position: targetData.propsData.position,
- scale: targetData.propsData.scale,
- eulerAngles: targetData.propsData.eulerAngles
- }
- if (targetData.isOffset) {
- toData.position = this.node.position.clone().add(targetData.propsData.position);
- toData.scale = this.node.scale.clone().add(targetData.propsData.scale);
- toData.eulerAngles = this.node.eulerAngles.clone().add(targetData.propsData.eulerAngles);
- }
- this.t = this.t.to(
- targetData.duration,
- toData,
- {
- easing: TweenEasing[this.tweenEasing] as any,
- onComplete: (target: Node) => {
- targetData.onComplete && targetData.onComplete.emit([target]);
- },
- onStart: (target: Node) => { targetData.onStart && targetData.onStart.emit([target]) },
- onUpdate: (target: Node, ratio: number) => { targetData.onUpdate && targetData.onUpdate.emit([target, ratio]) }
- }
- );
- }
- }
- if (this.onOneRepeatComplete) {
- this.t = this.t.call(() => {
- self.onOneRepeatComplete.emit([this, this.t])
- });
- }
- }
- }
|