pastime/js/plugins/TorigoyaMZ_FrameTween.js
2026-03-15 16:45:22 -05:00

309 lines
9.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*---------------------------------------------------------------------------*
* TorigoyaMZ_FrameTween.js v.2.2.1
*---------------------------------------------------------------------------*
* 2023/09/23 02:17 (JST)
*---------------------------------------------------------------------------*
* Ruたん ( @ru_shalm )
* https://torigoya-plugin.rutan.dev
*---------------------------------------------------------------------------*/
/*:
* @target MZ
* @plugindesc [Base] Tween-animation Engine (v.2.2.1)
* @author Rutan(ru_shalm)
* @license public domain
* @version 2.2.1
* @url https://raw.githubusercontent.com/rutan/torigoya-rpg-maker-plugin/gh-pages/TorigoyaMZ_FrameTween.js
* @help
* [Base] Tween-animation Engine (v.2.2.1)
* https://torigoya-plugin.rutan.dev
*
* This plugin is a base-plugin for Torigoya plugins.
*/
/*:ja
* @target MZ
* @plugindesc [鳥小屋.txt ベースプラグイン] Tweenアニメーション (v.2.2.1)
* @author Ruたんru_shalm
* @license public domain
* @version 2.2.1
* @url https://raw.githubusercontent.com/rutan/torigoya-rpg-maker-plugin/gh-pages/TorigoyaMZ_FrameTween.js
* @help
* [鳥小屋.txt ベースプラグイン] Tweenアニメーション (v.2.2.1)
* https://torigoya-plugin.rutan.dev
*
* このプラグインはベースプラグインです。
* このプラグインを導入しただけでは特に何も起きません。
* Tweenアニメーション用の処理を追加します。
*/
(function () {
'use strict';
// Bundled with Packemon: https://packemon.dev
// Platform: browser, Support: stable, Format: esm
const linear = (n) => n;
const easeInSine = (n) => 1 - Math.cos((n * Math.PI) / 2);
const easeOutSine = (n) => Math.sin((n * Math.PI) / 2);
const easeInOutSine = (n) => (1 - Math.cos(n * Math.PI)) / 2;
const easeInQuad = (n) => n * n;
const easeOutQuad = (n) => n * (2 - n);
const easeInOutQuad = (n) => {
n *= 2;
if (n < 1) {
return (n * n) / 2;
} else {
--n;
return (1 + n * (2 - n)) / 2;
}
};
const easeInCubic = (n) => Math.pow(n, 3);
const easeOutCubic = (n) => {
--n;
return Math.pow(n, 3) + 1;
};
const easeInOutCubic = (n) => {
n *= 2;
if (n < 1) {
return Math.pow(n, 3) / 2;
} else {
n -= 2;
return (Math.pow(n, 3) + 2) / 2;
}
};
const easeInCircular = (n) => 1 - Math.sqrt(1 - n * n);
const easeOutCircular = (n) => {
n--;
return Math.sqrt(1 - n * n);
};
const easeInOutCircular = (n) => {
n *= 2;
if (n < 1) {
return -(Math.sqrt(1 - n * n) - 1) / 2;
} else {
n -= 2;
return (Math.sqrt(1 - n * n) + 1) / 2;
}
};
class Group {
_items = [];
get length() {
return this._items.length;
}
clear() {
this._items.forEach(([tween, _]) => tween.abort());
this._items.length = 0;
}
add(tween) {
const state = {
startParams: {},
finishParams: {},
duration: 0,
easingFunc: linear,
timer: 0,
isWaitingCallback: false,
};
if (!this._beginAnimation(tween, state)) return;
this._items.push([tween, state]);
}
remove(tween) {
this._items = this._items.filter(([t, _]) => t !== tween);
}
update() {
const items = this._items.slice();
this._items.length = 0;
this._items = items
.filter(([tween, state]) => {
if (tween.finished) return false;
if (state.isWaitingCallback) return true;
++state.timer;
if (state.timer < state.duration) {
const n = state.easingFunc(state.timer / state.duration);
Object.keys(state.finishParams).forEach((key) => {
tween.target[key] =
state.startParams[key] + (state.finishParams[key] - state.startParams[key]) * n;
});
} else {
Object.keys(state.finishParams).forEach((key) => {
tween.target[key] = state.finishParams[key];
});
}
const result = state.timer < state.duration || this._beginAnimation(tween, state);
tween.callUpdateListeners();
if (!result) tween.abort();
return result;
})
.concat(this._items);
}
_beginAnimation(tween, state) {
while (true) {
const stack = tween.stacks.shift();
if (!stack) return false;
switch (stack.type) {
case 'call':
if (stack.func.length === 0) {
stack.func();
} else {
state.isWaitingCallback = true;
stack.func(() => (state.isWaitingCallback = false));
}
if (state.isWaitingCallback) {
return true;
} else {
break; // loop!
}
case 'move': {
const startParams = {};
Object.keys(stack.params).forEach((key) => {
startParams[key] = tween.target[key];
});
state.startParams = startParams;
state.finishParams = stack.params;
state.duration = stack.duration;
state.easingFunc = stack.easingFunc;
state.timer = 0;
return true;
}
}
}
}
}
class Tween {
_target;
_stacks;
_group;
_onUpdateListeners;
_finished;
constructor(target, initialParams) {
this._target = target;
this._stacks = [];
this._group = null;
this._onUpdateListeners = [];
this._finished = false;
if (initialParams) {
Object.keys(initialParams).forEach((key) => {
target[key] = initialParams[key];
});
}
}
get stacks() {
return this._stacks;
}
get target() {
return this._target;
}
get finished() {
return this._finished;
}
group(group) {
this._group = group;
return this;
}
addUpdateListener(func) {
this._onUpdateListeners.push(func);
return this;
}
removeUpdateListener(func) {
this._onUpdateListeners = this._onUpdateListeners.filter((f) => f !== func);
return this;
}
callUpdateListeners() {
this._onUpdateListeners.forEach((f) => f());
}
to(params, duration, easingFunc) {
this._stacks.push({
type: 'move',
params,
duration,
easingFunc: easingFunc || linear,
});
return this;
}
wait(duration) {
this._stacks.push({
type: 'move',
params: {},
duration,
easingFunc: linear,
});
return this;
}
call(func) {
this._stacks.push({
type: 'call',
func,
});
return this;
}
start() {
if (!this._group) throw new Error('not grouped');
this._group.add(this);
return this;
}
abort() {
this._stacks.length = 0;
this._finished = true;
return this;
}
}
const Torigoya = (window.Torigoya = window.Torigoya || {});
function getPluginName() {
const cs = document.currentScript;
return cs ? cs.src.split('/').pop().replace(/\.js$/, '') : 'TorigoyaMZ_FrameTween';
}
function readParameter() {
PluginManager.parameters(getPluginName());
return {
version: '2.2.1',
};
}
const globalGroup = new Group();
Torigoya.FrameTween = {
name: getPluginName(),
parameter: readParameter(),
Tween,
Group,
Easing: {
linear,
easeInSine,
easeOutSine,
easeInOutSine,
easeInQuad,
easeOutQuad,
easeInOutQuad,
easeInCubic,
easeOutCubic,
easeInOutCubic,
easeInCircular,
easeOutCircular,
easeInOutCircular,
},
group: globalGroup,
create(obj, initParams = {}) {
return new Tween(obj, initParams).group(globalGroup);
},
};
(() => {
const upstream_updateScene = SceneManager.updateScene;
SceneManager.updateScene = function () {
const isStarted = this._scene && this._scene.isStarted() && this.isGameActive();
upstream_updateScene.apply(this);
if (isStarted) Torigoya.FrameTween.group.update();
};
const upstream_onSceneTerminate = SceneManager.onSceneTerminate;
SceneManager.onSceneTerminate = function () {
upstream_onSceneTerminate.apply(this);
Torigoya.FrameTween.group.clear();
};
})();
})();