import { _decorator, Component, Node, tween, Tween, Vec3 } from 'cc'; import type { TweenEasing } from 'cc'; const { ccclass, property } = _decorator; @ccclass('BlinkScaleAnimator') export default class BlinkScaleAnimator extends Component { @property({ tooltip: '放大比例因子(相对于初始缩放)' }) public scaleFactor: number = 1.3; @property({ tooltip: '放大阶段时长(秒)' }) public upDuration: number = 0.15; @property({ tooltip: '缩小阶段时长(秒)' }) public downDuration: number = 0.15; @property({ tooltip: '放大阶段缓动' }) public easingUp: TweenEasing | ((k: number) => number) = 'sineOut'; @property({ tooltip: '缩小阶段缓动' }) public easingDown: TweenEasing | ((k: number) => number) = 'sineIn'; @property({ tooltip: '启用组件时自动开始闪烁' }) public playOnEnable: boolean = false; // 默认不自动播放,避免误触发 private _originalScale: Vec3 = Vec3.ONE.clone(); private _blinkTween: Tween | null = null; private _isPlaying: boolean = false; onLoad() { this._originalScale = this.node.scale.clone(); } onEnable() { if (this.playOnEnable) { this.play(); } } onDisable() { this.stop(); } onDestroy() { this.stop(); } public play(): void { if (this._isPlaying) { return; } this.stop(); this._isPlaying = true; const targetScale = new Vec3( this._originalScale.x * this.scaleFactor, this._originalScale.y * this.scaleFactor, this._originalScale.z ); this._blinkTween = tween(this.node) .to(this.upDuration, { scale: targetScale }, { easing: this.easingUp }) .to(this.downDuration, { scale: this._originalScale }, { easing: this.easingDown }) .union() .repeatForever() .start(); } public stop(): void { this._isPlaying = false; if (this._blinkTween) { this._blinkTween.stop(); this._blinkTween = null; } Tween.stopAllByTarget(this.node); // 恢复初始缩放 this.node.scale = this._originalScale.clone(); } }