diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/src/core/const.js b/src/core/const.js index a2003c3..470852b 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -187,6 +187,8 @@ * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU. * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not get filled up. * Handy for mobile devices! + * This property only affects WebGL + * Handy for mobile devices! * This property only affects WebGL. * * @static @@ -294,7 +296,8 @@ // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines - SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32) //this is the MAXIMUM - various gpus will have there own limits. + SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32), //this is the MAXIMUM - various gpus will have there own limits. + TEXT_STYLE_CHANGED: 'changed' //Name of the event that fires when a text style is changed }; module.exports = CONST; diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/src/core/const.js b/src/core/const.js index a2003c3..470852b 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -187,6 +187,8 @@ * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU. * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not get filled up. * Handy for mobile devices! + * This property only affects WebGL + * Handy for mobile devices! * This property only affects WebGL. * * @static @@ -294,7 +296,8 @@ // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines - SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32) //this is the MAXIMUM - various gpus will have there own limits. + SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32), //this is the MAXIMUM - various gpus will have there own limits. + TEXT_STYLE_CHANGED: 'changed' //Name of the event that fires when a text style is changed }; module.exports = CONST; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 95d69f9..782994b 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -10,6 +10,7 @@ * * @class * @extends EventEmitter + * @mixes PIXI.interaction.interactiveTarget * @memberof PIXI */ function DisplayObject() @@ -73,13 +74,6 @@ this.filterArea = null; /** - * Interaction shape. Children will be hit first, then this shape will be checked. - * - * @member {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} - */ - this.hitArea = null; - - /** * The original, cached bounds of the object * * @member {PIXI.Rectangle} diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/src/core/const.js b/src/core/const.js index a2003c3..470852b 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -187,6 +187,8 @@ * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU. * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not get filled up. * Handy for mobile devices! + * This property only affects WebGL + * Handy for mobile devices! * This property only affects WebGL. * * @static @@ -294,7 +296,8 @@ // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines - SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32) //this is the MAXIMUM - various gpus will have there own limits. + SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32), //this is the MAXIMUM - various gpus will have there own limits. + TEXT_STYLE_CHANGED: 'changed' //Name of the event that fires when a text style is changed }; module.exports = CONST; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 95d69f9..782994b 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -10,6 +10,7 @@ * * @class * @extends EventEmitter + * @mixes PIXI.interaction.interactiveTarget * @memberof PIXI */ function DisplayObject() @@ -73,13 +74,6 @@ this.filterArea = null; /** - * Interaction shape. Children will be hit first, then this shape will be checked. - * - * @member {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} - */ - this.hitArea = null; - - /** * The original, cached bounds of the object * * @member {PIXI.Rectangle} diff --git a/src/core/index.js b/src/core/index.js index 8b36190..464870a 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -28,7 +28,7 @@ // text Text: require('./text/Text'), - + TextStyle: require('./text/TextStyle'), // primitives Graphics: require('./graphics/Graphics'), GraphicsData: require('./graphics/GraphicsData'), diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/src/core/const.js b/src/core/const.js index a2003c3..470852b 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -187,6 +187,8 @@ * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU. * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not get filled up. * Handy for mobile devices! + * This property only affects WebGL + * Handy for mobile devices! * This property only affects WebGL. * * @static @@ -294,7 +296,8 @@ // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines - SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32) //this is the MAXIMUM - various gpus will have there own limits. + SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32), //this is the MAXIMUM - various gpus will have there own limits. + TEXT_STYLE_CHANGED: 'changed' //Name of the event that fires when a text style is changed }; module.exports = CONST; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 95d69f9..782994b 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -10,6 +10,7 @@ * * @class * @extends EventEmitter + * @mixes PIXI.interaction.interactiveTarget * @memberof PIXI */ function DisplayObject() @@ -73,13 +74,6 @@ this.filterArea = null; /** - * Interaction shape. Children will be hit first, then this shape will be checked. - * - * @member {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} - */ - this.hitArea = null; - - /** * The original, cached bounds of the object * * @member {PIXI.Rectangle} diff --git a/src/core/index.js b/src/core/index.js index 8b36190..464870a 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -28,7 +28,7 @@ // text Text: require('./text/Text'), - + TextStyle: require('./text/TextStyle'), // primitives Graphics: require('./graphics/Graphics'), GraphicsData: require('./graphics/GraphicsData'), diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 40b84a4..854f5f1 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -346,27 +346,28 @@ */ SpriteRenderer.prototype.destroy = function () { - for (var i = 0; i < this.vaoMax; i++) { + for (var i = 0; i < this.vertexCount; i++) { this.vertexBuffers[i].destroy(); this.vaos[i].destroy(); } this.indexBuffer.destroy(); + this.renderer.off('prerender', this.onPrerender, this); ObjectRenderer.prototype.destroy.call(this); this.shader.destroy(); - this.renderer = null; - - this.vertexBuffer = null; + this.vertexBuffers = null; + this.vaos = null; this.indexBuffer = null; + this.indices = null; this.sprites = null; this.shader = null; for (i = 0; i < this.buffers.length; i++) { - this.buffers[i].destroy(); + this.buffers[i].destroy(); } }; diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/src/core/const.js b/src/core/const.js index a2003c3..470852b 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -187,6 +187,8 @@ * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU. * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not get filled up. * Handy for mobile devices! + * This property only affects WebGL + * Handy for mobile devices! * This property only affects WebGL. * * @static @@ -294,7 +296,8 @@ // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines - SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32) //this is the MAXIMUM - various gpus will have there own limits. + SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32), //this is the MAXIMUM - various gpus will have there own limits. + TEXT_STYLE_CHANGED: 'changed' //Name of the event that fires when a text style is changed }; module.exports = CONST; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 95d69f9..782994b 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -10,6 +10,7 @@ * * @class * @extends EventEmitter + * @mixes PIXI.interaction.interactiveTarget * @memberof PIXI */ function DisplayObject() @@ -73,13 +74,6 @@ this.filterArea = null; /** - * Interaction shape. Children will be hit first, then this shape will be checked. - * - * @member {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} - */ - this.hitArea = null; - - /** * The original, cached bounds of the object * * @member {PIXI.Rectangle} diff --git a/src/core/index.js b/src/core/index.js index 8b36190..464870a 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -28,7 +28,7 @@ // text Text: require('./text/Text'), - + TextStyle: require('./text/TextStyle'), // primitives Graphics: require('./graphics/Graphics'), GraphicsData: require('./graphics/GraphicsData'), diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 40b84a4..854f5f1 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -346,27 +346,28 @@ */ SpriteRenderer.prototype.destroy = function () { - for (var i = 0; i < this.vaoMax; i++) { + for (var i = 0; i < this.vertexCount; i++) { this.vertexBuffers[i].destroy(); this.vaos[i].destroy(); } this.indexBuffer.destroy(); + this.renderer.off('prerender', this.onPrerender, this); ObjectRenderer.prototype.destroy.call(this); this.shader.destroy(); - this.renderer = null; - - this.vertexBuffer = null; + this.vertexBuffers = null; + this.vaos = null; this.indexBuffer = null; + this.indices = null; this.sprites = null; this.shader = null; for (i = 0; i < this.buffers.length; i++) { - this.buffers[i].destroy(); + this.buffers[i].destroy(); } }; diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 4afdfdb..5e24ff2 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -1,8 +1,8 @@ var Sprite = require('../sprites/Sprite'), Texture = require('../textures/Texture'), math = require('../math'), - utils = require('../utils'), - CONST = require('../const'); + CONST = require('../const'), + TextStyle = require('./TextStyle'); /** * A Text Object will create a line or multiple lines of text. To split a line you can use '\n' in your text string, @@ -18,30 +18,8 @@ * @extends PIXI.Sprite * @memberof PIXI * @param text {string} The copy that you would like the text to display - * @param [style] {object} The style parameters - * @param resolution {number} The resolution of the canvas - * @param [style.font] {string} default 'bold 20px Arial' The style and size of the font - * @param [style.fill='black'] {String|Number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00' - * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke] {String|Number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap, it needs wordWrap to be set to true - * @param [style.letterSpacing=0] {number} The amount of spacing between letters, default is 0 - * @param [style.breakWords=false] {boolean} Indicates if lines can be wrapped within words, it needs wordWrap to be set to true - * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses - * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {string} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/4] {number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow - * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius - * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will - * prevent this from happening by adding padding to the top and bottom of text height. - * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. - * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve - * spiked text issues. Default is 'miter' (creates a sharp corner). - * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce - * or increase the spikiness of rendered text. + * @param [style] {object|PIXI.TextStyle} The style parameters + * @param [resolution=CONST.RESOLUTION] The resolution of the canvas */ function Text(text, style, resolution) { @@ -79,6 +57,13 @@ * @private */ this._style = null; + /** + * Private listener to track style changes. + * + * @member {Function} + * @private + */ + this._styleListener = null; var texture = Texture.fromCanvas(this.canvas); texture.trim = new math.Rectangle(); @@ -107,10 +92,7 @@ width: { get: function () { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return this.scale.x * this._texture._frame.width; }, @@ -130,10 +112,7 @@ height: { get: function () { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return this.scale.y * this._texture._frame.height; }, @@ -145,29 +124,9 @@ }, /** - * Set the style of the text + * Set the style of the text. Set up an event listener to listen for changes on the style object and mark the text as dirty. * - * @param [style] {object} The style parameters - * @param [style.font='bold 20pt Arial'] {string} The style and size of the font - * @param [style.fill='black'] {string|number} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' - * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke='black'] {string|number} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap - * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses - * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {string|number} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/6] {number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow - * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius - * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will - * prevent this from happening by adding padding to the top and bottom of text height. - * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. - * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve - * spiked text issues. Default is 'miter' (creates a sharp corner). - * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce - * or increase the spikiness of rendered text. + * @param [style] {object|TextStyle} The style parameters * @memberof PIXI.Text# */ style: { @@ -177,44 +136,19 @@ }, set: function (style) { + if (this._style) { + this._style.off(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); + } + style = style || {}; - - if (typeof style.fill === 'number') { - style.fill = utils.hex2string(style.fill); + if (style instanceof TextStyle) + { + this._style = style; + } else + { + this._style = new TextStyle(style); } - - if (typeof style.stroke === 'number') { - style.stroke = utils.hex2string(style.stroke); - } - - if (typeof style.dropShadowColor === 'number') { - style.dropShadowColor = utils.hex2string(style.dropShadowColor); - } - - style.font = style.font || 'bold 20pt Arial'; - style.fill = style.fill || 'black'; - style.align = style.align || 'left'; - style.stroke = style.stroke || 'black'; //provide a default, see: https://github.com/pixijs/pixi.js/issues/136 - style.strokeThickness = style.strokeThickness || 0; - style.wordWrap = style.wordWrap || false; - style.wordWrapWidth = style.wordWrapWidth || 100; - style.breakWords = style.breakWords || false; - style.letterSpacing = style.letterSpacing || 0; - - style.dropShadow = style.dropShadow || false; - style.dropShadowColor = style.dropShadowColor || '#000000'; - style.dropShadowAngle = style.dropShadowAngle !== undefined ? style.dropShadowAngle : Math.PI / 6; - style.dropShadowDistance = style.dropShadowDistance !== undefined ? style.dropShadowDistance : 5; - style.dropShadowBlur = style.dropShadowBlur !== undefined ? style.dropShadowBlur : 0; //shadowBlur is '0' by default according to HTML - - style.padding = style.padding || 0; - - style.textBaseline = style.textBaseline || 'alphabetic'; - - style.lineJoin = style.lineJoin || 'miter'; - style.miterLimit = style.miterLimit || 10; - - this._style = style; + this._style.on(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); this.dirty = true; } }, @@ -247,11 +181,14 @@ /** * Renders text and updates it when needed - * + * @param respectDirty {boolean} Whether to abort updating the text if the Text isn't dirty and the function is called. * @private */ -Text.prototype.updateText = function () +Text.prototype.updateText = function (respectDirty) { + if (!this.dirty && respectDirty) { + return; + } var style = this._style; this.context.font = style.font; @@ -411,7 +348,7 @@ while (index < text.length) { current = characters[index++]; - if (isStroke) + if (isStroke) { this.context.strokeText(current, currentPosition, y); } @@ -462,12 +399,7 @@ */ Text.prototype.renderWebGL = function (renderer) { - if (this.dirty) - { - //this.resolution = 1//renderer.resolution; - - this.updateText(); - } + this.updateText(true); Sprite.prototype.renderWebGL.call(this, renderer); }; @@ -480,12 +412,7 @@ */ Text.prototype._renderCanvas = function (renderer) { - if (this.dirty) - { - // this.resolution = 1//renderer.resolution; - - this.updateText(); - } + this.updateText(true); Sprite.prototype._renderCanvas.call(this, renderer); }; @@ -613,21 +540,21 @@ for (var j = 0; j < words.length; j++) { var wordWidth = this.context.measureText(words[j]).width; - if (this._style.breakWords && wordWidth > wordWrapWidth) + if (this._style.breakWords && wordWidth > wordWrapWidth) { // Word should be split in the middle var characters = words[j].split(''); - for (var c = 0; c < characters.length; c++) + for (var c = 0; c < characters.length; c++) { var characterWidth = this.context.measureText(characters[c]).width; - if (characterWidth > spaceLeft) + if (characterWidth > spaceLeft) { result += '\n' + characters[c]; spaceLeft = wordWrapWidth - characterWidth; - } - else + } + else { - if (c === 0) + if (c === 0) { result += ' '; } @@ -636,7 +563,7 @@ } } } - else + else { var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; if (j === 0 || wordWidthWithSpace > spaceLeft) @@ -674,15 +601,21 @@ */ Text.prototype.getBounds = function (matrix) { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return Sprite.prototype.getBounds.call(this, matrix); }; /** + * Method to be called upon a TextStyle change. + * @private + */ +Text.prototype._onStyleChange = function () +{ + this.dirty = true; +}; + +/** * Destroys this text object. * * @param [destroyBaseTexture=true] {boolean} whether to destroy the base texture as well @@ -693,7 +626,9 @@ this.context = null; this.canvas = null; + this._style.off(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); this._style = null; this._texture.destroy(destroyBaseTexture === undefined ? true : destroyBaseTexture); + }; diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/src/core/const.js b/src/core/const.js index a2003c3..470852b 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -187,6 +187,8 @@ * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU. * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not get filled up. * Handy for mobile devices! + * This property only affects WebGL + * Handy for mobile devices! * This property only affects WebGL. * * @static @@ -294,7 +296,8 @@ // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines - SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32) //this is the MAXIMUM - various gpus will have there own limits. + SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32), //this is the MAXIMUM - various gpus will have there own limits. + TEXT_STYLE_CHANGED: 'changed' //Name of the event that fires when a text style is changed }; module.exports = CONST; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 95d69f9..782994b 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -10,6 +10,7 @@ * * @class * @extends EventEmitter + * @mixes PIXI.interaction.interactiveTarget * @memberof PIXI */ function DisplayObject() @@ -73,13 +74,6 @@ this.filterArea = null; /** - * Interaction shape. Children will be hit first, then this shape will be checked. - * - * @member {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} - */ - this.hitArea = null; - - /** * The original, cached bounds of the object * * @member {PIXI.Rectangle} diff --git a/src/core/index.js b/src/core/index.js index 8b36190..464870a 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -28,7 +28,7 @@ // text Text: require('./text/Text'), - + TextStyle: require('./text/TextStyle'), // primitives Graphics: require('./graphics/Graphics'), GraphicsData: require('./graphics/GraphicsData'), diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 40b84a4..854f5f1 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -346,27 +346,28 @@ */ SpriteRenderer.prototype.destroy = function () { - for (var i = 0; i < this.vaoMax; i++) { + for (var i = 0; i < this.vertexCount; i++) { this.vertexBuffers[i].destroy(); this.vaos[i].destroy(); } this.indexBuffer.destroy(); + this.renderer.off('prerender', this.onPrerender, this); ObjectRenderer.prototype.destroy.call(this); this.shader.destroy(); - this.renderer = null; - - this.vertexBuffer = null; + this.vertexBuffers = null; + this.vaos = null; this.indexBuffer = null; + this.indices = null; this.sprites = null; this.shader = null; for (i = 0; i < this.buffers.length; i++) { - this.buffers[i].destroy(); + this.buffers[i].destroy(); } }; diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 4afdfdb..5e24ff2 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -1,8 +1,8 @@ var Sprite = require('../sprites/Sprite'), Texture = require('../textures/Texture'), math = require('../math'), - utils = require('../utils'), - CONST = require('../const'); + CONST = require('../const'), + TextStyle = require('./TextStyle'); /** * A Text Object will create a line or multiple lines of text. To split a line you can use '\n' in your text string, @@ -18,30 +18,8 @@ * @extends PIXI.Sprite * @memberof PIXI * @param text {string} The copy that you would like the text to display - * @param [style] {object} The style parameters - * @param resolution {number} The resolution of the canvas - * @param [style.font] {string} default 'bold 20px Arial' The style and size of the font - * @param [style.fill='black'] {String|Number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00' - * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke] {String|Number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap, it needs wordWrap to be set to true - * @param [style.letterSpacing=0] {number} The amount of spacing between letters, default is 0 - * @param [style.breakWords=false] {boolean} Indicates if lines can be wrapped within words, it needs wordWrap to be set to true - * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses - * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {string} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/4] {number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow - * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius - * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will - * prevent this from happening by adding padding to the top and bottom of text height. - * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. - * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve - * spiked text issues. Default is 'miter' (creates a sharp corner). - * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce - * or increase the spikiness of rendered text. + * @param [style] {object|PIXI.TextStyle} The style parameters + * @param [resolution=CONST.RESOLUTION] The resolution of the canvas */ function Text(text, style, resolution) { @@ -79,6 +57,13 @@ * @private */ this._style = null; + /** + * Private listener to track style changes. + * + * @member {Function} + * @private + */ + this._styleListener = null; var texture = Texture.fromCanvas(this.canvas); texture.trim = new math.Rectangle(); @@ -107,10 +92,7 @@ width: { get: function () { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return this.scale.x * this._texture._frame.width; }, @@ -130,10 +112,7 @@ height: { get: function () { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return this.scale.y * this._texture._frame.height; }, @@ -145,29 +124,9 @@ }, /** - * Set the style of the text + * Set the style of the text. Set up an event listener to listen for changes on the style object and mark the text as dirty. * - * @param [style] {object} The style parameters - * @param [style.font='bold 20pt Arial'] {string} The style and size of the font - * @param [style.fill='black'] {string|number} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' - * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke='black'] {string|number} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap - * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses - * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {string|number} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/6] {number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow - * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius - * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will - * prevent this from happening by adding padding to the top and bottom of text height. - * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. - * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve - * spiked text issues. Default is 'miter' (creates a sharp corner). - * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce - * or increase the spikiness of rendered text. + * @param [style] {object|TextStyle} The style parameters * @memberof PIXI.Text# */ style: { @@ -177,44 +136,19 @@ }, set: function (style) { + if (this._style) { + this._style.off(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); + } + style = style || {}; - - if (typeof style.fill === 'number') { - style.fill = utils.hex2string(style.fill); + if (style instanceof TextStyle) + { + this._style = style; + } else + { + this._style = new TextStyle(style); } - - if (typeof style.stroke === 'number') { - style.stroke = utils.hex2string(style.stroke); - } - - if (typeof style.dropShadowColor === 'number') { - style.dropShadowColor = utils.hex2string(style.dropShadowColor); - } - - style.font = style.font || 'bold 20pt Arial'; - style.fill = style.fill || 'black'; - style.align = style.align || 'left'; - style.stroke = style.stroke || 'black'; //provide a default, see: https://github.com/pixijs/pixi.js/issues/136 - style.strokeThickness = style.strokeThickness || 0; - style.wordWrap = style.wordWrap || false; - style.wordWrapWidth = style.wordWrapWidth || 100; - style.breakWords = style.breakWords || false; - style.letterSpacing = style.letterSpacing || 0; - - style.dropShadow = style.dropShadow || false; - style.dropShadowColor = style.dropShadowColor || '#000000'; - style.dropShadowAngle = style.dropShadowAngle !== undefined ? style.dropShadowAngle : Math.PI / 6; - style.dropShadowDistance = style.dropShadowDistance !== undefined ? style.dropShadowDistance : 5; - style.dropShadowBlur = style.dropShadowBlur !== undefined ? style.dropShadowBlur : 0; //shadowBlur is '0' by default according to HTML - - style.padding = style.padding || 0; - - style.textBaseline = style.textBaseline || 'alphabetic'; - - style.lineJoin = style.lineJoin || 'miter'; - style.miterLimit = style.miterLimit || 10; - - this._style = style; + this._style.on(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); this.dirty = true; } }, @@ -247,11 +181,14 @@ /** * Renders text and updates it when needed - * + * @param respectDirty {boolean} Whether to abort updating the text if the Text isn't dirty and the function is called. * @private */ -Text.prototype.updateText = function () +Text.prototype.updateText = function (respectDirty) { + if (!this.dirty && respectDirty) { + return; + } var style = this._style; this.context.font = style.font; @@ -411,7 +348,7 @@ while (index < text.length) { current = characters[index++]; - if (isStroke) + if (isStroke) { this.context.strokeText(current, currentPosition, y); } @@ -462,12 +399,7 @@ */ Text.prototype.renderWebGL = function (renderer) { - if (this.dirty) - { - //this.resolution = 1//renderer.resolution; - - this.updateText(); - } + this.updateText(true); Sprite.prototype.renderWebGL.call(this, renderer); }; @@ -480,12 +412,7 @@ */ Text.prototype._renderCanvas = function (renderer) { - if (this.dirty) - { - // this.resolution = 1//renderer.resolution; - - this.updateText(); - } + this.updateText(true); Sprite.prototype._renderCanvas.call(this, renderer); }; @@ -613,21 +540,21 @@ for (var j = 0; j < words.length; j++) { var wordWidth = this.context.measureText(words[j]).width; - if (this._style.breakWords && wordWidth > wordWrapWidth) + if (this._style.breakWords && wordWidth > wordWrapWidth) { // Word should be split in the middle var characters = words[j].split(''); - for (var c = 0; c < characters.length; c++) + for (var c = 0; c < characters.length; c++) { var characterWidth = this.context.measureText(characters[c]).width; - if (characterWidth > spaceLeft) + if (characterWidth > spaceLeft) { result += '\n' + characters[c]; spaceLeft = wordWrapWidth - characterWidth; - } - else + } + else { - if (c === 0) + if (c === 0) { result += ' '; } @@ -636,7 +563,7 @@ } } } - else + else { var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; if (j === 0 || wordWidthWithSpace > spaceLeft) @@ -674,15 +601,21 @@ */ Text.prototype.getBounds = function (matrix) { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return Sprite.prototype.getBounds.call(this, matrix); }; /** + * Method to be called upon a TextStyle change. + * @private + */ +Text.prototype._onStyleChange = function () +{ + this.dirty = true; +}; + +/** * Destroys this text object. * * @param [destroyBaseTexture=true] {boolean} whether to destroy the base texture as well @@ -693,7 +626,9 @@ this.context = null; this.canvas = null; + this._style.off(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); this._style = null; this._texture.destroy(destroyBaseTexture === undefined ? true : destroyBaseTexture); + }; diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js new file mode 100644 index 0000000..7c3d7be --- /dev/null +++ b/src/core/text/TextStyle.js @@ -0,0 +1,334 @@ +var EventEmitter = require('eventemitter3'), + CONST = require('../const'), + utils = require('../utils'); + +/** + * A TextStyle Object decorates a Text Object. It acts as an event emitter, and can be shared between + * multiple Text objects. + * + * @class + * @extends EventEmitter + * @memberof PIXI + * @param [style] {object} The style parameters + * @param [style.font='bold 20pt Arial'] {string} The style and size of the font + * @param [style.fill='black'] {string|number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00' + * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text + * @param [style.stroke='black'] {string|number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00' + * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) + * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used + * @param [style.wordWrapWidth=100] {number} The width at which text will wrap, it needs wordWrap to be set to true + * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses + * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text + * @param [style.dropShadowColor='#000000'] {string} A fill style to be used on the dropshadow e.g 'red', '#00FF00' + * @param [style.dropShadowAngle=Math.PI/6] {number} Set a angle of the drop shadow + * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow + * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius + * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will + * prevent this from happening by adding padding to the top and bottom of text height. + * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. + * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve + * spiked text issues. Default is 'miter' (creates a sharp corner). + * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce + * or increase the spikiness of rendered text. + */ +function TextStyle(style) +{ + EventEmitter.call(this); + Object.assign(this, this._defaults, style); +} + +TextStyle.prototype = Object.create(EventEmitter.prototype); +TextStyle.prototype.constructor = TextStyle; +module.exports = TextStyle; + +// Default settings. Explained in the constructor. +TextStyle.prototype._defaults = { + align: 'left', + dropShadow: false, + dropShadowAngle: Math.PI / 6, + dropShadowBlur: 0, + dropShadowColor: '#000000', + dropShadowDistance: 5, + lineHeight: null, + lineJoin: 'miter', + fill: 'black', + font: 'bold 20pt Arial', + miterLimit: 10, + padding: 0, + stroke: 'black', + strokeThickness: 0, + textBaseline: 'alphabetic', + wordWrap: false, + wordWrapWidth: 100 +}; + +/** + * Creates a new TextStyle object with the same values as this one. + * Note that the only the properties of the object are cloned, not its event emitter. + * + * @return {PIXI.TextStyle} + */ +TextStyle.prototype.clone = function () +{ + var clonedProperties = {}; + for (var key in this._defaults) + { + clonedProperties[key] = this[key]; + } + return new TextStyle(clonedProperties); +}; + +/** + * Resets all properties to the defaults specified in TextStyle.prototype._default + */ +TextStyle.prototype.reset = function () +{ + Object.assign(this, this._defaults); +}; + +/** + * Create setters and getters for each of the style properties. Converts colors where necessary. + * Any set operation will emit a styleChanged event. + */ +Object.defineProperties(TextStyle.prototype, { + font: { + get: function () + { + return this._font; + }, set: function (font) + { + if (this._font !== font) + { + this._font = font; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + fill: { + get: function () + { + return this._fill; + }, set: function (fill) + { + var outputColor = getColor(fill); + if (this._fill !== outputColor) + { + this._fill = outputColor; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + align: { + get: function () + { + return this._align; + }, set: function (align) + { + if (this._align !== align) + { + this._align = align; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + stroke: { + get: function () + { + return this._stroke; + }, set: function (stroke) + { + var outputColor = getColor(stroke); + if (this._stroke !== outputColor) + { + this._stroke = outputColor; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + strokeThickness: { + get: function () + { + return this._strokeThickness; + }, set: function (strokeThickness) + { + if (this._strokeThickness !== strokeThickness) + { + this._strokeThickness = strokeThickness; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + wordWrap: { + get: function () + { + return this._wordWrap; + }, set: function (wordWrap) + { + if (this._wordWrap !== wordWrap) + { + this._wordWrap = wordWrap; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + wordWrapWidth: { + get: function () + { + return this._wordWrapWidth; + }, set: function (wordWrapWidth) + { + if (this._wordWrapWidth !== wordWrapWidth) + { + this._wordWrapWidth = wordWrapWidth; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadow: { + get: function () + { + return this._dropShadow; + }, set: function (dropShadow) + { + if (this._dropShadow !== dropShadow) + { + this._dropShadow = dropShadow; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowColor: { + get: function () + { + return this._dropShadowColor; + }, set: function (dropShadowColor) + { + var outputColor = getColor(dropShadowColor); + if (this._dropShadowColor !== outputColor) + { + this._dropShadowColor = outputColor; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowAngle: { + get: function () + { + return this._dropShadowAngle; + }, set: function (dropShadowAngle) + { + if (this._dropShadowAngle !== dropShadowAngle) + { + this._dropShadowAngle = dropShadowAngle; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowDistance: { + get: function () + { + return this._dropShadowDistance; + }, set: function (dropShadowDistance) + { + if (this._dropShadowDistance !== dropShadowDistance) + { + this._dropShadowDistance = dropShadowDistance; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowBlur: { + get: function () + { + return this._dropShadowBlur; + }, set: function (dropShadowBlur) + { + if (this._dropShadowBlur !== dropShadowBlur) + { + this._dropShadowBlur = dropShadowBlur; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + padding: { + get: function () + { + return this._padding; + }, set: function (padding) + { + if (this._padding !== padding) + { + this._padding = padding; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + textBaseline: { + get: function () + { + return this._textBaseline; + }, set: function (textBaseline) + { + if (this._textBaseline !== textBaseline) + { + this._textBaseline = textBaseline; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + lineJoin: { + get: function () + { + return this._lineJoin; + }, set: function (lineJoin) + { + if (this._lineJoin !== lineJoin) + { + this._lineJoin = lineJoin; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + lineHeight: { + get: function () + { + return this._lineHeight; + }, set: function (lineHeight) + { + if (this._lineHeight !== lineHeight) + { + this._lineHeight = lineHeight; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + miterLimit: { + get: function () + { + return this._miterLimit; + }, set: function (miterLimit) + { + if (this._miterLimit !== miterLimit) + { + this._miterLimit = miterLimit; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + } +}); + +/** + * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. + * + * @return {string} The color as a string. + */ +function getColor(color) +{ + if (typeof color === 'number') + { + return utils.hex2string(color); + } else + { + return color; + } +} diff --git a/package.json b/package.json index 930eb86..29d4a10 100644 --- a/package.json +++ b/package.json @@ -30,9 +30,11 @@ "README.md" ], "dependencies": { + "async": "^2.0.0-rc.3", "bit-twiddle": "^1.0.2", "earcut": "^2.0.7", "eventemitter3": "^1.1.1", + "glslify": "^5.0.2", "ismobilejs": "git+https://github.com/kaimallea/isMobile.git", "object-assign": "^4.0.1", "pixi-gl-core": "git+https://github.com/GoodBoyDigital/pixi-gl-core.git", @@ -43,7 +45,6 @@ "browserify-versionify": "^1.0.6", "chai": "^3.2.0", "del": "^2.0.2", - "glslify": "^5.0.2", "gulp": "^3.9.0", "gulp-cached": "^1.1.0", "gulp-concat": "^2.6.0", diff --git a/src/core/const.js b/src/core/const.js index a2003c3..470852b 100644 --- a/src/core/const.js +++ b/src/core/const.js @@ -187,6 +187,8 @@ * If set to DEFAULT, the renderer will occasianally check textures usage. If they are not used for a specified period of time they will be removed from the GPU. * They will of corse be uploaded again when they are required. This is a silent behind the scenes process that should ensure that the GPU does not get filled up. * Handy for mobile devices! + * This property only affects WebGL + * Handy for mobile devices! * This property only affects WebGL. * * @static @@ -294,7 +296,8 @@ // TODO: maybe change to SPRITE.BATCH_SIZE: 2000 // TODO: maybe add PARTICLE.BATCH_SIZE: 15000 SPRITE_BATCH_SIZE: 4096, //nice balance between mobile and desktop machines - SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32) //this is the MAXIMUM - various gpus will have there own limits. + SPRITE_MAX_TEXTURES: require('./utils/maxRecommendedTextures')(32), //this is the MAXIMUM - various gpus will have there own limits. + TEXT_STYLE_CHANGED: 'changed' //Name of the event that fires when a text style is changed }; module.exports = CONST; diff --git a/src/core/display/DisplayObject.js b/src/core/display/DisplayObject.js index 95d69f9..782994b 100644 --- a/src/core/display/DisplayObject.js +++ b/src/core/display/DisplayObject.js @@ -10,6 +10,7 @@ * * @class * @extends EventEmitter + * @mixes PIXI.interaction.interactiveTarget * @memberof PIXI */ function DisplayObject() @@ -73,13 +74,6 @@ this.filterArea = null; /** - * Interaction shape. Children will be hit first, then this shape will be checked. - * - * @member {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} - */ - this.hitArea = null; - - /** * The original, cached bounds of the object * * @member {PIXI.Rectangle} diff --git a/src/core/index.js b/src/core/index.js index 8b36190..464870a 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -28,7 +28,7 @@ // text Text: require('./text/Text'), - + TextStyle: require('./text/TextStyle'), // primitives Graphics: require('./graphics/Graphics'), GraphicsData: require('./graphics/GraphicsData'), diff --git a/src/core/sprites/webgl/SpriteRenderer.js b/src/core/sprites/webgl/SpriteRenderer.js index 40b84a4..854f5f1 100644 --- a/src/core/sprites/webgl/SpriteRenderer.js +++ b/src/core/sprites/webgl/SpriteRenderer.js @@ -346,27 +346,28 @@ */ SpriteRenderer.prototype.destroy = function () { - for (var i = 0; i < this.vaoMax; i++) { + for (var i = 0; i < this.vertexCount; i++) { this.vertexBuffers[i].destroy(); this.vaos[i].destroy(); } this.indexBuffer.destroy(); + this.renderer.off('prerender', this.onPrerender, this); ObjectRenderer.prototype.destroy.call(this); this.shader.destroy(); - this.renderer = null; - - this.vertexBuffer = null; + this.vertexBuffers = null; + this.vaos = null; this.indexBuffer = null; + this.indices = null; this.sprites = null; this.shader = null; for (i = 0; i < this.buffers.length; i++) { - this.buffers[i].destroy(); + this.buffers[i].destroy(); } }; diff --git a/src/core/text/Text.js b/src/core/text/Text.js index 4afdfdb..5e24ff2 100644 --- a/src/core/text/Text.js +++ b/src/core/text/Text.js @@ -1,8 +1,8 @@ var Sprite = require('../sprites/Sprite'), Texture = require('../textures/Texture'), math = require('../math'), - utils = require('../utils'), - CONST = require('../const'); + CONST = require('../const'), + TextStyle = require('./TextStyle'); /** * A Text Object will create a line or multiple lines of text. To split a line you can use '\n' in your text string, @@ -18,30 +18,8 @@ * @extends PIXI.Sprite * @memberof PIXI * @param text {string} The copy that you would like the text to display - * @param [style] {object} The style parameters - * @param resolution {number} The resolution of the canvas - * @param [style.font] {string} default 'bold 20px Arial' The style and size of the font - * @param [style.fill='black'] {String|Number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00' - * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke] {String|Number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap, it needs wordWrap to be set to true - * @param [style.letterSpacing=0] {number} The amount of spacing between letters, default is 0 - * @param [style.breakWords=false] {boolean} Indicates if lines can be wrapped within words, it needs wordWrap to be set to true - * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses - * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {string} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/4] {number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow - * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius - * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will - * prevent this from happening by adding padding to the top and bottom of text height. - * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. - * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve - * spiked text issues. Default is 'miter' (creates a sharp corner). - * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce - * or increase the spikiness of rendered text. + * @param [style] {object|PIXI.TextStyle} The style parameters + * @param [resolution=CONST.RESOLUTION] The resolution of the canvas */ function Text(text, style, resolution) { @@ -79,6 +57,13 @@ * @private */ this._style = null; + /** + * Private listener to track style changes. + * + * @member {Function} + * @private + */ + this._styleListener = null; var texture = Texture.fromCanvas(this.canvas); texture.trim = new math.Rectangle(); @@ -107,10 +92,7 @@ width: { get: function () { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return this.scale.x * this._texture._frame.width; }, @@ -130,10 +112,7 @@ height: { get: function () { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return this.scale.y * this._texture._frame.height; }, @@ -145,29 +124,9 @@ }, /** - * Set the style of the text + * Set the style of the text. Set up an event listener to listen for changes on the style object and mark the text as dirty. * - * @param [style] {object} The style parameters - * @param [style.font='bold 20pt Arial'] {string} The style and size of the font - * @param [style.fill='black'] {string|number} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' - * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text - * @param [style.stroke='black'] {string|number} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00' - * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) - * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used - * @param [style.wordWrapWidth=100] {number} The width at which text will wrap - * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses - * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text - * @param [style.dropShadowColor='#000000'] {string|number} A fill style to be used on the dropshadow e.g 'red', '#00FF00' - * @param [style.dropShadowAngle=Math.PI/6] {number} Set a angle of the drop shadow - * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow - * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius - * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will - * prevent this from happening by adding padding to the top and bottom of text height. - * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. - * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve - * spiked text issues. Default is 'miter' (creates a sharp corner). - * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce - * or increase the spikiness of rendered text. + * @param [style] {object|TextStyle} The style parameters * @memberof PIXI.Text# */ style: { @@ -177,44 +136,19 @@ }, set: function (style) { + if (this._style) { + this._style.off(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); + } + style = style || {}; - - if (typeof style.fill === 'number') { - style.fill = utils.hex2string(style.fill); + if (style instanceof TextStyle) + { + this._style = style; + } else + { + this._style = new TextStyle(style); } - - if (typeof style.stroke === 'number') { - style.stroke = utils.hex2string(style.stroke); - } - - if (typeof style.dropShadowColor === 'number') { - style.dropShadowColor = utils.hex2string(style.dropShadowColor); - } - - style.font = style.font || 'bold 20pt Arial'; - style.fill = style.fill || 'black'; - style.align = style.align || 'left'; - style.stroke = style.stroke || 'black'; //provide a default, see: https://github.com/pixijs/pixi.js/issues/136 - style.strokeThickness = style.strokeThickness || 0; - style.wordWrap = style.wordWrap || false; - style.wordWrapWidth = style.wordWrapWidth || 100; - style.breakWords = style.breakWords || false; - style.letterSpacing = style.letterSpacing || 0; - - style.dropShadow = style.dropShadow || false; - style.dropShadowColor = style.dropShadowColor || '#000000'; - style.dropShadowAngle = style.dropShadowAngle !== undefined ? style.dropShadowAngle : Math.PI / 6; - style.dropShadowDistance = style.dropShadowDistance !== undefined ? style.dropShadowDistance : 5; - style.dropShadowBlur = style.dropShadowBlur !== undefined ? style.dropShadowBlur : 0; //shadowBlur is '0' by default according to HTML - - style.padding = style.padding || 0; - - style.textBaseline = style.textBaseline || 'alphabetic'; - - style.lineJoin = style.lineJoin || 'miter'; - style.miterLimit = style.miterLimit || 10; - - this._style = style; + this._style.on(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); this.dirty = true; } }, @@ -247,11 +181,14 @@ /** * Renders text and updates it when needed - * + * @param respectDirty {boolean} Whether to abort updating the text if the Text isn't dirty and the function is called. * @private */ -Text.prototype.updateText = function () +Text.prototype.updateText = function (respectDirty) { + if (!this.dirty && respectDirty) { + return; + } var style = this._style; this.context.font = style.font; @@ -411,7 +348,7 @@ while (index < text.length) { current = characters[index++]; - if (isStroke) + if (isStroke) { this.context.strokeText(current, currentPosition, y); } @@ -462,12 +399,7 @@ */ Text.prototype.renderWebGL = function (renderer) { - if (this.dirty) - { - //this.resolution = 1//renderer.resolution; - - this.updateText(); - } + this.updateText(true); Sprite.prototype.renderWebGL.call(this, renderer); }; @@ -480,12 +412,7 @@ */ Text.prototype._renderCanvas = function (renderer) { - if (this.dirty) - { - // this.resolution = 1//renderer.resolution; - - this.updateText(); - } + this.updateText(true); Sprite.prototype._renderCanvas.call(this, renderer); }; @@ -613,21 +540,21 @@ for (var j = 0; j < words.length; j++) { var wordWidth = this.context.measureText(words[j]).width; - if (this._style.breakWords && wordWidth > wordWrapWidth) + if (this._style.breakWords && wordWidth > wordWrapWidth) { // Word should be split in the middle var characters = words[j].split(''); - for (var c = 0; c < characters.length; c++) + for (var c = 0; c < characters.length; c++) { var characterWidth = this.context.measureText(characters[c]).width; - if (characterWidth > spaceLeft) + if (characterWidth > spaceLeft) { result += '\n' + characters[c]; spaceLeft = wordWrapWidth - characterWidth; - } - else + } + else { - if (c === 0) + if (c === 0) { result += ' '; } @@ -636,7 +563,7 @@ } } } - else + else { var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; if (j === 0 || wordWidthWithSpace > spaceLeft) @@ -674,15 +601,21 @@ */ Text.prototype.getBounds = function (matrix) { - if (this.dirty) - { - this.updateText(); - } + this.updateText(true); return Sprite.prototype.getBounds.call(this, matrix); }; /** + * Method to be called upon a TextStyle change. + * @private + */ +Text.prototype._onStyleChange = function () +{ + this.dirty = true; +}; + +/** * Destroys this text object. * * @param [destroyBaseTexture=true] {boolean} whether to destroy the base texture as well @@ -693,7 +626,9 @@ this.context = null; this.canvas = null; + this._style.off(CONST.TEXT_STYLE_CHANGED, this._onStyleChange, this); this._style = null; this._texture.destroy(destroyBaseTexture === undefined ? true : destroyBaseTexture); + }; diff --git a/src/core/text/TextStyle.js b/src/core/text/TextStyle.js new file mode 100644 index 0000000..7c3d7be --- /dev/null +++ b/src/core/text/TextStyle.js @@ -0,0 +1,334 @@ +var EventEmitter = require('eventemitter3'), + CONST = require('../const'), + utils = require('../utils'); + +/** + * A TextStyle Object decorates a Text Object. It acts as an event emitter, and can be shared between + * multiple Text objects. + * + * @class + * @extends EventEmitter + * @memberof PIXI + * @param [style] {object} The style parameters + * @param [style.font='bold 20pt Arial'] {string} The style and size of the font + * @param [style.fill='black'] {string|number} A canvas fillstyle that will be used on the text e.g 'red', '#00FF00' + * @param [style.align='left'] {string} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text + * @param [style.stroke='black'] {string|number} A canvas fillstyle that will be used on the text stroke e.g 'blue', '#FCFF00' + * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke) + * @param [style.wordWrap=false] {boolean} Indicates if word wrap should be used + * @param [style.wordWrapWidth=100] {number} The width at which text will wrap, it needs wordWrap to be set to true + * @param [style.lineHeight] {number} The line height, a number that represents the vertical space that a letter uses + * @param [style.dropShadow=false] {boolean} Set a drop shadow for the text + * @param [style.dropShadowColor='#000000'] {string} A fill style to be used on the dropshadow e.g 'red', '#00FF00' + * @param [style.dropShadowAngle=Math.PI/6] {number} Set a angle of the drop shadow + * @param [style.dropShadowDistance=5] {number} Set a distance of the drop shadow + * @param [style.dropShadowBlur=0] {number} Set a shadow blur radius + * @param [style.padding=0] {number} Occasionally some fonts are cropped on top or bottom. Adding some padding will + * prevent this from happening by adding padding to the top and bottom of text height. + * @param [style.textBaseline='alphabetic'] {string} The baseline of the text that is rendered. + * @param [style.lineJoin='miter'] {string} The lineJoin property sets the type of corner created, it can resolve + * spiked text issues. Default is 'miter' (creates a sharp corner). + * @param [style.miterLimit=10] {number} The miter limit to use when using the 'miter' lineJoin mode. This can reduce + * or increase the spikiness of rendered text. + */ +function TextStyle(style) +{ + EventEmitter.call(this); + Object.assign(this, this._defaults, style); +} + +TextStyle.prototype = Object.create(EventEmitter.prototype); +TextStyle.prototype.constructor = TextStyle; +module.exports = TextStyle; + +// Default settings. Explained in the constructor. +TextStyle.prototype._defaults = { + align: 'left', + dropShadow: false, + dropShadowAngle: Math.PI / 6, + dropShadowBlur: 0, + dropShadowColor: '#000000', + dropShadowDistance: 5, + lineHeight: null, + lineJoin: 'miter', + fill: 'black', + font: 'bold 20pt Arial', + miterLimit: 10, + padding: 0, + stroke: 'black', + strokeThickness: 0, + textBaseline: 'alphabetic', + wordWrap: false, + wordWrapWidth: 100 +}; + +/** + * Creates a new TextStyle object with the same values as this one. + * Note that the only the properties of the object are cloned, not its event emitter. + * + * @return {PIXI.TextStyle} + */ +TextStyle.prototype.clone = function () +{ + var clonedProperties = {}; + for (var key in this._defaults) + { + clonedProperties[key] = this[key]; + } + return new TextStyle(clonedProperties); +}; + +/** + * Resets all properties to the defaults specified in TextStyle.prototype._default + */ +TextStyle.prototype.reset = function () +{ + Object.assign(this, this._defaults); +}; + +/** + * Create setters and getters for each of the style properties. Converts colors where necessary. + * Any set operation will emit a styleChanged event. + */ +Object.defineProperties(TextStyle.prototype, { + font: { + get: function () + { + return this._font; + }, set: function (font) + { + if (this._font !== font) + { + this._font = font; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + fill: { + get: function () + { + return this._fill; + }, set: function (fill) + { + var outputColor = getColor(fill); + if (this._fill !== outputColor) + { + this._fill = outputColor; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + align: { + get: function () + { + return this._align; + }, set: function (align) + { + if (this._align !== align) + { + this._align = align; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + stroke: { + get: function () + { + return this._stroke; + }, set: function (stroke) + { + var outputColor = getColor(stroke); + if (this._stroke !== outputColor) + { + this._stroke = outputColor; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + strokeThickness: { + get: function () + { + return this._strokeThickness; + }, set: function (strokeThickness) + { + if (this._strokeThickness !== strokeThickness) + { + this._strokeThickness = strokeThickness; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + wordWrap: { + get: function () + { + return this._wordWrap; + }, set: function (wordWrap) + { + if (this._wordWrap !== wordWrap) + { + this._wordWrap = wordWrap; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + wordWrapWidth: { + get: function () + { + return this._wordWrapWidth; + }, set: function (wordWrapWidth) + { + if (this._wordWrapWidth !== wordWrapWidth) + { + this._wordWrapWidth = wordWrapWidth; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadow: { + get: function () + { + return this._dropShadow; + }, set: function (dropShadow) + { + if (this._dropShadow !== dropShadow) + { + this._dropShadow = dropShadow; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowColor: { + get: function () + { + return this._dropShadowColor; + }, set: function (dropShadowColor) + { + var outputColor = getColor(dropShadowColor); + if (this._dropShadowColor !== outputColor) + { + this._dropShadowColor = outputColor; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowAngle: { + get: function () + { + return this._dropShadowAngle; + }, set: function (dropShadowAngle) + { + if (this._dropShadowAngle !== dropShadowAngle) + { + this._dropShadowAngle = dropShadowAngle; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowDistance: { + get: function () + { + return this._dropShadowDistance; + }, set: function (dropShadowDistance) + { + if (this._dropShadowDistance !== dropShadowDistance) + { + this._dropShadowDistance = dropShadowDistance; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + dropShadowBlur: { + get: function () + { + return this._dropShadowBlur; + }, set: function (dropShadowBlur) + { + if (this._dropShadowBlur !== dropShadowBlur) + { + this._dropShadowBlur = dropShadowBlur; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + padding: { + get: function () + { + return this._padding; + }, set: function (padding) + { + if (this._padding !== padding) + { + this._padding = padding; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + textBaseline: { + get: function () + { + return this._textBaseline; + }, set: function (textBaseline) + { + if (this._textBaseline !== textBaseline) + { + this._textBaseline = textBaseline; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + lineJoin: { + get: function () + { + return this._lineJoin; + }, set: function (lineJoin) + { + if (this._lineJoin !== lineJoin) + { + this._lineJoin = lineJoin; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + lineHeight: { + get: function () + { + return this._lineHeight; + }, set: function (lineHeight) + { + if (this._lineHeight !== lineHeight) + { + this._lineHeight = lineHeight; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + }, + miterLimit: { + get: function () + { + return this._miterLimit; + }, set: function (miterLimit) + { + if (this._miterLimit !== miterLimit) + { + this._miterLimit = miterLimit; + this.emit(CONST.TEXT_STYLE_CHANGED); + } + } + } +}); + +/** + * Utility function to convert hexadecimal colors to strings, and simply return the color if it's a string. + * + * @return {string} The color as a string. + */ +function getColor(color) +{ + if (typeof color === 'number') + { + return utils.hex2string(color); + } else + { + return color; + } +} diff --git a/src/interaction/interactiveTarget.js b/src/interaction/interactiveTarget.js index a331ca2..726e71b 100644 --- a/src/interaction/interactiveTarget.js +++ b/src/interaction/interactiveTarget.js @@ -1,6 +1,6 @@ /** * Default property values of interactive objects - * used by {@link PIXI.interaction.InteractionManager}. + * Used by {@link PIXI.interaction.InteractionManager} to automatically give all DisplayObjects these properties * * @mixin * @memberof PIXI.interaction @@ -14,34 +14,74 @@ */ var interactiveTarget = { /** - * @todo Needs docs. + * Determines if the displayObject be clicked/touched + * + * @inner {boolean} */ interactive: false, + /** - * @todo Needs docs. - */ - buttonMode: false, - /** - * @todo Needs docs. + * Determines if the children to the displayObject can be clicked/touched + * Setting this to false allows pixi to bypass a recursive hitTest function + * + * @inner {boolean} */ interactiveChildren: true, + /** - * @todo Needs docs. + * Interaction shape. Children will be hit first, then this shape will be checked. + * + * @inner {PIXI.Rectangle|PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.RoundedRectangle} + */ + hitArea: null, + + /** + * If enabled, the mouse cursor will change when hovered over the displayObject if it is interactive + * + * @inner {boolean} + */ + buttonMode: false, + + /** + * If buttonMode is enabled, this defines what CSS cursor property is used when the mouse cursor is hovered over the displayObject + * https://developer.mozilla.org/en/docs/Web/CSS/cursor + * + * @inner {string} */ defaultCursor: 'pointer', // some internal checks.. - /** - * @todo Needs docs. + * Internal check to detect if the mouse cursor is hovered over the displayObject + * + * @inner {boolean} * @private */ _over: false, + /** - * @todo Needs docs. + * Internal check to detect if the left mouse button is pressed on the displayObject + * + * @inner {boolean} + * @private + */ + _isLeftDown: false, + + /** + * Internal check to detect if the right mouse button is pressed on the displayObject + * + * @inner {boolean} + * @private + */ + _isRightDown: false, + + /** + * Internal check to detect if a user has touched the displayObject + * + * @inner {boolean} * @private */ _touchDown: false -}; + }; module.exports = interactiveTarget;