perf: 子元素渲染性能

This commit is contained in:
unanmed 2025-01-12 12:03:53 +08:00
parent ba30d111a5
commit 7d8cbac246
6 changed files with 30 additions and 46 deletions

View File

@ -107,5 +107,5 @@ export function buildFont(
weight: number = 500,
italic: boolean = false
) {
return `${italic ? 'italic ' : ''}${weight} ${size}px ${family}`;
return `${italic ? 'italic ' : ''}${weight} ${size}px "${family}"`;
}

View File

@ -36,13 +36,9 @@ export class Container<E extends EContainerEvent = EContainerEvent>
canvas: MotaOffscreenCanvas2D,
transform: Transform
): void {
const { ctx } = canvas;
this.sortedChildren.forEach(v => {
if (v.hidden) return;
ctx.save();
v.renderContent(canvas, transform);
ctx.restore();
});
}

View File

@ -140,8 +140,6 @@ interface IRenderVueSupport {
}
export interface ERenderItemEvent {
beforeUpdate: [item?: RenderItem];
afterUpdate: [item?: RenderItem];
beforeRender: [transform: Transform];
afterRender: [transform: Transform];
destroy: [];
@ -344,7 +342,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
canvas.ctx.translate(ax, ay);
this.render(canvas, tran);
}
canvas.ctx.restore();
ctx.restore();
this.emit('afterRender', transform);
}
@ -389,6 +387,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
* 使
*/
getAbsolutePosition(): LocArr {
if (this.type === 'absolute') return [0, 0];
const { x, y } = this.transform;
if (!this.parent) return [x, y];
else {
@ -400,13 +399,15 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
setAnchor(x: number, y: number): void {
this.anchorX = x;
this.anchorY = y;
this.update();
}
update(item: RenderItem<any> = this, force: boolean = false): void {
if ((this.needUpdate || this.hidden) && !force) return;
update(item: RenderItem<any> = this): void {
if (this.needUpdate) return;
this.needUpdate = true;
this.cacheDirty = true;
this.parent?.update(item, force);
if (this.hidden) return;
this.parent?.update(item);
}
setHD(hd: boolean): void {
@ -475,7 +476,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
hide() {
if (this.hidden) return;
this.hidden = true;
this.update(this, true);
this.update(this);
}
/**
@ -484,13 +485,13 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
show() {
if (!this.hidden) return;
this.hidden = false;
this.refreshAllChildren(true);
this.refreshAllChildren();
}
/**
*
*/
refreshAllChildren(force: boolean = false) {
refreshAllChildren() {
if (this.children.size > 0) {
const stack: RenderItem[] = [this];
while (stack.length > 0) {
@ -500,7 +501,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
item.children.forEach(v => stack.push(v));
}
}
this.update(this, force);
this.update(this);
}
/**
@ -523,6 +524,7 @@ export abstract class RenderItem<E extends ERenderItemEvent = ERenderItemEvent>
/**
*
* @returns
*/
remove(): boolean {
if (!this.parent) return false;

View File

@ -2,20 +2,10 @@ import { MotaOffscreenCanvas2D } from '@/core/fx/canvas2d';
import { Container, EContainerEvent } from '../container';
import { Sprite } from '../sprite';
import { TimingFn } from 'mutate-animate';
import {
ERenderItemEvent,
IAnimateFrame,
renderEmits,
RenderItem
} from '../item';
import { IAnimateFrame, renderEmits, RenderItem } from '../item';
import { logger } from '@/core/common/logger';
import { RenderableData, texture } from '../cache';
import {
BlockCacher,
CanvasCacheItem,
IBlockCacheable,
ICanvasCacheItem
} from './block';
import { BlockCacher, CanvasCacheItem, ICanvasCacheItem } from './block';
import { Transform } from '../transform';
import { LayerFloorBinder, LayerGroupFloorBinder } from './floor';
import { RenderAdapter } from '../adapter';
@ -148,13 +138,9 @@ export class LayerGroup
}
protected render(canvas: MotaOffscreenCanvas2D): void {
const { ctx } = canvas;
this.sortedChildren.forEach(v => {
if (v.hidden) return;
ctx.save();
v.renderContent(canvas, this.camera);
ctx.restore();
});
}
@ -362,13 +348,14 @@ export class LayerGroup
if (!this.assertType(nextValue, 'number', key)) return;
this.setBlockSize(nextValue);
return;
case 'floorId':
case 'floorId': {
if (!this.assertType(nextValue, 'number', key)) return;
const binder = this.getExtends('floor-binder');
if (binder instanceof LayerGroupFloorBinder) {
binder.bindFloor(nextValue);
}
return;
}
case 'camera':
if (!this.assertType(nextValue, Camera, key)) return;
this.camera = nextValue;
@ -1376,7 +1363,7 @@ export class Layer extends Container<ELayerEvent> {
// 删除原始位置的图块
this.putRenderData([0], 1, fx, fy);
let nowZ = fy;
const nowZ = fy;
const startTime = Date.now();
return new Promise<void>(resolve => {
this.delegateTicker(
@ -1423,7 +1410,7 @@ export class Layer extends Container<ELayerEvent> {
time: number,
relative: boolean = true
) {
let nowZ = y;
const nowZ = y;
const startTime = Date.now();
return new Promise<void>(resolve => {
this.delegateTicker(
@ -1459,7 +1446,7 @@ export class Layer extends Container<ELayerEvent> {
parentComponent?: ComponentInternalInstance | null
): void {
switch (key) {
case 'layer':
case 'layer': {
if (!this.assertType(nextValue, 'string', key)) return;
const parent = this.parent;
if (parent instanceof LayerGroup) {
@ -1471,6 +1458,7 @@ export class Layer extends Container<ELayerEvent> {
}
this.update();
return;
}
case 'cellSize':
if (!this.assertType(nextValue, 'number', key)) return;
this.setCellSize(nextValue);

View File

@ -31,21 +31,19 @@ export class MotaRenderer extends Container {
MotaRenderer.list.set(id, this);
}
update(item: RenderItem = this) {
update(_item: RenderItem = this) {
if (this.needUpdate || this.hidden) return;
this.needUpdate = true;
this.requestRenderFrame(() => {
this.refresh(item);
this.refresh();
});
}
protected refresh(item: RenderItem = this): void {
protected refresh(): void {
if (!this.needUpdate) return;
this.needUpdate = false;
this.emit('beforeUpdate', item);
this.target.clear();
this.renderContent(this.target, Transform.identity);
this.emit('afterUpdate', item);
}
/**

View File

@ -1,8 +1,8 @@
import { Ticker, TimingFn } from 'mutate-animate';
import { TimingFn } from 'mutate-animate';
import { RenderAdapter } from './adapter';
import { FloorViewport } from './preset/viewport';
import { JSX } from 'vue/jsx-runtime';
import { Component, DefineComponent, DefineSetupFnComponent } from 'vue';
import { DefineComponent, DefineSetupFnComponent } from 'vue';
export type Props<
T extends
@ -12,10 +12,10 @@ export type Props<
> = T extends keyof JSX.IntrinsicElements
? JSX.IntrinsicElements[T]
: T extends DefineSetupFnComponent<any>
? InstanceType<T>['$props']
: T extends DefineComponent
? InstanceType<T>['$props']
: unknown;
? InstanceType<T>['$props']
: T extends DefineComponent
? InstanceType<T>['$props']
: unknown;
export function disableViewport() {
const adapter = RenderAdapter.get<FloorViewport>('viewport');