|
@@ -44,7 +44,7 @@ export namespace MiniRender {
|
|
|
|
|
|
|
|
export type RenderObjectEventName = "added" | "removed" | "click" |
|
|
export type RenderObjectEventName = "added" | "removed" | "click" |
|
|
|
"touchstart" | "touchmove" | "touchend" | "touchcancel" |
|
|
"touchstart" | "touchmove" | "touchend" | "touchcancel" |
|
|
|
- "animationEnd";
|
|
|
|
|
|
|
+ "animationEnd" | "fadeInEnd" | "fadeOutEnd";
|
|
|
export type RenderObjectEventHandler = (obj: RenderObject, data?: any) => void;
|
|
export type RenderObjectEventHandler = (obj: RenderObject, data?: any) => void;
|
|
|
|
|
|
|
|
export class RenderObject implements TransformLike, IRenderable, IUpdatable {
|
|
export class RenderObject implements TransformLike, IRenderable, IUpdatable {
|
|
@@ -70,6 +70,8 @@ export namespace MiniRender {
|
|
|
|
|
|
|
|
public data: any = null;
|
|
public data: any = null;
|
|
|
|
|
|
|
|
|
|
+ private _fade: { type: 'in' | 'out'; duration: number; elapsed: number; from: number; to: number } | null = null;
|
|
|
|
|
+
|
|
|
private listeners = new Map<RenderObjectEventName, Set<RenderObjectEventHandler>>();
|
|
private listeners = new Map<RenderObjectEventName, Set<RenderObjectEventHandler>>();
|
|
|
|
|
|
|
|
constructor(id?: RenderObjectId) {
|
|
constructor(id?: RenderObjectId) {
|
|
@@ -128,7 +130,28 @@ export namespace MiniRender {
|
|
|
this.withTransform(rc, () => this.draw(rc));
|
|
this.withTransform(rc, () => this.draw(rc));
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- public update(_dtMs: number): void {}
|
|
|
|
|
|
|
+ public update(_dtMs: number): void {
|
|
|
|
|
+ if (this._fade) {
|
|
|
|
|
+ this._fade.elapsed += _dtMs;
|
|
|
|
|
+ const t = Math.min(1, this._fade.elapsed / this._fade.duration);
|
|
|
|
|
+ this.alpha = this._fade.from + (this._fade.to - this._fade.from) * t;
|
|
|
|
|
+ if (t >= 1) {
|
|
|
|
|
+ const type = this._fade.type;
|
|
|
|
|
+ this._fade = null;
|
|
|
|
|
+ this.emit(type === 'in' ? 'fadeInEnd' : 'fadeOutEnd');
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public fadeIn(durationMs = 300): void {
|
|
|
|
|
+ this.alpha = 0;
|
|
|
|
|
+ this.visible = true;
|
|
|
|
|
+ this._fade = { type: 'in', duration: durationMs, elapsed: 0, from: 0, to: 1 };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public fadeOut(durationMs = 300): void {
|
|
|
|
|
+ this._fade = { type: 'out', duration: durationMs, elapsed: 0, from: this.alpha, to: 0 };
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
public parentToLocal(px: number, py: number): { x: number; y: number } | null {
|
|
public parentToLocal(px: number, py: number): { x: number; y: number } | null {
|
|
|
const ax = this.anchorX * this.width;
|
|
const ax = this.anchorX * this.width;
|
|
@@ -551,7 +574,10 @@ export namespace MiniRender {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
public override update(dtMs: number): void {
|
|
public override update(dtMs: number): void {
|
|
|
- if (!this.playing || this._waitingForImage) return;
|
|
|
|
|
|
|
+ super.update(dtMs);
|
|
|
|
|
+
|
|
|
|
|
+ if (!this.playing || this._waitingForImage)
|
|
|
|
|
+ return;
|
|
|
|
|
|
|
|
const seq = this.getAnimationSequence();
|
|
const seq = this.getAnimationSequence();
|
|
|
if (seq.length <= 1) return;
|
|
if (seq.length <= 1) return;
|
|
@@ -580,22 +606,26 @@ export namespace MiniRender {
|
|
|
|
|
|
|
|
protected override draw(rc: RenderContext): void {
|
|
protected override draw(rc: RenderContext): void {
|
|
|
const { ctx, scene } = rc;
|
|
const { ctx, scene } = rc;
|
|
|
- if (!this.frames.length) return;
|
|
|
|
|
|
|
+ if (!this.frames.length)
|
|
|
|
|
+ return;
|
|
|
|
|
|
|
|
const fIdx = this.currentFrameIndex;
|
|
const fIdx = this.currentFrameIndex;
|
|
|
const frame = this.frames[fIdx];
|
|
const frame = this.frames[fIdx];
|
|
|
- if (!frame) return;
|
|
|
|
|
|
|
+ if (!frame)
|
|
|
|
|
+ return;
|
|
|
|
|
|
|
|
const [sx, sy, sw, sh, originX = 0, originY = 0, imageIndex = 0] = frame;
|
|
const [sx, sy, sw, sh, originX = 0, originY = 0, imageIndex = 0] = frame;
|
|
|
- if (sw <= 0 || sh <= 0) return;
|
|
|
|
|
-
|
|
|
|
|
- const src = this.images[imageIndex] ?? this.images[0];
|
|
|
|
|
- if (!src) return;
|
|
|
|
|
-
|
|
|
|
|
|
|
+ if (sw <= 0 || sh <= 0)
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
// 默认使用帧尺寸作为显示尺寸
|
|
// 默认使用帧尺寸作为显示尺寸
|
|
|
if (this.width <= 0) this.width = sw;
|
|
if (this.width <= 0) this.width = sw;
|
|
|
if (this.height <= 0) this.height = sh;
|
|
if (this.height <= 0) this.height = sh;
|
|
|
|
|
|
|
|
|
|
+ const src = this.images[imageIndex] ?? this.images[0];
|
|
|
|
|
+ if (!src)
|
|
|
|
|
+ return;
|
|
|
|
|
+
|
|
|
let img = this._resolvedImages[imageIndex] ?? null;
|
|
let img = this._resolvedImages[imageIndex] ?? null;
|
|
|
img = img ?? scene.assets.getImageSync(src);
|
|
img = img ?? scene.assets.getImageSync(src);
|
|
|
if (!img) {
|
|
if (!img) {
|
|
@@ -624,13 +654,23 @@ export namespace MiniRender {
|
|
|
constructor(private canvas: RendeCanvasInterface) {}
|
|
constructor(private canvas: RendeCanvasInterface) {}
|
|
|
|
|
|
|
|
public getImage(src: string): Promise<any> {
|
|
public getImage(src: string): Promise<any> {
|
|
|
- if (this.imageResolved.has(src)) return Promise.resolve(this.imageResolved.get(src));
|
|
|
|
|
|
|
+ if (this.imageResolved.has(src))
|
|
|
|
|
+ return Promise.resolve(this.imageResolved.get(src));
|
|
|
const inflight = this.imageCache.get(src);
|
|
const inflight = this.imageCache.get(src);
|
|
|
- if (inflight) return inflight;
|
|
|
|
|
-
|
|
|
|
|
- const p = this.canvas.createImage(src).then((img) => {
|
|
|
|
|
- this.imageResolved.set(src, img);
|
|
|
|
|
- return img;
|
|
|
|
|
|
|
+ if (inflight)
|
|
|
|
|
+ return inflight;
|
|
|
|
|
+
|
|
|
|
|
+ console.log('[AssetManager] Load image', src);
|
|
|
|
|
+
|
|
|
|
|
+ const p = new Promise<any>((resolve, reject) => {
|
|
|
|
|
+ this.canvas.createImage(src).then((img) => {
|
|
|
|
|
+ this.imageResolved.set(src, img);
|
|
|
|
|
+ resolve(img);
|
|
|
|
|
+ return img;
|
|
|
|
|
+ }).catch((e) => {
|
|
|
|
|
+ console.error('[AssetManager] Failed to load image', src, e);
|
|
|
|
|
+ reject(e);
|
|
|
|
|
+ })
|
|
|
});
|
|
});
|
|
|
this.imageCache.set(src, p);
|
|
this.imageCache.set(src, p);
|
|
|
return p;
|
|
return p;
|