kiwiengine 1.0.1 → 1.0.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.
@@ -14,6 +14,12 @@ export class Renderer extends RenderableNode {
14
14
  camera = new Camera();
15
15
  fpsDisplay;
16
16
  timeScale = 1;
17
+ get targetFps() {
18
+ return this.#ticker.fpsCap;
19
+ }
20
+ set targetFps(value) {
21
+ this.#ticker.fpsCap = value;
22
+ }
17
23
  #fixedWidth;
18
24
  #fixedHeight;
19
25
  logicalWidth;
@@ -61,6 +67,8 @@ export class Renderer extends RenderableNode {
61
67
  this.#layers[layerOption.name] = layer;
62
68
  }
63
69
  }
70
+ if (options.targetFps !== undefined)
71
+ this.targetFps = options.targetFps;
64
72
  }
65
73
  if (debugMode) {
66
74
  this.fpsDisplay = new FpsDisplay(container);
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/renderer/renderer.ts"],"names":[],"mappings":"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","sourcesContent":["import { EventMap } from '@webtaku/event-emitter'\nimport { AutoDetectOptions, autoDetectRenderer, ColorSource, Container as PixiContainer, Renderer as PixiRenderer } from 'pixi.js'\nimport { debugMode } from '../debug'\nimport { setStyle } from '../dom/dom-utils'\nimport { RenderableNode } from '../node/core/renderable'\nimport { Camera } from './camera'\nimport { RendererContainerManager } from './container-manager'\nimport { FpsDisplay } from './fps-display'\nimport { Layer } from './layer'\nimport { Ticker } from './ticker'\n\nexport type RendererOptions = {\n fixedWidth?: number\n fixedHeight?: number\n logicalWidth?: number\n logicalHeight?: number\n backgroundColor?: ColorSource\n backgroundAlpha?: number\n layers?: { name: string; drawOrder: number }[]\n}\n\nexport class Renderer extends RenderableNode<PixiContainer, {\n resize: (width: number, height: number) => void\n}> {\n #containerManager: RendererContainerManager\n #ticker = new Ticker((dt) => this.#render(dt))\n camera = new Camera()\n fpsDisplay?: FpsDisplay\n timeScale = 1\n\n #fixedWidth?: number\n #fixedHeight?: number\n logicalWidth?: number\n logicalHeight?: number\n #backgroundColor?: ColorSource\n #backgroundAlpha?: number\n\n #pixiRenderer?: PixiRenderer\n #layers: { [name: string]: Layer } = {}\n _isSizeDirty = false\n\n canvasWidth = 0\n canvasHeight = 0\n canvasLeft = 0\n canvasTop = 0\n viewportScale = 1\n centerX = 0\n centerY = 0\n\n constructor(public container: HTMLElement, options?: RendererOptions) {\n super(new PixiContainer({ sortableChildren: true }))\n this.renderer = this\n\n this.worldTransform.x.v = 0\n this.worldTransform.y.v = 0\n this.worldTransform.resetDirty()\n\n this.#containerManager = new RendererContainerManager(container)\n this.#containerManager.on('resize', (width, height) => this.#updateSize(width, height))\n\n this.camera.on('positionChanged', () => this.#updatePosition())\n this.camera.on('scaleChanged', () => this.#updatePosition())\n\n if (options) {\n if (options.fixedWidth !== undefined) this.#fixedWidth = options.fixedWidth\n if (options.fixedHeight !== undefined) this.#fixedHeight = options.fixedHeight\n if (options.logicalWidth !== undefined) this.logicalWidth = options.logicalWidth\n if (options.logicalHeight !== undefined) this.logicalHeight = options.logicalHeight\n if (options.backgroundColor !== undefined) this.#backgroundColor = options.backgroundColor\n if (options.backgroundAlpha !== undefined) this.#backgroundAlpha = options.backgroundAlpha\n\n if (options.layers) {\n for (const layerOption of options.layers) {\n const layer = new Layer(layerOption.drawOrder)\n this._pixiContainer.addChild(layer._pixiContainer)\n this.#layers[layerOption.name] = layer\n }\n }\n }\n\n if (debugMode) {\n this.fpsDisplay = new FpsDisplay(container)\n }\n\n this.init()\n }\n\n private async init() {\n const options: Partial<AutoDetectOptions> = {\n eventMode: 'none',\n resolution: window.devicePixelRatio,\n }\n\n if (this.#fixedWidth) options.width = this.#fixedWidth\n if (this.#fixedHeight) options.height = this.#fixedHeight\n if (this.logicalWidth) options.width = this.logicalWidth\n if (this.logicalHeight) options.height = this.logicalHeight\n if (this.#backgroundColor !== undefined) options.backgroundColor = this.#backgroundColor\n if (this.#backgroundAlpha !== undefined) options.backgroundAlpha = this.#backgroundAlpha\n\n const pr = await autoDetectRenderer(options)\n\n setStyle(pr.canvas, {\n position: 'absolute',\n touchAction: 'auto',\n })\n this.container.appendChild(pr.canvas)\n\n this.#pixiRenderer = pr\n\n const cr = this.container.getBoundingClientRect()\n this.#updateSize(cr.width, cr.height)\n }\n\n #updatePosition() {\n const S = this.camera.scale\n this._pixiContainer.scale = S\n this._pixiContainer.position.set(\n this.centerX - this.camera.x * S,\n this.centerY - this.camera.y * S\n )\n }\n\n #updateSize(containerWidth: number, containerHeight: number) {\n if (this.#fixedWidth) containerWidth = this.#fixedWidth\n if (this.#fixedHeight) containerHeight = this.#fixedHeight\n\n const canvasWidth = this.logicalWidth ?? containerWidth\n const canvasHeight = this.logicalHeight ?? containerHeight\n this.canvasWidth = canvasWidth\n this.canvasHeight = canvasHeight\n\n this.centerX = canvasWidth / 2\n this.centerY = canvasHeight / 2\n this.#updatePosition()\n\n const S = Math.min(containerWidth / canvasWidth, containerHeight / canvasHeight)\n this.viewportScale = S\n\n const displayWidth = canvasWidth * S\n const displayHeight = canvasHeight * S\n\n const canvasLeft = (containerWidth - displayWidth) / 2\n const canvasTop = (containerHeight - displayHeight) / 2\n this.canvasLeft = canvasLeft\n this.canvasTop = canvasTop\n\n if (this.#pixiRenderer) {\n this.#pixiRenderer.resize(canvasWidth, canvasHeight)\n\n setStyle(this.#pixiRenderer.canvas, {\n width: `${displayWidth}px`,\n height: `${displayHeight}px`,\n left: `${canvasLeft}px`,\n top: `${canvasTop}px`,\n })\n\n this.emit('resize', canvasWidth, canvasHeight)\n }\n\n this._isSizeDirty = true\n }\n\n #render(dt: number) {\n const scaledDt = dt * this.timeScale\n this.update(scaledDt)\n this._updateWorldTransform()\n this._resetWorldTransformDirty()\n this.#pixiRenderer?.render(this._pixiContainer)\n this.fpsDisplay?.update()\n\n this._isSizeDirty = false\n }\n\n _addToLayer(node: RenderableNode<PixiContainer, EventMap>, layerName: string) {\n const layer = this.#layers[layerName]\n if (!layer) throw new Error(`Layer ${layerName} does not exist.`)\n layer._pixiContainer.addChild(node._pixiContainer)\n }\n\n override remove() {\n this.#containerManager.remove()\n this.#ticker.remove()\n this.#pixiRenderer?.destroy()\n this.fpsDisplay?.remove()\n super.remove()\n }\n\n screenToWorld(screenX: number, screenY: number) {\n const x = (screenX - this.canvasLeft) / this.viewportScale - this.canvasWidth / 2\n const y = (screenY - this.canvasTop) / this.viewportScale - this.canvasHeight / 2\n return { x, y }\n }\n}\n"]}
1
+ {"version":3,"file":"renderer.js","sourceRoot":"","sources":["../../src/renderer/renderer.ts"],"names":[],"mappings":"AACA,OAAO,EAAqB,kBAAkB,EAAe,SAAS,IAAI,aAAa,EAA4B,MAAM,SAAS,CAAA;AAClI,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAA;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AACjC,OAAO,EAAE,wBAAwB,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC1C,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAajC,MAAM,OAAO,QAAS,SAAQ,cAE5B;IAkCmB;IAjCnB,iBAAiB,CAA0B;IAC3C,OAAO,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9C,MAAM,GAAG,IAAI,MAAM,EAAE,CAAA;IACrB,UAAU,CAAa;IACvB,SAAS,GAAG,CAAC,CAAA;IAEb,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAA;IAC5B,CAAC;IAED,IAAI,SAAS,CAAC,KAAyB;QACrC,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,KAAK,CAAA;IAC7B,CAAC;IAED,WAAW,CAAS;IACpB,YAAY,CAAS;IACrB,YAAY,CAAS;IACrB,aAAa,CAAS;IACtB,gBAAgB,CAAc;IAC9B,gBAAgB,CAAS;IAEzB,aAAa,CAAe;IAC5B,OAAO,GAA8B,EAAE,CAAA;IACvC,YAAY,GAAG,KAAK,CAAA;IAEpB,WAAW,GAAG,CAAC,CAAA;IACf,YAAY,GAAG,CAAC,CAAA;IAChB,UAAU,GAAG,CAAC,CAAA;IACd,SAAS,GAAG,CAAC,CAAA;IACb,aAAa,GAAG,CAAC,CAAA;IACjB,OAAO,GAAG,CAAC,CAAA;IACX,OAAO,GAAG,CAAC,CAAA;IAEX,YAAmB,SAAsB,EAAE,OAAyB;QAClE,KAAK,CAAC,IAAI,aAAa,CAAC,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;QADnC,cAAS,GAAT,SAAS,CAAa;QAEvC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QAEpB,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3B,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QAC3B,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,CAAA;QAEhC,IAAI,CAAC,iBAAiB,GAAG,IAAI,wBAAwB,CAAC,SAAS,CAAC,CAAA;QAChE,IAAI,CAAC,iBAAiB,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;QAEvF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,iBAAiB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAA;QAC/D,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC,CAAA;QAE5D,IAAI,OAAO,EAAE,CAAC;YACZ,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;gBAAE,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,UAAU,CAAA;YAC3E,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;gBAAE,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAA;YAC9E,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS;gBAAE,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAA;YAChF,IAAI,OAAO,CAAC,aAAa,KAAK,SAAS;gBAAE,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAA;YACnF,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS;gBAAE,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAA;YAC1F,IAAI,OAAO,CAAC,eAAe,KAAK,SAAS;gBAAE,IAAI,CAAC,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAA;YAE1F,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;gBACnB,KAAK,MAAM,WAAW,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;oBACzC,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,WAAW,CAAC,SAAS,CAAC,CAAA;oBAC9C,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,CAAA;oBAClD,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,KAAK,CAAA;gBACxC,CAAC;YACH,CAAC;YACD,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;gBAAE,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAA;QACzE,CAAC;QAED,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,UAAU,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,CAAA;QAC7C,CAAC;QAED,IAAI,CAAC,IAAI,EAAE,CAAA;IACb,CAAC;IAEO,KAAK,CAAC,IAAI;QAChB,MAAM,OAAO,GAA+B;YAC1C,SAAS,EAAE,MAAM;YACjB,UAAU,EAAE,MAAM,CAAC,gBAAgB;SACpC,CAAA;QAED,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,WAAW,CAAA;QACtD,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,CAAA;QACzD,IAAI,IAAI,CAAC,YAAY;YAAE,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,YAAY,CAAA;QACxD,IAAI,IAAI,CAAC,aAAa;YAAE,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,aAAa,CAAA;QAC3D,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS;YAAE,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAAA;QACxF,IAAI,IAAI,CAAC,gBAAgB,KAAK,SAAS;YAAE,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAAA;QAExF,MAAM,EAAE,GAAG,MAAM,kBAAkB,CAAC,OAAO,CAAC,CAAA;QAE5C,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE;YAClB,QAAQ,EAAE,UAAU;YACpB,WAAW,EAAE,MAAM;SACpB,CAAC,CAAA;QACF,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC,MAAM,CAAC,CAAA;QAErC,IAAI,CAAC,aAAa,GAAG,EAAE,CAAA;QAEvB,MAAM,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,qBAAqB,EAAE,CAAA;QACjD,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,CAAA;IACvC,CAAC;IAED,eAAe;QACb,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAA;QAC3B,IAAI,CAAC,cAAc,CAAC,KAAK,GAAG,CAAC,CAAA;QAC7B,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,GAAG,CAC9B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,EAChC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CACjC,CAAA;IACH,CAAC;IAED,WAAW,CAAC,cAAsB,EAAE,eAAuB;QACzD,IAAI,IAAI,CAAC,WAAW;YAAE,cAAc,GAAG,IAAI,CAAC,WAAW,CAAA;QACvD,IAAI,IAAI,CAAC,YAAY;YAAE,eAAe,GAAG,IAAI,CAAC,YAAY,CAAA;QAE1D,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,IAAI,cAAc,CAAA;QACvD,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,IAAI,eAAe,CAAA;QAC1D,IAAI,CAAC,WAAW,GAAG,WAAW,CAAA;QAC9B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAA;QAEhC,IAAI,CAAC,OAAO,GAAG,WAAW,GAAG,CAAC,CAAA;QAC9B,IAAI,CAAC,OAAO,GAAG,YAAY,GAAG,CAAC,CAAA;QAC/B,IAAI,CAAC,eAAe,EAAE,CAAA;QAEtB,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,WAAW,EAAE,eAAe,GAAG,YAAY,CAAC,CAAA;QAChF,IAAI,CAAC,aAAa,GAAG,CAAC,CAAA;QAEtB,MAAM,YAAY,GAAG,WAAW,GAAG,CAAC,CAAA;QACpC,MAAM,aAAa,GAAG,YAAY,GAAG,CAAC,CAAA;QAEtC,MAAM,UAAU,GAAG,CAAC,cAAc,GAAG,YAAY,CAAC,GAAG,CAAC,CAAA;QACtD,MAAM,SAAS,GAAG,CAAC,eAAe,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;QACvD,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAA;QAE1B,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAAA;YAEpD,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE;gBAClC,KAAK,EAAE,GAAG,YAAY,IAAI;gBAC1B,MAAM,EAAE,GAAG,aAAa,IAAI;gBAC5B,IAAI,EAAE,GAAG,UAAU,IAAI;gBACvB,GAAG,EAAE,GAAG,SAAS,IAAI;aACtB,CAAC,CAAA;YAEF,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,YAAY,CAAC,CAAA;QAChD,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;IAC1B,CAAC;IAED,OAAO,CAAC,EAAU;QAChB,MAAM,QAAQ,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAA;QACpC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACrB,IAAI,CAAC,qBAAqB,EAAE,CAAA;QAC5B,IAAI,CAAC,yBAAyB,EAAE,CAAA;QAChC,IAAI,CAAC,aAAa,EAAE,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;QAC/C,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAA;QAEzB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAA;IAC3B,CAAC;IAED,WAAW,CAAC,IAA6C,EAAE,SAAiB;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACrC,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,SAAS,kBAAkB,CAAC,CAAA;QACjE,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,cAAc,CAAC,CAAA;IACpD,CAAC;IAEQ,MAAM;QACb,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAA;QAC/B,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAA;QACrB,IAAI,CAAC,aAAa,EAAE,OAAO,EAAE,CAAA;QAC7B,IAAI,CAAC,UAAU,EAAE,MAAM,EAAE,CAAA;QACzB,KAAK,CAAC,MAAM,EAAE,CAAA;IAChB,CAAC;IAED,aAAa,CAAC,OAAe,EAAE,OAAe;QAC5C,MAAM,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,WAAW,GAAG,CAAC,CAAA;QACjF,MAAM,CAAC,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,GAAG,CAAC,CAAA;QACjF,OAAO,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;IACjB,CAAC;CACF","sourcesContent":["import { EventMap } from '@webtaku/event-emitter'\nimport { AutoDetectOptions, autoDetectRenderer, ColorSource, Container as PixiContainer, Renderer as PixiRenderer } from 'pixi.js'\nimport { debugMode } from '../debug'\nimport { setStyle } from '../dom/dom-utils'\nimport { RenderableNode } from '../node/core/renderable'\nimport { Camera } from './camera'\nimport { RendererContainerManager } from './container-manager'\nimport { FpsDisplay } from './fps-display'\nimport { Layer } from './layer'\nimport { Ticker } from './ticker'\n\nexport type RendererOptions = {\n fixedWidth?: number\n fixedHeight?: number\n logicalWidth?: number\n logicalHeight?: number\n backgroundColor?: ColorSource\n backgroundAlpha?: number\n layers?: { name: string; drawOrder: number }[]\n targetFps?: number\n}\n\nexport class Renderer extends RenderableNode<PixiContainer, {\n resize: (width: number, height: number) => void\n}> {\n #containerManager: RendererContainerManager\n #ticker = new Ticker((dt) => this.#render(dt))\n camera = new Camera()\n fpsDisplay?: FpsDisplay\n timeScale = 1\n\n get targetFps(): number | undefined {\n return this.#ticker.fpsCap\n }\n\n set targetFps(value: number | undefined) {\n this.#ticker.fpsCap = value\n }\n\n #fixedWidth?: number\n #fixedHeight?: number\n logicalWidth?: number\n logicalHeight?: number\n #backgroundColor?: ColorSource\n #backgroundAlpha?: number\n\n #pixiRenderer?: PixiRenderer\n #layers: { [name: string]: Layer } = {}\n _isSizeDirty = false\n\n canvasWidth = 0\n canvasHeight = 0\n canvasLeft = 0\n canvasTop = 0\n viewportScale = 1\n centerX = 0\n centerY = 0\n\n constructor(public container: HTMLElement, options?: RendererOptions) {\n super(new PixiContainer({ sortableChildren: true }))\n this.renderer = this\n\n this.worldTransform.x.v = 0\n this.worldTransform.y.v = 0\n this.worldTransform.resetDirty()\n\n this.#containerManager = new RendererContainerManager(container)\n this.#containerManager.on('resize', (width, height) => this.#updateSize(width, height))\n\n this.camera.on('positionChanged', () => this.#updatePosition())\n this.camera.on('scaleChanged', () => this.#updatePosition())\n\n if (options) {\n if (options.fixedWidth !== undefined) this.#fixedWidth = options.fixedWidth\n if (options.fixedHeight !== undefined) this.#fixedHeight = options.fixedHeight\n if (options.logicalWidth !== undefined) this.logicalWidth = options.logicalWidth\n if (options.logicalHeight !== undefined) this.logicalHeight = options.logicalHeight\n if (options.backgroundColor !== undefined) this.#backgroundColor = options.backgroundColor\n if (options.backgroundAlpha !== undefined) this.#backgroundAlpha = options.backgroundAlpha\n\n if (options.layers) {\n for (const layerOption of options.layers) {\n const layer = new Layer(layerOption.drawOrder)\n this._pixiContainer.addChild(layer._pixiContainer)\n this.#layers[layerOption.name] = layer\n }\n }\n if (options.targetFps !== undefined) this.targetFps = options.targetFps\n }\n\n if (debugMode) {\n this.fpsDisplay = new FpsDisplay(container)\n }\n\n this.init()\n }\n\n private async init() {\n const options: Partial<AutoDetectOptions> = {\n eventMode: 'none',\n resolution: window.devicePixelRatio,\n }\n\n if (this.#fixedWidth) options.width = this.#fixedWidth\n if (this.#fixedHeight) options.height = this.#fixedHeight\n if (this.logicalWidth) options.width = this.logicalWidth\n if (this.logicalHeight) options.height = this.logicalHeight\n if (this.#backgroundColor !== undefined) options.backgroundColor = this.#backgroundColor\n if (this.#backgroundAlpha !== undefined) options.backgroundAlpha = this.#backgroundAlpha\n\n const pr = await autoDetectRenderer(options)\n\n setStyle(pr.canvas, {\n position: 'absolute',\n touchAction: 'auto',\n })\n this.container.appendChild(pr.canvas)\n\n this.#pixiRenderer = pr\n\n const cr = this.container.getBoundingClientRect()\n this.#updateSize(cr.width, cr.height)\n }\n\n #updatePosition() {\n const S = this.camera.scale\n this._pixiContainer.scale = S\n this._pixiContainer.position.set(\n this.centerX - this.camera.x * S,\n this.centerY - this.camera.y * S\n )\n }\n\n #updateSize(containerWidth: number, containerHeight: number) {\n if (this.#fixedWidth) containerWidth = this.#fixedWidth\n if (this.#fixedHeight) containerHeight = this.#fixedHeight\n\n const canvasWidth = this.logicalWidth ?? containerWidth\n const canvasHeight = this.logicalHeight ?? containerHeight\n this.canvasWidth = canvasWidth\n this.canvasHeight = canvasHeight\n\n this.centerX = canvasWidth / 2\n this.centerY = canvasHeight / 2\n this.#updatePosition()\n\n const S = Math.min(containerWidth / canvasWidth, containerHeight / canvasHeight)\n this.viewportScale = S\n\n const displayWidth = canvasWidth * S\n const displayHeight = canvasHeight * S\n\n const canvasLeft = (containerWidth - displayWidth) / 2\n const canvasTop = (containerHeight - displayHeight) / 2\n this.canvasLeft = canvasLeft\n this.canvasTop = canvasTop\n\n if (this.#pixiRenderer) {\n this.#pixiRenderer.resize(canvasWidth, canvasHeight)\n\n setStyle(this.#pixiRenderer.canvas, {\n width: `${displayWidth}px`,\n height: `${displayHeight}px`,\n left: `${canvasLeft}px`,\n top: `${canvasTop}px`,\n })\n\n this.emit('resize', canvasWidth, canvasHeight)\n }\n\n this._isSizeDirty = true\n }\n\n #render(dt: number) {\n const scaledDt = dt * this.timeScale\n this.update(scaledDt)\n this._updateWorldTransform()\n this._resetWorldTransformDirty()\n this.#pixiRenderer?.render(this._pixiContainer)\n this.fpsDisplay?.update()\n\n this._isSizeDirty = false\n }\n\n _addToLayer(node: RenderableNode<PixiContainer, EventMap>, layerName: string) {\n const layer = this.#layers[layerName]\n if (!layer) throw new Error(`Layer ${layerName} does not exist.`)\n layer._pixiContainer.addChild(node._pixiContainer)\n }\n\n override remove() {\n this.#containerManager.remove()\n this.#ticker.remove()\n this.#pixiRenderer?.destroy()\n this.fpsDisplay?.remove()\n super.remove()\n }\n\n screenToWorld(screenX: number, screenY: number) {\n const x = (screenX - this.canvasLeft) / this.viewportScale - this.canvasWidth / 2\n const y = (screenY - this.canvasTop) / this.viewportScale - this.canvasHeight / 2\n return { x, y }\n }\n}\n"]}
@@ -1,7 +1,15 @@
1
1
  import { debugMode } from '../debug';
2
2
  export class Ticker {
3
3
  #fpsCap;
4
+ #userFpsCap;
4
5
  #frameId = 0;
6
+ get fpsCap() {
7
+ return this.#userFpsCap;
8
+ }
9
+ set fpsCap(value) {
10
+ this.#userFpsCap = value;
11
+ this.#fpsCap = value;
12
+ }
5
13
  constructor(onTick) {
6
14
  let prevTime = 0;
7
15
  let lagSeconds = 0;
@@ -40,10 +48,10 @@ export class Ticker {
40
48
  }
41
49
  }
42
50
  #blurListener = () => { this.#fpsCap = 6; };
43
- #focusListener = () => { this.#fpsCap = undefined; };
51
+ #focusListener = () => { this.#fpsCap = this.#userFpsCap; };
44
52
  #pageshowListener = (event) => {
45
53
  if (event.persisted) {
46
- this.#fpsCap = undefined;
54
+ this.#fpsCap = this.#userFpsCap;
47
55
  }
48
56
  };
49
57
  remove() {
@@ -1 +1 @@
1
- {"version":3,"file":"ticker.js","sourceRoot":"","sources":["../../src/renderer/ticker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AAEpC,MAAM,OAAO,MAAM;IACjB,OAAO,CAAS;IAChB,QAAQ,GAAG,CAAC,CAAA;IAEZ,YAAY,MAA4B;QACtC,IAAI,QAAQ,GAAG,CAAC,CAAA;QAChB,IAAI,UAAU,GAAG,CAAC,CAAA;QAElB,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAE,EAAE;YACjC,MAAM,EAAE,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,GAAG,IAAI,CAAA;YACxC,IAAI,EAAE,GAAG,CAAC,EAAE,CAAC;gBACX,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAA;gBAC3B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;oBACvC,UAAU,IAAI,EAAE,CAAA;oBAChB,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAA;oBAC5B,IAAI,UAAU,IAAI,SAAS,EAAE,CAAC;wBAC5B,MAAM,CAAC,SAAS,CAAC,CAAA;wBACjB,IAAI,UAAU,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;4BAAC,MAAM,CAAC,EAAE,CAAC,CAAC;4BAAC,UAAU,GAAG,CAAC,CAAA;wBAAC,CAAC;6BAC1D,CAAC;4BAAC,UAAU,IAAI,SAAS,CAAA;wBAAC,CAAC;oBAClC,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,EAAE,CAAC,CAAA;gBACZ,CAAC;gBACD,QAAQ,GAAG,SAAS,CAAA;YACtB,CAAC;YACD,IAAI,CAAC,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;QAC7C,CAAC,CAAA;QACD,IAAI,CAAC,QAAQ,GAAG,qBAAqB,CAAC,IAAI,CAAC,CAAA;QAE3C,IAAI,SAAS,EAAE,CAAC;YACd,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE;gBAAE,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA;YAC1C,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;YACnD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;YACrD,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;QAC7D,CAAC;IACH,CAAC;IAED,aAAa,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,CAAC,CAAA,CAAC,CAAC,CAAA;IAC1C,cAAc,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA,CAAC,CAAC,CAAA;IACnD,iBAAiB,GAAG,CAAC,KAA0B,EAAE,EAAE;QACjD,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACpB,IAAI,CAAC,OAAO,GAAG,SAAS,CAAA;QAC1B,CAAC;IACH,CAAC,CAAA;IAED,MAAM;QACJ,oBAAoB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACnC,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,IAAI,CAAC,aAAa,CAAC,CAAA;QACtD,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,CAAC,CAAA;QACxD,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,iBAAiB,CAAC,CAAA;IAChE,CAAC;CACF","sourcesContent":["import { debugMode } from '../debug'\n\nexport class Ticker {\n #fpsCap?: number\n #frameId = 0\n\n constructor(onTick: (dt: number) => void) {\n let prevTime = 0\n let lagSeconds = 0\n\n const step = (timestamp: number) => {\n const dt = (timestamp - prevTime) / 1000\n if (dt > 0) {\n const fpsCap = this.#fpsCap\n if (fpsCap !== undefined && fpsCap > 0) {\n lagSeconds += dt\n const fixedStep = 1 / fpsCap\n if (lagSeconds >= fixedStep) {\n onTick(fixedStep)\n if (lagSeconds >= fixedStep * 2) { onTick(dt); lagSeconds = 0 }\n else { lagSeconds -= fixedStep }\n }\n } else {\n onTick(dt)\n }\n prevTime = timestamp\n }\n this.#frameId = requestAnimationFrame(step)\n }\n this.#frameId = requestAnimationFrame(step)\n\n if (debugMode) {\n if (!document.hasFocus()) this.#fpsCap = 6\n window.addEventListener('blur', this.#blurListener)\n window.addEventListener('focus', this.#focusListener)\n window.addEventListener('pageshow', this.#pageshowListener)\n }\n }\n\n #blurListener = () => { this.#fpsCap = 6 }\n #focusListener = () => { this.#fpsCap = undefined }\n #pageshowListener = (event: PageTransitionEvent) => {\n if (event.persisted) {\n this.#fpsCap = undefined\n }\n }\n\n remove() {\n cancelAnimationFrame(this.#frameId)\n window.removeEventListener('blur', this.#blurListener)\n window.removeEventListener('focus', this.#focusListener)\n window.removeEventListener('pageshow', this.#pageshowListener)\n }\n}\n"]}
1
+ {"version":3,"file":"ticker.js","sourceRoot":"","sources":["../../src/renderer/ticker.ts"],"names":[],"mappings":"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","sourcesContent":["import { debugMode } from '../debug'\n\nexport class Ticker {\n #fpsCap?: number\n #userFpsCap?: number\n #frameId = 0\n\n get fpsCap(): number | undefined {\n return this.#userFpsCap\n }\n\n set fpsCap(value: number | undefined) {\n this.#userFpsCap = value\n this.#fpsCap = value\n }\n\n constructor(onTick: (dt: number) => void) {\n let prevTime = 0\n let lagSeconds = 0\n\n const step = (timestamp: number) => {\n const dt = (timestamp - prevTime) / 1000\n if (dt > 0) {\n const fpsCap = this.#fpsCap\n if (fpsCap !== undefined && fpsCap > 0) {\n lagSeconds += dt\n const fixedStep = 1 / fpsCap\n if (lagSeconds >= fixedStep) {\n onTick(fixedStep)\n if (lagSeconds >= fixedStep * 2) { onTick(dt); lagSeconds = 0 }\n else { lagSeconds -= fixedStep }\n }\n } else {\n onTick(dt)\n }\n prevTime = timestamp\n }\n this.#frameId = requestAnimationFrame(step)\n }\n this.#frameId = requestAnimationFrame(step)\n\n if (debugMode) {\n if (!document.hasFocus()) this.#fpsCap = 6\n window.addEventListener('blur', this.#blurListener)\n window.addEventListener('focus', this.#focusListener)\n window.addEventListener('pageshow', this.#pageshowListener)\n }\n }\n\n #blurListener = () => { this.#fpsCap = 6 }\n #focusListener = () => { this.#fpsCap = this.#userFpsCap }\n #pageshowListener = (event: PageTransitionEvent) => {\n if (event.persisted) {\n this.#fpsCap = this.#userFpsCap\n }\n }\n\n remove() {\n cancelAnimationFrame(this.#frameId)\n window.removeEventListener('blur', this.#blurListener)\n window.removeEventListener('focus', this.#focusListener)\n window.removeEventListener('pageshow', this.#pageshowListener)\n }\n}\n"]}
@@ -14,6 +14,7 @@ export type RendererOptions = {
14
14
  name: string;
15
15
  drawOrder: number;
16
16
  }[];
17
+ targetFps?: number;
17
18
  };
18
19
  export declare class Renderer extends RenderableNode<PixiContainer, {
19
20
  resize: (width: number, height: number) => void;
@@ -23,6 +24,8 @@ export declare class Renderer extends RenderableNode<PixiContainer, {
23
24
  camera: Camera;
24
25
  fpsDisplay?: FpsDisplay;
25
26
  timeScale: number;
27
+ get targetFps(): number | undefined;
28
+ set targetFps(value: number | undefined);
26
29
  logicalWidth?: number;
27
30
  logicalHeight?: number;
28
31
  _isSizeDirty: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/renderer/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAyC,WAAW,EAAE,SAAS,IAAI,aAAa,EAA4B,MAAM,SAAS,CAAA;AAGlI,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAI1C,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,WAAW,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAC/C,CAAA;AAED,qBAAa,QAAS,SAAQ,cAAc,CAAC,aAAa,EAAE;IAC1D,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAChD,CAAC;;IA0BmB,SAAS,EAAE,WAAW;IAvBzC,MAAM,SAAe;IACrB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,SAAS,SAAI;IAIb,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IAMtB,YAAY,UAAQ;IAEpB,WAAW,SAAI;IACf,YAAY,SAAI;IAChB,UAAU,SAAI;IACd,SAAS,SAAI;IACb,aAAa,SAAI;IACjB,OAAO,SAAI;IACX,OAAO,SAAI;gBAEQ,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,eAAe;YAsCtD,IAAI;IAuFlB,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,MAAM;IAMnE,MAAM;IAQf,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;CAK/C"}
1
+ {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../../../src/renderer/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,EAAyC,WAAW,EAAE,SAAS,IAAI,aAAa,EAA4B,MAAM,SAAS,CAAA;AAGlI,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAI1C,MAAM,MAAM,eAAe,GAAG;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,eAAe,CAAC,EAAE,WAAW,CAAA;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,MAAM,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB,CAAA;AAED,qBAAa,QAAS,SAAQ,cAAc,CAAC,aAAa,EAAE;IAC1D,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;CAChD,CAAC;;IAkCmB,SAAS,EAAE,WAAW;IA/BzC,MAAM,SAAe;IACrB,UAAU,CAAC,EAAE,UAAU,CAAA;IACvB,SAAS,SAAI;IAEb,IAAI,SAAS,IAAI,MAAM,GAAG,SAAS,CAElC;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAEtC;IAID,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IAMtB,YAAY,UAAQ;IAEpB,WAAW,SAAI;IACf,YAAY,SAAI;IAChB,UAAU,SAAI;IACd,SAAS,SAAI;IACb,aAAa,SAAI;IACjB,OAAO,SAAI;IACX,OAAO,SAAI;gBAEQ,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,EAAE,eAAe;YAuCtD,IAAI;IAuFlB,WAAW,CAAC,IAAI,EAAE,cAAc,CAAC,aAAa,EAAE,QAAQ,CAAC,EAAE,SAAS,EAAE,MAAM;IAMnE,MAAM;IAQf,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;CAK/C"}
@@ -1,5 +1,7 @@
1
1
  export declare class Ticker {
2
2
  #private;
3
+ get fpsCap(): number | undefined;
4
+ set fpsCap(value: number | undefined);
3
5
  constructor(onTick: (dt: number) => void);
4
6
  remove(): void;
5
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ticker.d.ts","sourceRoot":"","sources":["../../../src/renderer/ticker.ts"],"names":[],"mappings":"AAEA,qBAAa,MAAM;;gBAIL,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;IAyCxC,MAAM;CAMP"}
1
+ {"version":3,"file":"ticker.d.ts","sourceRoot":"","sources":["../../../src/renderer/ticker.ts"],"names":[],"mappings":"AAEA,qBAAa,MAAM;;IAKjB,IAAI,MAAM,IAAI,MAAM,GAAG,SAAS,CAE/B;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,EAGnC;gBAEW,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI;IAyCxC,MAAM;CAMP"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kiwiengine",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "types": "./lib/types/index.d.ts",
5
5
  "main": "./lib/index.js",
6
6
  "dependencies": {
@@ -19,6 +19,5 @@
19
19
  "ts-jest": "^29.4.6",
20
20
  "ts-node": "^10.9.2",
21
21
  "typescript": "^5.9.3"
22
- },
23
- "packageManager": "yarn@1.22.22"
22
+ }
24
23
  }
@@ -17,6 +17,7 @@ export type RendererOptions = {
17
17
  backgroundColor?: ColorSource
18
18
  backgroundAlpha?: number
19
19
  layers?: { name: string; drawOrder: number }[]
20
+ targetFps?: number
20
21
  }
21
22
 
22
23
  export class Renderer extends RenderableNode<PixiContainer, {
@@ -28,6 +29,14 @@ export class Renderer extends RenderableNode<PixiContainer, {
28
29
  fpsDisplay?: FpsDisplay
29
30
  timeScale = 1
30
31
 
32
+ get targetFps(): number | undefined {
33
+ return this.#ticker.fpsCap
34
+ }
35
+
36
+ set targetFps(value: number | undefined) {
37
+ this.#ticker.fpsCap = value
38
+ }
39
+
31
40
  #fixedWidth?: number
32
41
  #fixedHeight?: number
33
42
  logicalWidth?: number
@@ -76,6 +85,7 @@ export class Renderer extends RenderableNode<PixiContainer, {
76
85
  this.#layers[layerOption.name] = layer
77
86
  }
78
87
  }
88
+ if (options.targetFps !== undefined) this.targetFps = options.targetFps
79
89
  }
80
90
 
81
91
  if (debugMode) {
@@ -2,8 +2,18 @@ import { debugMode } from '../debug'
2
2
 
3
3
  export class Ticker {
4
4
  #fpsCap?: number
5
+ #userFpsCap?: number
5
6
  #frameId = 0
6
7
 
8
+ get fpsCap(): number | undefined {
9
+ return this.#userFpsCap
10
+ }
11
+
12
+ set fpsCap(value: number | undefined) {
13
+ this.#userFpsCap = value
14
+ this.#fpsCap = value
15
+ }
16
+
7
17
  constructor(onTick: (dt: number) => void) {
8
18
  let prevTime = 0
9
19
  let lagSeconds = 0
@@ -38,10 +48,10 @@ export class Ticker {
38
48
  }
39
49
 
40
50
  #blurListener = () => { this.#fpsCap = 6 }
41
- #focusListener = () => { this.#fpsCap = undefined }
51
+ #focusListener = () => { this.#fpsCap = this.#userFpsCap }
42
52
  #pageshowListener = (event: PageTransitionEvent) => {
43
53
  if (event.persisted) {
44
- this.#fpsCap = undefined
54
+ this.#fpsCap = this.#userFpsCap
45
55
  }
46
56
  }
47
57