import utils from '../utils'; import math from '../math'; import CONST from '../const'; import Container from '../display/Container'; import RenderTexture from '../textures/RenderTexture'; import EventEmitter from 'eventemitter3'; const tempMatrix = new math.Matrix(); /** * The CanvasRenderer draws the scene and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. * Don't forget to add the CanvasRenderer.view to your DOM or you will not see anything :) * * @class * @memberof PIXI * @param system {string} The name of the system this renderer is for. * @param [width=800] {number} the width of the canvas view * @param [height=600] {number} the height of the canvas view * @param [options] {object} The optional renderer parameters * @param [options.view] {HTMLCanvasElement} the canvas to use as a view, optional * @param [options.transparent=false] {boolean} If the render view is transparent, default false * @param [options.autoResize=false] {boolean} If the render view is automatically resized, default false * @param [options.antialias=false] {boolean} sets antialias (only applicable in chrome at the moment) * @param [options.resolution=1] {number} The resolution / device pixel ratio of the renderer. The resolution of the renderer retina would be 2. * @param [options.clearBeforeRender=true] {boolean} This sets if the CanvasRenderer will clear the canvas or * not before the new render pass. * @param [options.backgroundColor=0x000000] {number} The background color of the rendered area (shown if not transparent). * @param [options.roundPixels=false] {boolean} If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation. */ class SystemRenderer extends EventEmitter { constructor(system, width, height, options) { super(); utils.sayHello(system); // prepare options if (options) { for (let i in CONST.DEFAULT_RENDER_OPTIONS) { if (typeof options[i] === 'undefined') { options[i] = CONST.DEFAULT_RENDER_OPTIONS[i]; } } } else { options = CONST.DEFAULT_RENDER_OPTIONS; } /** * The type of the renderer. * * @member {number} * @default PIXI.RENDERER_TYPE.UNKNOWN * @see PIXI.RENDERER_TYPE */ this.type = CONST.RENDERER_TYPE.UNKNOWN; /** * The width of the canvas view * * @member {number} * @default 800 */ this.width = width || 800; /** * The height of the canvas view * * @member {number} * @default 600 */ this.height = height || 600; /** * The canvas element that everything is drawn to * * @member {HTMLCanvasElement} */ this.view = options.view || document.createElement('canvas'); /** * The resolution / device pixel ratio of the renderer * * @member {number} * @default 1 */ this.resolution = options.resolution; /** * Whether the render view is transparent * * @member {boolean} */ this.transparent = options.transparent; /** * Whether the render view should be resized automatically * * @member {boolean} */ this.autoResize = options.autoResize || false; /** * Tracks the blend modes useful for this renderer. * * @member {object<string, mixed>} */ this.blendModes = null; /** * The value of the preserveDrawingBuffer flag affects whether or not the contents of the stencil buffer is retained after rendering. * * @member {boolean} */ this.preserveDrawingBuffer = options.preserveDrawingBuffer; /** * This sets if the CanvasRenderer will clear the canvas or not before the new render pass. * If the scene is NOT transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color. * If the scene is transparent Pixi will use clearRect to clear the canvas every frame. * Disable this by setting this to false. For example if your game has a canvas filling background image you often don't need this set. * * @member {boolean} * @default */ this.clearBeforeRender = options.clearBeforeRender; /** * If true Pixi will Math.floor() x/y values when rendering, stopping pixel interpolation. * Handy for crisp pixel art and speed on legacy devices. * * @member {boolean} */ this.roundPixels = options.roundPixels; /** * The background color as a number. * * @member {number} * @private */ this._backgroundColor = 0x000000; /** * The background color as an [R, G, B] array. * * @member {number[]} * @private */ this._backgroundColorRgba = [0, 0, 0, 0]; /** * The background color as a string. * * @member {string} * @private */ this._backgroundColorString = '#000000'; this.backgroundColor = options.backgroundColor || this._backgroundColor; // run bg color setter /** * This temporary display object used as the parent of the currently being rendered item * * @member {PIXI.DisplayObject} * @private */ this._tempDisplayObjectParent = new Container(); /** * The last root object that the renderer tried to render. * * @member {PIXI.DisplayObject} * @private */ this._lastObjectRendered = this._tempDisplayObjectParent; } /** * Resizes the canvas view to the specified width and height * * @param width {number} the new width of the canvas view * @param height {number} the new height of the canvas view */ resize(width, height) { this.width = width * this.resolution; this.height = height * this.resolution; this.view.width = this.width; this.view.height = this.height; if (this.autoResize) { this.view.style.width = this.width / this.resolution + 'px'; this.view.style.height = this.height / this.resolution + 'px'; } } /** * Useful function that returns a texture of the display object that can then be used to create sprites * This can be quite useful if your displayObject is complicated and needs to be reused multiple times. * * @param displayObject {PIXI.DisplayObject} The displayObject the object will be generated from * @param scaleMode {number} Should be one of the scaleMode consts * @param resolution {number} The resolution / device pixel ratio of the texture being generated * @return {PIXI.Texture} a texture of the graphics object */ generateTexture(displayObject, scaleMode, resolution) { const bounds = displayObject.getLocalBounds(); const renderTexture = RenderTexture.create(bounds.width | 0, bounds.height | 0, scaleMode, resolution); tempMatrix.tx = -bounds.x; tempMatrix.ty = -bounds.y; this.render(displayObject, renderTexture, false, tempMatrix, true); return renderTexture; } /** * Removes everything from the renderer and optionally removes the Canvas DOM element. * * @param [removeView=false] {boolean} Removes the Canvas element from the DOM. */ destroy(removeView) { if (removeView && this.view.parentNode) { this.view.parentNode.removeChild(this.view); } this.type = CONST.RENDERER_TYPE.UNKNOWN; this.width = 0; this.height = 0; this.view = null; this.resolution = 0; this.transparent = false; this.autoResize = false; this.blendModes = null; this.preserveDrawingBuffer = false; this.clearBeforeRender = false; this.roundPixels = false; this._backgroundColor = 0; this._backgroundColorRgba = null; this._backgroundColorString = null; this.backgroundColor = 0; this._tempDisplayObjectParent = null; this._lastObjectRendered = null; } /** * The background color to fill if not transparent * * @member {number} * @memberof PIXI.SystemRenderer# */ get backgroundColor() { return this._backgroundColor; } set backgroundColor(val) { this._backgroundColor = val; this._backgroundColorString = utils.hex2string(val); utils.hex2rgb(val, this._backgroundColorRgba); } } export default SystemRenderer;