2024-05-09 23:49:53 +08:00
|
|
|
|
import { MotaOffscreenCanvas2D } from '../fx/canvas2d';
|
2024-08-24 00:43:22 +08:00
|
|
|
|
import {
|
|
|
|
|
ERenderItemEvent,
|
|
|
|
|
IRenderChildable,
|
|
|
|
|
RenderItem,
|
|
|
|
|
RenderItemPosition
|
|
|
|
|
} from './item';
|
2024-08-22 23:29:15 +08:00
|
|
|
|
import { Transform } from './transform';
|
2024-05-09 23:49:53 +08:00
|
|
|
|
|
2024-08-24 00:43:22 +08:00
|
|
|
|
export interface EContainerEvent extends ERenderItemEvent {}
|
|
|
|
|
|
|
|
|
|
export class Container<E extends EContainerEvent = EContainerEvent>
|
|
|
|
|
extends RenderItem<E | EContainerEvent>
|
|
|
|
|
implements IRenderChildable
|
|
|
|
|
{
|
2024-05-09 23:49:53 +08:00
|
|
|
|
children: RenderItem[] = [];
|
|
|
|
|
sortedChildren: RenderItem[] = [];
|
|
|
|
|
|
2024-08-23 20:58:23 +08:00
|
|
|
|
private needSort: boolean = false;
|
|
|
|
|
|
2024-08-17 23:11:20 +08:00
|
|
|
|
/**
|
|
|
|
|
* 创建一个容器,容器中可以包含其他渲染对象
|
2024-08-22 23:29:15 +08:00
|
|
|
|
* @param type 渲染模式,absolute表示绝对位置,static表示跟随摄像机移动
|
2024-08-17 23:11:20 +08:00
|
|
|
|
* @param cache 是否启用缓存机制
|
|
|
|
|
*/
|
|
|
|
|
constructor(type: RenderItemPosition = 'static', cache: boolean = true) {
|
2024-08-23 20:58:23 +08:00
|
|
|
|
super(type, cache);
|
2024-05-09 23:49:53 +08:00
|
|
|
|
this.type = type;
|
2024-08-17 23:11:20 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-08-22 23:29:15 +08:00
|
|
|
|
protected render(
|
|
|
|
|
canvas: MotaOffscreenCanvas2D,
|
|
|
|
|
transform: Transform
|
|
|
|
|
): void {
|
2024-08-17 23:11:20 +08:00
|
|
|
|
const { ctx } = canvas;
|
2024-08-23 20:58:23 +08:00
|
|
|
|
|
2024-08-17 23:11:20 +08:00
|
|
|
|
this.sortedChildren.forEach(v => {
|
|
|
|
|
if (v.hidden) return;
|
|
|
|
|
ctx.save();
|
2024-08-22 23:29:15 +08:00
|
|
|
|
v.renderContent(canvas, transform);
|
2024-08-17 23:11:20 +08:00
|
|
|
|
ctx.restore();
|
|
|
|
|
});
|
2024-05-09 23:49:53 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 添加子元素到这个容器上,然后在下一个tick执行更新
|
|
|
|
|
* @param children 要添加的子元素
|
|
|
|
|
*/
|
2024-08-22 23:29:15 +08:00
|
|
|
|
appendChild(...children: RenderItem<any>[]) {
|
2024-05-09 23:49:53 +08:00
|
|
|
|
children.forEach(v => (v.parent = this));
|
|
|
|
|
this.children.push(...children);
|
2024-08-23 20:58:23 +08:00
|
|
|
|
if (!this.needSort) {
|
|
|
|
|
this.needSort = true;
|
|
|
|
|
this.requestBeforeFrame(() => {
|
|
|
|
|
this.needSort = false;
|
|
|
|
|
this.sortChildren();
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-05-23 23:55:08 +08:00
|
|
|
|
this.update(this);
|
|
|
|
|
}
|
|
|
|
|
|
2024-08-22 23:29:15 +08:00
|
|
|
|
removeChild(...child: RenderItem<any>[]): void {
|
2024-05-23 23:55:08 +08:00
|
|
|
|
child.forEach(v => {
|
|
|
|
|
const index = this.children.indexOf(v);
|
|
|
|
|
if (index === -1) return;
|
|
|
|
|
this.children.splice(index, 1);
|
|
|
|
|
});
|
|
|
|
|
this.sortChildren();
|
|
|
|
|
this.update(this);
|
2024-05-16 22:43:24 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
sortChildren() {
|
2024-05-09 23:49:53 +08:00
|
|
|
|
this.sortedChildren = this.children
|
|
|
|
|
.slice()
|
|
|
|
|
.sort((a, b) => a.zIndex - b.zIndex);
|
|
|
|
|
}
|
2024-05-16 22:43:24 +08:00
|
|
|
|
|
2024-05-23 23:55:08 +08:00
|
|
|
|
destroy(): void {
|
|
|
|
|
super.destroy();
|
|
|
|
|
this.children.forEach(v => {
|
|
|
|
|
v.destroy();
|
|
|
|
|
});
|
|
|
|
|
}
|
2024-05-09 23:49:53 +08:00
|
|
|
|
}
|