refactor: reorganize package structure and decouple framework packages (#338)
* refactor: reorganize package structure and decouple framework packages ## Package Structure Reorganization - Reorganized 55 packages into categorized subdirectories: - packages/framework/ - Generic framework (Laya/Cocos compatible) - packages/engine/ - ESEngine core modules - packages/rendering/ - Rendering modules (WASM dependent) - packages/physics/ - Physics modules - packages/streaming/ - World streaming - packages/network-ext/ - Network extensions - packages/editor/ - Editor framework and plugins - packages/rust/ - Rust WASM engine - packages/tools/ - Build tools and SDK ## Framework Package Decoupling - Decoupled behavior-tree and blueprint packages from ESEngine dependencies - Created abstracted interfaces (IBTAssetManager, IBehaviorTreeAssetContent) - ESEngine-specific code moved to esengine/ subpath exports - Framework packages now usable with Cocos/Laya without ESEngine ## CI Configuration - Updated CI to only type-check and lint framework packages - Added type-check:framework and lint:framework scripts ## Breaking Changes - Package import paths changed due to directory reorganization - ESEngine integrations now use subpath imports (e.g., '@esengine/behavior-tree/esengine') * fix: update es-engine file path after directory reorganization * docs: update README to focus on framework over engine * ci: only build framework packages, remove Rust/WASM dependencies * fix: remove esengine subpath from behavior-tree and blueprint builds ESEngine integration code will only be available in full engine builds. Framework packages are now purely engine-agnostic. * fix: move network-protocols to framework, build both in CI * fix: update workflow paths from packages/core to packages/framework/core * fix: exclude esengine folder from type-check in behavior-tree and blueprint * fix: update network tsconfig references to new paths * fix: add test:ci:framework to only test framework packages in CI * fix: only build core and math npm packages in CI * fix: exclude test files from CodeQL and fix string escaping security issue
This commit is contained in:
464
packages/framework/math/src/Animation/Easing.ts
Normal file
464
packages/framework/math/src/Animation/Easing.ts
Normal file
@@ -0,0 +1,464 @@
|
||||
/**
|
||||
* 缓动函数集合
|
||||
*
|
||||
* 提供各种常用的缓动函数,用于创建平滑的动画效果
|
||||
* 所有函数接受时间参数 t (0-1),返回缓动后的值 (通常0-1)
|
||||
*/
|
||||
export class Easing {
|
||||
|
||||
// 线性缓动
|
||||
|
||||
/**
|
||||
* 线性缓动(无缓动)
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static linear(t: number): number {
|
||||
return t;
|
||||
}
|
||||
|
||||
// 二次方缓动 (Quadratic)
|
||||
|
||||
/**
|
||||
* 二次方缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quadIn(t: number): number {
|
||||
return t * t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 二次方缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quadOut(t: number): number {
|
||||
return 1 - (1 - t) * (1 - t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 二次方缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quadInOut(t: number): number {
|
||||
return t < 0.5 ? 2 * t * t : 1 - 2 * (1 - t) * (1 - t);
|
||||
}
|
||||
|
||||
// 三次方缓动 (Cubic)
|
||||
|
||||
/**
|
||||
* 三次方缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static cubicIn(t: number): number {
|
||||
return t * t * t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 三次方缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static cubicOut(t: number): number {
|
||||
return 1 - Math.pow(1 - t, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* 三次方缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static cubicInOut(t: number): number {
|
||||
return t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
|
||||
}
|
||||
|
||||
// 四次方缓动 (Quartic)
|
||||
|
||||
/**
|
||||
* 四次方缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quartIn(t: number): number {
|
||||
return t * t * t * t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 四次方缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quartOut(t: number): number {
|
||||
return 1 - Math.pow(1 - t, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* 四次方缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quartInOut(t: number): number {
|
||||
return t < 0.5 ? 8 * t * t * t * t : 1 - Math.pow(-2 * t + 2, 4) / 2;
|
||||
}
|
||||
|
||||
// 五次方缓动 (Quintic)
|
||||
|
||||
/**
|
||||
* 五次方缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quintIn(t: number): number {
|
||||
return t * t * t * t * t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 五次方缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quintOut(t: number): number {
|
||||
return 1 - Math.pow(1 - t, 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* 五次方缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static quintInOut(t: number): number {
|
||||
return t < 0.5 ? 16 * t * t * t * t * t : 1 - Math.pow(-2 * t + 2, 5) / 2;
|
||||
}
|
||||
|
||||
// 正弦缓动 (Sine)
|
||||
|
||||
/**
|
||||
* 正弦缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static sineIn(t: number): number {
|
||||
return 1 - Math.cos((t * Math.PI) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 正弦缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static sineOut(t: number): number {
|
||||
return Math.sin((t * Math.PI) / 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 正弦缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static sineInOut(t: number): number {
|
||||
return -(Math.cos(Math.PI * t) - 1) / 2;
|
||||
}
|
||||
|
||||
// 指数缓动 (Exponential)
|
||||
|
||||
/**
|
||||
* 指数缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static expoIn(t: number): number {
|
||||
return t === 0 ? 0 : Math.pow(2, 10 * (t - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* 指数缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static expoOut(t: number): number {
|
||||
return t === 1 ? 1 : 1 - Math.pow(2, -10 * t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 指数缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static expoInOut(t: number): number {
|
||||
if (t === 0) return 0;
|
||||
if (t === 1) return 1;
|
||||
|
||||
return t < 0.5
|
||||
? Math.pow(2, 20 * t - 10) / 2
|
||||
: (2 - Math.pow(2, -20 * t + 10)) / 2;
|
||||
}
|
||||
|
||||
// 圆形缓动 (Circular)
|
||||
|
||||
/**
|
||||
* 圆形缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static circIn(t: number): number {
|
||||
return 1 - Math.sqrt(1 - t * t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 圆形缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static circOut(t: number): number {
|
||||
return Math.sqrt(1 - (t - 1) * (t - 1));
|
||||
}
|
||||
|
||||
/**
|
||||
* 圆形缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static circInOut(t: number): number {
|
||||
return t < 0.5
|
||||
? (1 - Math.sqrt(1 - 4 * t * t)) / 2
|
||||
: (Math.sqrt(1 - (-2 * t + 2) * (-2 * t + 2)) + 1) / 2;
|
||||
}
|
||||
|
||||
// 回弹缓动 (Back)
|
||||
|
||||
/**
|
||||
* 回弹缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @param s 回弹强度,默认1.70158
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static backIn(t: number, s: number = 1.70158): number {
|
||||
const c1 = s;
|
||||
const c3 = c1 + 1;
|
||||
return c3 * t * t * t - c1 * t * t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 回弹缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @param s 回弹强度,默认1.70158
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static backOut(t: number, s: number = 1.70158): number {
|
||||
const c1 = s;
|
||||
const c3 = c1 + 1;
|
||||
return 1 + c3 * Math.pow(t - 1, 3) + c1 * Math.pow(t - 1, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* 回弹缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @param s 回弹强度,默认1.70158
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static backInOut(t: number, s: number = 1.70158): number {
|
||||
const c1 = s;
|
||||
const c2 = c1 * 1.525;
|
||||
|
||||
return t < 0.5
|
||||
? (Math.pow(2 * t, 2) * ((c2 + 1) * 2 * t - c2)) / 2
|
||||
: (Math.pow(2 * t - 2, 2) * ((c2 + 1) * (t * 2 - 2) + c2) + 2) / 2;
|
||||
}
|
||||
|
||||
// 弹性缓动 (Elastic)
|
||||
|
||||
/**
|
||||
* 弹性缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @param amplitude 振幅,默认1
|
||||
* @param period 周期,默认0.3
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static elasticIn(t: number, amplitude: number = 1, period: number = 0.3): number {
|
||||
if (t === 0) return 0;
|
||||
if (t === 1) return 1;
|
||||
|
||||
const s = period / 4;
|
||||
return -(amplitude * Math.pow(2, 10 * (t - 1)) * Math.sin((t - 1 - s) * (2 * Math.PI) / period));
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹性缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @param amplitude 振幅,默认1
|
||||
* @param period 周期,默认0.3
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static elasticOut(t: number, amplitude: number = 1, period: number = 0.3): number {
|
||||
if (t === 0) return 0;
|
||||
if (t === 1) return 1;
|
||||
|
||||
const s = period / 4;
|
||||
return amplitude * Math.pow(2, -10 * t) * Math.sin((t - s) * (2 * Math.PI) / period) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 弹性缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @param amplitude 振幅,默认1
|
||||
* @param period 周期,默认0.45
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static elasticInOut(t: number, amplitude: number = 1, period: number = 0.45): number {
|
||||
if (t === 0) return 0;
|
||||
if (t === 1) return 1;
|
||||
|
||||
const s = period / 4;
|
||||
|
||||
if (t < 0.5) {
|
||||
return -0.5 * (amplitude * Math.pow(2, 10 * (2 * t - 1)) * Math.sin((2 * t - 1 - s) * (2 * Math.PI) / period));
|
||||
}
|
||||
|
||||
return amplitude * Math.pow(2, -10 * (2 * t - 1)) * Math.sin((2 * t - 1 - s) * (2 * Math.PI) / period) * 0.5 + 1;
|
||||
}
|
||||
|
||||
// 跳跃缓动 (Bounce)
|
||||
|
||||
/**
|
||||
* 跳跃缓入
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static bounceIn(t: number): number {
|
||||
return 1 - Easing.bounceOut(1 - t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳跃缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static bounceOut(t: number): number {
|
||||
const n1 = 7.5625;
|
||||
const d1 = 2.75;
|
||||
|
||||
if (t < 1 / d1) {
|
||||
return n1 * t * t;
|
||||
} else if (t < 2 / d1) {
|
||||
return n1 * (t -= 1.5 / d1) * t + 0.75;
|
||||
} else if (t < 2.5 / d1) {
|
||||
return n1 * (t -= 2.25 / d1) * t + 0.9375;
|
||||
} else {
|
||||
return n1 * (t -= 2.625 / d1) * t + 0.984375;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳跃缓入缓出
|
||||
* @param t 时间参数 (0-1)
|
||||
* @returns 缓动值
|
||||
*/
|
||||
static bounceInOut(t: number): number {
|
||||
return t < 0.5
|
||||
? (1 - Easing.bounceOut(1 - 2 * t)) / 2
|
||||
: (1 + Easing.bounceOut(2 * t - 1)) / 2;
|
||||
}
|
||||
|
||||
// 组合缓动
|
||||
|
||||
/**
|
||||
* 创建自定义缓动函数(组合多个缓动)
|
||||
* @param easingFunctions 缓动函数数组
|
||||
* @param weights 权重数组,默认均等
|
||||
* @returns 组合后的缓动函数
|
||||
*/
|
||||
static combine(
|
||||
easingFunctions: ((t: number) => number)[],
|
||||
weights?: number[]
|
||||
): (t: number) => number {
|
||||
if (!weights) {
|
||||
weights = new Array(easingFunctions.length).fill(1 / easingFunctions.length);
|
||||
}
|
||||
|
||||
return (t: number): number => {
|
||||
let result = 0;
|
||||
for (let i = 0; i < easingFunctions.length; i++) {
|
||||
result += easingFunctions[i](t) * (weights![i] || 0);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建分段缓动函数
|
||||
* @param segments 分段配置数组,每段包含 {duration, easing}
|
||||
* @returns 分段缓动函数
|
||||
*/
|
||||
static piecewise(segments: Array<{duration: number; easing: (t: number) => number}>): (t: number) => number {
|
||||
// 计算总持续时间
|
||||
const totalDuration = segments.reduce((sum, seg) => sum + seg.duration, 0);
|
||||
|
||||
// 归一化持续时间
|
||||
const normalizedSegments = segments.map((seg) => ({
|
||||
...seg,
|
||||
duration: seg.duration / totalDuration
|
||||
}));
|
||||
|
||||
return (t: number): number => {
|
||||
let accumulatedTime = 0;
|
||||
|
||||
for (const segment of normalizedSegments) {
|
||||
if (t <= accumulatedTime + segment.duration) {
|
||||
const localT = (t - accumulatedTime) / segment.duration;
|
||||
return segment.easing(Math.max(0, Math.min(1, localT)));
|
||||
}
|
||||
accumulatedTime += segment.duration;
|
||||
}
|
||||
|
||||
// 如果超出范围,返回最后一段的结束值
|
||||
return normalizedSegments[normalizedSegments.length - 1].easing(1);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建反向缓动函数
|
||||
* @param easing 原缓动函数
|
||||
* @returns 反向缓动函数
|
||||
*/
|
||||
static reverse(easing: (t: number) => number): (t: number) => number {
|
||||
return (t: number): number => 1 - easing(1 - t);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建镜像缓动函数(先正向再反向)
|
||||
* @param easing 原缓动函数
|
||||
* @returns 镜像缓动函数
|
||||
*/
|
||||
static mirror(easing: (t: number) => number): (t: number) => number {
|
||||
return (t: number): number => {
|
||||
if (t < 0.5) {
|
||||
return easing(t * 2);
|
||||
} else {
|
||||
return easing(2 - t * 2);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// 常用预设
|
||||
|
||||
/** 平滑进入(常用于UI动画) */
|
||||
static readonly smoothIn = Easing.quadOut;
|
||||
|
||||
/** 平滑退出(常用于UI动画) */
|
||||
static readonly smoothOut = Easing.quadIn;
|
||||
|
||||
/** 快速进入(常用于出现动画) */
|
||||
static readonly quickIn = Easing.cubicOut;
|
||||
|
||||
/** 快速退出(常用于消失动画) */
|
||||
static readonly quickOut = Easing.cubicIn;
|
||||
|
||||
/** 自然运动(模拟物理) */
|
||||
static readonly natural = Easing.quartOut;
|
||||
|
||||
/** 强调效果(吸引注意力) */
|
||||
static readonly emphasize = Easing.backOut;
|
||||
}
|
||||
Reference in New Issue
Block a user