用户:
Nomen查看:0 回复:2 评论:0 创建时间:2024-01-03T06:14:19
这里是没有开场白的Nomen,我注意到很多作品优秀的UI,但是出现和消失都略显突兀,dao3没有为GUI提供动画效果相关的API,所以,我用interval做了一个简易的动效,目前这个类还过于简陋,没有什么功能,欢迎你提出意见或向仓库推送修改!
示例中使用了UiWrapper,可以从Box3-Tools仓库获取
// 这个例子,将创建一个提示文字,并在显示的时候从屏幕左上角移动到视野内
const UiNodeWrapper = createUiNodeWrapper();
const uiWrapper = new UiNodeWrapper(ui);
const Animation = GUIAnimation();
let r = uiWrapper.createChildNode(UiText)
.config("position", UiNodeWrapper.createCoord2({ x: -100, y: 25 })) // 开始时将文字隐藏在屏幕外面
.config("textContent", "欢迎加入游戏!")
let ani = new Animation({
easingFunction: Animation.easing.easeInOutSine, // 使用easeInOutSine作为填充效果
begin: 0, // 开始时
end: 100, // 结束时
time: 1000, // 持续时间
delay: 1 // 动画刷新间隔,越小动画越流畅
});
ani.start(c => {
// 当动画刷新时,调用工具更改文字的位置
r.config("position", UiNodeWrapper.createCoord2({ x: c, y: 25 }));
});
ani.onStop((a) => {
console.log("stop!");
});
ani.onStart((a) => {
console.log("start!");
});
/*
ani.cancel()可以取消事件
GUIAnimation可以传入配置参数
interval指的是全局刷新时间,如果这个值调高,那么全局刷新速度就会降低,注意,这会更改动画持续时间,通常建议为1
easeFunctions是一个对象,将会被赋值到easing上用于扩展easing函数
*/
function GUIAnimation({ interval = 1, easeFunctions } = {}) {
let animations = [], time = 0;
let timer = setInterval(() => {
time++;
animations.filter(a => ((time - a.startTime) % a.delay === 0)).forEach(v => {
if (time - v.startTime >= v.time) {
animations = animations.filter(t => t !== v);
v.stop();
}
else v.animate(time);
});
}, interval);
class Animation {
static easing = {
easeInSine: (x) => (1 - Math.cos((x * Math.PI) / 2)),
easeOutSine: (x) => (Math.sin((x * Math.PI) / 2)),
easeInOutSine: (x) => (-(Math.cos(Math.PI * x) - 1) / 2)
};
static stop() {
clearInterval(timer);
};
constructor(config) {
let def = {easingFunction: (x) => x,begin: 0,end: 1,time: 1000,delay: 10};
Object.keys(def).forEach(k => this[k] = config[k] ? config[k] : def[k]);
this._onStop = [];
this._onStart = [];
this.current = 0;
this.pending = false;
}
start(trigger) {
if (!this.pending) {
this.pending = true;
this.startTime = time;
this.trigger = trigger;
this.current = 0;
animations.push(this);
this._onStart.forEach(v => v(this));
}
}
animate() {
this.current += this.delay;
this.trigger(this.begin + (this.end - this.begin) * this.easingFunction(this.current / this.time));
}
stop() {
this.pending = false;
this._onStop.forEach(v => v(this));
}
onStop(f) {
this._onStop.push(f);
return {
cancel: () => this._onStop = this._onStop.filter(v => v !== f)
}
}
onStart(f) {
this._onStart.push(f);
return {
cancel: () => this._onStart = this._onStart.filter(v => v !== f)
}
}
};
if (easeFunctions) Object.assign(Animation.easing, easeFunctions);
return Animation;
}
Nomen七莓大佬制作的用户界面包装器UiNodeWrapper github.com/helloyork/Box3-Tools/tree/main/src/GUI/UiWrapper 以及本文所涉及的Animation.client.js github.com/helloyork/Box3-Tools/tree/main/src/GUI/Animation
点赞1
评论
神岛吉吉喵imgsrc="https://static.codemao.cn/emoji/codemao/%E7%BC%96%E7%A8%8B%E7%8C%AB_%E5%8A%A0%E6%B2%B9.gif"alt="emotion_编程猫_加油"
点赞1
评论