mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Allow to provide a canvas to be used for the game rendering instead of creating a new one (#7199)
Only show in developer changelog
This commit is contained in:
@@ -60,15 +60,29 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a standard canvas inside canvasArea.
|
||||
* Create the canvas on which the game will be rendered, inside the specified DOM element, and
|
||||
* setup the rendering of the game.
|
||||
* If you want to use your own canvas, use `initializeForCanvas` instead.
|
||||
*
|
||||
* @param parentElement The parent element to which the canvas will be added.
|
||||
*/
|
||||
createStandardCanvas(parentElement: HTMLElement) {
|
||||
this._throwIfDisposed();
|
||||
|
||||
let gameCanvas: HTMLCanvasElement;
|
||||
const gameCanvas = document.createElement('canvas');
|
||||
parentElement.appendChild(gameCanvas);
|
||||
|
||||
this.initializeForCanvas(gameCanvas);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setup the rendering of the game to use a canvas that was already created.
|
||||
* @param gameCanvas The canvas to use.
|
||||
*/
|
||||
initializeForCanvas(gameCanvas: HTMLCanvasElement): void {
|
||||
this._throwIfDisposed();
|
||||
|
||||
if (typeof THREE !== 'undefined') {
|
||||
gameCanvas = document.createElement('canvas');
|
||||
this._threeRenderer = new THREE.WebGLRenderer({
|
||||
canvas: gameCanvas,
|
||||
antialias:
|
||||
@@ -99,8 +113,6 @@ namespace gdjs {
|
||||
backgroundAlpha: 0,
|
||||
// TODO (3D): add a setting for pixel ratio (`resolution: window.devicePixelRatio`)
|
||||
});
|
||||
|
||||
gameCanvas = this._threeRenderer.domElement;
|
||||
} else {
|
||||
// Create the renderer and setup the rendering area.
|
||||
// "preserveDrawingBuffer: true" is needed to avoid flickering
|
||||
@@ -108,11 +120,10 @@ namespace gdjs {
|
||||
this._pixiRenderer = PIXI.autoDetectRenderer({
|
||||
width: this._game.getGameResolutionWidth(),
|
||||
height: this._game.getGameResolutionHeight(),
|
||||
view: gameCanvas,
|
||||
preserveDrawingBuffer: true,
|
||||
antialias: false,
|
||||
}) as PIXI.Renderer;
|
||||
|
||||
gameCanvas = this._pixiRenderer.view as HTMLCanvasElement;
|
||||
}
|
||||
|
||||
// Deactivating accessibility support in PixiJS renderer, as we want to be in control of this.
|
||||
@@ -121,7 +132,6 @@ namespace gdjs {
|
||||
delete this._pixiRenderer.plugins.accessibility;
|
||||
|
||||
// Add the renderer view element to the DOM
|
||||
parentElement.appendChild(gameCanvas);
|
||||
this._gameCanvas = gameCanvas;
|
||||
|
||||
gameCanvas.style.position = 'absolute';
|
||||
@@ -160,7 +170,7 @@ namespace gdjs {
|
||||
// but it seems not to affect us as the `domElementsContainer` has `pointerEvents` set to `none`.
|
||||
domElementsContainer.style['-webkit-user-select'] = 'none';
|
||||
|
||||
parentElement.appendChild(domElementsContainer);
|
||||
gameCanvas.parentNode?.appendChild(domElementsContainer);
|
||||
this._domElementsContainer = domElementsContainer;
|
||||
|
||||
this._resizeCanvas();
|
||||
@@ -938,14 +948,26 @@ namespace gdjs {
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispose PixiRenderer, ThreeRenderer and remove canvas from DOM.
|
||||
* Dispose the renderers (PixiJS and/or Three.js) as well as DOM elements
|
||||
* used for the game (the canvas, if specified, and the additional DOM container
|
||||
* created on top of it to allow display HTML elements, for example for text inputs).
|
||||
*
|
||||
* @param removeCanvas If true, the canvas will be removed from the DOM.
|
||||
*/
|
||||
dispose() {
|
||||
this._pixiRenderer?.destroy(true);
|
||||
dispose(removeCanvas?: boolean) {
|
||||
this._pixiRenderer?.destroy();
|
||||
this._threeRenderer?.dispose();
|
||||
this._pixiRenderer = null;
|
||||
this._threeRenderer = null;
|
||||
|
||||
if (removeCanvas && this._gameCanvas) {
|
||||
this._gameCanvas.parentNode?.removeChild(this._gameCanvas);
|
||||
}
|
||||
|
||||
this._gameCanvas = null;
|
||||
this._domElementsContainer?.parentNode?.removeChild(
|
||||
this._domElementsContainer
|
||||
);
|
||||
this._domElementsContainer = null;
|
||||
this._wasDisposed = true;
|
||||
}
|
||||
|
@@ -976,11 +976,12 @@ namespace gdjs {
|
||||
/**
|
||||
* Stop game loop, unload all scenes, dispose renderer and resources.
|
||||
* After calling this method, the RuntimeGame should not be used anymore.
|
||||
* @param removeCanvas If true, the canvas will be removed from the DOM.
|
||||
*/
|
||||
dispose(): void {
|
||||
dispose(removeCanvas?: boolean): void {
|
||||
this._renderer.stopGameLoop();
|
||||
this._sceneStack.dispose();
|
||||
this._renderer.dispose();
|
||||
this._renderer.dispose(removeCanvas);
|
||||
this._resourcesLoader.dispose();
|
||||
|
||||
this._wasDisposed = true;
|
||||
|
59
GDJS/tests/tests/game-canvas.js
Normal file
59
GDJS/tests/tests/game-canvas.js
Normal file
@@ -0,0 +1,59 @@
|
||||
describe('gdjs.RuntimeGameRenderer canvas tests', () => {
|
||||
let runtimeGame;
|
||||
let renderer;
|
||||
let gameContainer;
|
||||
|
||||
beforeEach(() => {
|
||||
runtimeGame = gdjs.getPixiRuntimeGame();
|
||||
renderer = runtimeGame.getRenderer();
|
||||
gameContainer = document.createElement('div');
|
||||
});
|
||||
|
||||
it('should correctly create standard canvas and domElementsContainer', () => {
|
||||
renderer.createStandardCanvas(gameContainer);
|
||||
|
||||
const actualGameCanvas = renderer.getCanvas();
|
||||
const actualDomElementsContainer = renderer.getDomElementContainer();
|
||||
|
||||
expect(actualGameCanvas).to.not.be(null);
|
||||
expect(actualDomElementsContainer).to.not.be(null);
|
||||
expect(actualGameCanvas.parentElement).to.be(gameContainer);
|
||||
expect(actualDomElementsContainer.parentElement).to.be(gameContainer);
|
||||
});
|
||||
|
||||
it('should correctly initialize external canvas and create domElementsContainer', () => {
|
||||
const gameCanvas = document.createElement('canvas');
|
||||
gameContainer.appendChild(gameCanvas);
|
||||
renderer.initializeForCanvas(gameCanvas);
|
||||
|
||||
const actualGameCanvas = renderer.getCanvas();
|
||||
const actualDomElementsContainer = renderer.getDomElementContainer();
|
||||
|
||||
expect(actualGameCanvas).to.not.be(null);
|
||||
expect(actualDomElementsContainer).to.not.be(null);
|
||||
expect(actualGameCanvas).to.be(gameCanvas);
|
||||
expect(actualDomElementsContainer.parentElement).to.be(gameContainer);
|
||||
});
|
||||
|
||||
it('should remove canvas and domElementsContainer on dispose', () => {
|
||||
renderer.createStandardCanvas(gameContainer);
|
||||
|
||||
const actualGameCanvas = renderer.getCanvas();
|
||||
const actualDomElementsContainer = renderer.getDomElementContainer();
|
||||
|
||||
expect(actualGameCanvas).to.not.be(null);
|
||||
expect(actualDomElementsContainer).to.not.be(null);
|
||||
expect(actualGameCanvas.parentElement).to.be(gameContainer);
|
||||
expect(actualDomElementsContainer.parentElement).to.be(gameContainer);
|
||||
|
||||
runtimeGame.dispose(true);
|
||||
|
||||
const actualGameCanvasAfterDispose = renderer.getCanvas();
|
||||
const actualDomElementsContainerAfterDispose = renderer.getDomElementContainer();
|
||||
|
||||
expect(actualGameCanvasAfterDispose).to.be(null);
|
||||
expect(actualDomElementsContainerAfterDispose).to.be(null);
|
||||
|
||||
expect(gameContainer.childNodes.length).to.be(0);
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user