kipphi 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -3
- package/basic.ts +285 -0
- package/bpm.ts +332 -0
- package/chart.ts +418 -106
- package/chartType.schema.json +584 -0
- package/chartType2.schema.json +1107 -0
- package/chartTypes.ts +131 -30
- package/easing.ts +125 -90
- package/env.ts +208 -0
- package/evaluator.ts +106 -20
- package/event.ts +357 -255
- package/index.d.ts +3055 -0
- package/index.js +5530 -0
- package/index.ts +17 -11
- package/judgeline.ts +395 -94
- package/jumparray.ts +10 -11
- package/line.ts +246 -0
- package/macro.ts +215 -0
- package/note.ts +32 -55
- package/operation/basic.ts +285 -0
- package/operation/chart.ts +21 -0
- package/operation/event.ts +511 -0
- package/operation/index.ts +6 -0
- package/operation/line.ts +304 -0
- package/operation/macro.ts +60 -0
- package/operation/note.ts +457 -0
- package/package.json +7 -1
- package/rpeChartCompiler.ts +133 -98
- package/time.ts +35 -223
- package/tsconfig.json +2 -3
- package/util.ts +21 -1
- package/version.ts +2 -1
package/chartTypes.ts
CHANGED
|
@@ -177,7 +177,8 @@ export enum EasingType {
|
|
|
177
177
|
normal,
|
|
178
178
|
template,
|
|
179
179
|
bezier,
|
|
180
|
-
segmented
|
|
180
|
+
segmented,
|
|
181
|
+
wrapper
|
|
181
182
|
}
|
|
182
183
|
|
|
183
184
|
export interface NormalEasingData {
|
|
@@ -190,6 +191,11 @@ export interface TemplateEasingData {
|
|
|
190
191
|
type: EasingType.template;
|
|
191
192
|
}
|
|
192
193
|
|
|
194
|
+
export interface WrapperEasingData {
|
|
195
|
+
type: EasingType.wrapper;
|
|
196
|
+
identifier: string;
|
|
197
|
+
}
|
|
198
|
+
|
|
193
199
|
export interface BezierEasingData {
|
|
194
200
|
type: EasingType.bezier;
|
|
195
201
|
bezier: [number, number, number, number];
|
|
@@ -202,11 +208,12 @@ export interface SegmentedEasingData {
|
|
|
202
208
|
inner: EasingDataKPA2;
|
|
203
209
|
}
|
|
204
210
|
|
|
205
|
-
export type EasingDataKPA2 = NormalEasingData | TemplateEasingData | BezierEasingData | SegmentedEasingData;
|
|
211
|
+
export type EasingDataKPA2 = NormalEasingData | TemplateEasingData | BezierEasingData | SegmentedEasingData | WrapperEasingData;
|
|
206
212
|
|
|
207
213
|
export enum EvaluatorType {
|
|
208
214
|
eased,
|
|
209
|
-
expressionbased
|
|
215
|
+
expressionbased,
|
|
216
|
+
macro
|
|
210
217
|
}
|
|
211
218
|
|
|
212
219
|
// Eased
|
|
@@ -219,7 +226,6 @@ interface EasedEvaluatorDataKPA2<T> {
|
|
|
219
226
|
export type NumericEasedEvaluatorKPA2 = EasedEvaluatorDataKPA2<number>;
|
|
220
227
|
export type ColorEasedEvaluatorKPA2 = EasedEvaluatorDataKPA2<RGB>;
|
|
221
228
|
export interface TextEasedEvaluatorKPA2 extends EasedEvaluatorDataKPA2<string> {
|
|
222
|
-
font: string;
|
|
223
229
|
interpretedAs: InterpreteAs;
|
|
224
230
|
}
|
|
225
231
|
|
|
@@ -232,14 +238,53 @@ export interface ExpressionEvaluatorDataKPA2 {
|
|
|
232
238
|
jsExpr: string;
|
|
233
239
|
}
|
|
234
240
|
|
|
241
|
+
export interface MacroEvaluatorDataKPA2 {
|
|
242
|
+
type: EvaluatorType.macro;
|
|
243
|
+
name: string;
|
|
244
|
+
compiled: string;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
|
|
248
|
+
export type EvaluatorDataKPA2<T> = EasedEvaluatorDataOfType<T> | ExpressionEvaluatorDataKPA2 | MacroEvaluatorDataKPA2;
|
|
249
|
+
|
|
250
|
+
export type MacroData = [id: string, proto: number] | string;
|
|
251
|
+
export type MacroLink = [macroTypeAndId: `${'value' | 'time'}:${string}`, nodeId: number]
|
|
235
252
|
|
|
236
|
-
export type EvaluatorDataKPA2<T> = EasedEvaluatorDataOfType<T> | ExpressionEvaluatorDataKPA2;
|
|
237
253
|
export interface EventDataKPA2<T = number> {
|
|
254
|
+
/** 开始时间 */
|
|
238
255
|
startTime: TimeT;
|
|
256
|
+
/** 结束时间 */
|
|
239
257
|
endTime: TimeT;
|
|
258
|
+
/** 起始值 */
|
|
240
259
|
start: T;
|
|
260
|
+
/** 终值 */
|
|
241
261
|
end: T;
|
|
262
|
+
/** 求值器 */
|
|
242
263
|
evaluator: EvaluatorDataKPA2<T>;
|
|
264
|
+
/** 终值绑定的宏的ID */
|
|
265
|
+
macroEnd?: MacroData;
|
|
266
|
+
/** 起始值绑定的宏的ID */
|
|
267
|
+
macroStart?: MacroData;
|
|
268
|
+
/** 起始时间绑定的宏的ID */
|
|
269
|
+
macroStartTime?: MacroData;
|
|
270
|
+
/** 将该事件的起始节点关联到一个宏的某个参数 */
|
|
271
|
+
startLinkedMacro?: MacroLink[];
|
|
272
|
+
endLinkedMacro?: MacroLink[];
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
export interface FinalEventStartNodeDataKPA2<T = number> {
|
|
276
|
+
/** 开始时间 */
|
|
277
|
+
startTime: TimeT;
|
|
278
|
+
/** 起始值 */
|
|
279
|
+
start: T;
|
|
280
|
+
/** 求值器 */
|
|
281
|
+
evaluator: EvaluatorDataKPA2<T>;
|
|
282
|
+
/** 起始值绑定的宏的ID */
|
|
283
|
+
macro?: MacroData;
|
|
284
|
+
/** 起始时间绑定的宏的ID */
|
|
285
|
+
macroTime?: MacroData;
|
|
286
|
+
/** 将该事件的起始节点关联到一个宏的某个参数 */
|
|
287
|
+
linkedMacro?: MacroLink[];
|
|
243
288
|
}
|
|
244
289
|
|
|
245
290
|
export enum EventValueType {
|
|
@@ -309,12 +354,12 @@ export interface JudgeLineDataRPE {
|
|
|
309
354
|
eventLayers: (EventLayerDataRPE | null)[];
|
|
310
355
|
/** 扩展事件 */
|
|
311
356
|
extended?: {
|
|
312
|
-
colorEvents
|
|
313
|
-
inclineEvents
|
|
314
|
-
scaleXEvents
|
|
315
|
-
scaleYEvents
|
|
316
|
-
textEvents
|
|
317
|
-
gifEvents
|
|
357
|
+
colorEvents?: EventDataRPELike<RGB>[];
|
|
358
|
+
inclineEvents?: EventDataRPELike[];
|
|
359
|
+
scaleXEvents?: EventDataRPELike[];
|
|
360
|
+
scaleYEvents?: EventDataRPELike[];
|
|
361
|
+
textEvents?: EventDataRPELike<string>[];
|
|
362
|
+
gifEvents?: EventDataRPELike<number>[];
|
|
318
363
|
};
|
|
319
364
|
/** 父线线号,没有父线则为-1 */
|
|
320
365
|
father: number;
|
|
@@ -355,19 +400,17 @@ export interface JudgeLineDataRPE {
|
|
|
355
400
|
zIndex?: number;
|
|
356
401
|
}
|
|
357
402
|
|
|
358
|
-
export interface JudgeLineDataRPEExtended extends JudgeLineDataRPE {
|
|
359
|
-
_id?: number;
|
|
360
|
-
children: number[]
|
|
361
|
-
}
|
|
362
403
|
|
|
363
|
-
|
|
404
|
+
|
|
405
|
+
export interface TemplateEasingBodyData {
|
|
364
406
|
content: string;
|
|
365
407
|
name: string;
|
|
366
|
-
usedBy: string[];
|
|
367
|
-
dependencies: string[];
|
|
408
|
+
// usedBy: string[];
|
|
409
|
+
// dependencies: string[];
|
|
368
410
|
}
|
|
369
411
|
|
|
370
412
|
|
|
413
|
+
|
|
371
414
|
// 使用对应标识符来标记事件节点序列
|
|
372
415
|
|
|
373
416
|
export interface EventLayerDataKPA {
|
|
@@ -378,6 +421,14 @@ export interface EventLayerDataKPA {
|
|
|
378
421
|
speed: string;
|
|
379
422
|
}
|
|
380
423
|
|
|
424
|
+
export interface EventLayerDataKPA2 {
|
|
425
|
+
moveX: string;
|
|
426
|
+
moveY: string;
|
|
427
|
+
rotate: string;
|
|
428
|
+
alpha: string;
|
|
429
|
+
// 移除了速度事件可以有多层的性质
|
|
430
|
+
}
|
|
431
|
+
|
|
381
432
|
|
|
382
433
|
export interface NoteNodeDataKPA {
|
|
383
434
|
notes: NoteDataKPA[];
|
|
@@ -412,6 +463,28 @@ export interface JudgeLineDataKPA {
|
|
|
412
463
|
zOrder: number;
|
|
413
464
|
}
|
|
414
465
|
|
|
466
|
+
export interface JudgeLineDataKPA2 {
|
|
467
|
+
cover: boolean;
|
|
468
|
+
id: number;
|
|
469
|
+
group: number;
|
|
470
|
+
nnLists: {[k: string]: NNListDataKPA};
|
|
471
|
+
hnLists: {[k: string]: NNListDataKPA};
|
|
472
|
+
name: string;
|
|
473
|
+
texture: string;
|
|
474
|
+
eventLayers: EventLayerDataKPA2[];
|
|
475
|
+
speedEventNodeSeq: string;
|
|
476
|
+
children: JudgeLineDataKPA2[];
|
|
477
|
+
rotatesWithFather: boolean;
|
|
478
|
+
|
|
479
|
+
anchor: [number, number];
|
|
480
|
+
extended?: {
|
|
481
|
+
scaleXEvents: string;
|
|
482
|
+
scaleYEvents: string;
|
|
483
|
+
textEvents?: string;
|
|
484
|
+
colorEvents?: string;
|
|
485
|
+
}
|
|
486
|
+
zOrder: number;
|
|
487
|
+
}
|
|
415
488
|
|
|
416
489
|
|
|
417
490
|
export interface EventNodeSequenceDataKPA<VT> {
|
|
@@ -425,9 +498,31 @@ export interface EventNodeSequenceDataKPA2<VT> {
|
|
|
425
498
|
events: EventDataKPA2<VT>[];
|
|
426
499
|
id: string;
|
|
427
500
|
type: EventType;
|
|
428
|
-
|
|
501
|
+
final: FinalEventStartNodeDataKPA2<VT>;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
export interface WrapperEasingBodyData {
|
|
505
|
+
jsExpr: string;
|
|
506
|
+
start: number;
|
|
507
|
+
end: number;
|
|
508
|
+
id: string;
|
|
429
509
|
}
|
|
430
510
|
|
|
511
|
+
export interface MacroEvaluatorBodyData {
|
|
512
|
+
macro: string;
|
|
513
|
+
id: string;
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
export interface MacroTimeBodyData {
|
|
517
|
+
id: string;
|
|
518
|
+
macro: string;
|
|
519
|
+
parametric?: boolean;
|
|
520
|
+
}
|
|
521
|
+
export interface MacroValueBodyData {
|
|
522
|
+
id: string;
|
|
523
|
+
macro: string;
|
|
524
|
+
parametric?: boolean;
|
|
525
|
+
}
|
|
431
526
|
export interface ChartDataKPA {
|
|
432
527
|
version: number;
|
|
433
528
|
offset: number;
|
|
@@ -448,7 +543,7 @@ export interface ChartDataKPA {
|
|
|
448
543
|
name: number;
|
|
449
544
|
level: number;
|
|
450
545
|
}
|
|
451
|
-
envEasings:
|
|
546
|
+
envEasings: TemplateEasingBodyData[]; // New!
|
|
452
547
|
eventNodeSequences: EventNodeSequenceDataKPA<any>[];
|
|
453
548
|
orphanLines: JudgeLineDataKPA[];
|
|
454
549
|
bpmList: BPMSegmentData[];
|
|
@@ -459,6 +554,7 @@ export interface ChartDataKPA {
|
|
|
459
554
|
|
|
460
555
|
export interface ChartDataKPA2 {
|
|
461
556
|
version: number;
|
|
557
|
+
$schema: string;
|
|
462
558
|
offset: number;
|
|
463
559
|
duration: number;
|
|
464
560
|
info: {
|
|
@@ -469,17 +565,21 @@ export interface ChartDataKPA2 {
|
|
|
469
565
|
composer: string;
|
|
470
566
|
};
|
|
471
567
|
ui: {
|
|
472
|
-
pause
|
|
473
|
-
combonumber
|
|
474
|
-
combo
|
|
475
|
-
score
|
|
476
|
-
bar
|
|
477
|
-
name
|
|
478
|
-
level
|
|
568
|
+
pause?: number;
|
|
569
|
+
combonumber?: number;
|
|
570
|
+
combo?: number;
|
|
571
|
+
score?: number;
|
|
572
|
+
bar?: number;
|
|
573
|
+
name?: number;
|
|
574
|
+
level?: number;
|
|
479
575
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
576
|
+
templateEasings: TemplateEasingBodyData[];
|
|
577
|
+
wrapperEasings: WrapperEasingBodyData[];
|
|
578
|
+
macroEvaluators: MacroEvaluatorBodyData[];
|
|
579
|
+
timeMacros: MacroTimeBodyData[];
|
|
580
|
+
valueMacros: MacroValueBodyData[];
|
|
581
|
+
eventNodeSequences: EventNodeSequenceDataKPA2<unknown>[];
|
|
582
|
+
orphanLines: JudgeLineDataKPA2[];
|
|
483
583
|
bpmList: BPMSegmentData[];
|
|
484
584
|
judgeLineGroups: string[];
|
|
485
585
|
chartTime?: number;
|
|
@@ -509,4 +609,5 @@ export enum NoteType {
|
|
|
509
609
|
|
|
510
610
|
export type ValueTypeOfEventType<T extends EventType> = [number, number, number, number, number, number, number, number, number, string, RGB][T]
|
|
511
611
|
|
|
612
|
+
export type ExtendedEventTypeName = "scaleX" | "scaleY" | "text" | "color"
|
|
512
613
|
/// #enddeclaration
|
package/easing.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { EventNodeSequence } from "./event";
|
|
1
|
+
import { type TemplateEasingBodyData, type EasingDataKPA2, EasingType, EventType, type SegmentedEasingData, type NormalEasingData, type BezierEasingData, type TemplateEasingData, WrapperEasingData, WrapperEasingBodyData } from "./chartTypes";
|
|
2
|
+
import { type EventNodeSequence } from "./event";
|
|
3
3
|
import { type TupleCoord } from "./util";
|
|
4
|
-
import Environment from "./env";
|
|
4
|
+
import Environment, { err } from "./env";
|
|
5
|
+
import { type ExpressionEvaluator } from "./evaluator";
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
/// #declaration:global
|
|
@@ -43,10 +44,6 @@ const easeOutBack = (x: number): number =>{
|
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
const linear = (x: number): number => x
|
|
46
|
-
const linearLine: CurveDrawer = (context: CanvasRenderingContext2D, startX: number, startY: number, endX: number , endY: number) =>
|
|
47
|
-
drawLine(context, startX, startY, endX, endY);
|
|
48
|
-
|
|
49
|
-
|
|
50
47
|
|
|
51
48
|
const easeOutSine = (x: number): number => Math.sin((x * Math.PI) / 2);
|
|
52
49
|
|
|
@@ -95,7 +92,46 @@ const easeInOutBack = toEaseInOut(easeInBack, easeOutBack);
|
|
|
95
92
|
const easeInOutElastic = toEaseInOut(easeInElastic, easeOutElastic);
|
|
96
93
|
const easeInOutBounce = toEaseInOut(easeInBounce, easeOutBounce);
|
|
97
94
|
|
|
98
|
-
|
|
95
|
+
|
|
96
|
+
export const easingFns = {
|
|
97
|
+
linear,
|
|
98
|
+
easeInSine,
|
|
99
|
+
easeOutSine,
|
|
100
|
+
easeInOutSine,
|
|
101
|
+
easeInQuad,
|
|
102
|
+
easeOutQuad,
|
|
103
|
+
easeInOutQuad,
|
|
104
|
+
easeInCubic,
|
|
105
|
+
easeOutCubic,
|
|
106
|
+
easeInOutCubic,
|
|
107
|
+
easeInQuart,
|
|
108
|
+
easeOutQuart,
|
|
109
|
+
easeInOutQuart,
|
|
110
|
+
easeInQuint,
|
|
111
|
+
easeOutQuint,
|
|
112
|
+
easeInOutQuint,
|
|
113
|
+
easeInExpo,
|
|
114
|
+
easeOutExpo,
|
|
115
|
+
easeInOutExpo,
|
|
116
|
+
easeInCirc,
|
|
117
|
+
easeOutCirc,
|
|
118
|
+
easeInOutCirc,
|
|
119
|
+
easeInBack,
|
|
120
|
+
easeOutBack,
|
|
121
|
+
easeInOutBack,
|
|
122
|
+
easeInElastic,
|
|
123
|
+
easeOutElastic,
|
|
124
|
+
easeInOutElastic,
|
|
125
|
+
easeInBounce,
|
|
126
|
+
easeOutBounce,
|
|
127
|
+
easeInOutBounce
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
type FuncType = "linear" | "sine" | "quad" | "cubic" | "quart" | "quint" | "expo" | "circ" | "back" | "elastic" | "bounce"
|
|
131
|
+
|
|
132
|
+
export const easingFnMap: {
|
|
133
|
+
[k in FuncType]: [(x: number) => number, (x: number) => number, (x: number) => number]
|
|
134
|
+
} = {
|
|
99
135
|
"linear": [linear, linear, linear],
|
|
100
136
|
"sine": [easeInSine, easeOutSine, toEaseInOut(easeInSine, easeOutSine)],
|
|
101
137
|
"quad": [easeInQuad, easeOutQuad, toEaseInOut(easeInQuad, easeOutQuad)],
|
|
@@ -134,24 +170,9 @@ export abstract class Easing {
|
|
|
134
170
|
}
|
|
135
171
|
return (t: number) => (this.getValue(easingLeft + timeDelta * t) - leftValue) / delta;
|
|
136
172
|
}
|
|
137
|
-
drawCurve(context: CanvasRenderingContext2D, startX: number, startY: number, endX: number , endY: number): void {
|
|
138
|
-
const delta = endY - startY;
|
|
139
|
-
const timeDelta = endX - startX;
|
|
140
|
-
let last = startY;
|
|
141
|
-
context.beginPath()
|
|
142
|
-
context.moveTo(startX, last)
|
|
143
|
-
for (let t = 4; t <= timeDelta; t += 4) {
|
|
144
|
-
const ratio = t / timeDelta
|
|
145
|
-
const curPosY = this.getValue(ratio) * delta + startY;
|
|
146
|
-
context.lineTo(startX + t, curPosY);
|
|
147
|
-
last = curPosY;
|
|
148
|
-
}
|
|
149
|
-
context.stroke();
|
|
150
|
-
}
|
|
151
173
|
}
|
|
152
174
|
|
|
153
175
|
|
|
154
|
-
type CurveDrawer = (context: CanvasRenderingContext2D, startX: number, startY: number, endX: number , endY: number) => void
|
|
155
176
|
|
|
156
177
|
|
|
157
178
|
/**
|
|
@@ -191,22 +212,13 @@ export class NormalEasing extends Easing {
|
|
|
191
212
|
funcType: string;
|
|
192
213
|
easeType: string;
|
|
193
214
|
_getValue: (t: number) => number;
|
|
194
|
-
_drawCurve: CurveDrawer;
|
|
195
215
|
constructor(fn: (t: number) => number);
|
|
196
|
-
constructor(fn: (t: number) => number
|
|
197
|
-
constructor(fn: (t: number) => number
|
|
216
|
+
constructor(fn: (t: number) => number);
|
|
217
|
+
constructor(fn: (t: number) => number) {
|
|
198
218
|
super()
|
|
199
219
|
this._getValue = fn;
|
|
200
|
-
if (curveDrawer) {
|
|
201
|
-
this._drawCurve = curveDrawer;
|
|
202
|
-
}
|
|
203
220
|
}
|
|
204
221
|
getValue(t: number): number {
|
|
205
|
-
if (t > 1 || t < 0) {
|
|
206
|
-
console.warn("缓动超出定义域!")
|
|
207
|
-
// debugger;
|
|
208
|
-
}
|
|
209
|
-
// console.log("t:", t, "rat", this._getValue(t))
|
|
210
222
|
return this._getValue(t)
|
|
211
223
|
}
|
|
212
224
|
private dumpCache: NormalEasingData;
|
|
@@ -216,13 +228,6 @@ export class NormalEasing extends Easing {
|
|
|
216
228
|
identifier: this.rpeId
|
|
217
229
|
}
|
|
218
230
|
}
|
|
219
|
-
drawCurve(context: CanvasRenderingContext2D, startX: number, startY: number, endX: number , endY: number) {
|
|
220
|
-
if (this._drawCurve) {
|
|
221
|
-
this._drawCurve(context, startX, startY, endX, endY)
|
|
222
|
-
} else {
|
|
223
|
-
super.drawCurve(context, startX, startY, endX, endY);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
231
|
}
|
|
227
232
|
|
|
228
233
|
|
|
@@ -234,18 +239,18 @@ export class NormalEasing extends Easing {
|
|
|
234
239
|
* uses the Bezier curve formula to describe an easing.
|
|
235
240
|
*/
|
|
236
241
|
export class BezierEasing extends Easing {
|
|
237
|
-
readonly xs:
|
|
238
|
-
readonly ys:
|
|
239
|
-
readonly jumper:
|
|
242
|
+
readonly xs: Float64Array;
|
|
243
|
+
readonly ys: Float64Array;
|
|
244
|
+
readonly jumper: Uint8Array;
|
|
240
245
|
constructor(public readonly cp1: TupleCoord, public readonly cp2: TupleCoord) {
|
|
241
246
|
super()
|
|
242
247
|
const BEZIER_INTERPOLATION_DENSITY = Environment.BEZIER_INTERPOLATION_DENSITY;
|
|
243
248
|
const BEZIER_INTERPOLATION_STEP = 1 / BEZIER_INTERPOLATION_DENSITY;
|
|
244
249
|
// 插值,把贝塞尔曲线近似成256段折线
|
|
245
|
-
const xs
|
|
246
|
-
const ys
|
|
250
|
+
const xs = new Float64Array(BEZIER_INTERPOLATION_DENSITY - 1);
|
|
251
|
+
const ys = new Float64Array(BEZIER_INTERPOLATION_DENSITY - 1);
|
|
247
252
|
/** 一把尺子,刻度均匀,从`插值步长*下标`映射到xs里面的下标 */
|
|
248
|
-
const jumper
|
|
253
|
+
const jumper = new Uint8Array(BEZIER_INTERPOLATION_DENSITY);
|
|
249
254
|
let nextToFill = 0;
|
|
250
255
|
for (let i = 1; i < BEZIER_INTERPOLATION_DENSITY; i++) {
|
|
251
256
|
// 这个t是贝塞尔曲线生成参数
|
|
@@ -261,9 +266,9 @@ export class BezierEasing extends Easing {
|
|
|
261
266
|
for (; 1 > nextToFill * BEZIER_INTERPOLATION_STEP; nextToFill++) {
|
|
262
267
|
jumper[nextToFill] = BEZIER_INTERPOLATION_DENSITY - 1;
|
|
263
268
|
}
|
|
264
|
-
this.xs =
|
|
265
|
-
this.ys =
|
|
266
|
-
this.jumper =
|
|
269
|
+
this.xs = xs;
|
|
270
|
+
this.ys = ys;
|
|
271
|
+
this.jumper = jumper;
|
|
267
272
|
}
|
|
268
273
|
/**
|
|
269
274
|
* 从横坐标获得纵坐标
|
|
@@ -296,19 +301,6 @@ export class BezierEasing extends Easing {
|
|
|
296
301
|
bezier: [this.cp1[0], this.cp1[1], this.cp2[0], this.cp2[1]]
|
|
297
302
|
}
|
|
298
303
|
}
|
|
299
|
-
drawCurve(context: CanvasRenderingContext2D, startX: number, startY: number, endX: number , endY: number): void {
|
|
300
|
-
const [cp1x, cp1y] = this.cp1;
|
|
301
|
-
const [cp2x, cp2y] = this.cp2
|
|
302
|
-
const delta = endY - startY;
|
|
303
|
-
const timeDelta = endX - startX;
|
|
304
|
-
drawBezierCurve(
|
|
305
|
-
context,
|
|
306
|
-
startX, startY,
|
|
307
|
-
endX, endY,
|
|
308
|
-
startX + cp1x * timeDelta, startY + cp1y * delta,
|
|
309
|
-
startX + cp2x * timeDelta, startY + cp2y * delta,
|
|
310
|
-
)
|
|
311
|
-
}
|
|
312
304
|
}
|
|
313
305
|
|
|
314
306
|
/**
|
|
@@ -341,7 +333,7 @@ export class TemplateEasing extends Easing {
|
|
|
341
333
|
}
|
|
342
334
|
}
|
|
343
335
|
get valueDelta(): number {
|
|
344
|
-
|
|
336
|
+
const seq = this.eventNodeSequence;
|
|
345
337
|
return seq.tail.previous.value - seq.head.next.value;
|
|
346
338
|
}
|
|
347
339
|
get headValue(): number {
|
|
@@ -349,6 +341,24 @@ export class TemplateEasing extends Easing {
|
|
|
349
341
|
}
|
|
350
342
|
}
|
|
351
343
|
|
|
344
|
+
export class WrapperEasing extends Easing {
|
|
345
|
+
// 需要一对面对面节点
|
|
346
|
+
constructor(public evaluator: ExpressionEvaluator<number>, public start: number, public end: number, public name: string) {
|
|
347
|
+
super()
|
|
348
|
+
}
|
|
349
|
+
getValue(t: number): number {
|
|
350
|
+
const end = this.end;
|
|
351
|
+
const start = this.start;
|
|
352
|
+
return (this.evaluator.func(t) - start) / (end - start);
|
|
353
|
+
}
|
|
354
|
+
dump(): WrapperEasingData {
|
|
355
|
+
return {
|
|
356
|
+
type: EasingType.wrapper,
|
|
357
|
+
identifier: this.name
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
|
|
352
362
|
|
|
353
363
|
|
|
354
364
|
|
|
@@ -356,8 +366,10 @@ export class TemplateEasing extends Easing {
|
|
|
356
366
|
* 缓动库
|
|
357
367
|
* 用于管理模板缓动
|
|
358
368
|
* for template easing management
|
|
369
|
+
*
|
|
359
370
|
* 谱面的一个属性
|
|
360
371
|
* a property of chart
|
|
372
|
+
*
|
|
361
373
|
* 加载谱面时,先加载事件序列,所需的模板缓动会被加入到缓动库,但并不立即实现,在读取模板缓动时,才实现缓动。
|
|
362
374
|
* To load a chart, the eventNodeSquences will be first loaded, during which process
|
|
363
375
|
* the easings will be added to the easing library but not implemented immediately.
|
|
@@ -365,31 +377,42 @@ export class TemplateEasing extends Easing {
|
|
|
365
377
|
*
|
|
366
378
|
*/
|
|
367
379
|
export class TemplateEasingLib {
|
|
368
|
-
easings
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
constructor() {
|
|
372
|
-
this.easings = {};
|
|
380
|
+
easings = new Map<string, TemplateEasing>();
|
|
381
|
+
wrapperEasings = new Map<string, WrapperEasing>();
|
|
382
|
+
// 被迫给一个静态方法进行依赖注入,恨死你了,ESM
|
|
383
|
+
constructor(public getNewSequence: (type: EventType, effectiveBeats: number) => EventNodeSequence<number>, public ExpressionEvaluatorCon: typeof ExpressionEvaluator) {
|
|
373
384
|
}
|
|
374
385
|
getOrNew(name: string): TemplateEasing {
|
|
375
386
|
const DEFAULT_TEMPLATE_LENGTH = Environment.DEFAULT_TEMPLATE_LENGTH;
|
|
376
|
-
if (this.easings
|
|
377
|
-
return this.easings
|
|
387
|
+
if (this.easings.has(name)) {
|
|
388
|
+
return this.easings.get(name);
|
|
378
389
|
} else {
|
|
379
|
-
const easing = new TemplateEasing(name,
|
|
390
|
+
const easing = new TemplateEasing(name, this.getNewSequence(EventType.easing, DEFAULT_TEMPLATE_LENGTH));
|
|
380
391
|
easing.eventNodeSequence.id = "*" + name;
|
|
381
|
-
|
|
392
|
+
this.easings.set(name, easing)
|
|
393
|
+
return easing;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
readWrapperEasings(data: WrapperEasingBodyData[]) {
|
|
397
|
+
const len = data.length;
|
|
398
|
+
for (let i = 0; i < len; i++) {
|
|
399
|
+
const datum = data[i];
|
|
400
|
+
// 属于是油饼
|
|
401
|
+
this.wrapperEasings.set(datum.id, new WrapperEasing(new this.ExpressionEvaluatorCon(datum.jsExpr), datum.start, datum.end, datum.id))
|
|
382
402
|
}
|
|
383
403
|
}
|
|
404
|
+
getWrapper(name: string): WrapperEasing {
|
|
405
|
+
return this.wrapperEasings.get(name);
|
|
406
|
+
}
|
|
384
407
|
/**
|
|
385
408
|
* 注册一个模板缓动,但不会实现它
|
|
386
409
|
* register a template easing when reading eventNodeSequences, but does not implement it immediately
|
|
387
410
|
*/
|
|
388
411
|
require(name: string) {
|
|
389
|
-
this.easings
|
|
412
|
+
this.easings.set(name, new TemplateEasing(name, null));
|
|
390
413
|
}
|
|
391
414
|
implement(name: string, sequence: EventNodeSequence) {
|
|
392
|
-
this.easings
|
|
415
|
+
this.easings.get(name).eventNodeSequence = sequence;
|
|
393
416
|
}
|
|
394
417
|
/**
|
|
395
418
|
* 检查所有模板缓动是否实现
|
|
@@ -398,20 +421,19 @@ export class TemplateEasingLib {
|
|
|
398
421
|
* should be invoked after all template easings are read
|
|
399
422
|
*/
|
|
400
423
|
check() {
|
|
401
|
-
for (
|
|
402
|
-
if (!
|
|
403
|
-
|
|
424
|
+
for (const [name, easing] of this.easings) {
|
|
425
|
+
if (!easing.eventNodeSequence) {
|
|
426
|
+
err.UNIMPLEMENTED_TEMPLATE_EASING(name).warn();
|
|
404
427
|
}
|
|
405
428
|
}
|
|
406
429
|
}
|
|
407
430
|
get(key: string): TemplateEasing | undefined {
|
|
408
|
-
return this.easings
|
|
431
|
+
return this.easings.get(key);
|
|
409
432
|
}
|
|
410
433
|
|
|
411
|
-
dump(eventNodeSequences: Set<EventNodeSequence>):
|
|
412
|
-
const customEasingDataList:
|
|
413
|
-
for (
|
|
414
|
-
const templateEasing = this.easings[key];
|
|
434
|
+
dump(eventNodeSequences: Set<EventNodeSequence>): TemplateEasingBodyData[] {
|
|
435
|
+
const customEasingDataList: TemplateEasingBodyData[] = [];
|
|
436
|
+
for (const [key, templateEasing] of this.easings) {
|
|
415
437
|
const eventNodeSequence = templateEasing.eventNodeSequence;
|
|
416
438
|
if (eventNodeSequences.has(eventNodeSequence)) {
|
|
417
439
|
continue;
|
|
@@ -419,16 +441,26 @@ export class TemplateEasingLib {
|
|
|
419
441
|
eventNodeSequences.add(eventNodeSequence);
|
|
420
442
|
customEasingDataList.push({
|
|
421
443
|
name: key,
|
|
422
|
-
content: eventNodeSequence.id
|
|
423
|
-
usedBy: [],
|
|
424
|
-
dependencies: []
|
|
444
|
+
content: eventNodeSequence.id // 这里只存储编号,具体内容在保存时再编码
|
|
425
445
|
});
|
|
426
446
|
}
|
|
427
447
|
return customEasingDataList;
|
|
428
448
|
}
|
|
449
|
+
dumpWrapperEasings(): WrapperEasingBodyData[] {
|
|
450
|
+
const wrapperEasingDataList: WrapperEasingBodyData[] = [];
|
|
451
|
+
for (const [key, wrapperEasing] of this.wrapperEasings) {
|
|
452
|
+
wrapperEasingDataList.push({
|
|
453
|
+
id: key,
|
|
454
|
+
jsExpr: wrapperEasing.evaluator.jsExpr,
|
|
455
|
+
start: wrapperEasing.start,
|
|
456
|
+
end: wrapperEasing.end
|
|
457
|
+
})
|
|
458
|
+
}
|
|
459
|
+
return wrapperEasingDataList;
|
|
460
|
+
}
|
|
429
461
|
}
|
|
430
462
|
|
|
431
|
-
export const linearEasing = new NormalEasing(linear
|
|
463
|
+
export const linearEasing = new NormalEasing(linear);
|
|
432
464
|
export const fixedEasing = new NormalEasing((x: number): number => (x === 1 ? 1 : 0));
|
|
433
465
|
|
|
434
466
|
export const easingMap = {
|
|
@@ -446,8 +478,8 @@ export const easingMap = {
|
|
|
446
478
|
"bounce": {in: new NormalEasing(easeInBounce), out: new NormalEasing(easeOutBounce), inout: new NormalEasing(easeInOutBounce)}
|
|
447
479
|
}
|
|
448
480
|
|
|
449
|
-
for (
|
|
450
|
-
for (
|
|
481
|
+
for (const funcType in easingMap) {
|
|
482
|
+
for (const easeType in easingMap[funcType]) {
|
|
451
483
|
const easing = easingMap[funcType][easeType];
|
|
452
484
|
easing.funcType = funcType;
|
|
453
485
|
easing.easeType = easeType;
|
|
@@ -499,7 +531,7 @@ easingArray.forEach((easing, index) => {
|
|
|
499
531
|
})
|
|
500
532
|
|
|
501
533
|
export const rpeEasingArray = [
|
|
502
|
-
|
|
534
|
+
fixedEasing,
|
|
503
535
|
linearEasing, // 1
|
|
504
536
|
easingMap.sine.out, // 2
|
|
505
537
|
easingMap.sine.in, // 3
|
|
@@ -539,5 +571,8 @@ rpeEasingArray.forEach((easing, index) => {
|
|
|
539
571
|
}
|
|
540
572
|
easing.rpeId = index;
|
|
541
573
|
})
|
|
574
|
+
// 强行添加,避免存储不了这些缓动
|
|
575
|
+
easingMap.expo.inout.rpeId = 101;
|
|
576
|
+
easingMap.quint.inout.rpeId = 102;
|
|
542
577
|
|
|
543
578
|
/// #enddeclaration
|