@eva/plugin-renderer 2.0.2 → 2.1.0-beta.2

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.
@@ -35,6 +35,10 @@ function __decorate(decorators, target, key, desc) {
35
35
  return c > 3 && r && Object.defineProperty(target, key, r), r;
36
36
  }
37
37
 
38
+ function __metadata(metadataKey, metadataValue) {
39
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue);
40
+ }
41
+
38
42
  function __awaiter(thisArg, _arguments, P, generator) {
39
43
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
40
44
  return new (P || (P = Promise))(function (resolve, reject) {
@@ -146,6 +150,22 @@ class RendererManager {
146
150
  }
147
151
  var RendererManager$1 = RendererManager;
148
152
 
153
+ const toRenderBounds = (bounds, coordinateSpace, source) => {
154
+ const x = Number.isFinite(bounds.x) ? bounds.x : 0;
155
+ const y = Number.isFinite(bounds.y) ? bounds.y : 0;
156
+ const width = Number.isFinite(bounds.width) ? bounds.width : 0;
157
+ const height = Number.isFinite(bounds.height) ? bounds.height : 0;
158
+ return {
159
+ x,
160
+ y,
161
+ width,
162
+ height,
163
+ right: x + width,
164
+ bottom: y + height,
165
+ coordinateSpace,
166
+ source,
167
+ };
168
+ };
149
169
  class ContainerManager {
150
170
  constructor() {
151
171
  this.containerMap = {};
@@ -157,6 +177,64 @@ class ContainerManager {
157
177
  getContainer(name) {
158
178
  return this.containerMap[name];
159
179
  }
180
+ /**
181
+ * Return actual rendered bounds for a GameObject.
182
+ *
183
+ * The primary path uses PixiJS Container#getBounds(), so renderers such as
184
+ * Text/Img/Graphics/Sprite/Spine report the real display size after loading
185
+ * and style application. If the display object is not ready yet, callers can
186
+ * fall back to Transform.size in the same Eva design/canvas coordinate space.
187
+ */
188
+ getBounds(gameObject, options = {}) {
189
+ if (!gameObject || gameObject.destroyed)
190
+ return null;
191
+ const coordinateSpace = options.coordinateSpace || 'world';
192
+ const fallbackToTransform = options.fallbackToTransform !== false;
193
+ const container = this.getContainer(gameObject.id);
194
+ if (container === null || container === void 0 ? void 0 : container.getBounds) {
195
+ try {
196
+ const bounds = container.getBounds();
197
+ if (bounds && Number.isFinite(bounds.width) && Number.isFinite(bounds.height) && (bounds.width !== 0 || bounds.height !== 0)) {
198
+ return toRenderBounds(bounds, coordinateSpace, 'pixi');
199
+ }
200
+ }
201
+ catch (error) {
202
+ // Pixi can throw while async resources are still being attached; fallback below keeps editor tools stable.
203
+ }
204
+ }
205
+ if (!fallbackToTransform)
206
+ return null;
207
+ return this.getTransformBounds(gameObject, coordinateSpace);
208
+ }
209
+ getTransformBounds(gameObject, coordinateSpace) {
210
+ var _a, _b, _c, _d, _e, _f;
211
+ const transform = gameObject.transform;
212
+ const container = this.getContainer(gameObject.id);
213
+ let x = (_a = container === null || container === void 0 ? void 0 : container.worldTransform) === null || _a === void 0 ? void 0 : _a.tx;
214
+ let y = (_b = container === null || container === void 0 ? void 0 : container.worldTransform) === null || _b === void 0 ? void 0 : _b.ty;
215
+ if (!Number.isFinite(x) || !Number.isFinite(y)) {
216
+ const position = this.resolveFallbackWorldPosition(transform);
217
+ x = position.x;
218
+ y = position.y;
219
+ }
220
+ const scaleX = Number.isFinite((_c = transform.scale) === null || _c === void 0 ? void 0 : _c.x) ? transform.scale.x : 1;
221
+ const scaleY = Number.isFinite((_d = transform.scale) === null || _d === void 0 ? void 0 : _d.y) ? transform.scale.y : 1;
222
+ const width = Math.abs((((_e = transform.size) === null || _e === void 0 ? void 0 : _e.width) || 0) * scaleX);
223
+ const height = Math.abs((((_f = transform.size) === null || _f === void 0 ? void 0 : _f.height) || 0) * scaleY);
224
+ return toRenderBounds({ x, y, width, height }, coordinateSpace, 'transform');
225
+ }
226
+ resolveFallbackWorldPosition(transform) {
227
+ var _a, _b, _c, _d;
228
+ if (!transform)
229
+ return { x: 0, y: 0 };
230
+ const parent = transform.parent;
231
+ const parentPosition = parent ? this.resolveFallbackWorldPosition(parent) : { x: 0, y: 0 };
232
+ const parentSize = (parent === null || parent === void 0 ? void 0 : parent.size) || { width: 0, height: 0 };
233
+ return {
234
+ x: parentPosition.x + (((_a = transform.position) === null || _a === void 0 ? void 0 : _a.x) || 0) + parentSize.width * (((_b = transform.anchor) === null || _b === void 0 ? void 0 : _b.x) || 0),
235
+ y: parentPosition.y + (((_c = transform.position) === null || _c === void 0 ? void 0 : _c.y) || 0) + parentSize.height * (((_d = transform.anchor) === null || _d === void 0 ? void 0 : _d.y) || 0),
236
+ };
237
+ }
160
238
  removeContainer(name) {
161
239
  const container = this.containerMap[name];
162
240
  if (container) {
@@ -276,7 +354,8 @@ let Transform = class Transform extends EventEmitter__default {
276
354
  Transform = __decorate([
277
355
  eva_js.decorators.componentObserver({
278
356
  Transform: ['_parent'],
279
- })
357
+ }),
358
+ __metadata("design:paramtypes", [Object])
280
359
  ], Transform);
281
360
  var Transform$1 = Transform;
282
361
 
@@ -294,26 +373,42 @@ const enableScroll = renderer => {
294
373
  renderer.events.autoPreventDefault = false;
295
374
  renderer.canvas.style.touchAction = 'auto';
296
375
  };
376
+ function isRendererGameLike(value) {
377
+ if (!value || typeof value !== 'object')
378
+ return false;
379
+ const candidate = value;
380
+ return Boolean(candidate.scene || candidate.gameObjects || typeof candidate.on === 'function');
381
+ }
297
382
  let Renderer$1 = class Renderer extends eva_js.System {
298
383
  constructor() {
299
384
  super(...arguments);
300
385
  this.multiApps = [];
386
+ this.destroyed = false;
301
387
  }
302
- init(params) {
388
+ init(params = {}) {
389
+ var _a, _b, _c, _d, _e, _f, _g, _h;
303
390
  return __awaiter(this, void 0, void 0, function* () {
304
- this.params = params;
305
- this.application = yield this.createApplication(params);
391
+ this.destroyed = false;
392
+ const gameLike = !this.game && isRendererGameLike(params) ? params : undefined;
393
+ if (gameLike) {
394
+ this.game = gameLike;
395
+ }
396
+ const rendererParams = gameLike ? this.__systemDefaultParams || {} : params;
397
+ this.params = rendererParams;
398
+ this.application = yield this.createApplication(rendererParams);
306
399
  this.containerManager = new ContainerManager();
307
400
  this.rendererManager = new RendererManager$1({
308
401
  game: this.game,
309
402
  rendererSystem: this,
310
403
  });
311
- this.game.canvas = this.application.canvas;
404
+ if (this.game) {
405
+ this.game.canvas = this.application.canvas;
406
+ }
312
407
  this.transform = new Transform$1({
313
408
  system: this,
314
409
  containerManager: this.containerManager,
315
410
  });
316
- this.game.on('sceneChanged', ({ scene, mode, params }) => __awaiter(this, void 0, void 0, function* () {
411
+ (_b = (_a = this.game) === null || _a === void 0 ? void 0 : _a.on) === null || _b === void 0 ? void 0 : _b.call(_a, 'sceneChanged', ({ scene, mode, params }) => __awaiter(this, void 0, void 0, function* () {
317
412
  let application;
318
413
  switch (mode) {
319
414
  case eva_js.LOAD_SCENE_MODE.SINGLE:
@@ -330,13 +425,13 @@ let Renderer$1 = class Renderer extends eva_js.System {
330
425
  application,
331
426
  });
332
427
  }));
333
- this.game.on('pauseScene', ({ scene }) => {
428
+ (_d = (_c = this.game) === null || _c === void 0 ? void 0 : _c.on) === null || _d === void 0 ? void 0 : _d.call(_c, 'pauseScene', ({ scene }) => {
334
429
  this.onPauseScene(scene);
335
430
  });
336
- this.game.on('startScene', ({ scene }) => {
431
+ (_f = (_e = this.game) === null || _e === void 0 ? void 0 : _e.on) === null || _f === void 0 ? void 0 : _f.call(_e, 'startScene', ({ scene }) => {
337
432
  this.onStartScene(scene);
338
433
  });
339
- this.game.on('sceneDestroyed', ({ scene }) => __awaiter(this, void 0, void 0, function* () {
434
+ (_h = (_g = this.game) === null || _g === void 0 ? void 0 : _g.on) === null || _h === void 0 ? void 0 : _h.call(_g, 'sceneDestroyed', ({ scene }) => __awaiter(this, void 0, void 0, function* () {
340
435
  const index = this.multiApps.findIndex(app => app.canvas === scene.canvas);
341
436
  if (index > -1) {
342
437
  const app = this.multiApps.splice(index, 1)[0];
@@ -381,6 +476,8 @@ let Renderer$1 = class Renderer extends eva_js.System {
381
476
  });
382
477
  }
383
478
  update() {
479
+ if (this.destroyed || !this.game || !this.containerManager || !this.rendererManager)
480
+ return;
384
481
  const changes = this.componentObserver.clear();
385
482
  for (const changed of changes) {
386
483
  this.transform.componentChanged(changed);
@@ -394,15 +491,23 @@ let Renderer$1 = class Renderer extends eva_js.System {
394
491
  }
395
492
  }
396
493
  lateUpdate(e) {
494
+ if (this.destroyed || !this.transform || !this.application)
495
+ return;
397
496
  this.transform.update();
398
497
  this.application.ticker.update(e.time);
399
498
  }
400
499
  onDestroy() {
401
- this.application.destroy();
500
+ var _a, _b, _c, _d, _e, _f, _g;
501
+ if (this.destroyed)
502
+ return;
503
+ this.destroyed = true;
504
+ (_c = (_b = (_a = this.application) === null || _a === void 0 ? void 0 : _a.ticker) === null || _b === void 0 ? void 0 : _b.stop) === null || _c === void 0 ? void 0 : _c.call(_b);
505
+ (_d = this.application) === null || _d === void 0 ? void 0 : _d.destroy(false, { children: true, context: true });
402
506
  for (const app of this.multiApps) {
403
- app && app.destroy();
507
+ (_f = (_e = app === null || app === void 0 ? void 0 : app.ticker) === null || _e === void 0 ? void 0 : _e.stop) === null || _f === void 0 ? void 0 : _f.call(_e);
508
+ app && app.destroy(false, { children: true, context: true });
404
509
  }
405
- this.transform.destroy();
510
+ (_g = this.transform) === null || _g === void 0 ? void 0 : _g.destroy();
406
511
  this.transform = null;
407
512
  this.params = null;
408
513
  this.rendererManager = null;
@@ -411,11 +516,102 @@ let Renderer$1 = class Renderer extends eva_js.System {
411
516
  this.game = null;
412
517
  this.multiApps = null;
413
518
  }
414
- resize(width, height) {
519
+ resize(width, height, resolution) {
415
520
  this.params.width = width;
416
521
  this.params.height = height;
522
+ if (resolution != null) {
523
+ this.params.resolution = this.clampResolution(resolution);
524
+ }
417
525
  // @ts-ignore
418
- this.application.renderer.resize(width, height);
526
+ this.application.renderer.resize(width, height, this.params.resolution);
527
+ if (resolution != null) {
528
+ this.syncDisplayObjectResolution(this.params.resolution);
529
+ }
530
+ }
531
+ /**
532
+ * 更新 Pixi renderer backing-store resolution,不改变 Eva 设计坐标系。
533
+ *
534
+ * 预览画布可用该入口在 zoom/devicePixelRatio 变化时提高清晰度;
535
+ * getBounds/Transform/worldTransform 仍返回设计逻辑坐标,不乘 resolution。
536
+ */
537
+ resizeRenderer(options) {
538
+ var _a, _b, _c, _d, _e, _f;
539
+ const width = (_b = (_a = options.width) !== null && _a !== void 0 ? _a : this.params.width) !== null && _b !== void 0 ? _b : this.application.renderer.width;
540
+ const height = (_d = (_c = options.height) !== null && _c !== void 0 ? _c : this.params.height) !== null && _d !== void 0 ? _d : this.application.renderer.height;
541
+ const resolution = options.resolution == null
542
+ ? (_f = (_e = this.params.resolution) !== null && _e !== void 0 ? _e : this.application.renderer.resolution) !== null && _f !== void 0 ? _f : 1
543
+ : this.clampResolution(options.resolution, options.maxResolution);
544
+ this.params.width = width;
545
+ this.params.height = height;
546
+ this.params.resolution = resolution;
547
+ // @ts-ignore Pixi v8 accepts resolution as the third resize argument.
548
+ this.application.renderer.resize(width, height, resolution);
549
+ const displayResolutionSyncCount = this.syncDisplayObjectResolution(resolution);
550
+ return { width, height, resolution, displayResolutionSyncCount };
551
+ }
552
+ setResolution(resolution, options = {}) {
553
+ return this.resizeRenderer(Object.assign(Object.assign({}, options), { resolution }));
554
+ }
555
+ clampResolution(resolution, maxResolution = 3) {
556
+ const normalized = Number.isFinite(resolution) && resolution > 0 ? resolution : 1;
557
+ return Math.min(normalized, maxResolution);
558
+ }
559
+ /**
560
+ * Keep renderer-owned display objects that expose a resolution property in
561
+ * sync with the backing-store resolution. This is intentionally display-tree
562
+ * based rather than component-type based, so Text/HTMLText and future Pixi
563
+ * objects with resolution support all follow the same renderer contract.
564
+ */
565
+ syncDisplayObjectResolution(resolution) {
566
+ var _a;
567
+ const roots = ((_a = this.containerManager) === null || _a === void 0 ? void 0 : _a.containerMap) ? Object.values(this.containerManager.containerMap) : [];
568
+ const visited = typeof WeakSet !== 'undefined' ? new WeakSet() : undefined;
569
+ let syncedCount = 0;
570
+ const visit = (displayObject) => {
571
+ if (!displayObject || typeof displayObject !== 'object')
572
+ return;
573
+ if (visited === null || visited === void 0 ? void 0 : visited.has(displayObject))
574
+ return;
575
+ visited === null || visited === void 0 ? void 0 : visited.add(displayObject);
576
+ if ('resolution' in displayObject) {
577
+ const currentResolution = displayObject.resolution;
578
+ if ((typeof currentResolution === 'number' || currentResolution === null) &&
579
+ Math.abs((currentResolution !== null && currentResolution !== void 0 ? currentResolution : 1) - resolution) > 0.001) {
580
+ try {
581
+ displayObject.resolution = resolution;
582
+ if (typeof displayObject.resolution === 'number' &&
583
+ Math.abs(displayObject.resolution - resolution) <= 0.001) {
584
+ syncedCount += 1;
585
+ }
586
+ }
587
+ catch (_) {
588
+ // Some Pixi objects expose a readonly or unsupported resolution setter.
589
+ }
590
+ }
591
+ }
592
+ if (Array.isArray(displayObject.children)) {
593
+ for (const child of displayObject.children) {
594
+ visit(child);
595
+ }
596
+ }
597
+ };
598
+ for (const root of roots) {
599
+ visit(root);
600
+ }
601
+ return syncedCount;
602
+ }
603
+ /**
604
+ * 获取 GameObject 的真实渲染 bounds。
605
+ *
606
+ * 默认返回 PixiJS display object 的 world bounds。Eva 的 Pixi world 坐标
607
+ * 与 canvas/design 逻辑坐标一致;如果画布被 CSS 缩放,调用方再按
608
+ * canvas.getBoundingClientRect() / renderer width 做屏幕坐标换算。
609
+ *
610
+ * 当渲染对象尚未挂载或资源未加载完成时,会回退到 Transform.size。
611
+ */
612
+ getBounds(gameObject, options) {
613
+ var _a;
614
+ return ((_a = this.containerManager) === null || _a === void 0 ? void 0 : _a.getBounds(gameObject, options)) || null;
419
615
  }
420
616
  getApplicationByScene(scene) {
421
617
  const index = this.multiApps.findIndex(app => app.canvas === scene.canvas);
@@ -439,11 +635,11 @@ let Renderer$1 = class Renderer extends eva_js.System {
439
635
  app.start();
440
636
  }
441
637
  }
442
- resizeByScene(scene, width, height) {
638
+ resizeByScene(scene, width, height, resolution) {
443
639
  const app = this.getApplicationByScene(scene);
444
640
  if (app) {
445
641
  // @ts-ignore
446
- app.renderer.resize(width, height);
642
+ app.renderer.resize(width, height, resolution);
447
643
  }
448
644
  }
449
645
  };
@@ -536,7 +732,7 @@ class Renderer extends eva_js.System {
536
732
  * 每帧调用
537
733
  *
538
734
  * called by every loop
539
- * @param _gameObject gameObject
735
+ * @param _gameObject - gameObject
540
736
  */
541
737
  rendererUpdate(_gameObject) { }
542
738
  // @ts-ignore
@@ -1 +1 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@eva/eva.js"),t=require("@eva/renderer-adapter"),n=require("lodash-es/isEqual"),r=require("eventemitter3"),s=require("pixi.js");function a(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var o=a(n),i=a(r);function c(e,t,n,r){var s,a=arguments.length,o=a<3?t:null===r?r=Object.getOwnPropertyDescriptor(t,n):r;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)o=Reflect.decorate(e,t,n,r);else for(var i=e.length-1;i>=0;i--)(s=e[i])&&(o=(a<3?s(o):a>3?s(t,n,o):s(t,n))||o);return a>3&&o&&Object.defineProperty(t,n,o),o}function p(e,t,n,r){return new(n||(n=Promise))(function(s,a){function o(e){try{c(r.next(e))}catch(e){a(e)}}function i(e){try{c(r.throw(e))}catch(e){a(e)}}function c(e){var t;e.done?s(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(o,i)}c((r=r.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;var d=class{constructor({game:e,rendererSystem:t}){this.renderers=[],this.game=e,this.rendererSystem=t}register(...e){for(const t of e)t.game=this.game,t.rendererManager=this.rendererSystem.rendererManager,t.containerManager=this.rendererSystem.containerManager,this.renderers.push(t)}componentChanged(t){for(const n of t)for(const t of this.renderers){const r=t.observerInfo[n.componentName];if(r){if([e.OBSERVER_TYPE.ADD,e.OBSERVER_TYPE.REMOVE].indexOf(n.type)>-1){try{t.componentChanged&&t.componentChanged(n)}catch(e){console.error(`gameObject: ${n.gameObject.name}, ${n.componentName} is error.`,n,e)}continue}if(r.findIndex(e=>o(e,n.prop))>-1)try{t.componentChanged&&t.componentChanged(n)}catch(e){console.error(`gameObject: ${n.gameObject&&n.gameObject.name}, ${n.componentName} is componentChanged error.`,n,e)}}}}update(e){for(const t of e.components)for(const n of this.renderers){const r=[];if(n.observerInfo[t.name]&&-1===r.indexOf(e)){r.push(e);try{n.rendererUpdate&&n.rendererUpdate(e)}catch(n){console.info(`gameObject: ${e.name}, ${t.name} is update error`,n)}}}}};class h{constructor(){this.containerMap={}}addContainer({name:e,container:t,gameObject:n}){this.containerMap[e]=t,t.gName=n.name||e}getContainer(e){return this.containerMap[e]}removeContainer(e){const t=this.containerMap[e];t&&t.destroy({children:!0}),delete this.containerMap[e]}updateTransform({name:e,transform:t}){const n=this.containerMap[e];if(!n||!t)return;const{anchor:r,origin:s,position:a,rotation:o,scale:i,size:c,skew:p}=t;n.rotation=o,n.scale=i,n.pivot.x=c.width*s.x,n.pivot.y=c.height*s.y,n.skew=p;let d=a.x,h=a.y;if(t.parent){const e=t.parent;d+=e.size.width*r.x,h+=e.size.height*r.y}n.position={x:d,y:h}}}let m=class extends i{constructor({system:e,containerManager:t}){super(),this.name="Transform",this.waitRemoveIds=[],this.waitChangeScenes=[],this.containerManager=t,this.init(e)}init(e){this.system=e,this.on("changeScene",({scene:e,mode:t,application:n})=>{this.waitChangeScenes.push({scene:e,mode:t,application:n})})}update(){for(const e of this.waitRemoveIds)this.containerManager.removeContainer(e);this.waitRemoveIds=[];for(const e of this.waitChangeScenes){const t=this.containerManager.getContainer(e.scene.id);t&&(e.application.stage.removeChildren(),e.application.stage.addChild(t))}this.waitChangeScenes=[]}componentChanged(t){t.type===e.OBSERVER_TYPE.ADD?this.addContainer(t):t.type===e.OBSERVER_TYPE.CHANGE?this.change(t):t.type===e.OBSERVER_TYPE.REMOVE&&this.waitRemoveIds.push(t.gameObject.id)}addContainer(e){const n=new t.Container;n.label=e.gameObject.name,this.containerManager.addContainer({name:e.gameObject.id,container:n,gameObject:e.gameObject});const r=e.component;Object.defineProperty(r,"worldTransform",{get:()=>n.renderGroup||n.parentRenderGroup?n.worldTransform:void 0})}change(e){const t=e.component;if(t.parent){this.containerManager.getContainer(t.parent.gameObject.id).addChild(this.containerManager.getContainer(e.gameObject.id));const n=e.gameObject.transform.parent&&e.gameObject.transform.parent.gameObject.getComponent("Render");n&&(n.sortDirty=!0)}else{const t=this.containerManager.getContainer(e.gameObject.id);t.parent&&t.parent.removeChild(t)}}destroy(){this.removeAllListeners(),this.waitRemoveIds=null,this.waitChangeScenes=null,this.system=null,this.containerManager=null}};m=c([e.decorators.componentObserver({Transform:["_parent"]})],m);var l,u=m;exports.RENDERER_TYPE=void 0,(l=exports.RENDERER_TYPE||(exports.RENDERER_TYPE={}))[l.UNKNOWN=0]="UNKNOWN",l[l.WEBGL=1]="WEBGL",l[l.CANVAS=2]="CANVAS";let g=class extends e.System{constructor(){super(...arguments),this.multiApps=[]}init(t){return p(this,void 0,void 0,function*(){this.params=t,this.application=yield this.createApplication(t),this.containerManager=new h,this.rendererManager=new d({game:this.game,rendererSystem:this}),this.game.canvas=this.application.canvas,this.transform=new u({system:this,containerManager:this.containerManager}),this.game.on("sceneChanged",({scene:t,mode:n,params:r})=>p(this,void 0,void 0,function*(){let s;switch(n){case e.LOAD_SCENE_MODE.SINGLE:s=this.application;break;case e.LOAD_SCENE_MODE.MULTI_CANVAS:s=yield this.createMultiApplication({params:r})}t.canvas=s.canvas,this.transform.emit("changeScene",{scene:t,mode:n,application:s})})),this.game.on("pauseScene",({scene:e})=>{this.onPauseScene(e)}),this.game.on("startScene",({scene:e})=>{this.onStartScene(e)}),this.game.on("sceneDestroyed",({scene:e})=>p(this,void 0,void 0,function*(){const t=this.multiApps.findIndex(t=>t.canvas===e.canvas);if(t>-1){this.multiApps.splice(t,1)[0].destroy(),e.destroy()}}))})}registerObserver(e){const t=this.constructor.observerInfo;for(const n in e)t[n]||(t[n]=[]),t[n].push(...e[n])}createMultiApplication({params:e}){return p(this,void 0,void 0,function*(){const t=yield this.createApplication(e);return this.multiApps.push(t),t})}createApplication(e){return p(this,void 0,void 0,function*(){const n=new t.Application;var r;return e.debugMode&&(globalThis.__PIXI_APP__=n),yield n.init(Object.assign(Object.assign({sharedTicker:!0},e),{hello:!0})),void 0!==e.enableScroll&&(e.enableScroll?((r=n.renderer).events.autoPreventDefault=!1,r.canvas.style.touchAction="auto"):(e=>{e.events.autoPreventDefault=!0,e.canvas.style.touchAction="none"})(n.renderer)),s.Ticker.shared.stop(),s.Ticker.shared.autoStart=!1,n})}update(){const e=this.componentObserver.clear();for(const t of e)this.transform.componentChanged(t);for(const e of this.game.gameObjects)this.containerManager.updateTransform({name:e.id,transform:e.transform}),this.rendererManager.update(e)}lateUpdate(e){this.transform.update(),this.application.ticker.update(e.time)}onDestroy(){this.application.destroy();for(const e of this.multiApps)e&&e.destroy();this.transform.destroy(),this.transform=null,this.params=null,this.rendererManager=null,this.containerManager=null,this.application=null,this.game=null,this.multiApps=null}resize(e,t){this.params.width=e,this.params.height=t,this.application.renderer.resize(e,t)}getApplicationByScene(e){const t=this.multiApps.findIndex(t=>t.canvas===e.canvas);if(t>-1){return this.multiApps[t]}console.warn("application not found")}onPauseScene(e){const t=this.getApplicationByScene(e);t&&t.stop()}onStartScene(e){const t=this.getApplicationByScene(e);t&&t.start()}resizeByScene(e,t,n){const r=this.getApplicationByScene(e);r&&r.renderer.resize(t,n)}};g.systemName="Renderer",g=c([e.decorators.componentObserver({Transform:["_parent"]})],g);var f=g;let v;function y(e){e.addPreProcessResourceHandler(function(e){var t,n,r;let s=null===(n=null===(t=e.src)||void 0===t?void 0:t.image)||void 0===n?void 0:n.texture;if(!s)return;Array.isArray(s)||(s=[s]);const a=null!==(r=function(){if(v)return v;const e=document.createElement("canvas").getContext("webgl2");if(!e)return console.warn("WebGL not available for compressed textures. Silently failing."),{s3tc:!1,etc:!1,etc1:!1,pvrtc:!1,atc:!1,astc:!1};v={s3tc:!!e.getExtension("WEBGL_compressed_texture_s3tc"),etc:!!e.getExtension("WEBGL_compressed_texture_etc"),etc1:!!e.getExtension("WEBGL_compressed_texture_etc1"),pvrtc:!!e.getExtension("WEBGL_compressed_texture_pvrtc")||!!e.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),atc:!!e.getExtension("WEBGL_compressed_texture_atc"),astc:!!e.getExtension("WEBGL_compressed_texture_astc")};try{console.log("Eva.js Supported Compressed Texture Format List: "+Object.keys(v).filter(e=>v[e]).join(", "))}catch(e){}return v}())&&void 0!==r?r:{};let o=s.find(e=>a[e.type]);o&&Object.assign(e.src.image,o)})}class E extends e.System{constructor(e){super(e),this.asyncIdMap={},this.observerInfo=this.constructor.observerInfo}componentChanged(e){}rendererUpdate(e){}update(e){const t=this.componentObserver.clear();for(const e of t)this.componentChanged(e)}increaseAsyncId(e){return this.asyncIdMap[e]=(this.asyncIdMap[e]||0)+1,this.asyncIdMap[e]}validateAsyncId(e,t){return this.asyncIdMap[e]===t}}exports.ContainerManager=h,exports.Renderer=E,exports.RendererManager=d,exports.RendererSystem=f,exports.registerKtx2CompressedTexture=function(t){s.setKTXTranscoderPath(t),s.extensions.add(s.loadKTX2),s.extensions.add(s.resolveCompressedTextureUrl),s.extensions.add(s.detectCompressed),y(e.resource)};
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("@eva/eva.js"),t=require("@eva/renderer-adapter"),n=require("lodash-es/isEqual"),i=require("eventemitter3"),r=require("pixi.js");function o(e){return e&&"object"==typeof e&&"default"in e?e.default:e}var s=o(n),a=o(i);function c(e,t,n,i){var r,o=arguments.length,s=o<3?t:null===i?i=Object.getOwnPropertyDescriptor(t,n):i;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)s=Reflect.decorate(e,t,n,i);else for(var a=e.length-1;a>=0;a--)(r=e[a])&&(s=(o<3?r(s):o>3?r(t,n,s):r(t,n))||s);return o>3&&s&&Object.defineProperty(t,n,s),s}function l(e,t,n,i){return new(n||(n=Promise))(function(r,o){function s(e){try{c(i.next(e))}catch(e){o(e)}}function a(e){try{c(i.throw(e))}catch(e){o(e)}}function c(e){var t;e.done?r(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(s,a)}c((i=i.apply(e,t||[])).next())})}"function"==typeof SuppressedError&&SuppressedError;var d=class{constructor({game:e,rendererSystem:t}){this.renderers=[],this.game=e,this.rendererSystem=t}register(...e){for(const t of e)t.game=this.game,t.rendererManager=this.rendererSystem.rendererManager,t.containerManager=this.rendererSystem.containerManager,this.renderers.push(t)}componentChanged(t){for(const n of t)for(const t of this.renderers){const i=t.observerInfo[n.componentName];if(i){if([e.OBSERVER_TYPE.ADD,e.OBSERVER_TYPE.REMOVE].indexOf(n.type)>-1){try{t.componentChanged&&t.componentChanged(n)}catch(e){console.error(`gameObject: ${n.gameObject.name}, ${n.componentName} is error.`,n,e)}continue}if(i.findIndex(e=>s(e,n.prop))>-1)try{t.componentChanged&&t.componentChanged(n)}catch(e){console.error(`gameObject: ${n.gameObject&&n.gameObject.name}, ${n.componentName} is componentChanged error.`,n,e)}}}}update(e){for(const t of e.components)for(const n of this.renderers){const i=[];if(n.observerInfo[t.name]&&-1===i.indexOf(e)){i.push(e);try{n.rendererUpdate&&n.rendererUpdate(e)}catch(n){console.info(`gameObject: ${e.name}, ${t.name} is update error`,n)}}}}};const h=(e,t,n)=>{const i=Number.isFinite(e.x)?e.x:0,r=Number.isFinite(e.y)?e.y:0,o=Number.isFinite(e.width)?e.width:0,s=Number.isFinite(e.height)?e.height:0;return{x:i,y:r,width:o,height:s,right:i+o,bottom:r+s,coordinateSpace:t,source:n}};class u{constructor(){this.containerMap={}}addContainer({name:e,container:t,gameObject:n}){this.containerMap[e]=t,t.gName=n.name||e}getContainer(e){return this.containerMap[e]}getBounds(e,t={}){if(!e||e.destroyed)return null;const n=t.coordinateSpace||"world",i=!1!==t.fallbackToTransform,r=this.getContainer(e.id);if(null==r?void 0:r.getBounds)try{const e=r.getBounds();if(e&&Number.isFinite(e.width)&&Number.isFinite(e.height)&&(0!==e.width||0!==e.height))return h(e,n,"pixi")}catch(e){}return i?this.getTransformBounds(e,n):null}getTransformBounds(e,t){var n,i,r,o,s,a;const c=e.transform,l=this.getContainer(e.id);let d=null===(n=null==l?void 0:l.worldTransform)||void 0===n?void 0:n.tx,u=null===(i=null==l?void 0:l.worldTransform)||void 0===i?void 0:i.ty;if(!Number.isFinite(d)||!Number.isFinite(u)){const e=this.resolveFallbackWorldPosition(c);d=e.x,u=e.y}const p=Number.isFinite(null===(r=c.scale)||void 0===r?void 0:r.x)?c.scale.x:1,m=Number.isFinite(null===(o=c.scale)||void 0===o?void 0:o.y)?c.scale.y:1,g=Math.abs(((null===(s=c.size)||void 0===s?void 0:s.width)||0)*p),v=Math.abs(((null===(a=c.size)||void 0===a?void 0:a.height)||0)*m);return h({x:d,y:u,width:g,height:v},t,"transform")}resolveFallbackWorldPosition(e){var t,n,i,r;if(!e)return{x:0,y:0};const o=e.parent,s=o?this.resolveFallbackWorldPosition(o):{x:0,y:0},a=(null==o?void 0:o.size)||{width:0,height:0};return{x:s.x+((null===(t=e.position)||void 0===t?void 0:t.x)||0)+a.width*((null===(n=e.anchor)||void 0===n?void 0:n.x)||0),y:s.y+((null===(i=e.position)||void 0===i?void 0:i.y)||0)+a.height*((null===(r=e.anchor)||void 0===r?void 0:r.y)||0)}}removeContainer(e){const t=this.containerMap[e];t&&t.destroy({children:!0}),delete this.containerMap[e]}updateTransform({name:e,transform:t}){const n=this.containerMap[e];if(!n||!t)return;const{anchor:i,origin:r,position:o,rotation:s,scale:a,size:c,skew:l}=t;n.rotation=s,n.scale=a,n.pivot.x=c.width*r.x,n.pivot.y=c.height*r.y,n.skew=l;let d=o.x,h=o.y;if(t.parent){const e=t.parent;d+=e.size.width*i.x,h+=e.size.height*i.y}n.position={x:d,y:h}}}let p=class extends a{constructor({system:e,containerManager:t}){super(),this.name="Transform",this.waitRemoveIds=[],this.waitChangeScenes=[],this.containerManager=t,this.init(e)}init(e){this.system=e,this.on("changeScene",({scene:e,mode:t,application:n})=>{this.waitChangeScenes.push({scene:e,mode:t,application:n})})}update(){for(const e of this.waitRemoveIds)this.containerManager.removeContainer(e);this.waitRemoveIds=[];for(const e of this.waitChangeScenes){const t=this.containerManager.getContainer(e.scene.id);t&&(e.application.stage.removeChildren(),e.application.stage.addChild(t))}this.waitChangeScenes=[]}componentChanged(t){t.type===e.OBSERVER_TYPE.ADD?this.addContainer(t):t.type===e.OBSERVER_TYPE.CHANGE?this.change(t):t.type===e.OBSERVER_TYPE.REMOVE&&this.waitRemoveIds.push(t.gameObject.id)}addContainer(e){const n=new t.Container;n.label=e.gameObject.name,this.containerManager.addContainer({name:e.gameObject.id,container:n,gameObject:e.gameObject});const i=e.component;Object.defineProperty(i,"worldTransform",{get:()=>n.renderGroup||n.parentRenderGroup?n.worldTransform:void 0})}change(e){const t=e.component;if(t.parent){this.containerManager.getContainer(t.parent.gameObject.id).addChild(this.containerManager.getContainer(e.gameObject.id));const n=e.gameObject.transform.parent&&e.gameObject.transform.parent.gameObject.getComponent("Render");n&&(n.sortDirty=!0)}else{const t=this.containerManager.getContainer(e.gameObject.id);t.parent&&t.parent.removeChild(t)}}destroy(){this.removeAllListeners(),this.waitRemoveIds=null,this.waitChangeScenes=null,this.system=null,this.containerManager=null}};p=c([e.decorators.componentObserver({Transform:["_parent"]}),function(e,t){if("object"==typeof Reflect&&"function"==typeof Reflect.metadata)return Reflect.metadata(e,t)}("design:paramtypes",[Object])],p);var m,g=p;exports.RENDERER_TYPE=void 0,(m=exports.RENDERER_TYPE||(exports.RENDERER_TYPE={}))[m.UNKNOWN=0]="UNKNOWN",m[m.WEBGL=1]="WEBGL",m[m.CANVAS=2]="CANVAS";let v=class extends e.System{constructor(){super(...arguments),this.multiApps=[],this.destroyed=!1}init(t={}){var n,i,r,o,s,a,c,h;return l(this,void 0,void 0,function*(){this.destroyed=!1;const p=!this.game&&function(e){if(!e||"object"!=typeof e)return!1;const t=e;return Boolean(t.scene||t.gameObjects||"function"==typeof t.on)}(t)?t:void 0;p&&(this.game=p);const m=p?this.__systemDefaultParams||{}:t;this.params=m,this.application=yield this.createApplication(m),this.containerManager=new u,this.rendererManager=new d({game:this.game,rendererSystem:this}),this.game&&(this.game.canvas=this.application.canvas),this.transform=new g({system:this,containerManager:this.containerManager}),null===(i=null===(n=this.game)||void 0===n?void 0:n.on)||void 0===i||i.call(n,"sceneChanged",({scene:t,mode:n,params:i})=>l(this,void 0,void 0,function*(){let r;switch(n){case e.LOAD_SCENE_MODE.SINGLE:r=this.application;break;case e.LOAD_SCENE_MODE.MULTI_CANVAS:r=yield this.createMultiApplication({params:i})}t.canvas=r.canvas,this.transform.emit("changeScene",{scene:t,mode:n,application:r})})),null===(o=null===(r=this.game)||void 0===r?void 0:r.on)||void 0===o||o.call(r,"pauseScene",({scene:e})=>{this.onPauseScene(e)}),null===(a=null===(s=this.game)||void 0===s?void 0:s.on)||void 0===a||a.call(s,"startScene",({scene:e})=>{this.onStartScene(e)}),null===(h=null===(c=this.game)||void 0===c?void 0:c.on)||void 0===h||h.call(c,"sceneDestroyed",({scene:e})=>l(this,void 0,void 0,function*(){const t=this.multiApps.findIndex(t=>t.canvas===e.canvas);if(t>-1){this.multiApps.splice(t,1)[0].destroy(),e.destroy()}}))})}registerObserver(e){const t=this.constructor.observerInfo;for(const n in e)t[n]||(t[n]=[]),t[n].push(...e[n])}createMultiApplication({params:e}){return l(this,void 0,void 0,function*(){const t=yield this.createApplication(e);return this.multiApps.push(t),t})}createApplication(e){return l(this,void 0,void 0,function*(){const n=new t.Application;var i;return e.debugMode&&(globalThis.__PIXI_APP__=n),yield n.init(Object.assign(Object.assign({sharedTicker:!0},e),{hello:!0})),void 0!==e.enableScroll&&(e.enableScroll?((i=n.renderer).events.autoPreventDefault=!1,i.canvas.style.touchAction="auto"):(e=>{e.events.autoPreventDefault=!0,e.canvas.style.touchAction="none"})(n.renderer)),r.Ticker.shared.stop(),r.Ticker.shared.autoStart=!1,n})}update(){if(this.destroyed||!this.game||!this.containerManager||!this.rendererManager)return;const e=this.componentObserver.clear();for(const t of e)this.transform.componentChanged(t);for(const e of this.game.gameObjects)this.containerManager.updateTransform({name:e.id,transform:e.transform}),this.rendererManager.update(e)}lateUpdate(e){!this.destroyed&&this.transform&&this.application&&(this.transform.update(),this.application.ticker.update(e.time))}onDestroy(){var e,t,n,i,r,o,s;if(!this.destroyed){this.destroyed=!0,null===(n=null===(t=null===(e=this.application)||void 0===e?void 0:e.ticker)||void 0===t?void 0:t.stop)||void 0===n||n.call(t),null===(i=this.application)||void 0===i||i.destroy(!1,{children:!0,context:!0});for(const e of this.multiApps)null===(o=null===(r=null==e?void 0:e.ticker)||void 0===r?void 0:r.stop)||void 0===o||o.call(r),e&&e.destroy(!1,{children:!0,context:!0});null===(s=this.transform)||void 0===s||s.destroy(),this.transform=null,this.params=null,this.rendererManager=null,this.containerManager=null,this.application=null,this.game=null,this.multiApps=null}}resize(e,t,n){this.params.width=e,this.params.height=t,null!=n&&(this.params.resolution=this.clampResolution(n)),this.application.renderer.resize(e,t,this.params.resolution),null!=n&&this.syncDisplayObjectResolution(this.params.resolution)}resizeRenderer(e){var t,n,i,r,o,s;const a=null!==(n=null!==(t=e.width)&&void 0!==t?t:this.params.width)&&void 0!==n?n:this.application.renderer.width,c=null!==(r=null!==(i=e.height)&&void 0!==i?i:this.params.height)&&void 0!==r?r:this.application.renderer.height,l=null==e.resolution?null!==(s=null!==(o=this.params.resolution)&&void 0!==o?o:this.application.renderer.resolution)&&void 0!==s?s:1:this.clampResolution(e.resolution,e.maxResolution);this.params.width=a,this.params.height=c,this.params.resolution=l,this.application.renderer.resize(a,c,l);return{width:a,height:c,resolution:l,displayResolutionSyncCount:this.syncDisplayObjectResolution(l)}}setResolution(e,t={}){return this.resizeRenderer(Object.assign(Object.assign({},t),{resolution:e}))}clampResolution(e,t=3){const n=Number.isFinite(e)&&e>0?e:1;return Math.min(n,t)}syncDisplayObjectResolution(e){var t;const n=(null===(t=this.containerManager)||void 0===t?void 0:t.containerMap)?Object.values(this.containerManager.containerMap):[],i="undefined"!=typeof WeakSet?new WeakSet:void 0;let r=0;const o=t=>{if(t&&"object"==typeof t&&!(null==i?void 0:i.has(t))){if(null==i||i.add(t),"resolution"in t){const n=t.resolution;if(("number"==typeof n||null===n)&&Math.abs((null!=n?n:1)-e)>.001)try{t.resolution=e,"number"==typeof t.resolution&&Math.abs(t.resolution-e)<=.001&&(r+=1)}catch(e){}}if(Array.isArray(t.children))for(const e of t.children)o(e)}};for(const e of n)o(e);return r}getBounds(e,t){var n;return(null===(n=this.containerManager)||void 0===n?void 0:n.getBounds(e,t))||null}getApplicationByScene(e){const t=this.multiApps.findIndex(t=>t.canvas===e.canvas);if(t>-1){return this.multiApps[t]}console.warn("application not found")}onPauseScene(e){const t=this.getApplicationByScene(e);t&&t.stop()}onStartScene(e){const t=this.getApplicationByScene(e);t&&t.start()}resizeByScene(e,t,n,i){const r=this.getApplicationByScene(e);r&&r.renderer.resize(t,n,i)}};v.systemName="Renderer",v=c([e.decorators.componentObserver({Transform:["_parent"]})],v);var f=v;let y;function b(e){e.addPreProcessResourceHandler(function(e){var t,n,i;let r=null===(n=null===(t=e.src)||void 0===t?void 0:t.image)||void 0===n?void 0:n.texture;if(!r)return;Array.isArray(r)||(r=[r]);const o=null!==(i=function(){if(y)return y;const e=document.createElement("canvas").getContext("webgl2");if(!e)return console.warn("WebGL not available for compressed textures. Silently failing."),{s3tc:!1,etc:!1,etc1:!1,pvrtc:!1,atc:!1,astc:!1};y={s3tc:!!e.getExtension("WEBGL_compressed_texture_s3tc"),etc:!!e.getExtension("WEBGL_compressed_texture_etc"),etc1:!!e.getExtension("WEBGL_compressed_texture_etc1"),pvrtc:!!e.getExtension("WEBGL_compressed_texture_pvrtc")||!!e.getExtension("WEBKIT_WEBGL_compressed_texture_pvrtc"),atc:!!e.getExtension("WEBGL_compressed_texture_atc"),astc:!!e.getExtension("WEBGL_compressed_texture_astc")};try{console.log("Eva.js Supported Compressed Texture Format List: "+Object.keys(y).filter(e=>y[e]).join(", "))}catch(e){}return y}())&&void 0!==i?i:{};let s=r.find(e=>o[e.type]);s&&Object.assign(e.src.image,s)})}class x extends e.System{constructor(e){super(e),this.asyncIdMap={},this.observerInfo=this.constructor.observerInfo}componentChanged(e){}rendererUpdate(e){}update(e){const t=this.componentObserver.clear();for(const e of t)this.componentChanged(e)}increaseAsyncId(e){return this.asyncIdMap[e]=(this.asyncIdMap[e]||0)+1,this.asyncIdMap[e]}validateAsyncId(e,t){return this.asyncIdMap[e]===t}}exports.ContainerManager=u,exports.Renderer=x,exports.RendererManager=d,exports.RendererSystem=f,exports.registerKtx2CompressedTexture=function(t){r.setKTXTranscoderPath(t),r.extensions.add(r.loadKTX2),r.extensions.add(r.resolveCompressedTextureUrl),r.extensions.add(r.detectCompressed),b(e.resource)};
@@ -12,6 +12,8 @@ import { System } from '@eva/eva.js';
12
12
  import { Transform } from '@eva/eva.js';
13
13
  import { UpdateParams } from '@eva/eva.js';
14
14
 
15
+ export declare type BoundsCoordinateSpace = 'world' | 'canvas' | 'design';
16
+
15
17
  export declare class ContainerManager {
16
18
  containerMap: {
17
19
  [propName: number]: Container;
@@ -22,6 +24,17 @@ export declare class ContainerManager {
22
24
  gameObject: GameObject;
23
25
  }): void;
24
26
  getContainer(name: number): Container;
27
+ /**
28
+ * Return actual rendered bounds for a GameObject.
29
+ *
30
+ * The primary path uses PixiJS Container#getBounds(), so renderers such as
31
+ * Text/Img/Graphics/Sprite/Spine report the real display size after loading
32
+ * and style application. If the display object is not ready yet, callers can
33
+ * fall back to Transform.size in the same Eva design/canvas coordinate space.
34
+ */
35
+ getBounds(gameObject: GameObject, options?: GetBoundsOptions): RenderBounds | null;
36
+ private getTransformBounds;
37
+ private resolveFallbackWorldPosition;
25
38
  removeContainer(name: number): void;
26
39
  updateTransform({ name, transform }: {
27
40
  name: number;
@@ -29,6 +42,16 @@ export declare class ContainerManager {
29
42
  }): void;
30
43
  }
31
44
 
45
+ export declare interface GetBoundsOptions {
46
+ /**
47
+ * Returned coordinate space.
48
+ * Eva's Pixi world coordinates use the same logical units as canvas/design coordinates.
49
+ */
50
+ coordinateSpace?: BoundsCoordinateSpace;
51
+ /** Use Transform.size when Pixi bounds are unavailable or still zero. Defaults to true. */
52
+ fallbackToTransform?: boolean;
53
+ }
54
+
32
55
  declare interface Params {
33
56
  jsUrl: string;
34
57
  wasmUrl: string;
@@ -36,6 +59,25 @@ declare interface Params {
36
59
 
37
60
  export declare function registerKtx2CompressedTexture(params: Params): void;
38
61
 
62
+ export declare interface RenderBounds {
63
+ /** Bounds x in Eva design/canvas coordinates. */
64
+ x: number;
65
+ /** Bounds y in Eva design/canvas coordinates. */
66
+ y: number;
67
+ /** Actual rendered width measured from Pixi getBounds(), or Transform.size fallback. */
68
+ width: number;
69
+ /** Actual rendered height measured from Pixi getBounds(), or Transform.size fallback. */
70
+ height: number;
71
+ /** Bounds right edge in the same coordinate space. */
72
+ right: number;
73
+ /** Bounds bottom edge in the same coordinate space. */
74
+ bottom: number;
75
+ /** Coordinate space of the returned values. world/canvas/design are the same logical Eva coordinates. */
76
+ coordinateSpace: BoundsCoordinateSpace;
77
+ /** Whether this value came from Pixi display object bounds or Transform.size fallback. */
78
+ source: 'pixi' | 'transform';
79
+ }
80
+
39
81
  export declare class Renderer<T extends {} = {}> extends System<T> {
40
82
  /**
41
83
  * Renderer name
@@ -69,7 +111,7 @@ export declare class Renderer<T extends {} = {}> extends System<T> {
69
111
  * 每帧调用
70
112
  *
71
113
  * called by every loop
72
- * @param _gameObject gameObject
114
+ * @param _gameObject - gameObject
73
115
  */
74
116
  rendererUpdate(_gameObject: GameObject): void;
75
117
  update(e?: UpdateParams): void;
@@ -84,6 +126,12 @@ export declare enum RENDERER_TYPE {
84
126
  CANVAS = 2
85
127
  }
86
128
 
129
+ declare type RendererGameLike = Partial<Game> & {
130
+ scene?: unknown;
131
+ gameObjects?: unknown;
132
+ on?: (name: string, handler: (...args: any[]) => void) => void;
133
+ };
134
+
87
135
  /**
88
136
  * 渲染管理器类
89
137
  *
@@ -132,6 +180,14 @@ export declare class RendererManager {
132
180
  update(gameObject: GameObject): void;
133
181
  }
134
182
 
183
+ export declare interface RendererResolutionState {
184
+ width: number;
185
+ height: number;
186
+ resolution: number;
187
+ /** Number of display objects whose own resolution was synchronized. */
188
+ displayResolutionSyncCount?: number;
189
+ }
190
+
135
191
  export declare class RendererSystem extends System<RendererSystemParams> {
136
192
  static systemName: string;
137
193
  params: Partial<RendererSystemParams>;
@@ -142,7 +198,8 @@ export declare class RendererSystem extends System<RendererSystemParams> {
142
198
  transform: Transform_2;
143
199
  multiApps: Application[];
144
200
  suportedCompressedTextureFormats: SuportedCompressedTexture;
145
- init(params: Partial<RendererSystemParams>): Promise<void>;
201
+ private destroyed;
202
+ init(params?: Partial<RendererSystemParams> | RendererGameLike): Promise<void>;
146
203
  registerObserver(observerInfo: any): void;
147
204
  createMultiApplication({ params }: {
148
205
  params: RendererSystemParams;
@@ -151,11 +208,37 @@ export declare class RendererSystem extends System<RendererSystemParams> {
151
208
  update(): void;
152
209
  lateUpdate(e: any): void;
153
210
  onDestroy(): void;
154
- resize(width: any, height: any): void;
211
+ resize(width: number, height: number, resolution?: number): void;
212
+ /**
213
+ * 更新 Pixi renderer backing-store resolution,不改变 Eva 设计坐标系。
214
+ *
215
+ * 预览画布可用该入口在 zoom/devicePixelRatio 变化时提高清晰度;
216
+ * getBounds/Transform/worldTransform 仍返回设计逻辑坐标,不乘 resolution。
217
+ */
218
+ resizeRenderer(options: ResizeRendererOptions): RendererResolutionState;
219
+ setResolution(resolution: number, options?: Omit<ResizeRendererOptions, 'resolution'>): RendererResolutionState;
220
+ private clampResolution;
221
+ /**
222
+ * Keep renderer-owned display objects that expose a resolution property in
223
+ * sync with the backing-store resolution. This is intentionally display-tree
224
+ * based rather than component-type based, so Text/HTMLText and future Pixi
225
+ * objects with resolution support all follow the same renderer contract.
226
+ */
227
+ private syncDisplayObjectResolution;
228
+ /**
229
+ * 获取 GameObject 的真实渲染 bounds。
230
+ *
231
+ * 默认返回 PixiJS display object 的 world bounds。Eva 的 Pixi world 坐标
232
+ * 与 canvas/design 逻辑坐标一致;如果画布被 CSS 缩放,调用方再按
233
+ * canvas.getBoundingClientRect() / renderer width 做屏幕坐标换算。
234
+ *
235
+ * 当渲染对象尚未挂载或资源未加载完成时,会回退到 Transform.size。
236
+ */
237
+ getBounds(gameObject: GameObject, options?: GetBoundsOptions): RenderBounds | null;
155
238
  private getApplicationByScene;
156
239
  private onPauseScene;
157
240
  private onStartScene;
158
- resizeByScene(scene: any, width: number, height: number): void;
241
+ resizeByScene(scene: any, width: number, height: number, resolution?: number): void;
159
242
  }
160
243
 
161
244
  export declare interface RendererSystemParams extends Partial<ApplicationOptions> {
@@ -165,6 +248,17 @@ export declare interface RendererSystemParams extends Partial<ApplicationOptions
165
248
  debugMode?: boolean;
166
249
  }
167
250
 
251
+ export declare interface ResizeRendererOptions {
252
+ /** Eva design/canvas logical width. This does not include resolution scaling. */
253
+ width?: number;
254
+ /** Eva design/canvas logical height. This does not include resolution scaling. */
255
+ height?: number;
256
+ /** Pixi backing-store resolution. Does not change Eva design coordinates. */
257
+ resolution?: number;
258
+ /** Upper bound for resolution to avoid oversized backing stores. Defaults to 3. */
259
+ maxResolution?: number;
260
+ }
261
+
168
262
  declare interface SuportedCompressedTexture {
169
263
  s3tc: boolean;
170
264
  etc: boolean;