diff --git a/README.md b/README.md index 07b6a39e..98ebf75b 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,7 @@ New features: * Tweens have a new event: onLoop. * You can now load any binary file via the Loader: game.load.binary(key, url, callback) - the optional callback allows for post-load processing before entering the Cache. * Group.set will let you deep set a new propery on a single child of the Group. +* Stage.display property added. A direct reference to the root Pixi Stage object (very useful for RenderTexture manipulation) New Examples: @@ -74,10 +75,12 @@ New Examples: * Added touch joystick example showing how to use the clay.io virtual game controller (thanks gabehollombe) * Games - Matching Pairs by Patrick OReilly. * Tweens - Example showing how to use the tween events, onStart, onLoop and onComplete. +* Display - Pixi Render Texture. A Phaser conversion of the Pixi.js Render Texture example. Updates: +* Updated to latest Pixi.js dev branch build * When a Sprite is destroyed any active filters are removed as well. * Updated Pixi.js so that removing filters now works correctly without breaking the display list. * Phaser.Canvas.create updated to it can be given an ID as the 3rd parameter. @@ -109,6 +112,7 @@ Bug Fixes: * Fixed Pixi bug (#425) incorrect width property for multi-line BitmapText (thanks jcd-as) * Tween.onStart is now called when the tween starts AFTER the delay value, if given (thanks stevenbouma) * Sprites that are fixedToCamera can now be input dragged regardless of world position (thanks RafaelOliveira) +* RenderTexture now displays correctly in Canvas games. You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md diff --git a/examples/_site/examples.json b/examples/_site/examples.json index 55124fa8..cc779cba 100644 --- a/examples/_site/examples.json +++ b/examples/_site/examples.json @@ -160,6 +160,10 @@ "file": "graphics.js", "title": "graphics" }, + { + "file": "pixi+render+texture.js", + "title": "pixi render texture" + }, { "file": "render+crisp.js", "title": "render crisp" diff --git a/examples/assets/audio/protracker/global_trash_3_v2.mod b/examples/assets/audio/protracker/global_trash_3_v2.mod new file mode 100644 index 00000000..876ec467 Binary files /dev/null and b/examples/assets/audio/protracker/global_trash_3_v2.mod differ diff --git a/examples/assets/audio/protracker/sd-ingame1.mod b/examples/assets/audio/protracker/sd-ingame1.mod new file mode 100644 index 00000000..ec3434f6 Binary files /dev/null and b/examples/assets/audio/protracker/sd-ingame1.mod differ diff --git a/examples/assets/sprites/spinObj_01.png b/examples/assets/sprites/spinObj_01.png new file mode 100644 index 00000000..86873665 Binary files /dev/null and b/examples/assets/sprites/spinObj_01.png differ diff --git a/examples/assets/sprites/spinObj_02.png b/examples/assets/sprites/spinObj_02.png new file mode 100644 index 00000000..a140876d Binary files /dev/null and b/examples/assets/sprites/spinObj_02.png differ diff --git a/examples/assets/sprites/spinObj_03.png b/examples/assets/sprites/spinObj_03.png new file mode 100644 index 00000000..82532c79 Binary files /dev/null and b/examples/assets/sprites/spinObj_03.png differ diff --git a/examples/assets/sprites/spinObj_04.png b/examples/assets/sprites/spinObj_04.png new file mode 100644 index 00000000..9c790c37 Binary files /dev/null and b/examples/assets/sprites/spinObj_04.png differ diff --git a/examples/assets/sprites/spinObj_05.png b/examples/assets/sprites/spinObj_05.png new file mode 100644 index 00000000..ebb28c84 Binary files /dev/null and b/examples/assets/sprites/spinObj_05.png differ diff --git a/examples/assets/sprites/spinObj_06.png b/examples/assets/sprites/spinObj_06.png new file mode 100644 index 00000000..1dec5c81 Binary files /dev/null and b/examples/assets/sprites/spinObj_06.png differ diff --git a/examples/assets/sprites/spinObj_07.png b/examples/assets/sprites/spinObj_07.png new file mode 100644 index 00000000..e14a0215 Binary files /dev/null and b/examples/assets/sprites/spinObj_07.png differ diff --git a/examples/assets/sprites/spinObj_08.png b/examples/assets/sprites/spinObj_08.png new file mode 100644 index 00000000..0197fefa Binary files /dev/null and b/examples/assets/sprites/spinObj_08.png differ diff --git a/examples/display/pixi render texture.js b/examples/display/pixi render texture.js new file mode 100644 index 00000000..0e92b0f6 --- /dev/null +++ b/examples/display/pixi render texture.js @@ -0,0 +1,78 @@ +// Original version by @author Mat Groves http://matgroves.com/ @Doormat23 from the Pixi.js examples +// Ported to Phaser by Richard Davey + +var game = new Phaser.Game(800, 600, Phaser.WEBGL, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.image('spin1', 'assets/sprites/spinObj_01.png'); + game.load.image('spin2', 'assets/sprites/spinObj_02.png'); + game.load.image('spin3', 'assets/sprites/spinObj_03.png'); + game.load.image('spin4', 'assets/sprites/spinObj_04.png'); + game.load.image('spin5', 'assets/sprites/spinObj_05.png'); + game.load.image('spin6', 'assets/sprites/spinObj_06.png'); + game.load.image('spin7', 'assets/sprites/spinObj_07.png'); + game.load.image('spin8', 'assets/sprites/spinObj_08.png'); + +} + +var renderTexture; +var renderTexture2; +var currentTexture; +var outputSprite; +var stuffContainer; +var count = 0; + +function create() { + + // create two render textures.. these dynamic textures will be used to draw the scene into itself + renderTexture = game.add.renderTexture('texture1', 800, 600); + renderTexture2 = game.add.renderTexture('textur2e', 800, 600); + currentTexture = renderTexture; + + // create a new sprite that uses the render texture we created above + outputSprite = game.add.sprite(400, 300, currentTexture); + + // align the sprite + outputSprite.anchor.x = 0.5; + outputSprite.anchor.y = 0.5; + + stuffContainer = game.add.group(); + stuffContainer.x = 800/2; + stuffContainer.y = 600/2 + + // now create some items and randomly position them in the stuff container + for (var i = 0; i < 20; i++) + { + var item = stuffContainer.create(Math.random() * 400 - 200, Math.random() * 400 - 200, game.rnd.pick(game.cache.getImageKeys())); + item.anchor.setTo(0.5, 0.5); + } + + // used for spinning! + count = 0; + +} + +function update() { + + stuffContainer.addAll('rotation', 0.1); + + count += 0.01; + + // swap the buffers.. + var temp = renderTexture; + renderTexture = renderTexture2; + renderTexture2 = temp; + + // set the new texture + outputSprite.setTexture(renderTexture); + + // twist this up! + stuffContainer.rotation -= 0.01 + outputSprite.scale.x = outputSprite.scale.y = 1 + Math.sin(count) * 0.2; + + // render the stage to the texture + // the true clears the texture before content is rendered + renderTexture2.renderXY(game.stage.display, 0, 0, true); + +} diff --git a/examples/wip/mod.js b/examples/wip/mod.js index be244748..d244e0e6 100644 --- a/examples/wip/mod.js +++ b/examples/wip/mod.js @@ -8,6 +8,11 @@ function preload() { game.load.binary('macrocosm', 'assets/audio/protracker/macrocosm.mod', modLoaded, this); game.load.binary('enigma', 'assets/audio/protracker/enigma.mod', modLoaded, this); game.load.binary('elysium', 'assets/audio/protracker/elysium.mod', modLoaded, this); + game.load.binary('stardust', 'assets/audio/protracker/sd-ingame1.mod', modLoaded, this); + game.load.binary('globaltrash', 'assets/audio/protracker/global_trash_3_v2.mod', modLoaded, this); + game.load.image('vu1', 'assets/sprites/flectrum.png'); + game.load.image('vu2', 'assets/sprites/flectrum2.png'); + game.load.image('vu3', 'assets/sprites/healthbar.png'); } @@ -21,35 +26,148 @@ function modLoaded(key, data) { } -var sprite; +var vu1; +var vu2; +var vu3; +var vu4; + var modsample = new Array(); var module; +var sample1; +var sample2; +var sample3; +var sample4; +var sampleName1; +var sampleName2; +var sampleName3; +var sampleName4; + +var r1; +var r2; +var r3; +var r4; + function create() { + // vu1 = game.add.sprite(400, 100, 'vu3'); + // vu2 = game.add.sprite(400, 150, 'vu3'); + // vu3 = game.add.sprite(400, 200, 'vu3'); + // vu4 = game.add.sprite(400, 250, 'vu3'); + module = new Protracker(); - module.buffer = game.cache.getBinary('impulse'); + module.buffer = game.cache.getBinary('globaltrash'); module.parse(); module.play(); + r1 = new Phaser.Rectangle(400, 100, 100, 32); + r2 = new Phaser.Rectangle(400, 150, 100, 32); + r3 = new Phaser.Rectangle(400, 200, 100, 32); + r4 = new Phaser.Rectangle(400, 250, 100, 32); + + // console.log(module.sample); + } function update() { - if (module.channel[0].noteon) {sam1=module.channel[0].sample; modsamples=1;}else{modsamples=0;} - if (module.channel[1].noteon) {sam2=module.channel[1].sample; modsamples=1;}else{modsamples=0;} - if (module.channel[2].noteon) {sam3=module.channel[2].sample; modsamples=1;}else{modsamples=0;} - if (module.channel[3].noteon) {sam4=module.channel[3].sample; modsamples=1;}else{modsamples=0;} + sampleName1 = ''; + sampleName2 = ''; + sampleName3 = ''; + sampleName4 = ''; + + sample1 = module.channel[0].sample; + sample2 = module.channel[1].sample; + sample3 = module.channel[2].sample; + sample4 = module.channel[3].sample; - var posi=module.position; - var patt=module.row; - var bpm=module.bpm; - var spd=module.speed; - var modname=module.title; - var modauth=module.signature; + /* + module.sample = array of Objects containing: + + data (Float32Array) + finetime + length (ms? bytes?) + looplength + loopstart + name + volume + +arpeggio: 0 +command: 0 +data: 0 +flags: 0 +note: 22 +noteon: 1 +period: 240 +sample: 11 +samplepos: 314.3411880952386 +samplespeed: 0.335118537414966 +semitone: 14 +slidespeed: 0 +slideto: 214 +slidetospeed: 0 +vibratodepth: 0 +vibratopos: 0 +vibratospeed: 0 +vibratowave: 0 +voiceperiod: 240 +volume: 64 + */ + + if (module.sample[sample1]) + { + sampleName1 = module.sample[sample1].name; + } + + if (module.sample[sample2]) + { + sampleName2 = module.sample[sample2].name; + } + + if (module.sample[sample3]) + { + sampleName3 = module.sample[sample3].name; + } + + if (module.sample[sample4]) + { + sampleName4 = module.sample[sample4].name; + } + + // vu1.width = Math.round(module.vu[0] * 400); + // vu2.width = Math.round(module.vu[1] * 400); + // vu3.width = Math.round(module.vu[2] * 400); + // vu4.width = Math.round(module.vu[3] * 400); + + r1.width = Math.round(module.vu[0] * 500); + r2.width = Math.round(module.vu[1] * 500); + r3.width = Math.round(module.vu[2] * 500); + r4.width = Math.round(module.vu[3] * 500); } function render() { + game.debug.renderText('Sample ' + sample1 + ' : ' + sampleName1, 16, 32); + game.debug.renderText('Sample ' + sample2 + ' : ' + sampleName2, 16, 64); + game.debug.renderText('Sample ' + sample3 + ' : ' + sampleName3, 16, 96); + game.debug.renderText('Sample ' + sample4 + ' : ' + sampleName4, 16, 128); + + game.debug.renderText('Position: ' + module.position, 16, 160); + game.debug.renderText('Pattern: ' + module.row, 16, 192); + game.debug.renderText('BPM: ' + module.bpm, 16, 224); + game.debug.renderText('Speed: ' + module.speed, 16, 256); + game.debug.renderText('Name: ' + module.title, 16, 288); + game.debug.renderText('Author: ' + module.signature, 16, 320); + + game.debug.renderText('vu1: ' + module.vu[0], 16, 352); + game.debug.renderText('vu2: ' + module.vu[1], 16, 384); + game.debug.renderText('vu3: ' + module.vu[2], 16, 416); + game.debug.renderText('vu4: ' + module.vu[3], 16, 448); + + game.debug.renderRectangle(r1); + game.debug.renderRectangle(r2); + game.debug.renderRectangle(r3); + game.debug.renderRectangle(r4); + } diff --git a/examples/wip/rendertexture1.js b/examples/wip/rendertexture1.js index 7ddf2305..83f1b89d 100644 --- a/examples/wip/rendertexture1.js +++ b/examples/wip/rendertexture1.js @@ -1,38 +1,76 @@ -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); +var game = new Phaser.Game(800, 600, Phaser.WEBGL, 'phaser-example', { preload: preload, create: create, update: update }); function preload() { - game.load.spritesheet('veggies', 'assets/sprites/fruitnveg32wh37.png', 32, 32); + game.load.image('spin1', 'assets/sprites/spinObj_01.png'); + game.load.image('spin2', 'assets/sprites/spinObj_02.png'); + game.load.image('spin3', 'assets/sprites/spinObj_03.png'); + game.load.image('spin4', 'assets/sprites/spinObj_04.png'); + game.load.image('spin5', 'assets/sprites/spinObj_05.png'); + game.load.image('spin6', 'assets/sprites/spinObj_06.png'); + game.load.image('spin7', 'assets/sprites/spinObj_07.png'); + game.load.image('spin8', 'assets/sprites/spinObj_08.png'); } -var group; -var texture; +var renderTexture; +var renderTexture2; +var currentTexture; +var outputSprite; +var stuffContainer; +var count = 0; function create() { - group = game.add.group(); - group.create(0, 0, 'veggies', 0); - group.create(32, 0, 'veggies', 1); - group.create(0, 32, 'veggies', 2); - group.create(32, 32, 'veggies', 3); - group.visible = false; + // create two render textures.. these dynamic textures will be used to draw the scene into itself + renderTexture = game.add.renderTexture('texture1', 800, 600); + renderTexture2 = game.add.renderTexture('textur2e', 800, 600); + currentTexture = renderTexture; - texture = game.add.renderTexture('texture', 800, 600); - - game.add.sprite(0, 0, texture); + // create a new sprite that uses the render texture we created above + outputSprite = game.add.sprite(400, 300, currentTexture); + + // align the sprite + outputSprite.anchor.x = 0.5; + outputSprite.anchor.y = 0.5; + + stuffContainer = game.add.group(); + stuffContainer.x = 800/2; + stuffContainer.y = 600/2 + + // now create some items and randomly position them in the stuff container + for (var i = 0; i < 20; i++) + { + var item = stuffContainer.create(Math.random() * 400 - 200, Math.random() * 400 - 200, game.rnd.pick(game.cache.getImageKeys())); + item.anchor.setTo(0.5, 0.5); + } + + // used for spinning! + count = 0; } function update() { - var clear = false; + stuffContainer.addAll('rotation', 0.1); - for (var i = 0; i < 60; i++) - { - clear = (i == 0); - texture.renderXY(group, game.world.randomX, game.world.randomY, clear); - } + count += 0.01; + + // swap the buffers.. + var temp = renderTexture; + renderTexture = renderTexture2; + renderTexture2 = temp; + + // set the new texture + outputSprite.setTexture(renderTexture); + + // twist this up! + stuffContainer.rotation -= 0.01 + outputSprite.scale.x = outputSprite.scale.y = 1 + Math.sin(count) * 0.2; + + // render the stage to the texture + // the true clears the texture before content is rendered + renderTexture2.renderXY(game.stage.display, 0, 0, true); } diff --git a/examples/wip/tilemap.js b/examples/wip/tilemap.js index 3d32ca17..859df4a3 100644 --- a/examples/wip/tilemap.js +++ b/examples/wip/tilemap.js @@ -65,7 +65,7 @@ function create() { layer.resizeWorld(); //coins = - map.createFromObjects(34, 'coin', 0) + map.createFromObjects('Object Layer 1', 34, 'coin', 0); // layer2 = game.add.tilemapLayer(0, 0, 400, 600, null, map, 0); // layer.cameraOffset.x = 400; diff --git a/src/PixiPatch.js b/src/PixiPatch.js index 65b17bde..2ad64c51 100644 --- a/src/PixiPatch.js +++ b/src/PixiPatch.js @@ -76,6 +76,13 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) { this.context.transform(1, 0, 0, 1, displayObject.texture.trim.x, displayObject.texture.trim.y); } + + //if smoothingEnabled is supported and we need to change the smoothing property for this texture + if (this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) + { + this.scaleMode = displayObject.texture.baseTexture.scaleMode; + this.context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); + } this.context.drawImage( displayObject.texture.baseTexture.source, diff --git a/src/core/Stage.js b/src/core/Stage.js index 2870dd93..83c0e804 100644 --- a/src/core/Stage.js +++ b/src/core/Stage.js @@ -47,6 +47,11 @@ Phaser.Stage = function (game, width, height) { this._stage.name = '_stage_root'; this._stage.interactive = false; + /** + * @property {PIXI.Stage} display - The Pixi Stage which is hooked to the renderer. + */ + this.display = this._stage; + /** * @property {number} scaleMode - The current scaleMode. */ diff --git a/src/gameobjects/RenderTexture.js b/src/gameobjects/RenderTexture.js index 4ab01752..9d43a85f 100644 --- a/src/gameobjects/RenderTexture.js +++ b/src/gameobjects/RenderTexture.js @@ -306,7 +306,7 @@ Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, { this.renderer.context.clearRect(0, 0, this.width, this.height); } - + this.renderer.renderDisplayObject(displayObject); this.renderer.context.setTransform(1, 0, 0, 1, 0, 0); diff --git a/src/pixi/InteractionManager.js b/src/pixi/InteractionManager.js index fc0dbb71..d1e80556 100644 --- a/src/pixi/InteractionManager.js +++ b/src/pixi/InteractionManager.js @@ -1,7 +1,7 @@ /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ - + /** * The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive * This manager also supports multitouch. @@ -12,57 +12,53 @@ */ PIXI.InteractionManager = function(stage) { - /** - * a refference to the stage - * - * @property stage - * @type Stage - */ - this.stage = stage; + /** + * a refference to the stage + * + * @property stage + * @type Stage + */ + this.stage = stage; - /** - * the mouse data - * - * @property mouse - * @type InteractionData - */ - this.mouse = new PIXI.InteractionData(); + /** + * the mouse data + * + * @property mouse + * @type InteractionData + */ + this.mouse = new PIXI.InteractionData(); - /** - * an object that stores current touches (InteractionData) by id reference - * - * @property touchs - * @type Object - */ - this.touchs = {}; + /** + * an object that stores current touches (InteractionData) by id reference + * + * @property touchs + * @type Object + */ + this.touchs = {}; + // helpers + this.tempPoint = new PIXI.Point(); + //this.tempMatrix = mat3.create(); - - // helpers - this.tempPoint = new PIXI.Point(); - //this.tempMatrix = mat3.create(); + this.mouseoverEnabled = true; - this.mouseoverEnabled = true; + //tiny little interactiveData pool! + this.pool = []; - //tiny little interactiveData pool! - this.pool = []; + this.interactiveItems = []; + this.interactionDOMElement = null; - this.interactiveItems = []; - this.interactionDOMElement = null; + //this will make it so that you dont have to call bind all the time + this.onMouseMove = this.onMouseMove.bind( this ); + this.onMouseDown = this.onMouseDown.bind(this); + this.onMouseOut = this.onMouseOut.bind(this); + this.onMouseUp = this.onMouseUp.bind(this); - //this will make it so that you dont have to call bind all the time - this.onMouseMove = this.onMouseMove.bind( this ); - this.onMouseDown = this.onMouseDown.bind(this); - this.onMouseOut = this.onMouseOut.bind(this); - this.onMouseUp = this.onMouseUp.bind(this); - - this.onTouchStart = this.onTouchStart.bind(this); - this.onTouchEnd = this.onTouchEnd.bind(this); - this.onTouchMove = this.onTouchMove.bind(this); - - - this.last = 0; -} + this.onTouchStart = this.onTouchStart.bind(this); + this.onTouchEnd = this.onTouchEnd.bind(this); + this.onTouchMove = this.onTouchMove.bind(this); + this.last = 0; +}; // constructor PIXI.InteractionManager.prototype.constructor = PIXI.InteractionManager; @@ -77,39 +73,39 @@ PIXI.InteractionManager.prototype.constructor = PIXI.InteractionManager; */ PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObject, iParent) { - var children = displayObject.children; - var length = children.length; - - /// make an interaction tree... {item.__interactiveParent} - for (var i = length-1; i >= 0; i--) - { - var child = children[i]; - -// if(child.visible) { - // push all interactive bits - if(child.interactive) - { - iParent.interactiveChildren = true; - //child.__iParent = iParent; - this.interactiveItems.push(child); + var children = displayObject.children; + var length = children.length; - if(child.children.length > 0) - { - this.collectInteractiveSprite(child, child); - } - } - else - { - child.__iParent = null; + /// make an interaction tree... {item.__interactiveParent} + for (var i = length-1; i >= 0; i--) + { + var child = children[i]; - if(child.children.length > 0) - { - this.collectInteractiveSprite(child, iParent); - } - } -// } - } -} +// if(child.visible) { + // push all interactive bits + if(child.interactive) + { + iParent.interactiveChildren = true; + //child.__iParent = iParent; + this.interactiveItems.push(child); + + if(child.children.length > 0) + { + this.collectInteractiveSprite(child, child); + } + } + else + { + child.__iParent = null; + + if(child.children.length > 0) + { + this.collectInteractiveSprite(child, iParent); + } + } +// } + } +}; /** * Sets the target for event delegation @@ -120,16 +116,16 @@ PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObj */ PIXI.InteractionManager.prototype.setTarget = function(target) { - this.target = target; + this.target = target; - //check if the dom element has been set. If it has don't do anything - if( this.interactionDOMElement === null ) { + //check if the dom element has been set. If it has don't do anything + if( this.interactionDOMElement === null ) { - this.setTargetDomElement( target.view ); - } + this.setTargetDomElement( target.view ); + } - document.body.addEventListener('mouseup', this.onMouseUp, true); -} + document.body.addEventListener('mouseup', this.onMouseUp, true); +}; /** @@ -143,44 +139,43 @@ PIXI.InteractionManager.prototype.setTarget = function(target) */ PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) { - //remove previouse listeners - if( this.interactionDOMElement !== null ) - { - this.interactionDOMElement.style['-ms-content-zooming'] = ''; - this.interactionDOMElement.style['-ms-touch-action'] = ''; + //remove previouse listeners + if( this.interactionDOMElement !== null ) + { + this.interactionDOMElement.style['-ms-content-zooming'] = ''; + this.interactionDOMElement.style['-ms-touch-action'] = ''; - this.interactionDOMElement.removeEventListener('mousemove', this.onMouseMove, true); - this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true); - this.interactionDOMElement.removeEventListener('mouseout', this.onMouseOut, true); + this.interactionDOMElement.removeEventListener('mousemove', this.onMouseMove, true); + this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true); + this.interactionDOMElement.removeEventListener('mouseout', this.onMouseOut, true); - // aint no multi touch just yet! - this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true); - this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true); - this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true); - } + // aint no multi touch just yet! + this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true); + this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true); + this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true); + } - if (window.navigator.msPointerEnabled) - { - // time to remove some of that zoom in ja.. - domElement.style['-ms-content-zooming'] = 'none'; - domElement.style['-ms-touch-action'] = 'none'; - - // DO some window specific touch! - } + if (window.navigator.msPointerEnabled) + { + // time to remove some of that zoom in ja.. + domElement.style['-ms-content-zooming'] = 'none'; + domElement.style['-ms-touch-action'] = 'none'; - this.interactionDOMElement = domElement; + // DO some window specific touch! + } - domElement.addEventListener('mousemove', this.onMouseMove, true); - domElement.addEventListener('mousedown', this.onMouseDown, true); - domElement.addEventListener('mouseout', this.onMouseOut, true); + this.interactionDOMElement = domElement; - // aint no multi touch just yet! - domElement.addEventListener('touchstart', this.onTouchStart, true); - domElement.addEventListener('touchend', this.onTouchEnd, true); - domElement.addEventListener('touchmove', this.onTouchMove, true); -} + domElement.addEventListener('mousemove', this.onMouseMove, true); + domElement.addEventListener('mousedown', this.onMouseDown, true); + domElement.addEventListener('mouseout', this.onMouseOut, true); + // aint no multi touch just yet! + domElement.addEventListener('touchstart', this.onTouchStart, true); + domElement.addEventListener('touchend', this.onTouchEnd, true); + domElement.addEventListener('touchmove', this.onTouchMove, true); +}; /** * updates the state of interactive objects @@ -190,85 +185,86 @@ PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement) */ PIXI.InteractionManager.prototype.update = function() { - if(!this.target)return; - - // frequency of 30fps?? - var now = Date.now(); - var diff = now - this.last; - diff = (diff * 30) / 1000; - if(diff < 1)return; - this.last = now; - // - - // ok.. so mouse events?? - // yes for now :) - // OPTIMSE - how often to check?? - if(this.dirty) - { - this.dirty = false; - - var len = this.interactiveItems.length; - - for (var i=0; i < len; i++) { - this.interactiveItems[i].interactiveChildren = false; - } - - this.interactiveItems = []; - - if(this.stage.interactive)this.interactiveItems.push(this.stage); - // go through and collect all the objects that are interactive.. - this.collectInteractiveSprite(this.stage, this.stage); - } - - // loop through interactive objects! - var length = this.interactiveItems.length; - - this.interactionDOMElement.style.cursor = "inherit"; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - - //if(!item.visible)continue; - - // OPTIMISATION - only calculate every time if the mousemove function exists.. - // OK so.. does the object have any other interactive functions? - // hit-test the clip! - - - if(item.mouseover || item.mouseout || item.buttonMode) - { - // ok so there are some functions so lets hit test it.. - item.__hit = this.hitTest(item, this.mouse); - this.mouse.target = item; - // ok so deal with interactions.. - // loks like there was a hit! - if(item.__hit) - { - if(item.buttonMode) this.interactionDOMElement.style.cursor = item.defaultCursor; - - if(!item.__isOver) - { - - if(item.mouseover)item.mouseover(this.mouse); - item.__isOver = true; - } - } - else - { - if(item.__isOver) - { - // roll out! - if(item.mouseout)item.mouseout(this.mouse); - item.__isOver = false; - } - } - } - - // ---> - } -} + if(!this.target)return; + + // frequency of 30fps?? + var now = Date.now(); + var diff = now - this.last; + diff = (diff * 30) / 1000; + if(diff < 1)return; + this.last = now; + // + + var i = 0; + + // ok.. so mouse events?? + // yes for now :) + // OPTIMSE - how often to check?? + if(this.dirty) + { + this.dirty = false; + + var len = this.interactiveItems.length; + + for (i = 0; i < len; i++) { + this.interactiveItems[i].interactiveChildren = false; + } + + this.interactiveItems = []; + + if(this.stage.interactive)this.interactiveItems.push(this.stage); + // go through and collect all the objects that are interactive.. + this.collectInteractiveSprite(this.stage, this.stage); + } + + // loop through interactive objects! + var length = this.interactiveItems.length; + + this.interactionDOMElement.style.cursor = 'inherit'; + + for (i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + + //if(!item.visible)continue; + + // OPTIMISATION - only calculate every time if the mousemove function exists.. + // OK so.. does the object have any other interactive functions? + // hit-test the clip! + + + if(item.mouseover || item.mouseout || item.buttonMode) + { + // ok so there are some functions so lets hit test it.. + item.__hit = this.hitTest(item, this.mouse); + this.mouse.target = item; + // ok so deal with interactions.. + // loks like there was a hit! + if(item.__hit) + { + if(item.buttonMode) this.interactionDOMElement.style.cursor = item.defaultCursor; + + if(!item.__isOver) + { + + if(item.mouseover)item.mouseover(this.mouse); + item.__isOver = true; + } + } + else + { + if(item.__isOver) + { + // roll out! + if(item.mouseout)item.mouseout(this.mouse); + item.__isOver = false; + } + } + } + // ---> + } +}; /** * Is called when the mouse moves accross the renderer element @@ -279,28 +275,26 @@ PIXI.InteractionManager.prototype.update = function() */ PIXI.InteractionManager.prototype.onMouseMove = function(event) { - this.mouse.originalEvent = event || window.event; //IE uses window.event - // TODO optimize by not check EVERY TIME! maybe half as often? // - var rect = this.interactionDOMElement.getBoundingClientRect(); - - this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width); - this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height); - - var length = this.interactiveItems.length; - var global = this.mouse.global; - - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if(item.mousemove) - { - //call the function! - item.mousemove(this.mouse); - } - } -} + this.mouse.originalEvent = event || window.event; //IE uses window.event + // TODO optimize by not check EVERY TIME! maybe half as often? // + var rect = this.interactionDOMElement.getBoundingClientRect(); + + this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width); + this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height); + + var length = this.interactiveItems.length; + + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + if(item.mousemove) + { + //call the function! + item.mousemove(this.mouse); + } + } +}; /** * Is called when the mouse button is pressed down on the renderer element @@ -311,61 +305,57 @@ PIXI.InteractionManager.prototype.onMouseMove = function(event) */ PIXI.InteractionManager.prototype.onMouseDown = function(event) { - this.mouse.originalEvent = event || window.event; //IE uses window.event - - // loop through inteaction tree... - // hit test each item! -> - // get interactive items under point?? - //stage.__i - var length = this.interactiveItems.length; - var global = this.mouse.global; - - var index = 0; - var parent = this.stage; - - // while - // hit test - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if(item.mousedown || item.click) - { - item.__mouseIsDown = true; - item.__hit = this.hitTest(item, this.mouse); - - if(item.__hit) - { - //call the function! - if(item.mousedown)item.mousedown(this.mouse); - item.__isDown = true; - - // just the one! - if(!item.interactiveChildren)break; - } - } - } -} + this.mouse.originalEvent = event || window.event; //IE uses window.event + + // loop through inteaction tree... + // hit test each item! -> + // get interactive items under point?? + //stage.__i + var length = this.interactiveItems.length; + + // while + // hit test + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + if(item.mousedown || item.click) + { + item.__mouseIsDown = true; + item.__hit = this.hitTest(item, this.mouse); + + if(item.__hit) + { + //call the function! + if(item.mousedown)item.mousedown(this.mouse); + item.__isDown = true; + + // just the one! + if(!item.interactiveChildren)break; + } + } + } +}; -PIXI.InteractionManager.prototype.onMouseOut = function(event) +PIXI.InteractionManager.prototype.onMouseOut = function() { - var length = this.interactiveItems.length; - - this.interactionDOMElement.style.cursor = "inherit"; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if(item.__isOver) - { - this.mouse.target = item; - if(item.mouseout)item.mouseout(this.mouse); - item.__isOver = false; - } - } -} + var length = this.interactiveItems.length; + + this.interactionDOMElement.style.cursor = 'inherit'; + + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + if(item.__isOver) + { + this.mouse.target = item; + if(item.mouseout)item.mouseout(this.mouse); + item.__isOver = false; + } + } +}; /** * Is called when the mouse button is released on the renderer element @@ -376,48 +366,45 @@ PIXI.InteractionManager.prototype.onMouseOut = function(event) */ PIXI.InteractionManager.prototype.onMouseUp = function(event) { - this.mouse.originalEvent = event || window.event; //IE uses window.event - - var global = this.mouse.global; - - - var length = this.interactiveItems.length; - var up = false; - - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - - if(item.mouseup || item.mouseupoutside || item.click) - { - item.__hit = this.hitTest(item, this.mouse); - - if(item.__hit && !up) - { - //call the function! - if(item.mouseup) - { - item.mouseup(this.mouse); - } - if(item.__isDown) - { - if(item.click)item.click(this.mouse); - } - - if(!item.interactiveChildren)up = true; - } - else - { - if(item.__isDown) - { - if(item.mouseupoutside)item.mouseupoutside(this.mouse); - } - } - - item.__isDown = false; - } - } -} + this.mouse.originalEvent = event || window.event; //IE uses window.event + + var length = this.interactiveItems.length; + var up = false; + + for (var i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + + if(item.mouseup || item.mouseupoutside || item.click) + { + item.__hit = this.hitTest(item, this.mouse); + + if(item.__hit && !up) + { + //call the function! + if(item.mouseup) + { + item.mouseup(this.mouse); + } + if(item.__isDown) + { + if(item.click)item.click(this.mouse); + } + + if(!item.interactiveChildren)up = true; + } + else + { + if(item.__isDown) + { + if(item.mouseupoutside)item.mouseupoutside(this.mouse); + } + } + + item.__isDown = false; + } + } +}; /** * Tests if the current mouse coords hit a sprite @@ -429,68 +416,68 @@ PIXI.InteractionManager.prototype.onMouseUp = function(event) */ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) { - var global = interactionData.global; - - if(item.vcount !== PIXI.visibleCount)return false; + var global = interactionData.global; - var isSprite = (item instanceof PIXI.Sprite), - worldTransform = item.worldTransform, - a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], - a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], - id = 1 / (a00 * a11 + a01 * -a10), - x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, - y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; + if(item.vcount !== PIXI.visibleCount)return false; - interactionData.target = item; - - //a sprite or display object with a hit area defined - if(item.hitArea && item.hitArea.contains) { - if(item.hitArea.contains(x, y)) { - //if(isSprite) - interactionData.target = item; + var isSprite = (item instanceof PIXI.Sprite), + worldTransform = item.worldTransform, + a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], + a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], + id = 1 / (a00 * a11 + a01 * -a10), + x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, + y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id; - return true; - } - - return false; - } - // a sprite with no hitarea defined - else if(isSprite) - { - var width = item.texture.frame.width, - height = item.texture.frame.height, - x1 = -width * item.anchor.x, - y1; - - if(x > x1 && x < x1 + width) - { - y1 = -height * item.anchor.y; - - if(y > y1 && y < y1 + height) - { - // set the target property if a hit is true! - interactionData.target = item - return true; - } - } - } + interactionData.target = item; - var length = item.children.length; - - for (var i = 0; i < length; i++) - { - var tempItem = item.children[i]; - var hit = this.hitTest(tempItem, interactionData); - if(hit) - { - // hmm.. TODO SET CORRECT TARGET? - interactionData.target = item - return true; - } - } + //a sprite or display object with a hit area defined + if(item.hitArea && item.hitArea.contains) { + if(item.hitArea.contains(x, y)) { + //if(isSprite) + interactionData.target = item; - return false; -} + return true; + } + + return false; + } + // a sprite with no hitarea defined + else if(isSprite) + { + var width = item.texture.frame.width, + height = item.texture.frame.height, + x1 = -width * item.anchor.x, + y1; + + if(x > x1 && x < x1 + width) + { + y1 = -height * item.anchor.y; + + if(y > y1 && y < y1 + height) + { + // set the target property if a hit is true! + interactionData.target = item; + return true; + } + } + } + + var length = item.children.length; + + for (var i = 0; i < length; i++) + { + var tempItem = item.children[i]; + var hit = this.hitTest(tempItem, interactionData); + if(hit) + { + // hmm.. TODO SET CORRECT TARGET? + interactionData.target = item; + return true; + } + } + + return false; +}; /** * Is called when a touch is moved accross the renderer element @@ -501,27 +488,30 @@ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData) */ PIXI.InteractionManager.prototype.onTouchMove = function(event) { - var rect = this.interactionDOMElement.getBoundingClientRect(); - var changedTouches = event.changedTouches; - - for (var i=0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - var touchData = this.touchs[touchEvent.identifier]; - touchData.originalEvent = event || window.event; - - // update the touch position - touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); - touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); - } - - var length = this.interactiveItems.length; - for (var i = 0; i < length; i++) - { - var item = this.interactiveItems[i]; - if(item.touchmove)item.touchmove(touchData); - } -} + var rect = this.interactionDOMElement.getBoundingClientRect(); + var changedTouches = event.changedTouches; + var touchData; + var i = 0; + + for (i = 0; i < changedTouches.length; i++) + { + var touchEvent = changedTouches[i]; + touchData = this.touchs[touchEvent.identifier]; + touchData.originalEvent = event || window.event; + + // update the touch position + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + } + + var length = this.interactiveItems.length; + for (i = 0; i < length; i++) + { + var item = this.interactiveItems[i]; + if(item.touchmove) + item.touchmove(touchData); + } +}; /** * Is called when a touch is started on the renderer element @@ -532,45 +522,45 @@ PIXI.InteractionManager.prototype.onTouchMove = function(event) */ PIXI.InteractionManager.prototype.onTouchStart = function(event) { - var rect = this.interactionDOMElement.getBoundingClientRect(); - - var changedTouches = event.changedTouches; - for (var i=0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - - var touchData = this.pool.pop(); - if(!touchData)touchData = new PIXI.InteractionData(); - - touchData.originalEvent = event || window.event; - - this.touchs[touchEvent.identifier] = touchData; - touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); - touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); - - var length = this.interactiveItems.length; - - for (var j = 0; j < length; j++) - { - var item = this.interactiveItems[j]; - - if(item.touchstart || item.tap) - { - item.__hit = this.hitTest(item, touchData); - - if(item.__hit) - { - //call the function! - if(item.touchstart)item.touchstart(touchData); - item.__isDown = true; - item.__touchData = touchData; - - if(!item.interactiveChildren)break; - } - } - } - } -} + var rect = this.interactionDOMElement.getBoundingClientRect(); + + var changedTouches = event.changedTouches; + for (var i=0; i < changedTouches.length; i++) + { + var touchEvent = changedTouches[i]; + + var touchData = this.pool.pop(); + if(!touchData)touchData = new PIXI.InteractionData(); + + touchData.originalEvent = event || window.event; + + this.touchs[touchEvent.identifier] = touchData; + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + + var length = this.interactiveItems.length; + + for (var j = 0; j < length; j++) + { + var item = this.interactiveItems[j]; + + if(item.touchstart || item.tap) + { + item.__hit = this.hitTest(item, touchData); + + if(item.__hit) + { + //call the function! + if(item.touchstart)item.touchstart(touchData); + item.__isDown = true; + item.__touchData = touchData; + + if(!item.interactiveChildren)break; + } + } + } + } +}; /** * Is called when a touch is ended on the renderer element @@ -581,67 +571,69 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event) */ PIXI.InteractionManager.prototype.onTouchEnd = function(event) { - //this.mouse.originalEvent = event || window.event; //IE uses window.event - var rect = this.interactionDOMElement.getBoundingClientRect(); - var changedTouches = event.changedTouches; - - for (var i=0; i < changedTouches.length; i++) - { - var touchEvent = changedTouches[i]; - var touchData = this.touchs[touchEvent.identifier]; - var up = false; - touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); - touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); - - var length = this.interactiveItems.length; - for (var j = 0; j < length; j++) - { - var item = this.interactiveItems[j]; - var itemTouchData = item.__touchData; // <-- Here! - item.__hit = this.hitTest(item, touchData); - - if(itemTouchData == touchData) - { - // so this one WAS down... - touchData.originalEvent = event || window.event; - // hitTest?? - - if(item.touchend || item.tap) - { - if(item.__hit && !up) - { - if(item.touchend)item.touchend(touchData); - if(item.__isDown) - { - if(item.tap)item.tap(touchData); - } - - if(!item.interactiveChildren)up = true; - } - else - { - if(item.__isDown) - { - if(item.touchendoutside)item.touchendoutside(touchData); - } - } - - item.__isDown = false; - } - - item.__touchData = null; - - } - else - { - - } - } - // remove the touch.. - this.pool.push(touchData); - this.touchs[touchEvent.identifier] = null; - } -} + //this.mouse.originalEvent = event || window.event; //IE uses window.event + var rect = this.interactionDOMElement.getBoundingClientRect(); + var changedTouches = event.changedTouches; + + for (var i=0; i < changedTouches.length; i++) + { + var touchEvent = changedTouches[i]; + var touchData = this.touchs[touchEvent.identifier]; + var up = false; + touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width); + touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height); + + var length = this.interactiveItems.length; + for (var j = 0; j < length; j++) + { + var item = this.interactiveItems[j]; + var itemTouchData = item.__touchData; // <-- Here! + item.__hit = this.hitTest(item, touchData); + + if(itemTouchData === touchData) + { + // so this one WAS down... + touchData.originalEvent = event || window.event; + // hitTest?? + + if(item.touchend || item.tap) + { + if(item.__hit && !up) + { + if(item.touchend)item.touchend(touchData); + if(item.__isDown) + { + if(item.tap)item.tap(touchData); + } + + if(!item.interactiveChildren)up = true; + } + else + { + if(item.__isDown) + { + if(item.touchendoutside)item.touchendoutside(touchData); + } + } + + item.__isDown = false; + } + + item.__touchData = null; + + } + /* + else + { + + } + */ + } + // remove the touch.. + this.pool.push(touchData); + this.touchs[touchEvent.identifier] = null; + } +}; /** * Holds all information related to an Interaction event @@ -651,33 +643,33 @@ PIXI.InteractionManager.prototype.onTouchEnd = function(event) */ PIXI.InteractionData = function() { - /** - * This point stores the global coords of where the touch/mouse event happened - * - * @property global - * @type Point - */ - this.global = new PIXI.Point(); - - // this is here for legacy... but will remove - this.local = new PIXI.Point(); + /** + * This point stores the global coords of where the touch/mouse event happened + * + * @property global + * @type Point + */ + this.global = new PIXI.Point(); - /** - * The target Sprite that was interacted with - * - * @property target - * @type Sprite - */ - this.target; + // this is here for legacy... but will remove + this.local = new PIXI.Point(); - /** - * When passed to an event handler, this will be the original DOM Event that was captured - * - * @property originalEvent - * @type Event - */ - this.originalEvent; -} + /** + * The target Sprite that was interacted with + * + * @property target + * @type Sprite + */ + this.target = null; + + /** + * When passed to an event handler, this will be the original DOM Event that was captured + * + * @property originalEvent + * @type Event + */ + this.originalEvent = null; +}; /** * This will return the local coords of the specified displayObject for this InteractionData @@ -688,17 +680,17 @@ PIXI.InteractionData = function() */ PIXI.InteractionData.prototype.getLocalPosition = function(displayObject) { - var worldTransform = displayObject.worldTransform; - var global = this.global; - - // do a cheeky transform to get the mouse coords; - var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], + var worldTransform = displayObject.worldTransform; + var global = this.global; + + // do a cheeky transform to get the mouse coords; + var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2], a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5], id = 1 / (a00 * a11 + a01 * -a10); - // set the mouse coords... - return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, - a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id) -} + // set the mouse coords... + return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id, + a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id); +}; // constructor PIXI.InteractionData.prototype.constructor = PIXI.InteractionData; diff --git a/src/pixi/Intro.js b/src/pixi/Intro.js index 4023084f..f485ffc0 100644 --- a/src/pixi/Intro.js +++ b/src/pixi/Intro.js @@ -4,4 +4,4 @@ (function(){ - var root = this; + var root = this; diff --git a/src/pixi/core/Circle.js b/src/pixi/core/Circle.js index e2728335..d1724619 100644 --- a/src/pixi/core/Circle.js +++ b/src/pixi/core/Circle.js @@ -33,7 +33,7 @@ PIXI.Circle = function(x, y, radius) * @default 0 */ this.radius = radius || 0; -} +}; /** * Creates a clone of this Circle instance @@ -44,7 +44,7 @@ PIXI.Circle = function(x, y, radius) PIXI.Circle.prototype.clone = function() { return new PIXI.Circle(this.x, this.y, this.radius); -} +}; /** * Checks if the x, and y coords passed to this function are contained within this circle @@ -67,7 +67,7 @@ PIXI.Circle.prototype.contains = function(x, y) dy *= dy; return (dx + dy <= r2); -} +}; // constructor PIXI.Circle.prototype.constructor = PIXI.Circle; diff --git a/src/pixi/core/Ellipse.js b/src/pixi/core/Ellipse.js index 1a95d20a..7a9c2f64 100644 --- a/src/pixi/core/Ellipse.js +++ b/src/pixi/core/Ellipse.js @@ -41,7 +41,7 @@ PIXI.Ellipse = function(x, y, width, height) * @default 0 */ this.height = height || 0; -} +}; /** * Creates a clone of this Ellipse instance @@ -52,7 +52,7 @@ PIXI.Ellipse = function(x, y, width, height) PIXI.Ellipse.prototype.clone = function() { return new PIXI.Ellipse(this.x, this.y, this.width, this.height); -} +}; /** * Checks if the x, and y coords passed to this function are contained within this ellipse @@ -76,12 +76,12 @@ PIXI.Ellipse.prototype.contains = function(x, y) normy *= normy; return (normx + normy < 0.25); -} +}; -PIXI.Ellipse.getBounds = function() +PIXI.Ellipse.prototype.getBounds = function() { return new PIXI.Rectangle(this.x, this.y, this.width, this.height); -} +}; // constructor PIXI.Ellipse.prototype.constructor = PIXI.Ellipse; diff --git a/src/pixi/core/Matrix.js b/src/pixi/core/Matrix.js index 923682c6..1f5a67a5 100644 --- a/src/pixi/core/Matrix.js +++ b/src/pixi/core/Matrix.js @@ -16,112 +16,112 @@ PIXI.mat3 = {}; PIXI.mat3.create = function() { - var matrix = new PIXI.Matrix(9); + var matrix = new PIXI.Matrix(9); - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 1; - matrix[5] = 0; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 1; + matrix[5] = 0; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 1; - return matrix; -} + return matrix; +}; PIXI.mat3.identity = function(matrix) { - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 1; - matrix[5] = 0; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 1; + matrix[5] = 0; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 1; - return matrix; -} + return matrix; +}; PIXI.mat4 = {}; PIXI.mat4.create = function() { - var matrix = new PIXI.Matrix(16); + var matrix = new PIXI.Matrix(16); - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 0; - matrix[5] = 1; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 0; - matrix[9] = 0; - matrix[10] = 1; - matrix[11] = 0; - matrix[12] = 0; - matrix[13] = 0; - matrix[14] = 0; - matrix[15] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 0; + matrix[5] = 1; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 0; + matrix[9] = 0; + matrix[10] = 1; + matrix[11] = 0; + matrix[12] = 0; + matrix[13] = 0; + matrix[14] = 0; + matrix[15] = 1; - return matrix; -} + return matrix; +}; PIXI.mat3.multiply = function (mat, mat2, dest) { - if (!dest) { dest = mat; } + if (!dest) { dest = mat; } - // Cache the matrix values (makes for huge speed increases!) - var a00 = mat[0], a01 = mat[1], a02 = mat[2], - a10 = mat[3], a11 = mat[4], a12 = mat[5], - a20 = mat[6], a21 = mat[7], a22 = mat[8], + // Cache the matrix values (makes for huge speed increases!) + var a00 = mat[0], a01 = mat[1], a02 = mat[2], + a10 = mat[3], a11 = mat[4], a12 = mat[5], + a20 = mat[6], a21 = mat[7], a22 = mat[8], - b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], - b10 = mat2[3], b11 = mat2[4], b12 = mat2[5], - b20 = mat2[6], b21 = mat2[7], b22 = mat2[8]; + b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], + b10 = mat2[3], b11 = mat2[4], b12 = mat2[5], + b20 = mat2[6], b21 = mat2[7], b22 = mat2[8]; - dest[0] = b00 * a00 + b01 * a10 + b02 * a20; - dest[1] = b00 * a01 + b01 * a11 + b02 * a21; - dest[2] = b00 * a02 + b01 * a12 + b02 * a22; + dest[0] = b00 * a00 + b01 * a10 + b02 * a20; + dest[1] = b00 * a01 + b01 * a11 + b02 * a21; + dest[2] = b00 * a02 + b01 * a12 + b02 * a22; - dest[3] = b10 * a00 + b11 * a10 + b12 * a20; - dest[4] = b10 * a01 + b11 * a11 + b12 * a21; - dest[5] = b10 * a02 + b11 * a12 + b12 * a22; + dest[3] = b10 * a00 + b11 * a10 + b12 * a20; + dest[4] = b10 * a01 + b11 * a11 + b12 * a21; + dest[5] = b10 * a02 + b11 * a12 + b12 * a22; - dest[6] = b20 * a00 + b21 * a10 + b22 * a20; - dest[7] = b20 * a01 + b21 * a11 + b22 * a21; - dest[8] = b20 * a02 + b21 * a12 + b22 * a22; + dest[6] = b20 * a00 + b21 * a10 + b22 * a20; + dest[7] = b20 * a01 + b21 * a11 + b22 * a21; + dest[8] = b20 * a02 + b21 * a12 + b22 * a22; - return dest; -} + return dest; +}; PIXI.mat3.clone = function(mat) { - var matrix = new PIXI.Matrix(9); + var matrix = new PIXI.Matrix(9); - matrix[0] = mat[0]; - matrix[1] = mat[1]; - matrix[2] = mat[2]; - matrix[3] = mat[3]; - matrix[4] = mat[4]; - matrix[5] = mat[5]; - matrix[6] = mat[6]; - matrix[7] = mat[7]; - matrix[8] = mat[8]; + matrix[0] = mat[0]; + matrix[1] = mat[1]; + matrix[2] = mat[2]; + matrix[3] = mat[3]; + matrix[4] = mat[4]; + matrix[5] = mat[5]; + matrix[6] = mat[6]; + matrix[7] = mat[7]; + matrix[8] = mat[8]; - return matrix; -} + return matrix; +}; PIXI.mat3.transpose = function (mat, dest) { - // If we are transposing ourselves we can skip a few steps but have to cache some values + // If we are transposing ourselves we can skip a few steps but have to cache some values if (!dest || mat === dest) { var a01 = mat[1], a02 = mat[2], a12 = mat[5]; @@ -145,34 +145,34 @@ PIXI.mat3.transpose = function (mat, dest) dest[7] = mat[5]; dest[8] = mat[8]; return dest; -} +}; PIXI.mat3.toMat4 = function (mat, dest) { - if (!dest) { dest = PIXI.mat4.create(); } + if (!dest) { dest = PIXI.mat4.create(); } - dest[15] = 1; - dest[14] = 0; - dest[13] = 0; - dest[12] = 0; + dest[15] = 1; + dest[14] = 0; + dest[13] = 0; + dest[12] = 0; - dest[11] = 0; - dest[10] = mat[8]; - dest[9] = mat[7]; - dest[8] = mat[6]; + dest[11] = 0; + dest[10] = mat[8]; + dest[9] = mat[7]; + dest[8] = mat[6]; - dest[7] = 0; - dest[6] = mat[5]; - dest[5] = mat[4]; - dest[4] = mat[3]; + dest[7] = 0; + dest[6] = mat[5]; + dest[5] = mat[4]; + dest[4] = mat[3]; - dest[3] = 0; - dest[2] = mat[2]; - dest[1] = mat[1]; - dest[0] = mat[0]; + dest[3] = 0; + dest[2] = mat[2]; + dest[1] = mat[1]; + dest[0] = mat[0]; - return dest; -} + return dest; +}; ///// @@ -180,82 +180,82 @@ PIXI.mat3.toMat4 = function (mat, dest) PIXI.mat4.create = function() { - var matrix = new PIXI.Matrix(16); + var matrix = new PIXI.Matrix(16); - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 0; - matrix[5] = 1; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 0; - matrix[9] = 0; - matrix[10] = 1; - matrix[11] = 0; - matrix[12] = 0; - matrix[13] = 0; - matrix[14] = 0; - matrix[15] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 0; + matrix[5] = 1; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 0; + matrix[9] = 0; + matrix[10] = 1; + matrix[11] = 0; + matrix[12] = 0; + matrix[13] = 0; + matrix[14] = 0; + matrix[15] = 1; - return matrix; -} + return matrix; +}; PIXI.mat4.transpose = function (mat, dest) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if (!dest || mat === dest) - { - var a01 = mat[1], a02 = mat[2], a03 = mat[3], - a12 = mat[6], a13 = mat[7], - a23 = mat[11]; + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (!dest || mat === dest) + { + var a01 = mat[1], a02 = mat[2], a03 = mat[3], + a12 = mat[6], a13 = mat[7], + a23 = mat[11]; - mat[1] = mat[4]; - mat[2] = mat[8]; - mat[3] = mat[12]; - mat[4] = a01; - mat[6] = mat[9]; - mat[7] = mat[13]; - mat[8] = a02; - mat[9] = a12; - mat[11] = mat[14]; - mat[12] = a03; - mat[13] = a13; - mat[14] = a23; - return mat; - } + mat[1] = mat[4]; + mat[2] = mat[8]; + mat[3] = mat[12]; + mat[4] = a01; + mat[6] = mat[9]; + mat[7] = mat[13]; + mat[8] = a02; + mat[9] = a12; + mat[11] = mat[14]; + mat[12] = a03; + mat[13] = a13; + mat[14] = a23; + return mat; + } - dest[0] = mat[0]; - dest[1] = mat[4]; - dest[2] = mat[8]; - dest[3] = mat[12]; - dest[4] = mat[1]; - dest[5] = mat[5]; - dest[6] = mat[9]; - dest[7] = mat[13]; - dest[8] = mat[2]; - dest[9] = mat[6]; - dest[10] = mat[10]; - dest[11] = mat[14]; - dest[12] = mat[3]; - dest[13] = mat[7]; - dest[14] = mat[11]; - dest[15] = mat[15]; - return dest; -} + dest[0] = mat[0]; + dest[1] = mat[4]; + dest[2] = mat[8]; + dest[3] = mat[12]; + dest[4] = mat[1]; + dest[5] = mat[5]; + dest[6] = mat[9]; + dest[7] = mat[13]; + dest[8] = mat[2]; + dest[9] = mat[6]; + dest[10] = mat[10]; + dest[11] = mat[14]; + dest[12] = mat[3]; + dest[13] = mat[7]; + dest[14] = mat[11]; + dest[15] = mat[15]; + return dest; +}; PIXI.mat4.multiply = function (mat, mat2, dest) { - if (!dest) { dest = mat; } + if (!dest) { dest = mat; } - // Cache the matrix values (makes for huge speed increases!) - var a00 = mat[ 0], a01 = mat[ 1], a02 = mat[ 2], a03 = mat[3]; - var a10 = mat[ 4], a11 = mat[ 5], a12 = mat[ 6], a13 = mat[7]; - var a20 = mat[ 8], a21 = mat[ 9], a22 = mat[10], a23 = mat[11]; - var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; + // Cache the matrix values (makes for huge speed increases!) + var a00 = mat[ 0], a01 = mat[ 1], a02 = mat[ 2], a03 = mat[3]; + var a10 = mat[ 4], a11 = mat[ 5], a12 = mat[ 6], a13 = mat[7]; + var a20 = mat[ 8], a21 = mat[ 9], a22 = mat[10], a23 = mat[11]; + var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; - // Cache only the current line of the second matrix + // Cache only the current line of the second matrix var b0 = mat2[0], b1 = mat2[1], b2 = mat2[2], b3 = mat2[3]; dest[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30; dest[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31; @@ -290,4 +290,4 @@ PIXI.mat4.multiply = function (mat, mat2, dest) dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33; return dest; -} +}; diff --git a/src/pixi/core/Point.js b/src/pixi/core/Point.js index 7c7fe2d7..c7e27720 100644 --- a/src/pixi/core/Point.js +++ b/src/pixi/core/Point.js @@ -12,20 +12,20 @@ */ PIXI.Point = function(x, y) { - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; + /** + * @property x + * @type Number + * @default 0 + */ + this.x = x || 0; - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; -} + /** + * @property y + * @type Number + * @default 0 + */ + this.y = y || 0; +}; /** * Creates a clone of this point @@ -35,8 +35,8 @@ PIXI.Point = function(x, y) */ PIXI.Point.prototype.clone = function() { - return new PIXI.Point(this.x, this.y); -} + return new PIXI.Point(this.x, this.y); +}; // constructor PIXI.Point.prototype.constructor = PIXI.Point; diff --git a/src/pixi/core/Polygon.js b/src/pixi/core/Polygon.js index 4ef74f11..4887f6c4 100644 --- a/src/pixi/core/Polygon.js +++ b/src/pixi/core/Polygon.js @@ -29,8 +29,8 @@ PIXI.Polygon = function(points) points = p; } - this.points = points; -} + this.points = points; +}; /** * Creates a clone of this polygon @@ -40,13 +40,13 @@ PIXI.Polygon = function(points) */ PIXI.Polygon.prototype.clone = function() { - var points = []; - for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); + intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); if(intersect) inside = !inside; } return inside; -} +}; // constructor PIXI.Polygon.prototype.constructor = PIXI.Polygon; diff --git a/src/pixi/core/Rectangle.js b/src/pixi/core/Rectangle.js index 8a0e0402..70390a16 100644 --- a/src/pixi/core/Rectangle.js +++ b/src/pixi/core/Rectangle.js @@ -14,34 +14,34 @@ */ PIXI.Rectangle = function(x, y, width, height) { - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; + /** + * @property x + * @type Number + * @default 0 + */ + this.x = x || 0; - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; + /** + * @property y + * @type Number + * @default 0 + */ + this.y = y || 0; - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; + /** + * @property width + * @type Number + * @default 0 + */ + this.width = width || 0; - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; -} + /** + * @property height + * @type Number + * @default 0 + */ + this.height = height || 0; +}; /** * Creates a clone of this Rectangle @@ -51,8 +51,8 @@ PIXI.Rectangle = function(x, y, width, height) */ PIXI.Rectangle.prototype.clone = function() { - return new PIXI.Rectangle(this.x, this.y, this.width, this.height); -} + return new PIXI.Rectangle(this.x, this.y, this.width, this.height); +}; /** * Checks if the x, and y coords passed to this function are contained within this Rectangle @@ -67,19 +67,19 @@ PIXI.Rectangle.prototype.contains = function(x, y) if(this.width <= 0 || this.height <= 0) return false; - var x1 = this.x; - if(x >= x1 && x <= x1 + this.width) - { - var y1 = this.y; + var x1 = this.x; + if(x >= x1 && x <= x1 + this.width) + { + var y1 = this.y; - if(y >= y1 && y <= y1 + this.height) - { - return true; - } - } + if(y >= y1 && y <= y1 + this.height) + { + return true; + } + } - return false; -} + return false; +}; // constructor PIXI.Rectangle.prototype.constructor = PIXI.Rectangle; diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js index df5e898b..53cce04d 100644 --- a/src/pixi/display/DisplayObject.js +++ b/src/pixi/display/DisplayObject.js @@ -10,238 +10,238 @@ */ PIXI.DisplayObject = function() { - this.last = this; - this.first = this; - /** - * The coordinate of the object relative to the local coordinates of the parent. - * - * @property position - * @type Point - */ - this.position = new PIXI.Point(); + this.last = this; + this.first = this; + /** + * The coordinate of the object relative to the local coordinates of the parent. + * + * @property position + * @type Point + */ + this.position = new PIXI.Point(); - /** - * The scale factor of the object. - * - * @property scale - * @type Point - */ - this.scale = new PIXI.Point(1,1);//{x:1, y:1}; + /** + * The scale factor of the object. + * + * @property scale + * @type Point + */ + this.scale = new PIXI.Point(1,1);//{x:1, y:1}; - /** - * The pivot point of the displayObject that it rotates around - * - * @property pivot - * @type Point - */ - this.pivot = new PIXI.Point(0,0); + /** + * The pivot point of the displayObject that it rotates around + * + * @property pivot + * @type Point + */ + this.pivot = new PIXI.Point(0,0); - /** - * The rotation of the object in radians. - * - * @property rotation - * @type Number - */ - this.rotation = 0; + /** + * The rotation of the object in radians. + * + * @property rotation + * @type Number + */ + this.rotation = 0; - /** - * The opacity of the object. - * - * @property alpha - * @type Number - */ - this.alpha = 1; + /** + * The opacity of the object. + * + * @property alpha + * @type Number + */ + this.alpha = 1; - /** - * The visibility of the object. - * - * @property visible - * @type Boolean - */ - this.visible = true; + /** + * The visibility of the object. + * + * @property visible + * @type Boolean + */ + this.visible = true; - /** - * This is the defined area that will pick up mouse / touch events. It is null by default. - * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children) - * - * @property hitArea - * @type Rectangle|Circle|Ellipse|Polygon - */ - this.hitArea = null; + /** + * This is the defined area that will pick up mouse / touch events. It is null by default. + * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children) + * + * @property hitArea + * @type Rectangle|Circle|Ellipse|Polygon + */ + this.hitArea = null; - /** - * This is used to indicate if the displayObject should display a mouse hand cursor on rollover - * - * @property buttonMode - * @type Boolean - */ - this.buttonMode = false; + /** + * This is used to indicate if the displayObject should display a mouse hand cursor on rollover + * + * @property buttonMode + * @type Boolean + */ + this.buttonMode = false; - /** - * Can this object be rendered - * - * @property renderable - * @type Boolean - */ - this.renderable = false; + /** + * Can this object be rendered + * + * @property renderable + * @type Boolean + */ + this.renderable = false; - /** - * [read-only] The display object container that contains this display object. - * - * @property parent - * @type DisplayObjectContainer - * @readOnly - */ - this.parent = null; + /** + * [read-only] The display object container that contains this display object. + * + * @property parent + * @type DisplayObjectContainer + * @readOnly + */ + this.parent = null; - /** - * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage. - * - * @property stage - * @type Stage - * @readOnly - */ - this.stage = null; + /** + * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage. + * + * @property stage + * @type Stage + * @readOnly + */ + this.stage = null; - /** - * [read-only] The multiplied alpha of the displayobject - * - * @property worldAlpha - * @type Number - * @readOnly - */ - this.worldAlpha = 1; + /** + * [read-only] The multiplied alpha of the displayobject + * + * @property worldAlpha + * @type Number + * @readOnly + */ + this.worldAlpha = 1; - /** - * [read-only] Whether or not the object is interactive, do not toggle directly! use the `interactive` property - * - * @property _interactive - * @type Boolean - * @readOnly - * @private - */ - this._interactive = false; + /** + * [read-only] Whether or not the object is interactive, do not toggle directly! use the `interactive` property + * + * @property _interactive + * @type Boolean + * @readOnly + * @private + */ + this._interactive = false; - this.defaultCursor = "pointer"; - - /** - * [read-only] Current transform of the object based on world (parent) factors - * - * @property worldTransform - * @type Mat3 - * @readOnly - * @private - */ - this.worldTransform = PIXI.mat3.create()//mat3.identity(); + this.defaultCursor = 'pointer'; - /** - * [read-only] Current transform of the object locally - * - * @property localTransform - * @type Mat3 - * @readOnly - * @private - */ - this.localTransform = PIXI.mat3.create()//mat3.identity(); + /** + * [read-only] Current transform of the object based on world (parent) factors + * + * @property worldTransform + * @type Mat3 + * @readOnly + * @private + */ + this.worldTransform = PIXI.mat3.create(); //mat3.identity(); - /** - * [NYI] Unkown - * - * @property color - * @type Array<> - * @private - */ - this.color = []; + /** + * [read-only] Current transform of the object locally + * + * @property localTransform + * @type Mat3 + * @readOnly + * @private + */ + this.localTransform = PIXI.mat3.create(); //mat3.identity(); - /** - * [NYI] Holds whether or not this object is dynamic, for rendering optimization - * - * @property dynamic - * @type Boolean - * @private - */ - this.dynamic = true; + /** + * [NYI] Unkown + * + * @property color + * @type Array<> + * @private + */ + this.color = []; - // chach that puppy! - this._sr = 0; - this._cr = 1; + /** + * [NYI] Holds whether or not this object is dynamic, for rendering optimization + * + * @property dynamic + * @type Boolean + * @private + */ + this.dynamic = true; + + // chach that puppy! + this._sr = 0; + this._cr = 1; - this.filterArea = new PIXI.Rectangle(0,0,1,1); - - /* - * MOUSE Callbacks - */ + this.filterArea = new PIXI.Rectangle(0,0,1,1); - /** - * A callback that is used when the users clicks on the displayObject with their mouse - * @method click - * @param interactionData {InteractionData} - */ + /* + * MOUSE Callbacks + */ - /** - * A callback that is used when the user clicks the mouse down over the sprite - * @method mousedown - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the users clicks on the displayObject with their mouse + * @method click + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases the mouse that was over the displayObject - * for this callback to be fired the mouse must have been pressed down over the displayObject - * @method mouseup - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user clicks the mouse down over the sprite + * @method mousedown + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject - * for this callback to be fired, The touch must have started over the displayObject - * @method mouseupoutside - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user releases the mouse that was over the displayObject + * for this callback to be fired the mouse must have been pressed down over the displayObject + * @method mouseup + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the users mouse rolls over the displayObject - * @method mouseover - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject + * for this callback to be fired, The touch must have started over the displayObject + * @method mouseupoutside + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the users mouse leaves the displayObject - * @method mouseout - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the users mouse rolls over the displayObject + * @method mouseover + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the users mouse leaves the displayObject + * @method mouseout + * @param interactionData {InteractionData} + */ - /* - * TOUCH Callbacks - */ + /* + * TOUCH Callbacks + */ - /** - * A callback that is used when the users taps on the sprite with their finger - * basically a touch version of click - * @method tap - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the users taps on the sprite with their finger + * basically a touch version of click + * @method tap + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user touch's over the displayObject - * @method touchstart - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user touch's over the displayObject + * @method touchstart + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases a touch over the displayObject - * @method touchend - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user releases a touch over the displayObject + * @method touchend + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases the touch that was over the displayObject - * for this callback to be fired, The touch must have started over the sprite - * @method touchendoutside - * @param interactionData {InteractionData} - */ -} + /** + * A callback that is used when the user releases the touch that was over the displayObject + * for this callback to be fired, The touch must have started over the sprite + * @method touchendoutside + * @param interactionData {InteractionData} + */ +}; // constructor PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject; @@ -256,8 +256,8 @@ PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject; */ PIXI.DisplayObject.prototype.setInteractive = function(interactive) { - this.interactive = interactive; -} + this.interactive = interactive; +}; /** * Indicates if the sprite will have touch and mouse interactivity. It is false by default @@ -271,11 +271,11 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', { return this._interactive; }, set: function(value) { - this._interactive = value; - - // TODO more to be done here.. - // need to sort out a re-crawl! - if(this.stage)this.stage.dirty = true; + this._interactive = value; + + // TODO more to be done here.. + // need to sort out a re-crawl! + if(this.stage)this.stage.dirty = true; } }); @@ -292,33 +292,33 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', { return this._mask; }, set: function(value) { - - + + if(value) { - if(this._mask) - { - value.start = this._mask.start; - value.end = this._mask.end; - } - else - { - this.addFilter(value); - value.renderable = false; - } + if(this._mask) + { + value.start = this._mask.start; + value.end = this._mask.end; + } + else + { + this.addFilter(value); + value.renderable = false; + } } else { - this.removeFilter(this._mask); - this._mask.renderable = true; + this.removeFilter(this._mask); + this._mask.renderable = true; } - + this._mask = value; } }); /** - * Sets the filters for the displayObject. + * Sets the filters for the displayObject. * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer. * To remove filters simply set this property to 'null' * @property filters @@ -329,35 +329,33 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { return this._filters; }, set: function(value) { - + if(value) { - if(this._filters)this.removeFilter(this._filters); - this.addFilter(value); + if(this._filters)this.removeFilter(this._filters); + this.addFilter(value); - // now put all the passes in one place.. - var passes = []; - for (var i = 0; i < value.length; i++) - { - var filterPasses = value[i].passes; - for (var j = 0; j < filterPasses.length; j++) - { - passes.push(filterPasses[j]); - }; - }; + // now put all the passes in one place.. + var passes = []; + for (var i = 0; i < value.length; i++) + { + var filterPasses = value[i].passes; + for (var j = 0; j < filterPasses.length; j++) + { + passes.push(filterPasses[j]); + } + } - value.start.filterPasses = passes; + value.start.filterPasses = passes; } else { - if(this._filters)this.removeFilter(this._filters); + if(this._filters) { + this.removeFilter(this._filters); + } } - + this._filters = value; - - - - } }); @@ -370,101 +368,99 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { */ PIXI.DisplayObject.prototype.addFilter = function(data) { - //if(this.filter)return; - //this.filter = true; -// data[0].target = this; - + //if(this.filter)return; + //this.filter = true; +// data[0].target = this; - // insert a filter block.. - // TODO Onject pool thease bad boys.. - var start = new PIXI.FilterBlock(); - var end = new PIXI.FilterBlock(); - - data.start = start; - data.end = end; - - start.data = data; - end.data = data; - - start.first = start.last = this; - end.first = end.last = this; - - start.open = true; - - start.target = this; - - /* - * insert start - */ - - var childFirst = start - var childLast = start - var nextObject; - var previousObject; - - previousObject = this.first._iPrev; - - if(previousObject) - { - nextObject = previousObject._iNext; - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; - } - else - { - nextObject = this; - } - - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - - // now insert the end filter block.. - - /* - * insert end filter - */ - var childFirst = end - var childLast = end - var nextObject = null; - var previousObject = null; - - previousObject = this.last; - nextObject = previousObject._iNext; - - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; - - var updateLast = this; - - var prevLast = this.last; - while(updateLast) - { - if(updateLast.last == prevLast) - { - updateLast.last = end; - } - updateLast = updateLast.parent; - } - - this.first = start; - - // if webGL... - if(this.__renderGroup) - { - this.__renderGroup.addFilterBlocks(start, end); - } - -} + + // insert a filter block.. + // TODO Onject pool thease bad boys.. + var start = new PIXI.FilterBlock(); + var end = new PIXI.FilterBlock(); + + data.start = start; + data.end = end; + + start.data = data; + end.data = data; + + start.first = start.last = this; + end.first = end.last = this; + + start.open = true; + + start.target = this; + + /* + * insert start + */ + + var childFirst = start; + var childLast = start; + var nextObject; + var previousObject; + + previousObject = this.first._iPrev; + + if(previousObject) + { + nextObject = previousObject._iNext; + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + } + else + { + nextObject = this; + } + + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + // now insert the end filter block.. + + /* + * insert end filter + */ + childFirst = end; + childLast = end; + nextObject = null; + previousObject = null; + + previousObject = this.last; + nextObject = previousObject._iNext; + + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + + var updateLast = this; + + var prevLast = this.last; + while(updateLast) + { + if(updateLast.last === prevLast) + { + updateLast.last = end; + } + updateLast = updateLast.parent; + } + + this.first = start; + + // if webGL... + if(this.__renderGroup) + { + this.__renderGroup.addFilterBlocks(start, end); + } +}; /* * Removes the filter to this displayObject @@ -474,47 +470,47 @@ PIXI.DisplayObject.prototype.addFilter = function(data) */ PIXI.DisplayObject.prototype.removeFilter = function(data) { - //if(!this.filter)return; - //this.filter = false; - // console.log("YUOIO") - // modify the list.. - var startBlock = data.start; - - - var nextObject = startBlock._iNext; - var previousObject = startBlock._iPrev; - - if(nextObject)nextObject._iPrev = previousObject; - if(previousObject)previousObject._iNext = nextObject; - - this.first = startBlock._iNext; - - // remove the end filter - var lastBlock = data.end; - - var nextObject = lastBlock._iNext; - var previousObject = lastBlock._iPrev; - - if(nextObject)nextObject._iPrev = previousObject; - previousObject._iNext = nextObject; - - // this is always true too! - var tempLast = lastBlock._iPrev; - // need to make sure the parents last is updated too - var updateLast = this; - while(updateLast.last == lastBlock) - { - updateLast.last = tempLast; - updateLast = updateLast.parent; - if(!updateLast)break; - } - - // if webGL... - if(this.__renderGroup) - { - this.__renderGroup.removeFilterBlocks(startBlock, lastBlock); - } -} + //if(!this.filter)return; + //this.filter = false; + // console.log('YUOIO') + // modify the list.. + var startBlock = data.start; + + + var nextObject = startBlock._iNext; + var previousObject = startBlock._iPrev; + + if(nextObject)nextObject._iPrev = previousObject; + if(previousObject)previousObject._iNext = nextObject; + + this.first = startBlock._iNext; + + // remove the end filter + var lastBlock = data.end; + + nextObject = lastBlock._iNext; + previousObject = lastBlock._iPrev; + + if(nextObject)nextObject._iPrev = previousObject; + previousObject._iNext = nextObject; + + // this is always true too! + var tempLast = lastBlock._iPrev; + // need to make sure the parents last is updated too + var updateLast = this; + while(updateLast.last === lastBlock) + { + updateLast.last = tempLast; + updateLast = updateLast.parent; + if(!updateLast)break; + } + + // if webGL... + if(this.__renderGroup) + { + this.__renderGroup.removeFilterBlocks(startBlock, lastBlock); + } +}; /* * Updates the object transform for rendering @@ -524,28 +520,28 @@ PIXI.DisplayObject.prototype.removeFilter = function(data) */ PIXI.DisplayObject.prototype.updateTransform = function() { - // TODO OPTIMIZE THIS!! with dirty - if(this.rotation !== this.rotationCache) - { - this.rotationCache = this.rotation; - this._sr = Math.sin(this.rotation); - this._cr = Math.cos(this.rotation); - } - - var localTransform = this.localTransform; - var parentTransform = this.parent.worldTransform; - var worldTransform = this.worldTransform; - //console.log(localTransform) - localTransform[0] = this._cr * this.scale.x; - localTransform[1] = -this._sr * this.scale.y - localTransform[3] = this._sr * this.scale.x; - localTransform[4] = this._cr * this.scale.y; - - // TODO --> do we even need a local matrix??? - - var px = this.pivot.x; - var py = this.pivot.y; - + // TODO OPTIMIZE THIS!! with dirty + if(this.rotation !== this.rotationCache) + { + this.rotationCache = this.rotation; + this._sr = Math.sin(this.rotation); + this._cr = Math.cos(this.rotation); + } + + var localTransform = this.localTransform; + var parentTransform = this.parent.worldTransform; + var worldTransform = this.worldTransform; + //console.log(localTransform) + localTransform[0] = this._cr * this.scale.x; + localTransform[1] = -this._sr * this.scale.y; + localTransform[3] = this._sr * this.scale.x; + localTransform[4] = this._cr * this.scale.y; + + // TODO --> do we even need a local matrix??? + + var px = this.pivot.x; + var py = this.pivot.y; + // Cache the matrix values (makes for huge speed increases!) var a00 = localTransform[0], a01 = localTransform[1], a02 = this.position.x - localTransform[0] * px - py * localTransform[1], a10 = localTransform[3], a11 = localTransform[4], a12 = this.position.y - localTransform[4] * py - px * localTransform[3], @@ -553,9 +549,9 @@ PIXI.DisplayObject.prototype.updateTransform = function() b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2], b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5]; - localTransform[2] = a02 - localTransform[5] = a12 - + localTransform[2] = a02; + localTransform[5] = a12; + worldTransform[0] = b00 * a00 + b01 * a10; worldTransform[1] = b00 * a01 + b01 * a11; worldTransform[2] = b00 * a02 + b01 * a12 + b02; @@ -564,12 +560,11 @@ PIXI.DisplayObject.prototype.updateTransform = function() worldTransform[4] = b10 * a01 + b11 * a11; worldTransform[5] = b10 * a02 + b11 * a12 + b12; - // because we are using affine transformation, we can optimise the matrix concatenation process.. wooo! - // mat3.multiply(this.localTransform, this.parent.worldTransform, this.worldTransform); - this.worldAlpha = this.alpha * this.parent.worldAlpha; - - this.vcount = PIXI.visibleCount; + // because we are using affine transformation, we can optimise the matrix concatenation process.. wooo! + // mat3.multiply(this.localTransform, this.parent.worldTransform, this.worldTransform); + this.worldAlpha = this.alpha * this.parent.worldAlpha; -} + this.vcount = PIXI.visibleCount; +}; PIXI.visibleCount = 0; \ No newline at end of file diff --git a/src/pixi/display/DisplayObjectContainer.js b/src/pixi/display/DisplayObjectContainer.js index eb95624a..44cbaa19 100644 --- a/src/pixi/display/DisplayObjectContainer.js +++ b/src/pixi/display/DisplayObjectContainer.js @@ -7,23 +7,23 @@ * A DisplayObjectContainer represents a collection of display objects. * It is the base class of all display objects that act as a container for other objects. * - * @class DisplayObjectContainer + * @class DisplayObjectContainer * @extends DisplayObject * @constructor */ PIXI.DisplayObjectContainer = function() { - PIXI.DisplayObject.call( this ); - - /** - * [read-only] The of children of this container. - * - * @property children - * @type Array - * @readOnly - */ - this.children = []; -} + PIXI.DisplayObject.call( this ); + + /** + * [read-only] The of children of this container. + * + * @property children + * @type Array + * @readOnly + */ + this.children = []; +}; // constructor PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype ); @@ -37,85 +37,83 @@ PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer; */ PIXI.DisplayObjectContainer.prototype.addChild = function(child) { - if(child.parent != undefined) - { - - //// COULD BE THIS??? - child.parent.removeChild(child); - // return; - } + if(child.parent && child.parent !== this) + { + //// COULD BE THIS??? + child.parent.removeChild(child); + // return; + } - child.parent = this; - - this.children.push(child); - - // update the stage refference.. - - if(this.stage) - { - var tmpChild = child; - do - { - if(tmpChild.interactive)this.stage.dirty = true; - tmpChild.stage = this.stage; - tmpChild = tmpChild._iNext; - } - while(tmpChild) - } - - // LINKED LIST // - - // modify the list.. - var childFirst = child.first - var childLast = child.last; - var nextObject; - var previousObject; - - // this could be wrong if there is a filter?? - if(this._filters || this._mask) - { - previousObject = this.last._iPrev; - } - else - { - previousObject = this.last; - } + child.parent = this; - nextObject = previousObject._iNext; - - // always true in this case - // need to make sure the parents last is updated too - var updateLast = this; - var prevLast = previousObject; - - while(updateLast) - { - if(updateLast.last == prevLast) - { - updateLast.last = child.last; - } - updateLast = updateLast.parent; - } - - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; + this.children.push(child); - // need to remove any render groups.. - if(this.__renderGroup) - { - // being used by a renderTexture.. if it exists then it must be from a render texture; - if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); - // add them to the new render group.. - this.__renderGroup.addDisplayObjectAndChildren(child); - } - -} + // update the stage refference.. + + if(this.stage) + { + var tmpChild = child; + do + { + if(tmpChild.interactive)this.stage.dirty = true; + tmpChild.stage = this.stage; + tmpChild = tmpChild._iNext; + } + while(tmpChild); + } + + // LINKED LIST // + + // modify the list.. + var childFirst = child.first; + var childLast = child.last; + var nextObject; + var previousObject; + + // this could be wrong if there is a filter?? + if(this._filters || this._mask) + { + previousObject = this.last._iPrev; + } + else + { + previousObject = this.last; + } + + nextObject = previousObject._iNext; + + // always true in this case + // need to make sure the parents last is updated too + var updateLast = this; + var prevLast = previousObject; + + while(updateLast) + { + if(updateLast.last === prevLast) + { + updateLast.last = child.last; + } + updateLast = updateLast.parent; + } + + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + + // need to remove any render groups.. + if(this.__renderGroup) + { + // being used by a renderTexture.. if it exists then it must be from a render texture; + if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); + // add them to the new render group.. + this.__renderGroup.addDisplayObjectAndChildren(child); + } +}; /** * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown @@ -126,83 +124,84 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child) */ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) { - if(index >= 0 && index <= this.children.length) - { - if(child.parent != undefined) - { - child.parent.removeChild(child); - } - child.parent = this; - - if(this.stage) - { - var tmpChild = child; - do - { - if(tmpChild.interactive)this.stage.dirty = true; - tmpChild.stage = this.stage; - tmpChild = tmpChild._iNext; - } - while(tmpChild) - } - - // modify the list.. - var childFirst = child.first; - var childLast = child.last; - var nextObject; - var previousObject; - - if(index == this.children.length) - { - previousObject = this.last; - var updateLast = this; - var prevLast = this.last; - while(updateLast) - { - if(updateLast.last == prevLast) - { - updateLast.last = child.last; - } - updateLast = updateLast.parent; - } - } - else if(index == 0) - { - previousObject = this; - } - else - { - previousObject = this.children[index-1].last; - } - - nextObject = previousObject._iNext; - - // always true in this case - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; + if(index >= 0 && index <= this.children.length) + { + if(child.parent !== undefined) + { + child.parent.removeChild(child); + } - this.children.splice(index, 0, child); - // need to remove any render groups.. - if(this.__renderGroup) - { - // being used by a renderTexture.. if it exists then it must be from a render texture; - if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); - // add them to the new render group.. - this.__renderGroup.addDisplayObjectAndChildren(child); - } - - } - else - { - throw new Error(child + " The index "+ index +" supplied is out of bounds " + this.children.length); - } -} + child.parent = this; + + if(this.stage) + { + var tmpChild = child; + do + { + if(tmpChild.interactive)this.stage.dirty = true; + tmpChild.stage = this.stage; + tmpChild = tmpChild._iNext; + } + while(tmpChild); + } + + // modify the list.. + var childFirst = child.first; + var childLast = child.last; + var nextObject; + var previousObject; + + if(index === this.children.length) + { + previousObject = this.last; + var updateLast = this; + var prevLast = this.last; + while(updateLast) + { + if(updateLast.last === prevLast) + { + updateLast.last = child.last; + } + updateLast = updateLast.parent; + } + } + else if(index === 0) + { + previousObject = this; + } + else + { + previousObject = this.children[index-1].last; + } + + nextObject = previousObject._iNext; + + // always true in this case + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + + this.children.splice(index, 0, child); + // need to remove any render groups.. + if(this.__renderGroup) + { + // being used by a renderTexture.. if it exists then it must be from a render texture; + if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); + // add them to the new render group.. + this.__renderGroup.addDisplayObjectAndChildren(child); + } + + } + else + { + throw new Error(child + ' The index '+ index +' supplied is out of bounds ' + this.children.length); + } +}; /** * [NYI] Swaps the depth of 2 displayObjects @@ -214,31 +213,31 @@ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) */ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) { - if(child === child2) { - return; - } + if(child === child2) { + return; + } - var index1 = this.children.indexOf(child); - var index2 = this.children.indexOf(child2); - - if(index1 < 0 || index2 < 0) { - throw new Error("swapChildren: Both the supplied DisplayObjects must be a child of the caller."); - } + var index1 = this.children.indexOf(child); + var index2 = this.children.indexOf(child2); - this.removeChild(child); - this.removeChild(child2); - - if(index1 < index2) - { - this.addChildAt(child2, index1); - this.addChildAt(child, index2); - } - else - { - this.addChildAt(child, index2); - this.addChildAt(child2, index1); - } -} + if(index1 < 0 || index2 < 0) { + throw new Error('swapChildren: Both the supplied DisplayObjects must be a child of the caller.'); + } + + this.removeChild(child); + this.removeChild(child2); + + if(index1 < index2) + { + this.addChildAt(child2, index1); + this.addChildAt(child, index2); + } + else + { + this.addChildAt(child, index2); + this.addChildAt(child2, index1); + } +}; /** * Returns the Child at the specified index @@ -248,15 +247,15 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) */ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) { - if(index >= 0 && index < this.children.length) - { - return this.children[index]; - } - else - { - throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this); - } -} + if(index >= 0 && index < this.children.length) + { + return this.children[index]; + } + else + { + throw new Error('Both the supplied DisplayObjects must be a child of the caller ' + this); + } +}; /** * Removes a child from the container. @@ -266,66 +265,65 @@ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) */ PIXI.DisplayObjectContainer.prototype.removeChild = function(child) { - var index = this.children.indexOf( child ); - if ( index !== -1 ) - { - // unlink // - // modify the list.. - var childFirst = child.first; - var childLast = child.last; - - var nextObject = childLast._iNext; - var previousObject = childFirst._iPrev; - - if(nextObject)nextObject._iPrev = previousObject; - previousObject._iNext = nextObject; - - if(this.last == childLast) - { + var index = this.children.indexOf( child ); + if ( index !== -1 ) + { + // unlink // + // modify the list.. + var childFirst = child.first; + var childLast = child.last; - var tempLast = childFirst._iPrev; - // need to make sure the parents last is updated too - var updateLast = this; - - while(updateLast.last == childLast) - { - updateLast.last = tempLast; - updateLast = updateLast.parent; - if(!updateLast)break; - - } - } - - childLast._iNext = null; - childFirst._iPrev = null; - - // update the stage reference.. - if(this.stage) - { - var tmpChild = child; - do - { - if(tmpChild.interactive)this.stage.dirty = true; - tmpChild.stage = null; - tmpChild = tmpChild._iNext; - } - while(tmpChild) - } - - // webGL trim - if(child.__renderGroup) - { - child.__renderGroup.removeDisplayObjectAndChildren(child); - } - - child.parent = undefined; - this.children.splice( index, 1 ); - } - else - { - throw new Error(child + " The supplied DisplayObject must be a child of the caller " + this); - } -} + var nextObject = childLast._iNext; + var previousObject = childFirst._iPrev; + + if(nextObject)nextObject._iPrev = previousObject; + previousObject._iNext = nextObject; + + if(this.last === childLast) + { + var tempLast = childFirst._iPrev; + // need to make sure the parents last is updated too + var updateLast = this; + + while(updateLast.last === childLast) + { + updateLast.last = tempLast; + updateLast = updateLast.parent; + if(!updateLast)break; + + } + } + + childLast._iNext = null; + childFirst._iPrev = null; + + // update the stage reference.. + if(this.stage) + { + var tmpChild = child; + do + { + if(tmpChild.interactive)this.stage.dirty = true; + tmpChild.stage = null; + tmpChild = tmpChild._iNext; + } + while(tmpChild); + } + + // webGL trim + if(child.__renderGroup) + { + child.__renderGroup.removeDisplayObjectAndChildren(child); + } + + child.parent = undefined; + this.children.splice( index, 1 ); + } + else + { + throw new Error(child + ' The supplied DisplayObject must be a child of the caller ' + this); + } +}; /* * Updates the container's children's transform for rendering @@ -335,12 +333,12 @@ PIXI.DisplayObjectContainer.prototype.removeChild = function(child) */ PIXI.DisplayObjectContainer.prototype.updateTransform = function() { - if(!this.visible)return; - - PIXI.DisplayObject.prototype.updateTransform.call( this ); - - for(var i=0,j=this.children.length; i= this.textures.length) - { - this.gotoAndStop(this.textures.length - 1); - if(this.onComplete) - { - this.onComplete(); - } - } -} \ No newline at end of file + if(this.loop || round < this.textures.length) + { + this.setTexture(this.textures[round % this.textures.length]); + } + else if(round >= this.textures.length) + { + this.gotoAndStop(this.textures.length - 1); + if(this.onComplete) + { + this.onComplete(); + } + } +}; diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js index e567c795..35f1db0a 100644 --- a/src/pixi/display/Sprite.js +++ b/src/pixi/display/Sprite.js @@ -18,66 +18,66 @@ PIXI.blendModes.SCREEN = 1; */ PIXI.Sprite = function(texture) { - PIXI.DisplayObjectContainer.call( this ); + PIXI.DisplayObjectContainer.call( this ); - /** - * The anchor sets the origin point of the texture. - * The default is 0,0 this means the textures origin is the top left - * Setting than anchor to 0.5,0.5 means the textures origin is centered - * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right - * + /** + * The anchor sets the origin point of the texture. + * The default is 0,0 this means the textures origin is the top left + * Setting than anchor to 0.5,0.5 means the textures origin is centered + * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right + * * @property anchor * @type Point */ - this.anchor = new PIXI.Point(); + this.anchor = new PIXI.Point(); - /** - * The texture that the sprite is using - * - * @property texture - * @type Texture - */ - this.texture = texture; + /** + * The texture that the sprite is using + * + * @property texture + * @type Texture + */ + this.texture = texture; - /** - * The blend mode of sprite. - * currently supports PIXI.blendModes.NORMAL and PIXI.blendModes.SCREEN - * - * @property blendMode - * @type Number - */ - this.blendMode = PIXI.blendModes.NORMAL; + /** + * The blend mode of sprite. + * currently supports PIXI.blendModes.NORMAL and PIXI.blendModes.SCREEN + * + * @property blendMode + * @type Number + */ + this.blendMode = PIXI.blendModes.NORMAL; - /** - * The width of the sprite (this is initially set by the texture) - * - * @property _width - * @type Number - * @private - */ - this._width = 0; + /** + * The width of the sprite (this is initially set by the texture) + * + * @property _width + * @type Number + * @private + */ + this._width = 0; - /** - * The height of the sprite (this is initially set by the texture) - * - * @property _height - * @type Number - * @private - */ - this._height = 0; + /** + * The height of the sprite (this is initially set by the texture) + * + * @property _height + * @type Number + * @private + */ + this._height = 0; - if(texture.baseTexture.hasLoaded) - { - this.updateFrame = true; - } - else - { - this.onTextureUpdateBind = this.onTextureUpdate.bind(this); - this.texture.addEventListener( 'update', this.onTextureUpdateBind ); - } + if(texture.baseTexture.hasLoaded) + { + this.updateFrame = true; + } + else + { + this.onTextureUpdateBind = this.onTextureUpdate.bind(this); + this.texture.addEventListener( 'update', this.onTextureUpdateBind ); + } - this.renderable = true; -} + this.renderable = true; +}; // constructor PIXI.Sprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); @@ -94,7 +94,7 @@ Object.defineProperty(PIXI.Sprite.prototype, 'width', { return this.scale.x * this.texture.frame.width; }, set: function(value) { - this.scale.x = value / this.texture.frame.width + this.scale.x = value / this.texture.frame.width; this._width = value; } }); @@ -110,7 +110,7 @@ Object.defineProperty(PIXI.Sprite.prototype, 'height', { return this.scale.y * this.texture.frame.height; }, set: function(value) { - this.scale.y = value / this.texture.frame.height + this.scale.y = value / this.texture.frame.height; this._height = value; } }); @@ -123,24 +123,24 @@ Object.defineProperty(PIXI.Sprite.prototype, 'height', { */ PIXI.Sprite.prototype.setTexture = function(texture) { - // stop current texture; - if(this.texture.baseTexture != texture.baseTexture) - { - this.textureChange = true; - this.texture = texture; - - if(this.__renderGroup) - { - this.__renderGroup.updateTexture(this); - } - } - else - { - this.texture = texture; - } - - this.updateFrame = true; -} + // stop current texture; + if(this.texture.baseTexture !== texture.baseTexture) + { + this.textureChange = true; + this.texture = texture; + + if(this.__renderGroup) + { + this.__renderGroup.updateTexture(this); + } + } + else + { + this.texture = texture; + } + + this.updateFrame = true; +}; /** * When the texture is updated, this event will fire to update the scale and frame @@ -149,21 +149,21 @@ PIXI.Sprite.prototype.setTexture = function(texture) * @param event * @private */ -PIXI.Sprite.prototype.onTextureUpdate = function(event) +PIXI.Sprite.prototype.onTextureUpdate = function() { - //this.texture.removeEventListener( 'update', this.onTextureUpdateBind ); - - // so if _width is 0 then width was not set.. - if(this._width)this.scale.x = this._width / this.texture.frame.width; - if(this._height)this.scale.y = this._height / this.texture.frame.height; - - this.updateFrame = true; -} + //this.texture.removeEventListener( 'update', this.onTextureUpdateBind ); + + // so if _width is 0 then width was not set.. + if(this._width)this.scale.x = this._width / this.texture.frame.width; + if(this._height)this.scale.y = this._height / this.texture.frame.height; + + this.updateFrame = true; +}; // some helper functions.. /** - * + * * Helper function that creates a sprite that will contain a texture from the TextureCache based on the frameId * The frame ids are created when a Texture packer file has been loaded * @@ -174,13 +174,13 @@ PIXI.Sprite.prototype.onTextureUpdate = function(event) */ PIXI.Sprite.fromFrame = function(frameId) { - var texture = PIXI.TextureCache[frameId]; - if(!texture)throw new Error("The frameId '"+ frameId +"' does not exist in the texture cache" + this); - return new PIXI.Sprite(texture); -} + var texture = PIXI.TextureCache[frameId]; + if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache' + this); + return new PIXI.Sprite(texture); +}; /** - * + * * Helper function that creates a sprite that will contain a texture based on an image url * If the image is not in the texture cache it will be loaded * @@ -191,6 +191,6 @@ PIXI.Sprite.fromFrame = function(frameId) */ PIXI.Sprite.fromImage = function(imageId) { - var texture = PIXI.Texture.fromImage(imageId); - return new PIXI.Sprite(texture); -} + var texture = PIXI.Texture.fromImage(imageId); + return new PIXI.Sprite(texture); +}; diff --git a/src/pixi/display/Stage.js b/src/pixi/display/Stage.js index 513c0ad0..1aa16202 100644 --- a/src/pixi/display/Stage.js +++ b/src/pixi/display/Stage.js @@ -9,59 +9,59 @@ * @extends DisplayObjectContainer * @constructor * @param backgroundColor {Number} the background color of the stage, easiest way to pass this in is in hex format - * like: 0xFFFFFF for white + * like: 0xFFFFFF for white */ PIXI.Stage = function(backgroundColor) { - PIXI.DisplayObjectContainer.call( this ); + PIXI.DisplayObjectContainer.call( this ); - /** - * [read-only] Current transform of the object based on world (parent) factors - * - * @property worldTransform - * @type Mat3 - * @readOnly - * @private - */ - this.worldTransform = PIXI.mat3.create(); + /** + * [read-only] Current transform of the object based on world (parent) factors + * + * @property worldTransform + * @type Mat3 + * @readOnly + * @private + */ + this.worldTransform = PIXI.mat3.create(); - /** - * Whether or not the stage is interactive - * - * @property interactive - * @type Boolean - */ - this.interactive = true; + /** + * Whether or not the stage is interactive + * + * @property interactive + * @type Boolean + */ + this.interactive = true; - /** - * The interaction manage for this stage, manages all interactive activity on the stage - * - * @property interactive - * @type InteractionManager - */ - this.interactionManager = new PIXI.InteractionManager(this); + /** + * The interaction manage for this stage, manages all interactive activity on the stage + * + * @property interactive + * @type InteractionManager + */ + this.interactionManager = new PIXI.InteractionManager(this); - /** - * Whether the stage is dirty and needs to have interactions updated - * - * @property dirty - * @type Boolean - * @private - */ - this.dirty = true; + /** + * Whether the stage is dirty and needs to have interactions updated + * + * @property dirty + * @type Boolean + * @private + */ + this.dirty = true; - this.__childrenAdded = []; - this.__childrenRemoved = []; + this.__childrenAdded = []; + this.__childrenRemoved = []; - //the stage is it's own stage - this.stage = this; + //the stage is it's own stage + this.stage = this; - //optimize hit detection a bit - this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000); + //optimize hit detection a bit + this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000); - this.setBackgroundColor(backgroundColor); - this.worldVisible = true; -} + this.setBackgroundColor(backgroundColor); + this.worldVisible = true; +}; // constructor PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); @@ -76,8 +76,8 @@ PIXI.Stage.prototype.constructor = PIXI.Stage; */ PIXI.Stage.prototype.setInteractionDelegate = function(domElement) { - this.interactionManager.setTargetDomElement( domElement ); -} + this.interactionManager.setTargetDomElement( domElement ); +}; /* * Updates the object transform for rendering @@ -87,40 +87,40 @@ PIXI.Stage.prototype.setInteractionDelegate = function(domElement) */ PIXI.Stage.prototype.updateTransform = function() { - this.worldAlpha = 1; - this.vcount = PIXI.visibleCount; - - for(var i=0,j=this.children.length; i 1) ratio = 1; - var ratio = (1 - (i / (total-1))) * 10; - if(ratio > 1)ratio = 1; + perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); + num = this.texture.height / 2; //(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; + perp.x /= perpLength; + perp.y /= perpLength; - var perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); - var num = this.texture.height/2//(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; - perp.x /= perpLength; - perp.y /= perpLength; + perp.x *= num; + perp.y *= num; - perp.x *= num; - perp.y *= num; + verticies[index] = point.x + perp.x; + verticies[index+1] = point.y + perp.y; + verticies[index+2] = point.x - perp.x; + verticies[index+3] = point.y - perp.y; - verticies[index] = point.x + perp.x - verticies[index+1] = point.y + perp.y - verticies[index+2] = point.x - perp.x - verticies[index+3] = point.y - perp.y + lastPoint = point; + } - lastPoint = point; - } - - PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); -} + PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); +}; PIXI.Rope.prototype.setTexture = function(texture) { - // stop current texture - this.texture = texture; - this.updateFrame = true; -} - - - - + // stop current texture + this.texture = texture; + this.updateFrame = true; +}; diff --git a/src/pixi/extras/Spine.js b/src/pixi/extras/Spine.js index 27995ae6..50db87d5 100644 --- a/src/pixi/extras/Spine.js +++ b/src/pixi/extras/Spine.js @@ -7,6 +7,1350 @@ * */ +/* + * Awesome JS run time provided by EsotericSoftware + * + * https://github.com/EsotericSoftware/spine-runtimes + * + */ + +var spine = {}; + +spine.BoneData = function (name, parent) { + this.name = name; + this.parent = parent; +}; +spine.BoneData.prototype = { + length: 0, + x: 0, y: 0, + rotation: 0, + scaleX: 1, scaleY: 1 +}; + +spine.SlotData = function (name, boneData) { + this.name = name; + this.boneData = boneData; +}; +spine.SlotData.prototype = { + r: 1, g: 1, b: 1, a: 1, + attachmentName: null +}; + +spine.Bone = function (boneData, parent) { + this.data = boneData; + this.parent = parent; + this.setToSetupPose(); +}; +spine.Bone.yDown = false; +spine.Bone.prototype = { + x: 0, y: 0, + rotation: 0, + scaleX: 1, scaleY: 1, + m00: 0, m01: 0, worldX: 0, // a b x + m10: 0, m11: 0, worldY: 0, // c d y + worldRotation: 0, + worldScaleX: 1, worldScaleY: 1, + updateWorldTransform: function (flipX, flipY) { + var parent = this.parent; + if (parent != null) { + this.worldX = this.x * parent.m00 + this.y * parent.m01 + parent.worldX; + this.worldY = this.x * parent.m10 + this.y * parent.m11 + parent.worldY; + this.worldScaleX = parent.worldScaleX * this.scaleX; + this.worldScaleY = parent.worldScaleY * this.scaleY; + this.worldRotation = parent.worldRotation + this.rotation; + } else { + this.worldX = this.x; + this.worldY = this.y; + this.worldScaleX = this.scaleX; + this.worldScaleY = this.scaleY; + this.worldRotation = this.rotation; + } + var radians = this.worldRotation * Math.PI / 180; + var cos = Math.cos(radians); + var sin = Math.sin(radians); + this.m00 = cos * this.worldScaleX; + this.m10 = sin * this.worldScaleX; + this.m01 = -sin * this.worldScaleY; + this.m11 = cos * this.worldScaleY; + if (flipX) { + this.m00 = -this.m00; + this.m01 = -this.m01; + } + if (flipY) { + this.m10 = -this.m10; + this.m11 = -this.m11; + } + if (spine.Bone.yDown) { + this.m10 = -this.m10; + this.m11 = -this.m11; + } + }, + setToSetupPose: function () { + var data = this.data; + this.x = data.x; + this.y = data.y; + this.rotation = data.rotation; + this.scaleX = data.scaleX; + this.scaleY = data.scaleY; + } +}; + +spine.Slot = function (slotData, skeleton, bone) { + this.data = slotData; + this.skeleton = skeleton; + this.bone = bone; + this.setToSetupPose(); +}; +spine.Slot.prototype = { + r: 1, g: 1, b: 1, a: 1, + _attachmentTime: 0, + attachment: null, + setAttachment: function (attachment) { + this.attachment = attachment; + this._attachmentTime = this.skeleton.time; + }, + setAttachmentTime: function (time) { + this._attachmentTime = this.skeleton.time - time; + }, + getAttachmentTime: function () { + return this.skeleton.time - this._attachmentTime; + }, + setToSetupPose: function () { + var data = this.data; + this.r = data.r; + this.g = data.g; + this.b = data.b; + this.a = data.a; + + var slotDatas = this.skeleton.data.slots; + for (var i = 0, n = slotDatas.length; i < n; i++) { + if (slotDatas[i] == data) { + this.setAttachment(!data.attachmentName ? null : this.skeleton.getAttachmentBySlotIndex(i, data.attachmentName)); + break; + } + } + } +}; + +spine.Skin = function (name) { + this.name = name; + this.attachments = {}; +}; +spine.Skin.prototype = { + addAttachment: function (slotIndex, name, attachment) { + this.attachments[slotIndex + ":" + name] = attachment; + }, + getAttachment: function (slotIndex, name) { + return this.attachments[slotIndex + ":" + name]; + }, + _attachAll: function (skeleton, oldSkin) { + for (var key in oldSkin.attachments) { + var colon = key.indexOf(":"); + var slotIndex = parseInt(key.substring(0, colon), 10); + var name = key.substring(colon + 1); + var slot = skeleton.slots[slotIndex]; + if (slot.attachment && slot.attachment.name == name) { + var attachment = this.getAttachment(slotIndex, name); + if (attachment) slot.setAttachment(attachment); + } + } + } +}; + +spine.Animation = function (name, timelines, duration) { + this.name = name; + this.timelines = timelines; + this.duration = duration; +}; +spine.Animation.prototype = { + apply: function (skeleton, time, loop) { + if (loop && this.duration) time %= this.duration; + var timelines = this.timelines; + for (var i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, time, 1); + }, + mix: function (skeleton, time, loop, alpha) { + if (loop && this.duration) time %= this.duration; + var timelines = this.timelines; + for (var i = 0, n = timelines.length; i < n; i++) + timelines[i].apply(skeleton, time, alpha); + } +}; + +spine.binarySearch = function (values, target, step) { + var low = 0; + var high = Math.floor(values.length / step) - 2; + if (!high) return step; + var current = high >>> 1; + while (true) { + if (values[(current + 1) * step] <= target) + low = current + 1; + else + high = current; + if (low == high) return (low + 1) * step; + current = (low + high) >>> 1; + } +}; +spine.linearSearch = function (values, target, step) { + for (var i = 0, last = values.length - step; i <= last; i += step) + if (values[i] > target) return i; + return -1; +}; + +spine.Curves = function (frameCount) { + this.curves = []; // dfx, dfy, ddfx, ddfy, dddfx, dddfy, ... + this.curves.length = (frameCount - 1) * 6; +}; +spine.Curves.prototype = { + setLinear: function (frameIndex) { + this.curves[frameIndex * 6] = 0/*LINEAR*/; + }, + setStepped: function (frameIndex) { + this.curves[frameIndex * 6] = -1/*STEPPED*/; + }, + /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. + * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of + * the difference between the keyframe's values. */ + setCurve: function (frameIndex, cx1, cy1, cx2, cy2) { + var subdiv_step = 1 / 10/*BEZIER_SEGMENTS*/; + var subdiv_step2 = subdiv_step * subdiv_step; + var subdiv_step3 = subdiv_step2 * subdiv_step; + var pre1 = 3 * subdiv_step; + var pre2 = 3 * subdiv_step2; + var pre4 = 6 * subdiv_step2; + var pre5 = 6 * subdiv_step3; + var tmp1x = -cx1 * 2 + cx2; + var tmp1y = -cy1 * 2 + cy2; + var tmp2x = (cx1 - cx2) * 3 + 1; + var tmp2y = (cy1 - cy2) * 3 + 1; + var i = frameIndex * 6; + var curves = this.curves; + curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3; + curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3; + curves[i + 2] = tmp1x * pre4 + tmp2x * pre5; + curves[i + 3] = tmp1y * pre4 + tmp2y * pre5; + curves[i + 4] = tmp2x * pre5; + curves[i + 5] = tmp2y * pre5; + }, + getCurvePercent: function (frameIndex, percent) { + percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent); + var curveIndex = frameIndex * 6; + var curves = this.curves; + var dfx = curves[curveIndex]; + if (!dfx/*LINEAR*/) return percent; + if (dfx == -1/*STEPPED*/) return 0; + var dfy = curves[curveIndex + 1]; + var ddfx = curves[curveIndex + 2]; + var ddfy = curves[curveIndex + 3]; + var dddfx = curves[curveIndex + 4]; + var dddfy = curves[curveIndex + 5]; + var x = dfx, y = dfy; + var i = 10/*BEZIER_SEGMENTS*/ - 2; + while (true) { + if (x >= percent) { + var lastX = x - dfx; + var lastY = y - dfy; + return lastY + (y - lastY) * (percent - lastX) / (x - lastX); + } + if (!i) break; + i--; + dfx += ddfx; + dfy += ddfy; + ddfx += dddfx; + ddfy += dddfy; + x += dfx; + y += dfy; + } + return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. + } +}; + +spine.RotateTimeline = function (frameCount) { + this.curves = new spine.Curves(frameCount); + this.frames = []; // time, angle, ... + this.frames.length = frameCount * 2; +}; +spine.RotateTimeline.prototype = { + boneIndex: 0, + getFrameCount: function () { + return this.frames.length / 2; + }, + setFrame: function (frameIndex, time, angle) { + frameIndex *= 2; + this.frames[frameIndex] = time; + this.frames[frameIndex + 1] = angle; + }, + apply: function (skeleton, time, alpha) { + var frames = this.frames, + amount; + + if (time < frames[0]) return; // Time is before first frame. + + var bone = skeleton.bones[this.boneIndex]; + + if (time >= frames[frames.length - 2]) { // Time is after last frame. + amount = bone.data.rotation + frames[frames.length - 1] - bone.rotation; + while (amount > 180) + amount -= 360; + while (amount < -180) + amount += 360; + bone.rotation += amount * alpha; + return; + } + + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 2); + var lastFrameValue = frames[frameIndex - 1]; + var frameTime = frames[frameIndex]; + var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*LAST_FRAME_TIME*/] - frameTime); + percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent); + + amount = frames[frameIndex + 1/*FRAME_VALUE*/] - lastFrameValue; + while (amount > 180) + amount -= 360; + while (amount < -180) + amount += 360; + amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation; + while (amount > 180) + amount -= 360; + while (amount < -180) + amount += 360; + bone.rotation += amount * alpha; + } +}; + +spine.TranslateTimeline = function (frameCount) { + this.curves = new spine.Curves(frameCount); + this.frames = []; // time, x, y, ... + this.frames.length = frameCount * 3; +}; +spine.TranslateTimeline.prototype = { + boneIndex: 0, + getFrameCount: function () { + return this.frames.length / 3; + }, + setFrame: function (frameIndex, time, x, y) { + frameIndex *= 3; + this.frames[frameIndex] = time; + this.frames[frameIndex + 1] = x; + this.frames[frameIndex + 2] = y; + }, + apply: function (skeleton, time, alpha) { + var frames = this.frames; + if (time < frames[0]) return; // Time is before first frame. + + var bone = skeleton.bones[this.boneIndex]; + + if (time >= frames[frames.length - 3]) { // Time is after last frame. + bone.x += (bone.data.x + frames[frames.length - 2] - bone.x) * alpha; + bone.y += (bone.data.y + frames[frames.length - 1] - bone.y) * alpha; + return; + } + + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 3); + var lastFrameX = frames[frameIndex - 2]; + var lastFrameY = frames[frameIndex - 1]; + var frameTime = frames[frameIndex]; + var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime); + percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); + + bone.x += (bone.data.x + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.x) * alpha; + bone.y += (bone.data.y + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.y) * alpha; + } +}; + +spine.ScaleTimeline = function (frameCount) { + this.curves = new spine.Curves(frameCount); + this.frames = []; // time, x, y, ... + this.frames.length = frameCount * 3; +}; +spine.ScaleTimeline.prototype = { + boneIndex: 0, + getFrameCount: function () { + return this.frames.length / 3; + }, + setFrame: function (frameIndex, time, x, y) { + frameIndex *= 3; + this.frames[frameIndex] = time; + this.frames[frameIndex + 1] = x; + this.frames[frameIndex + 2] = y; + }, + apply: function (skeleton, time, alpha) { + var frames = this.frames; + if (time < frames[0]) return; // Time is before first frame. + + var bone = skeleton.bones[this.boneIndex]; + + if (time >= frames[frames.length - 3]) { // Time is after last frame. + bone.scaleX += (bone.data.scaleX - 1 + frames[frames.length - 2] - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - 1 + frames[frames.length - 1] - bone.scaleY) * alpha; + return; + } + + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 3); + var lastFrameX = frames[frameIndex - 2]; + var lastFrameY = frames[frameIndex - 1]; + var frameTime = frames[frameIndex]; + var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime); + percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); + + bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.scaleX) * alpha; + bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.scaleY) * alpha; + } +}; + +spine.ColorTimeline = function (frameCount) { + this.curves = new spine.Curves(frameCount); + this.frames = []; // time, r, g, b, a, ... + this.frames.length = frameCount * 5; +}; +spine.ColorTimeline.prototype = { + slotIndex: 0, + getFrameCount: function () { + return this.frames.length / 2; + }, + setFrame: function (frameIndex, time, x, y) { + frameIndex *= 5; + this.frames[frameIndex] = time; + this.frames[frameIndex + 1] = r; + this.frames[frameIndex + 2] = g; + this.frames[frameIndex + 3] = b; + this.frames[frameIndex + 4] = a; + }, + apply: function (skeleton, time, alpha) { + var frames = this.frames; + if (time < frames[0]) return; // Time is before first frame. + + var slot = skeleton.slots[this.slotIndex]; + + if (time >= frames[frames.length - 5]) { // Time is after last frame. + var i = frames.length - 1; + slot.r = frames[i - 3]; + slot.g = frames[i - 2]; + slot.b = frames[i - 1]; + slot.a = frames[i]; + return; + } + + // Interpolate between the last frame and the current frame. + var frameIndex = spine.binarySearch(frames, time, 5); + var lastFrameR = frames[frameIndex - 4]; + var lastFrameG = frames[frameIndex - 3]; + var lastFrameB = frames[frameIndex - 2]; + var lastFrameA = frames[frameIndex - 1]; + var frameTime = frames[frameIndex]; + var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*LAST_FRAME_TIME*/] - frameTime); + percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent); + + var r = lastFrameR + (frames[frameIndex + 1/*FRAME_R*/] - lastFrameR) * percent; + var g = lastFrameG + (frames[frameIndex + 2/*FRAME_G*/] - lastFrameG) * percent; + var b = lastFrameB + (frames[frameIndex + 3/*FRAME_B*/] - lastFrameB) * percent; + var a = lastFrameA + (frames[frameIndex + 4/*FRAME_A*/] - lastFrameA) * percent; + if (alpha < 1) { + slot.r += (r - slot.r) * alpha; + slot.g += (g - slot.g) * alpha; + slot.b += (b - slot.b) * alpha; + slot.a += (a - slot.a) * alpha; + } else { + slot.r = r; + slot.g = g; + slot.b = b; + slot.a = a; + } + } +}; + +spine.AttachmentTimeline = function (frameCount) { + this.curves = new spine.Curves(frameCount); + this.frames = []; // time, ... + this.frames.length = frameCount; + this.attachmentNames = []; // time, ... + this.attachmentNames.length = frameCount; +}; +spine.AttachmentTimeline.prototype = { + slotIndex: 0, + getFrameCount: function () { + return this.frames.length; + }, + setFrame: function (frameIndex, time, attachmentName) { + this.frames[frameIndex] = time; + this.attachmentNames[frameIndex] = attachmentName; + }, + apply: function (skeleton, time, alpha) { + var frames = this.frames; + if (time < frames[0]) return; // Time is before first frame. + + var frameIndex; + if (time >= frames[frames.length - 1]) // Time is after last frame. + frameIndex = frames.length - 1; + else + frameIndex = spine.binarySearch(frames, time, 1) - 1; + + var attachmentName = this.attachmentNames[frameIndex]; + skeleton.slots[this.slotIndex].setAttachment(!attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName)); + } +}; + +spine.SkeletonData = function () { + this.bones = []; + this.slots = []; + this.skins = []; + this.animations = []; +}; +spine.SkeletonData.prototype = { + defaultSkin: null, + /** @return May be null. */ + findBone: function (boneName) { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].name == boneName) return bones[i]; + return null; + }, + /** @return -1 if the bone was not found. */ + findBoneIndex: function (boneName) { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].name == boneName) return i; + return -1; + }, + /** @return May be null. */ + findSlot: function (slotName) { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) { + if (slots[i].name == slotName) return slot[i]; + } + return null; + }, + /** @return -1 if the bone was not found. */ + findSlotIndex: function (slotName) { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].name == slotName) return i; + return -1; + }, + /** @return May be null. */ + findSkin: function (skinName) { + var skins = this.skins; + for (var i = 0, n = skins.length; i < n; i++) + if (skins[i].name == skinName) return skins[i]; + return null; + }, + /** @return May be null. */ + findAnimation: function (animationName) { + var animations = this.animations; + for (var i = 0, n = animations.length; i < n; i++) + if (animations[i].name == animationName) return animations[i]; + return null; + } +}; + +spine.Skeleton = function (skeletonData) { + this.data = skeletonData; + + this.bones = []; + for (var i = 0, n = skeletonData.bones.length; i < n; i++) { + var boneData = skeletonData.bones[i]; + var parent = !boneData.parent ? null : this.bones[skeletonData.bones.indexOf(boneData.parent)]; + this.bones.push(new spine.Bone(boneData, parent)); + } + + this.slots = []; + this.drawOrder = []; + for (i = 0, n = skeletonData.slots.length; i < n; i++) { + var slotData = skeletonData.slots[i]; + var bone = this.bones[skeletonData.bones.indexOf(slotData.boneData)]; + var slot = new spine.Slot(slotData, this, bone); + this.slots.push(slot); + this.drawOrder.push(slot); + } +}; +spine.Skeleton.prototype = { + x: 0, y: 0, + skin: null, + r: 1, g: 1, b: 1, a: 1, + time: 0, + flipX: false, flipY: false, + /** Updates the world transform for each bone. */ + updateWorldTransform: function () { + var flipX = this.flipX; + var flipY = this.flipY; + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + bones[i].updateWorldTransform(flipX, flipY); + }, + /** Sets the bones and slots to their setup pose values. */ + setToSetupPose: function () { + this.setBonesToSetupPose(); + this.setSlotsToSetupPose(); + }, + setBonesToSetupPose: function () { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + bones[i].setToSetupPose(); + }, + setSlotsToSetupPose: function () { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + slots[i].setToSetupPose(i); + }, + /** @return May return null. */ + getRootBone: function () { + return this.bones.length ? this.bones[0] : null; + }, + /** @return May be null. */ + findBone: function (boneName) { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].data.name == boneName) return bones[i]; + return null; + }, + /** @return -1 if the bone was not found. */ + findBoneIndex: function (boneName) { + var bones = this.bones; + for (var i = 0, n = bones.length; i < n; i++) + if (bones[i].data.name == boneName) return i; + return -1; + }, + /** @return May be null. */ + findSlot: function (slotName) { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].data.name == slotName) return slots[i]; + return null; + }, + /** @return -1 if the bone was not found. */ + findSlotIndex: function (slotName) { + var slots = this.slots; + for (var i = 0, n = slots.length; i < n; i++) + if (slots[i].data.name == slotName) return i; + return -1; + }, + setSkinByName: function (skinName) { + var skin = this.data.findSkin(skinName); + if (!skin) throw "Skin not found: " + skinName; + this.setSkin(skin); + }, + /** Sets the skin used to look up attachments not found in the {@link SkeletonData#getDefaultSkin() default skin}. Attachments + * from the new skin are attached if the corresponding attachment from the old skin was attached. + * @param newSkin May be null. */ + setSkin: function (newSkin) { + if (this.skin && newSkin) newSkin._attachAll(this, this.skin); + this.skin = newSkin; + }, + /** @return May be null. */ + getAttachmentBySlotName: function (slotName, attachmentName) { + return this.getAttachmentBySlotIndex(this.data.findSlotIndex(slotName), attachmentName); + }, + /** @return May be null. */ + getAttachmentBySlotIndex: function (slotIndex, attachmentName) { + if (this.skin) { + var attachment = this.skin.getAttachment(slotIndex, attachmentName); + if (attachment) return attachment; + } + if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); + return null; + }, + /** @param attachmentName May be null. */ + setAttachment: function (slotName, attachmentName) { + var slots = this.slots; + for (var i = 0, n = slots.size; i < n; i++) { + var slot = slots[i]; + if (slot.data.name == slotName) { + var attachment = null; + if (attachmentName) { + attachment = this.getAttachment(i, attachmentName); + if (attachment == null) throw "Attachment not found: " + attachmentName + ", for slot: " + slotName; + } + slot.setAttachment(attachment); + return; + } + } + throw "Slot not found: " + slotName; + }, + update: function (delta) { + time += delta; + } +}; + +spine.AttachmentType = { + region: 0 +}; + +spine.RegionAttachment = function () { + this.offset = []; + this.offset.length = 8; + this.uvs = []; + this.uvs.length = 8; +}; +spine.RegionAttachment.prototype = { + x: 0, y: 0, + rotation: 0, + scaleX: 1, scaleY: 1, + width: 0, height: 0, + rendererObject: null, + regionOffsetX: 0, regionOffsetY: 0, + regionWidth: 0, regionHeight: 0, + regionOriginalWidth: 0, regionOriginalHeight: 0, + setUVs: function (u, v, u2, v2, rotate) { + var uvs = this.uvs; + if (rotate) { + uvs[2/*X2*/] = u; + uvs[3/*Y2*/] = v2; + uvs[4/*X3*/] = u; + uvs[5/*Y3*/] = v; + uvs[6/*X4*/] = u2; + uvs[7/*Y4*/] = v; + uvs[0/*X1*/] = u2; + uvs[1/*Y1*/] = v2; + } else { + uvs[0/*X1*/] = u; + uvs[1/*Y1*/] = v2; + uvs[2/*X2*/] = u; + uvs[3/*Y2*/] = v; + uvs[4/*X3*/] = u2; + uvs[5/*Y3*/] = v; + uvs[6/*X4*/] = u2; + uvs[7/*Y4*/] = v2; + } + }, + updateOffset: function () { + var regionScaleX = this.width / this.regionOriginalWidth * this.scaleX; + var regionScaleY = this.height / this.regionOriginalHeight * this.scaleY; + var localX = -this.width / 2 * this.scaleX + this.regionOffsetX * regionScaleX; + var localY = -this.height / 2 * this.scaleY + this.regionOffsetY * regionScaleY; + var localX2 = localX + this.regionWidth * regionScaleX; + var localY2 = localY + this.regionHeight * regionScaleY; + var radians = this.rotation * Math.PI / 180; + var cos = Math.cos(radians); + var sin = Math.sin(radians); + var localXCos = localX * cos + this.x; + var localXSin = localX * sin; + var localYCos = localY * cos + this.y; + var localYSin = localY * sin; + var localX2Cos = localX2 * cos + this.x; + var localX2Sin = localX2 * sin; + var localY2Cos = localY2 * cos + this.y; + var localY2Sin = localY2 * sin; + var offset = this.offset; + offset[0/*X1*/] = localXCos - localYSin; + offset[1/*Y1*/] = localYCos + localXSin; + offset[2/*X2*/] = localXCos - localY2Sin; + offset[3/*Y2*/] = localY2Cos + localXSin; + offset[4/*X3*/] = localX2Cos - localY2Sin; + offset[5/*Y3*/] = localY2Cos + localX2Sin; + offset[6/*X4*/] = localX2Cos - localYSin; + offset[7/*Y4*/] = localYCos + localX2Sin; + }, + computeVertices: function (x, y, bone, vertices) { + x += bone.worldX; + y += bone.worldY; + var m00 = bone.m00; + var m01 = bone.m01; + var m10 = bone.m10; + var m11 = bone.m11; + var offset = this.offset; + vertices[0/*X1*/] = offset[0/*X1*/] * m00 + offset[1/*Y1*/] * m01 + x; + vertices[1/*Y1*/] = offset[0/*X1*/] * m10 + offset[1/*Y1*/] * m11 + y; + vertices[2/*X2*/] = offset[2/*X2*/] * m00 + offset[3/*Y2*/] * m01 + x; + vertices[3/*Y2*/] = offset[2/*X2*/] * m10 + offset[3/*Y2*/] * m11 + y; + vertices[4/*X3*/] = offset[4/*X3*/] * m00 + offset[5/*X3*/] * m01 + x; + vertices[5/*X3*/] = offset[4/*X3*/] * m10 + offset[5/*X3*/] * m11 + y; + vertices[6/*X4*/] = offset[6/*X4*/] * m00 + offset[7/*Y4*/] * m01 + x; + vertices[7/*Y4*/] = offset[6/*X4*/] * m10 + offset[7/*Y4*/] * m11 + y; + } +} + +spine.AnimationStateData = function (skeletonData) { + this.skeletonData = skeletonData; + this.animationToMixTime = {}; +}; +spine.AnimationStateData.prototype = { + defaultMix: 0, + setMixByName: function (fromName, toName, duration) { + var from = this.skeletonData.findAnimation(fromName); + if (!from) throw "Animation not found: " + fromName; + var to = this.skeletonData.findAnimation(toName); + if (!to) throw "Animation not found: " + toName; + this.setMix(from, to, duration); + }, + setMix: function (from, to, duration) { + this.animationToMixTime[from.name + ":" + to.name] = duration; + }, + getMix: function (from, to) { + var time = this.animationToMixTime[from.name + ":" + to.name]; + return time ? time : this.defaultMix; + } +}; + +spine.AnimationState = function (stateData) { + this.data = stateData; + this.queue = []; +}; +spine.AnimationState.prototype = { + current: null, + previous: null, + currentTime: 0, + previousTime: 0, + currentLoop: false, + previousLoop: false, + mixTime: 0, + mixDuration: 0, + update: function (delta) { + this.currentTime += delta; + this.previousTime += delta; + this.mixTime += delta; + + if (this.queue.length > 0) { + var entry = this.queue[0]; + if (this.currentTime >= entry.delay) { + this._setAnimation(entry.animation, entry.loop); + this.queue.shift(); + } + } + }, + apply: function (skeleton) { + if (!this.current) return; + if (this.previous) { + this.previous.apply(skeleton, this.previousTime, this.previousLoop); + var alpha = this.mixTime / this.mixDuration; + if (alpha >= 1) { + alpha = 1; + this.previous = null; + } + this.current.mix(skeleton, this.currentTime, this.currentLoop, alpha); + } else + this.current.apply(skeleton, this.currentTime, this.currentLoop); + }, + clearAnimation: function () { + this.previous = null; + this.current = null; + this.queue.length = 0; + }, + _setAnimation: function (animation, loop) { + this.previous = null; + if (animation && this.current) { + this.mixDuration = this.data.getMix(this.current, animation); + if (this.mixDuration > 0) { + this.mixTime = 0; + this.previous = this.current; + this.previousTime = this.currentTime; + this.previousLoop = this.currentLoop; + } + } + this.current = animation; + this.currentLoop = loop; + this.currentTime = 0; + }, + /** @see #setAnimation(Animation, Boolean) */ + setAnimationByName: function (animationName, loop) { + var animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) throw "Animation not found: " + animationName; + this.setAnimation(animation, loop); + }, + /** Set the current animation. Any queued animations are cleared and the current animation time is set to 0. + * @param animation May be null. */ + setAnimation: function (animation, loop) { + this.queue.length = 0; + this._setAnimation(animation, loop); + }, + /** @see #addAnimation(Animation, Boolean, Number) */ + addAnimationByName: function (animationName, loop, delay) { + var animation = this.data.skeletonData.findAnimation(animationName); + if (!animation) throw "Animation not found: " + animationName; + this.addAnimation(animation, loop, delay); + }, + /** Adds an animation to be played delay seconds after the current or last queued animation. + * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */ + addAnimation: function (animation, loop, delay) { + var entry = {}; + entry.animation = animation; + entry.loop = loop; + + if (!delay || delay <= 0) { + var previousAnimation = this.queue.length ? this.queue[this.queue.length - 1].animation : this.current; + if (previousAnimation != null) + delay = previousAnimation.duration - this.data.getMix(previousAnimation, animation) + (delay || 0); + else + delay = 0; + } + entry.delay = delay; + + this.queue.push(entry); + }, + /** Returns true if no animation is set or if the current time is greater than the animation duration, regardless of looping. */ + isComplete: function () { + return !this.current || this.currentTime >= this.current.duration; + } +}; + +spine.SkeletonJson = function (attachmentLoader) { + this.attachmentLoader = attachmentLoader; +}; +spine.SkeletonJson.prototype = { + scale: 1, + readSkeletonData: function (root) { + /*jshint -W069*/ + var skeletonData = new spine.SkeletonData(), + boneData; + + // Bones. + var bones = root["bones"]; + for (var i = 0, n = bones.length; i < n; i++) { + var boneMap = bones[i]; + var parent = null; + if (boneMap["parent"]) { + parent = skeletonData.findBone(boneMap["parent"]); + if (!parent) throw "Parent bone not found: " + boneMap["parent"]; + } + boneData = new spine.BoneData(boneMap["name"], parent); + boneData.length = (boneMap["length"] || 0) * this.scale; + boneData.x = (boneMap["x"] || 0) * this.scale; + boneData.y = (boneMap["y"] || 0) * this.scale; + boneData.rotation = (boneMap["rotation"] || 0); + boneData.scaleX = boneMap["scaleX"] || 1; + boneData.scaleY = boneMap["scaleY"] || 1; + skeletonData.bones.push(boneData); + } + + // Slots. + var slots = root["slots"]; + for (i = 0, n = slots.length; i < n; i++) { + var slotMap = slots[i]; + boneData = skeletonData.findBone(slotMap["bone"]); + if (!boneData) throw "Slot bone not found: " + slotMap["bone"]; + var slotData = new spine.SlotData(slotMap["name"], boneData); + + var color = slotMap["color"]; + if (color) { + slotData.r = spine.SkeletonJson.toColor(color, 0); + slotData.g = spine.SkeletonJson.toColor(color, 1); + slotData.b = spine.SkeletonJson.toColor(color, 2); + slotData.a = spine.SkeletonJson.toColor(color, 3); + } + + slotData.attachmentName = slotMap["attachment"]; + + skeletonData.slots.push(slotData); + } + + // Skins. + var skins = root["skins"]; + for (var skinName in skins) { + if (!skins.hasOwnProperty(skinName)) continue; + var skinMap = skins[skinName]; + var skin = new spine.Skin(skinName); + for (var slotName in skinMap) { + if (!skinMap.hasOwnProperty(slotName)) continue; + var slotIndex = skeletonData.findSlotIndex(slotName); + var slotEntry = skinMap[slotName]; + for (var attachmentName in slotEntry) { + if (!slotEntry.hasOwnProperty(attachmentName)) continue; + var attachment = this.readAttachment(skin, attachmentName, slotEntry[attachmentName]); + if (attachment != null) skin.addAttachment(slotIndex, attachmentName, attachment); + } + } + skeletonData.skins.push(skin); + if (skin.name == "default") skeletonData.defaultSkin = skin; + } + + // Animations. + var animations = root["animations"]; + for (var animationName in animations) { + if (!animations.hasOwnProperty(animationName)) continue; + this.readAnimation(animationName, animations[animationName], skeletonData); + } + + return skeletonData; + }, + readAttachment: function (skin, name, map) { + /*jshint -W069*/ + name = map["name"] || name; + + var type = spine.AttachmentType[map["type"] || "region"]; + + if (type == spine.AttachmentType.region) { + var attachment = new spine.RegionAttachment(); + attachment.x = (map["x"] || 0) * this.scale; + attachment.y = (map["y"] || 0) * this.scale; + attachment.scaleX = map["scaleX"] || 1; + attachment.scaleY = map["scaleY"] || 1; + attachment.rotation = map["rotation"] || 0; + attachment.width = (map["width"] || 32) * this.scale; + attachment.height = (map["height"] || 32) * this.scale; + attachment.updateOffset(); + + attachment.rendererObject = {}; + attachment.rendererObject.name = name; + attachment.rendererObject.scale = {}; + attachment.rendererObject.scale.x = attachment.scaleX; + attachment.rendererObject.scale.y = attachment.scaleY; + attachment.rendererObject.rotation = -attachment.rotation * Math.PI / 180; + return attachment; + } + + throw "Unknown attachment type: " + type; + }, + + readAnimation: function (name, map, skeletonData) { + /*jshint -W069*/ + var timelines = []; + var duration = 0; + var frameIndex, timeline, timelineName, valueMap, values, + i, n; + + var bones = map["bones"]; + for (var boneName in bones) { + if (!bones.hasOwnProperty(boneName)) continue; + var boneIndex = skeletonData.findBoneIndex(boneName); + if (boneIndex == -1) throw "Bone not found: " + boneName; + var boneMap = bones[boneName]; + + for (timelineName in boneMap) { + if (!boneMap.hasOwnProperty(timelineName)) continue; + values = boneMap[timelineName]; + if (timelineName == "rotate") { + timeline = new spine.RotateTimeline(values.length); + timeline.boneIndex = boneIndex; + + frameIndex = 0; + for (i = 0, n = values.length; i < n; i++) { + valueMap = values[i]; + timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]); + spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]); + + } else if (timelineName == "translate" || timelineName == "scale") { + var timelineScale = 1; + if (timelineName == "scale") + timeline = new spine.ScaleTimeline(values.length); + else { + timeline = new spine.TranslateTimeline(values.length); + timelineScale = this.scale; + } + timeline.boneIndex = boneIndex; + + frameIndex = 0; + for (i = 0, n = values.length; i < n; i++) { + valueMap = values[i]; + var x = (valueMap["x"] || 0) * timelineScale; + var y = (valueMap["y"] || 0) * timelineScale; + timeline.setFrame(frameIndex, valueMap["time"], x, y); + spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]); + + } else + throw "Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"; + } + } + var slots = map["slots"]; + for (var slotName in slots) { + if (!slots.hasOwnProperty(slotName)) continue; + var slotMap = slots[slotName]; + var slotIndex = skeletonData.findSlotIndex(slotName); + + for (timelineName in slotMap) { + if (!slotMap.hasOwnProperty(timelineName)) continue; + values = slotMap[timelineName]; + if (timelineName == "color") { + timeline = new spine.ColorTimeline(values.length); + timeline.slotIndex = slotIndex; + + frameIndex = 0; + for (i = 0, n = values.length; i < n; i++) { + valueMap = values[i]; + var color = valueMap["color"]; + var r = spine.SkeletonJson.toColor(color, 0); + var g = spine.SkeletonJson.toColor(color, 1); + var b = spine.SkeletonJson.toColor(color, 2); + var a = spine.SkeletonJson.toColor(color, 3); + timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a); + spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); + frameIndex++; + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5]); + + } else if (timelineName == "attachment") { + timeline = new spine.AttachmentTimeline(values.length); + timeline.slotIndex = slotIndex; + + frameIndex = 0; + for (i = 0, n = values.length; i < n; i++) { + valueMap = values[i]; + timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]); + } + timelines.push(timeline); + duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); + + } else + throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"; + } + } + skeletonData.animations.push(new spine.Animation(name, timelines, duration)); + } +}; +spine.SkeletonJson.readCurve = function (timeline, frameIndex, valueMap) { + /*jshint -W069*/ + var curve = valueMap["curve"]; + if (!curve) return; + if (curve == "stepped") + timeline.curves.setStepped(frameIndex); + else if (curve instanceof Array) + timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); +}; +spine.SkeletonJson.toColor = function (hexString, colorIndex) { + if (hexString.length != 8) throw "Color hexidecimal length must be 8, recieved: " + hexString; + return parseInt(hexString.substring(colorIndex * 2, 2), 16) / 255; +}; + +spine.Atlas = function (atlasText, textureLoader) { + this.textureLoader = textureLoader; + this.pages = []; + this.regions = []; + + var reader = new spine.AtlasReader(atlasText); + var tuple = []; + tuple.length = 4; + var page = null; + while (true) { + var line = reader.readLine(); + if (line == null) break; + line = reader.trim(line); + if (!line.length) + page = null; + else if (!page) { + page = new spine.AtlasPage(); + page.name = line; + + page.format = spine.Atlas.Format[reader.readValue()]; + + reader.readTuple(tuple); + page.minFilter = spine.Atlas.TextureFilter[tuple[0]]; + page.magFilter = spine.Atlas.TextureFilter[tuple[1]]; + + var direction = reader.readValue(); + page.uWrap = spine.Atlas.TextureWrap.clampToEdge; + page.vWrap = spine.Atlas.TextureWrap.clampToEdge; + if (direction == "x") + page.uWrap = spine.Atlas.TextureWrap.repeat; + else if (direction == "y") + page.vWrap = spine.Atlas.TextureWrap.repeat; + else if (direction == "xy") + page.uWrap = page.vWrap = spine.Atlas.TextureWrap.repeat; + + textureLoader.load(page, line); + + this.pages.push(page); + + } else { + var region = new spine.AtlasRegion(); + region.name = line; + region.page = page; + + region.rotate = reader.readValue() == "true"; + + reader.readTuple(tuple); + var x = parseInt(tuple[0], 10); + var y = parseInt(tuple[1], 10); + + reader.readTuple(tuple); + var width = parseInt(tuple[0], 10); + var height = parseInt(tuple[1], 10); + + region.u = x / page.width; + region.v = y / page.height; + if (region.rotate) { + region.u2 = (x + height) / page.width; + region.v2 = (y + width) / page.height; + } else { + region.u2 = (x + width) / page.width; + region.v2 = (y + height) / page.height; + } + region.x = x; + region.y = y; + region.width = Math.abs(width); + region.height = Math.abs(height); + + if (reader.readTuple(tuple) == 4) { // split is optional + region.splits = [parseInt(tuple[0], 10), parseInt(tuple[1], 10), parseInt(tuple[2], 10), parseInt(tuple[3], 10)]; + + if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits + region.pads = [parseInt(tuple[0], 10), parseInt(tuple[1], 10), parseInt(tuple[2], 10), parseInt(tuple[3], 10)]; + + reader.readTuple(tuple); + } + } + + region.originalWidth = parseInt(tuple[0], 10); + region.originalHeight = parseInt(tuple[1], 10); + + reader.readTuple(tuple); + region.offsetX = parseInt(tuple[0], 10); + region.offsetY = parseInt(tuple[1], 10); + + region.index = parseInt(reader.readValue(), 10); + + this.regions.push(region); + } + } +}; +spine.Atlas.prototype = { + findRegion: function (name) { + var regions = this.regions; + for (var i = 0, n = regions.length; i < n; i++) + if (regions[i].name == name) return regions[i]; + return null; + }, + dispose: function () { + var pages = this.pages; + for (var i = 0, n = pages.length; i < n; i++) + this.textureLoader.unload(pages[i].rendererObject); + }, + updateUVs: function (page) { + var regions = this.regions; + for (var i = 0, n = regions.length; i < n; i++) { + var region = regions[i]; + if (region.page != page) continue; + region.u = region.x / page.width; + region.v = region.y / page.height; + if (region.rotate) { + region.u2 = (region.x + region.height) / page.width; + region.v2 = (region.y + region.width) / page.height; + } else { + region.u2 = (region.x + region.width) / page.width; + region.v2 = (region.y + region.height) / page.height; + } + } + } +}; + +spine.Atlas.Format = { + alpha: 0, + intensity: 1, + luminanceAlpha: 2, + rgb565: 3, + rgba4444: 4, + rgb888: 5, + rgba8888: 6 +}; + +spine.Atlas.TextureFilter = { + nearest: 0, + linear: 1, + mipMap: 2, + mipMapNearestNearest: 3, + mipMapLinearNearest: 4, + mipMapNearestLinear: 5, + mipMapLinearLinear: 6 +}; + +spine.Atlas.TextureWrap = { + mirroredRepeat: 0, + clampToEdge: 1, + repeat: 2 +}; + +spine.AtlasPage = function () {}; +spine.AtlasPage.prototype = { + name: null, + format: null, + minFilter: null, + magFilter: null, + uWrap: null, + vWrap: null, + rendererObject: null, + width: 0, + height: 0 +}; + +spine.AtlasRegion = function () {}; +spine.AtlasRegion.prototype = { + page: null, + name: null, + x: 0, y: 0, + width: 0, height: 0, + u: 0, v: 0, u2: 0, v2: 0, + offsetX: 0, offsetY: 0, + originalWidth: 0, originalHeight: 0, + index: 0, + rotate: false, + splits: null, + pads: null, +}; + +spine.AtlasReader = function (text) { + this.lines = text.split(/\r\n|\r|\n/); +}; +spine.AtlasReader.prototype = { + index: 0, + trim: function (value) { + return value.replace(/^\s+|\s+$/g, ""); + }, + readLine: function () { + if (this.index >= this.lines.length) return null; + return this.lines[this.index++]; + }, + readValue: function () { + var line = this.readLine(); + var colon = line.indexOf(":"); + if (colon == -1) throw "Invalid line: " + line; + return this.trim(line.substring(colon + 1)); + }, + /** Returns the number of tuple values read (2 or 4). */ + readTuple: function (tuple) { + var line = this.readLine(); + var colon = line.indexOf(":"); + if (colon == -1) throw "Invalid line: " + line; + var i = 0, lastMatch= colon + 1; + for (; i < 3; i++) { + var comma = line.indexOf(",", lastMatch); + if (comma == -1) { + if (!i) throw "Invalid line: " + line; + break; + } + tuple[i] = this.trim(line.substr(lastMatch, comma - lastMatch)); + lastMatch = comma + 1; + } + tuple[i] = this.trim(line.substring(lastMatch)); + return i + 1; + } +} + +spine.AtlasAttachmentLoader = function (atlas) { + this.atlas = atlas; +} +spine.AtlasAttachmentLoader.prototype = { + newAttachment: function (skin, type, name) { + switch (type) { + case spine.AttachmentType.region: + var region = this.atlas.findRegion(name); + if (!region) throw "Region not found in atlas: " + name + " (" + type + ")"; + var attachment = new spine.RegionAttachment(name); + attachment.rendererObject = region; + attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate); + attachment.regionOffsetX = region.offsetX; + attachment.regionOffsetY = region.offsetY; + attachment.regionWidth = region.width; + attachment.regionHeight = region.height; + attachment.regionOriginalWidth = region.originalWidth; + attachment.regionOriginalHeight = region.originalHeight; + return attachment; + } + throw "Unknown attachment type: " + type; + } +} + +spine.Bone.yDown = true; +PIXI.AnimCache = {}; + /** * A class that enables the you to import and run your spine animations in pixi. * Spine animation data needs to be loaded using the PIXI.AssetLoader or PIXI.SpineLoader before it can be used by this class @@ -18,37 +1362,37 @@ * @param url {String} The url of the spine anim file to be used */ PIXI.Spine = function (url) { - PIXI.DisplayObjectContainer.call(this); + PIXI.DisplayObjectContainer.call(this); - this.spineData = PIXI.AnimCache[url]; + this.spineData = PIXI.AnimCache[url]; - if (!this.spineData) { - throw new Error("Spine data must be preloaded using PIXI.SpineLoader or PIXI.AssetLoader: " + url); - } + if (!this.spineData) { + throw new Error("Spine data must be preloaded using PIXI.SpineLoader or PIXI.AssetLoader: " + url); + } - this.skeleton = new spine.Skeleton(this.spineData); - this.skeleton.updateWorldTransform(); + this.skeleton = new spine.Skeleton(this.spineData); + this.skeleton.updateWorldTransform(); - this.stateData = new spine.AnimationStateData(this.spineData); - this.state = new spine.AnimationState(this.stateData); + this.stateData = new spine.AnimationStateData(this.spineData); + this.state = new spine.AnimationState(this.stateData); - this.slotContainers = []; + this.slotContainers = []; - for (var i = 0, n = this.skeleton.drawOrder.length; i < n; i++) { - var slot = this.skeleton.drawOrder[i]; - var attachment = slot.attachment; - var slotContainer = new PIXI.DisplayObjectContainer(); - this.slotContainers.push(slotContainer); - this.addChild(slotContainer); - if (!(attachment instanceof spine.RegionAttachment)) { - continue; - } - var spriteName = attachment.rendererObject.name; - var sprite = this.createSprite(slot, attachment.rendererObject); - slot.currentSprite = sprite; - slot.currentSpriteName = spriteName; - slotContainer.addChild(sprite); - } + for (var i = 0, n = this.skeleton.drawOrder.length; i < n; i++) { + var slot = this.skeleton.drawOrder[i]; + var attachment = slot.attachment; + var slotContainer = new PIXI.DisplayObjectContainer(); + this.slotContainers.push(slotContainer); + this.addChild(slotContainer); + if (!(attachment instanceof spine.RegionAttachment)) { + continue; + } + var spriteName = attachment.rendererObject.name; + var sprite = this.createSprite(slot, attachment.rendererObject); + slot.currentSprite = sprite; + slot.currentSpriteName = spriteName; + slotContainer.addChild(sprite); + } }; PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype); @@ -61,1400 +1405,64 @@ PIXI.Spine.prototype.constructor = PIXI.Spine; * @private */ PIXI.Spine.prototype.updateTransform = function () { - this.lastTime = this.lastTime || Date.now(); - var timeDelta = (Date.now() - this.lastTime) * 0.001; - this.lastTime = Date.now(); - this.state.update(timeDelta); - this.state.apply(this.skeleton); - this.skeleton.updateWorldTransform(); + this.lastTime = this.lastTime || Date.now(); + var timeDelta = (Date.now() - this.lastTime) * 0.001; + this.lastTime = Date.now(); + this.state.update(timeDelta); + this.state.apply(this.skeleton); + this.skeleton.updateWorldTransform(); - var drawOrder = this.skeleton.drawOrder; - for (var i = 0, n = drawOrder.length; i < n; i++) { - var slot = drawOrder[i]; - var attachment = slot.attachment; - var slotContainer = this.slotContainers[i]; - if (!(attachment instanceof spine.RegionAttachment)) { - slotContainer.visible = false; - continue; - } + var drawOrder = this.skeleton.drawOrder; + for (var i = 0, n = drawOrder.length; i < n; i++) { + var slot = drawOrder[i]; + var attachment = slot.attachment; + var slotContainer = this.slotContainers[i]; + if (!(attachment instanceof spine.RegionAttachment)) { + slotContainer.visible = false; + continue; + } - if (attachment.rendererObject) { - if (!slot.currentSpriteName || slot.currentSpriteName != attachment.name) { - var spriteName = attachment.rendererObject.name; - if (slot.currentSprite !== undefined) { - slot.currentSprite.visible = false; - } - slot.sprites = slot.sprites || {}; - if (slot.sprites[spriteName] !== undefined) { - slot.sprites[spriteName].visible = true; - } else { - var sprite = this.createSprite(slot, attachment.rendererObject); - slotContainer.addChild(sprite); - } - slot.currentSprite = slot.sprites[spriteName]; - slot.currentSpriteName = spriteName; - } - } - slotContainer.visible = true; + if (attachment.rendererObject) { + if (!slot.currentSpriteName || slot.currentSpriteName != attachment.name) { + var spriteName = attachment.rendererObject.name; + if (slot.currentSprite !== undefined) { + slot.currentSprite.visible = false; + } + slot.sprites = slot.sprites || {}; + if (slot.sprites[spriteName] !== undefined) { + slot.sprites[spriteName].visible = true; + } else { + var sprite = this.createSprite(slot, attachment.rendererObject); + slotContainer.addChild(sprite); + } + slot.currentSprite = slot.sprites[spriteName]; + slot.currentSpriteName = spriteName; + } + } + slotContainer.visible = true; - var bone = slot.bone; + var bone = slot.bone; - slotContainer.position.x = bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01; - slotContainer.position.y = bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11; - slotContainer.scale.x = bone.worldScaleX; - slotContainer.scale.y = bone.worldScaleY; + slotContainer.position.x = bone.worldX + attachment.x * bone.m00 + attachment.y * bone.m01; + slotContainer.position.y = bone.worldY + attachment.x * bone.m10 + attachment.y * bone.m11; + slotContainer.scale.x = bone.worldScaleX; + slotContainer.scale.y = bone.worldScaleY; - slotContainer.rotation = -(slot.bone.worldRotation * Math.PI / 180); - } + slotContainer.rotation = -(slot.bone.worldRotation * Math.PI / 180); + } - PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); + PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); }; PIXI.Spine.prototype.createSprite = function (slot, descriptor) { - var name = PIXI.TextureCache[descriptor.name] ? descriptor.name : descriptor.name + ".png"; - var sprite = new PIXI.Sprite(PIXI.Texture.fromFrame(name)); - sprite.scale = descriptor.scale; - sprite.rotation = descriptor.rotation; - sprite.anchor.x = sprite.anchor.y = 0.5; + var name = PIXI.TextureCache[descriptor.name] ? descriptor.name : descriptor.name + ".png"; + var sprite = new PIXI.Sprite(PIXI.Texture.fromFrame(name)); + sprite.scale = descriptor.scale; + sprite.rotation = descriptor.rotation; + sprite.anchor.x = sprite.anchor.y = 0.5; - slot.sprites = slot.sprites || {}; - slot.sprites[descriptor.name] = sprite; - return sprite; + slot.sprites = slot.sprites || {}; + slot.sprites[descriptor.name] = sprite; + return sprite; }; - -/* - * Awesome JS run time provided by EsotericSoftware - * - * https://github.com/EsotericSoftware/spine-runtimes - * - */ - -var spine = {}; - -spine.BoneData = function (name, parent) { - this.name = name; - this.parent = parent; -}; -spine.BoneData.prototype = { - length: 0, - x: 0, y: 0, - rotation: 0, - scaleX: 1, scaleY: 1 -}; - -spine.SlotData = function (name, boneData) { - this.name = name; - this.boneData = boneData; -}; -spine.SlotData.prototype = { - r: 1, g: 1, b: 1, a: 1, - attachmentName: null -}; - -spine.Bone = function (boneData, parent) { - this.data = boneData; - this.parent = parent; - this.setToSetupPose(); -}; -spine.Bone.yDown = false; -spine.Bone.prototype = { - x: 0, y: 0, - rotation: 0, - scaleX: 1, scaleY: 1, - m00: 0, m01: 0, worldX: 0, // a b x - m10: 0, m11: 0, worldY: 0, // c d y - worldRotation: 0, - worldScaleX: 1, worldScaleY: 1, - updateWorldTransform: function (flipX, flipY) { - var parent = this.parent; - if (parent != null) { - this.worldX = this.x * parent.m00 + this.y * parent.m01 + parent.worldX; - this.worldY = this.x * parent.m10 + this.y * parent.m11 + parent.worldY; - this.worldScaleX = parent.worldScaleX * this.scaleX; - this.worldScaleY = parent.worldScaleY * this.scaleY; - this.worldRotation = parent.worldRotation + this.rotation; - } else { - this.worldX = this.x; - this.worldY = this.y; - this.worldScaleX = this.scaleX; - this.worldScaleY = this.scaleY; - this.worldRotation = this.rotation; - } - var radians = this.worldRotation * Math.PI / 180; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - this.m00 = cos * this.worldScaleX; - this.m10 = sin * this.worldScaleX; - this.m01 = -sin * this.worldScaleY; - this.m11 = cos * this.worldScaleY; - if (flipX) { - this.m00 = -this.m00; - this.m01 = -this.m01; - } - if (flipY) { - this.m10 = -this.m10; - this.m11 = -this.m11; - } - if (spine.Bone.yDown) { - this.m10 = -this.m10; - this.m11 = -this.m11; - } - }, - setToSetupPose: function () { - var data = this.data; - this.x = data.x; - this.y = data.y; - this.rotation = data.rotation; - this.scaleX = data.scaleX; - this.scaleY = data.scaleY; - } -}; - -spine.Slot = function (slotData, skeleton, bone) { - this.data = slotData; - this.skeleton = skeleton; - this.bone = bone; - this.setToSetupPose(); -}; -spine.Slot.prototype = { - r: 1, g: 1, b: 1, a: 1, - _attachmentTime: 0, - attachment: null, - setAttachment: function (attachment) { - this.attachment = attachment; - this._attachmentTime = this.skeleton.time; - }, - setAttachmentTime: function (time) { - this._attachmentTime = this.skeleton.time - time; - }, - getAttachmentTime: function () { - return this.skeleton.time - this._attachmentTime; - }, - setToSetupPose: function () { - var data = this.data; - this.r = data.r; - this.g = data.g; - this.b = data.b; - this.a = data.a; - - var slotDatas = this.skeleton.data.slots; - for (var i = 0, n = slotDatas.length; i < n; i++) { - if (slotDatas[i] == data) { - this.setAttachment(!data.attachmentName ? null : this.skeleton.getAttachmentBySlotIndex(i, data.attachmentName)); - break; - } - } - } -}; - -spine.Skin = function (name) { - this.name = name; - this.attachments = {}; -}; -spine.Skin.prototype = { - addAttachment: function (slotIndex, name, attachment) { - this.attachments[slotIndex + ":" + name] = attachment; - }, - getAttachment: function (slotIndex, name) { - return this.attachments[slotIndex + ":" + name]; - }, - _attachAll: function (skeleton, oldSkin) { - for (var key in oldSkin.attachments) { - var colon = key.indexOf(":"); - var slotIndex = parseInt(key.substring(0, colon)); - var name = key.substring(colon + 1); - var slot = skeleton.slots[slotIndex]; - if (slot.attachment && slot.attachment.name == name) { - var attachment = this.getAttachment(slotIndex, name); - if (attachment) slot.setAttachment(attachment); - } - } - } -}; - -spine.Animation = function (name, timelines, duration) { - this.name = name; - this.timelines = timelines; - this.duration = duration; -}; -spine.Animation.prototype = { - apply: function (skeleton, time, loop) { - if (loop && this.duration != 0) time %= this.duration; - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, time, 1); - }, - mix: function (skeleton, time, loop, alpha) { - if (loop && this.duration != 0) time %= this.duration; - var timelines = this.timelines; - for (var i = 0, n = timelines.length; i < n; i++) - timelines[i].apply(skeleton, time, alpha); - } -}; - -spine.binarySearch = function (values, target, step) { - var low = 0; - var high = Math.floor(values.length / step) - 2; - if (high == 0) return step; - var current = high >>> 1; - while (true) { - if (values[(current + 1) * step] <= target) - low = current + 1; - else - high = current; - if (low == high) return (low + 1) * step; - current = (low + high) >>> 1; - } -}; -spine.linearSearch = function (values, target, step) { - for (var i = 0, last = values.length - step; i <= last; i += step) - if (values[i] > target) return i; - return -1; -}; - -spine.Curves = function (frameCount) { - this.curves = []; // dfx, dfy, ddfx, ddfy, dddfx, dddfy, ... - this.curves.length = (frameCount - 1) * 6; -}; -spine.Curves.prototype = { - setLinear: function (frameIndex) { - this.curves[frameIndex * 6] = 0/*LINEAR*/; - }, - setStepped: function (frameIndex) { - this.curves[frameIndex * 6] = -1/*STEPPED*/; - }, - /** Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next. - * cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of - * the difference between the keyframe's values. */ - setCurve: function (frameIndex, cx1, cy1, cx2, cy2) { - var subdiv_step = 1 / 10/*BEZIER_SEGMENTS*/; - var subdiv_step2 = subdiv_step * subdiv_step; - var subdiv_step3 = subdiv_step2 * subdiv_step; - var pre1 = 3 * subdiv_step; - var pre2 = 3 * subdiv_step2; - var pre4 = 6 * subdiv_step2; - var pre5 = 6 * subdiv_step3; - var tmp1x = -cx1 * 2 + cx2; - var tmp1y = -cy1 * 2 + cy2; - var tmp2x = (cx1 - cx2) * 3 + 1; - var tmp2y = (cy1 - cy2) * 3 + 1; - var i = frameIndex * 6; - var curves = this.curves; - curves[i] = cx1 * pre1 + tmp1x * pre2 + tmp2x * subdiv_step3; - curves[i + 1] = cy1 * pre1 + tmp1y * pre2 + tmp2y * subdiv_step3; - curves[i + 2] = tmp1x * pre4 + tmp2x * pre5; - curves[i + 3] = tmp1y * pre4 + tmp2y * pre5; - curves[i + 4] = tmp2x * pre5; - curves[i + 5] = tmp2y * pre5; - }, - getCurvePercent: function (frameIndex, percent) { - percent = percent < 0 ? 0 : (percent > 1 ? 1 : percent); - var curveIndex = frameIndex * 6; - var curves = this.curves; - var dfx = curves[curveIndex]; - if (!dfx/*LINEAR*/) return percent; - if (dfx == -1/*STEPPED*/) return 0; - var dfy = curves[curveIndex + 1]; - var ddfx = curves[curveIndex + 2]; - var ddfy = curves[curveIndex + 3]; - var dddfx = curves[curveIndex + 4]; - var dddfy = curves[curveIndex + 5]; - var x = dfx, y = dfy; - var i = 10/*BEZIER_SEGMENTS*/ - 2; - while (true) { - if (x >= percent) { - var lastX = x - dfx; - var lastY = y - dfy; - return lastY + (y - lastY) * (percent - lastX) / (x - lastX); - } - if (i == 0) break; - i--; - dfx += ddfx; - dfy += ddfy; - ddfx += dddfx; - ddfy += dddfy; - x += dfx; - y += dfy; - } - return y + (1 - y) * (percent - x) / (1 - x); // Last point is 1,1. - } -}; - -spine.RotateTimeline = function (frameCount) { - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, angle, ... - this.frames.length = frameCount * 2; -}; -spine.RotateTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 2; - }, - setFrame: function (frameIndex, time, angle) { - frameIndex *= 2; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = angle; - }, - apply: function (skeleton, time, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var bone = skeleton.bones[this.boneIndex]; - - if (time >= frames[frames.length - 2]) { // Time is after last frame. - var amount = bone.data.rotation + frames[frames.length - 1] - bone.rotation; - while (amount > 180) - amount -= 360; - while (amount < -180) - amount += 360; - bone.rotation += amount * alpha; - return; - } - - // Interpolate between the last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 2); - var lastFrameValue = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 2/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 2 - 1, percent); - - var amount = frames[frameIndex + 1/*FRAME_VALUE*/] - lastFrameValue; - while (amount > 180) - amount -= 360; - while (amount < -180) - amount += 360; - amount = bone.data.rotation + (lastFrameValue + amount * percent) - bone.rotation; - while (amount > 180) - amount -= 360; - while (amount < -180) - amount += 360; - bone.rotation += amount * alpha; - } -}; - -spine.TranslateTimeline = function (frameCount) { - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, x, y, ... - this.frames.length = frameCount * 3; -}; -spine.TranslateTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 3; - }, - setFrame: function (frameIndex, time, x, y) { - frameIndex *= 3; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = x; - this.frames[frameIndex + 2] = y; - }, - apply: function (skeleton, time, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var bone = skeleton.bones[this.boneIndex]; - - if (time >= frames[frames.length - 3]) { // Time is after last frame. - bone.x += (bone.data.x + frames[frames.length - 2] - bone.x) * alpha; - bone.y += (bone.data.y + frames[frames.length - 1] - bone.y) * alpha; - return; - } - - // Interpolate between the last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 3); - var lastFrameX = frames[frameIndex - 2]; - var lastFrameY = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); - - bone.x += (bone.data.x + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.x) * alpha; - bone.y += (bone.data.y + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.y) * alpha; - } -}; - -spine.ScaleTimeline = function (frameCount) { - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, x, y, ... - this.frames.length = frameCount * 3; -}; -spine.ScaleTimeline.prototype = { - boneIndex: 0, - getFrameCount: function () { - return this.frames.length / 3; - }, - setFrame: function (frameIndex, time, x, y) { - frameIndex *= 3; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = x; - this.frames[frameIndex + 2] = y; - }, - apply: function (skeleton, time, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var bone = skeleton.bones[this.boneIndex]; - - if (time >= frames[frames.length - 3]) { // Time is after last frame. - bone.scaleX += (bone.data.scaleX - 1 + frames[frames.length - 2] - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY - 1 + frames[frames.length - 1] - bone.scaleY) * alpha; - return; - } - - // Interpolate between the last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 3); - var lastFrameX = frames[frameIndex - 2]; - var lastFrameY = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex + -3/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 3 - 1, percent); - - bone.scaleX += (bone.data.scaleX - 1 + lastFrameX + (frames[frameIndex + 1/*FRAME_X*/] - lastFrameX) * percent - bone.scaleX) * alpha; - bone.scaleY += (bone.data.scaleY - 1 + lastFrameY + (frames[frameIndex + 2/*FRAME_Y*/] - lastFrameY) * percent - bone.scaleY) * alpha; - } -}; - -spine.ColorTimeline = function (frameCount) { - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, r, g, b, a, ... - this.frames.length = frameCount * 5; -}; -spine.ColorTimeline.prototype = { - slotIndex: 0, - getFrameCount: function () { - return this.frames.length / 2; - }, - setFrame: function (frameIndex, time, x, y) { - frameIndex *= 5; - this.frames[frameIndex] = time; - this.frames[frameIndex + 1] = r; - this.frames[frameIndex + 2] = g; - this.frames[frameIndex + 3] = b; - this.frames[frameIndex + 4] = a; - }, - apply: function (skeleton, time, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var slot = skeleton.slots[this.slotIndex]; - - if (time >= frames[frames.length - 5]) { // Time is after last frame. - var i = frames.length - 1; - slot.r = frames[i - 3]; - slot.g = frames[i - 2]; - slot.b = frames[i - 1]; - slot.a = frames[i]; - return; - } - - // Interpolate between the last frame and the current frame. - var frameIndex = spine.binarySearch(frames, time, 5); - var lastFrameR = frames[frameIndex - 4]; - var lastFrameG = frames[frameIndex - 3]; - var lastFrameB = frames[frameIndex - 2]; - var lastFrameA = frames[frameIndex - 1]; - var frameTime = frames[frameIndex]; - var percent = 1 - (time - frameTime) / (frames[frameIndex - 5/*LAST_FRAME_TIME*/] - frameTime); - percent = this.curves.getCurvePercent(frameIndex / 5 - 1, percent); - - var r = lastFrameR + (frames[frameIndex + 1/*FRAME_R*/] - lastFrameR) * percent; - var g = lastFrameG + (frames[frameIndex + 2/*FRAME_G*/] - lastFrameG) * percent; - var b = lastFrameB + (frames[frameIndex + 3/*FRAME_B*/] - lastFrameB) * percent; - var a = lastFrameA + (frames[frameIndex + 4/*FRAME_A*/] - lastFrameA) * percent; - if (alpha < 1) { - slot.r += (r - slot.r) * alpha; - slot.g += (g - slot.g) * alpha; - slot.b += (b - slot.b) * alpha; - slot.a += (a - slot.a) * alpha; - } else { - slot.r = r; - slot.g = g; - slot.b = b; - slot.a = a; - } - } -}; - -spine.AttachmentTimeline = function (frameCount) { - this.curves = new spine.Curves(frameCount); - this.frames = []; // time, ... - this.frames.length = frameCount; - this.attachmentNames = []; // time, ... - this.attachmentNames.length = frameCount; -}; -spine.AttachmentTimeline.prototype = { - slotIndex: 0, - getFrameCount: function () { - return this.frames.length; - }, - setFrame: function (frameIndex, time, attachmentName) { - this.frames[frameIndex] = time; - this.attachmentNames[frameIndex] = attachmentName; - }, - apply: function (skeleton, time, alpha) { - var frames = this.frames; - if (time < frames[0]) return; // Time is before first frame. - - var frameIndex; - if (time >= frames[frames.length - 1]) // Time is after last frame. - frameIndex = frames.length - 1; - else - frameIndex = spine.binarySearch(frames, time, 1) - 1; - - var attachmentName = this.attachmentNames[frameIndex]; - skeleton.slots[this.slotIndex].setAttachment(!attachmentName ? null : skeleton.getAttachmentBySlotIndex(this.slotIndex, attachmentName)); - } -}; - -spine.SkeletonData = function () { - this.bones = []; - this.slots = []; - this.skins = []; - this.animations = []; -}; -spine.SkeletonData.prototype = { - defaultSkin: null, - /** @return May be null. */ - findBone: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].name == boneName) return bones[i]; - return null; - }, - /** @return -1 if the bone was not found. */ - findBoneIndex: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].name == boneName) return i; - return -1; - }, - /** @return May be null. */ - findSlot: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) { - if (slots[i].name == slotName) return slot[i]; - } - return null; - }, - /** @return -1 if the bone was not found. */ - findSlotIndex: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].name == slotName) return i; - return -1; - }, - /** @return May be null. */ - findSkin: function (skinName) { - var skins = this.skins; - for (var i = 0, n = skins.length; i < n; i++) - if (skins[i].name == skinName) return skins[i]; - return null; - }, - /** @return May be null. */ - findAnimation: function (animationName) { - var animations = this.animations; - for (var i = 0, n = animations.length; i < n; i++) - if (animations[i].name == animationName) return animations[i]; - return null; - } -}; - -spine.Skeleton = function (skeletonData) { - this.data = skeletonData; - - this.bones = []; - for (var i = 0, n = skeletonData.bones.length; i < n; i++) { - var boneData = skeletonData.bones[i]; - var parent = !boneData.parent ? null : this.bones[skeletonData.bones.indexOf(boneData.parent)]; - this.bones.push(new spine.Bone(boneData, parent)); - } - - this.slots = []; - this.drawOrder = []; - for (var i = 0, n = skeletonData.slots.length; i < n; i++) { - var slotData = skeletonData.slots[i]; - var bone = this.bones[skeletonData.bones.indexOf(slotData.boneData)]; - var slot = new spine.Slot(slotData, this, bone); - this.slots.push(slot); - this.drawOrder.push(slot); - } -}; -spine.Skeleton.prototype = { - x: 0, y: 0, - skin: null, - r: 1, g: 1, b: 1, a: 1, - time: 0, - flipX: false, flipY: false, - /** Updates the world transform for each bone. */ - updateWorldTransform: function () { - var flipX = this.flipX; - var flipY = this.flipY; - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].updateWorldTransform(flipX, flipY); - }, - /** Sets the bones and slots to their setup pose values. */ - setToSetupPose: function () { - this.setBonesToSetupPose(); - this.setSlotsToSetupPose(); - }, - setBonesToSetupPose: function () { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - bones[i].setToSetupPose(); - }, - setSlotsToSetupPose: function () { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - slots[i].setToSetupPose(i); - }, - /** @return May return null. */ - getRootBone: function () { - return this.bones.length == 0 ? null : this.bones[0]; - }, - /** @return May be null. */ - findBone: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].data.name == boneName) return bones[i]; - return null; - }, - /** @return -1 if the bone was not found. */ - findBoneIndex: function (boneName) { - var bones = this.bones; - for (var i = 0, n = bones.length; i < n; i++) - if (bones[i].data.name == boneName) return i; - return -1; - }, - /** @return May be null. */ - findSlot: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].data.name == slotName) return slots[i]; - return null; - }, - /** @return -1 if the bone was not found. */ - findSlotIndex: function (slotName) { - var slots = this.slots; - for (var i = 0, n = slots.length; i < n; i++) - if (slots[i].data.name == slotName) return i; - return -1; - }, - setSkinByName: function (skinName) { - var skin = this.data.findSkin(skinName); - if (!skin) throw "Skin not found: " + skinName; - this.setSkin(skin); - }, - /** Sets the skin used to look up attachments not found in the {@link SkeletonData#getDefaultSkin() default skin}. Attachments - * from the new skin are attached if the corresponding attachment from the old skin was attached. - * @param newSkin May be null. */ - setSkin: function (newSkin) { - if (this.skin && newSkin) newSkin._attachAll(this, this.skin); - this.skin = newSkin; - }, - /** @return May be null. */ - getAttachmentBySlotName: function (slotName, attachmentName) { - return this.getAttachmentBySlotIndex(this.data.findSlotIndex(slotName), attachmentName); - }, - /** @return May be null. */ - getAttachmentBySlotIndex: function (slotIndex, attachmentName) { - if (this.skin) { - var attachment = this.skin.getAttachment(slotIndex, attachmentName); - if (attachment) return attachment; - } - if (this.data.defaultSkin) return this.data.defaultSkin.getAttachment(slotIndex, attachmentName); - return null; - }, - /** @param attachmentName May be null. */ - setAttachment: function (slotName, attachmentName) { - var slots = this.slots; - for (var i = 0, n = slots.size; i < n; i++) { - var slot = slots[i]; - if (slot.data.name == slotName) { - var attachment = null; - if (attachmentName) { - attachment = this.getAttachment(i, attachmentName); - if (attachment == null) throw "Attachment not found: " + attachmentName + ", for slot: " + slotName; - } - slot.setAttachment(attachment); - return; - } - } - throw "Slot not found: " + slotName; - }, - update: function (delta) { - time += delta; - } -}; - -spine.AttachmentType = { - region: 0 -}; - -spine.RegionAttachment = function () { - this.offset = []; - this.offset.length = 8; - this.uvs = []; - this.uvs.length = 8; -}; -spine.RegionAttachment.prototype = { - x: 0, y: 0, - rotation: 0, - scaleX: 1, scaleY: 1, - width: 0, height: 0, - rendererObject: null, - regionOffsetX: 0, regionOffsetY: 0, - regionWidth: 0, regionHeight: 0, - regionOriginalWidth: 0, regionOriginalHeight: 0, - setUVs: function (u, v, u2, v2, rotate) { - var uvs = this.uvs; - if (rotate) { - uvs[2/*X2*/] = u; - uvs[3/*Y2*/] = v2; - uvs[4/*X3*/] = u; - uvs[5/*Y3*/] = v; - uvs[6/*X4*/] = u2; - uvs[7/*Y4*/] = v; - uvs[0/*X1*/] = u2; - uvs[1/*Y1*/] = v2; - } else { - uvs[0/*X1*/] = u; - uvs[1/*Y1*/] = v2; - uvs[2/*X2*/] = u; - uvs[3/*Y2*/] = v; - uvs[4/*X3*/] = u2; - uvs[5/*Y3*/] = v; - uvs[6/*X4*/] = u2; - uvs[7/*Y4*/] = v2; - } - }, - updateOffset: function () { - var regionScaleX = this.width / this.regionOriginalWidth * this.scaleX; - var regionScaleY = this.height / this.regionOriginalHeight * this.scaleY; - var localX = -this.width / 2 * this.scaleX + this.regionOffsetX * regionScaleX; - var localY = -this.height / 2 * this.scaleY + this.regionOffsetY * regionScaleY; - var localX2 = localX + this.regionWidth * regionScaleX; - var localY2 = localY + this.regionHeight * regionScaleY; - var radians = this.rotation * Math.PI / 180; - var cos = Math.cos(radians); - var sin = Math.sin(radians); - var localXCos = localX * cos + this.x; - var localXSin = localX * sin; - var localYCos = localY * cos + this.y; - var localYSin = localY * sin; - var localX2Cos = localX2 * cos + this.x; - var localX2Sin = localX2 * sin; - var localY2Cos = localY2 * cos + this.y; - var localY2Sin = localY2 * sin; - var offset = this.offset; - offset[0/*X1*/] = localXCos - localYSin; - offset[1/*Y1*/] = localYCos + localXSin; - offset[2/*X2*/] = localXCos - localY2Sin; - offset[3/*Y2*/] = localY2Cos + localXSin; - offset[4/*X3*/] = localX2Cos - localY2Sin; - offset[5/*Y3*/] = localY2Cos + localX2Sin; - offset[6/*X4*/] = localX2Cos - localYSin; - offset[7/*Y4*/] = localYCos + localX2Sin; - }, - computeVertices: function (x, y, bone, vertices) { - x += bone.worldX; - y += bone.worldY; - var m00 = bone.m00; - var m01 = bone.m01; - var m10 = bone.m10; - var m11 = bone.m11; - var offset = this.offset; - vertices[0/*X1*/] = offset[0/*X1*/] * m00 + offset[1/*Y1*/] * m01 + x; - vertices[1/*Y1*/] = offset[0/*X1*/] * m10 + offset[1/*Y1*/] * m11 + y; - vertices[2/*X2*/] = offset[2/*X2*/] * m00 + offset[3/*Y2*/] * m01 + x; - vertices[3/*Y2*/] = offset[2/*X2*/] * m10 + offset[3/*Y2*/] * m11 + y; - vertices[4/*X3*/] = offset[4/*X3*/] * m00 + offset[5/*X3*/] * m01 + x; - vertices[5/*X3*/] = offset[4/*X3*/] * m10 + offset[5/*X3*/] * m11 + y; - vertices[6/*X4*/] = offset[6/*X4*/] * m00 + offset[7/*Y4*/] * m01 + x; - vertices[7/*Y4*/] = offset[6/*X4*/] * m10 + offset[7/*Y4*/] * m11 + y; - } -} - -spine.AnimationStateData = function (skeletonData) { - this.skeletonData = skeletonData; - this.animationToMixTime = {}; -}; -spine.AnimationStateData.prototype = { - defaultMix: 0, - setMixByName: function (fromName, toName, duration) { - var from = this.skeletonData.findAnimation(fromName); - if (!from) throw "Animation not found: " + fromName; - var to = this.skeletonData.findAnimation(toName); - if (!to) throw "Animation not found: " + toName; - this.setMix(from, to, duration); - }, - setMix: function (from, to, duration) { - this.animationToMixTime[from.name + ":" + to.name] = duration; - }, - getMix: function (from, to) { - var time = this.animationToMixTime[from.name + ":" + to.name]; - return time ? time : this.defaultMix; - } -}; - -spine.AnimationState = function (stateData) { - this.data = stateData; - this.queue = []; -}; -spine.AnimationState.prototype = { - current: null, - previous: null, - currentTime: 0, - previousTime: 0, - currentLoop: false, - previousLoop: false, - mixTime: 0, - mixDuration: 0, - update: function (delta) { - this.currentTime += delta; - this.previousTime += delta; - this.mixTime += delta; - - if (this.queue.length > 0) { - var entry = this.queue[0]; - if (this.currentTime >= entry.delay) { - this._setAnimation(entry.animation, entry.loop); - this.queue.shift(); - } - } - }, - apply: function (skeleton) { - if (!this.current) return; - if (this.previous) { - this.previous.apply(skeleton, this.previousTime, this.previousLoop); - var alpha = this.mixTime / this.mixDuration; - if (alpha >= 1) { - alpha = 1; - this.previous = null; - } - this.current.mix(skeleton, this.currentTime, this.currentLoop, alpha); - } else - this.current.apply(skeleton, this.currentTime, this.currentLoop); - }, - clearAnimation: function () { - this.previous = null; - this.current = null; - this.queue.length = 0; - }, - _setAnimation: function (animation, loop) { - this.previous = null; - if (animation && this.current) { - this.mixDuration = this.data.getMix(this.current, animation); - if (this.mixDuration > 0) { - this.mixTime = 0; - this.previous = this.current; - this.previousTime = this.currentTime; - this.previousLoop = this.currentLoop; - } - } - this.current = animation; - this.currentLoop = loop; - this.currentTime = 0; - }, - /** @see #setAnimation(Animation, Boolean) */ - setAnimationByName: function (animationName, loop) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) throw "Animation not found: " + animationName; - this.setAnimation(animation, loop); - }, - /** Set the current animation. Any queued animations are cleared and the current animation time is set to 0. - * @param animation May be null. */ - setAnimation: function (animation, loop) { - this.queue.length = 0; - this._setAnimation(animation, loop); - }, - /** @see #addAnimation(Animation, Boolean, Number) */ - addAnimationByName: function (animationName, loop, delay) { - var animation = this.data.skeletonData.findAnimation(animationName); - if (!animation) throw "Animation not found: " + animationName; - this.addAnimation(animation, loop, delay); - }, - /** Adds an animation to be played delay seconds after the current or last queued animation. - * @param delay May be <= 0 to use duration of previous animation minus any mix duration plus the negative delay. */ - addAnimation: function (animation, loop, delay) { - var entry = {}; - entry.animation = animation; - entry.loop = loop; - - if (!delay || delay <= 0) { - var previousAnimation = this.queue.length == 0 ? this.current : this.queue[this.queue.length - 1].animation; - if (previousAnimation != null) - delay = previousAnimation.duration - this.data.getMix(previousAnimation, animation) + (delay || 0); - else - delay = 0; - } - entry.delay = delay; - - this.queue.push(entry); - }, - /** Returns true if no animation is set or if the current time is greater than the animation duration, regardless of looping. */ - isComplete: function () { - return !this.current || this.currentTime >= this.current.duration; - } -}; - -spine.SkeletonJson = function (attachmentLoader) { - this.attachmentLoader = attachmentLoader; -}; -spine.SkeletonJson.prototype = { - scale: 1, - readSkeletonData: function (root) { - var skeletonData = new spine.SkeletonData(); - - // Bones. - var bones = root["bones"]; - for (var i = 0, n = bones.length; i < n; i++) { - var boneMap = bones[i]; - var parent = null; - if (boneMap["parent"]) { - parent = skeletonData.findBone(boneMap["parent"]); - if (!parent) throw "Parent bone not found: " + boneMap["parent"]; - } - var boneData = new spine.BoneData(boneMap["name"], parent); - boneData.length = (boneMap["length"] || 0) * this.scale; - boneData.x = (boneMap["x"] || 0) * this.scale; - boneData.y = (boneMap["y"] || 0) * this.scale; - boneData.rotation = (boneMap["rotation"] || 0); - boneData.scaleX = boneMap["scaleX"] || 1; - boneData.scaleY = boneMap["scaleY"] || 1; - skeletonData.bones.push(boneData); - } - - // Slots. - var slots = root["slots"]; - for (var i = 0, n = slots.length; i < n; i++) { - var slotMap = slots[i]; - var boneData = skeletonData.findBone(slotMap["bone"]); - if (!boneData) throw "Slot bone not found: " + slotMap["bone"]; - var slotData = new spine.SlotData(slotMap["name"], boneData); - - var color = slotMap["color"]; - if (color) { - slotData.r = spine.SkeletonJson.toColor(color, 0); - slotData.g = spine.SkeletonJson.toColor(color, 1); - slotData.b = spine.SkeletonJson.toColor(color, 2); - slotData.a = spine.SkeletonJson.toColor(color, 3); - } - - slotData.attachmentName = slotMap["attachment"]; - - skeletonData.slots.push(slotData); - } - - // Skins. - var skins = root["skins"]; - for (var skinName in skins) { - if (!skins.hasOwnProperty(skinName)) continue; - var skinMap = skins[skinName]; - var skin = new spine.Skin(skinName); - for (var slotName in skinMap) { - if (!skinMap.hasOwnProperty(slotName)) continue; - var slotIndex = skeletonData.findSlotIndex(slotName); - var slotEntry = skinMap[slotName]; - for (var attachmentName in slotEntry) { - if (!slotEntry.hasOwnProperty(attachmentName)) continue; - var attachment = this.readAttachment(skin, attachmentName, slotEntry[attachmentName]); - if (attachment != null) skin.addAttachment(slotIndex, attachmentName, attachment); - } - } - skeletonData.skins.push(skin); - if (skin.name == "default") skeletonData.defaultSkin = skin; - } - - // Animations. - var animations = root["animations"]; - for (var animationName in animations) { - if (!animations.hasOwnProperty(animationName)) continue; - this.readAnimation(animationName, animations[animationName], skeletonData); - } - - return skeletonData; - }, - readAttachment: function (skin, name, map) { - name = map["name"] || name; - - var type = spine.AttachmentType[map["type"] || "region"]; - - if (type == spine.AttachmentType.region) { - var attachment = new spine.RegionAttachment(); - attachment.x = (map["x"] || 0) * this.scale; - attachment.y = (map["y"] || 0) * this.scale; - attachment.scaleX = map["scaleX"] || 1; - attachment.scaleY = map["scaleY"] || 1; - attachment.rotation = map["rotation"] || 0; - attachment.width = (map["width"] || 32) * this.scale; - attachment.height = (map["height"] || 32) * this.scale; - attachment.updateOffset(); - - attachment.rendererObject = {}; - attachment.rendererObject.name = name; - attachment.rendererObject.scale = {}; - attachment.rendererObject.scale.x = attachment.scaleX; - attachment.rendererObject.scale.y = attachment.scaleY; - attachment.rendererObject.rotation = -attachment.rotation * Math.PI / 180; - return attachment; - } - - throw "Unknown attachment type: " + type; - }, - - readAnimation: function (name, map, skeletonData) { - var timelines = []; - var duration = 0; - - var bones = map["bones"]; - for (var boneName in bones) { - if (!bones.hasOwnProperty(boneName)) continue; - var boneIndex = skeletonData.findBoneIndex(boneName); - if (boneIndex == -1) throw "Bone not found: " + boneName; - var boneMap = bones[boneName]; - - for (var timelineName in boneMap) { - if (!boneMap.hasOwnProperty(timelineName)) continue; - var values = boneMap[timelineName]; - if (timelineName == "rotate") { - var timeline = new spine.RotateTimeline(values.length); - timeline.boneIndex = boneIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - timeline.setFrame(frameIndex, valueMap["time"], valueMap["angle"]); - spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 2 - 2]); - - } else if (timelineName == "translate" || timelineName == "scale") { - var timeline; - var timelineScale = 1; - if (timelineName == "scale") - timeline = new spine.ScaleTimeline(values.length); - else { - timeline = new spine.TranslateTimeline(values.length); - timelineScale = this.scale; - } - timeline.boneIndex = boneIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - var x = (valueMap["x"] || 0) * timelineScale; - var y = (valueMap["y"] || 0) * timelineScale; - timeline.setFrame(frameIndex, valueMap["time"], x, y); - spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 3 - 3]); - - } else - throw "Invalid timeline type for a bone: " + timelineName + " (" + boneName + ")"; - } - } - var slots = map["slots"]; - for (var slotName in slots) { - if (!slots.hasOwnProperty(slotName)) continue; - var slotMap = slots[slotName]; - var slotIndex = skeletonData.findSlotIndex(slotName); - - for (var timelineName in slotMap) { - if (!slotMap.hasOwnProperty(timelineName)) continue; - var values = slotMap[timelineName]; - if (timelineName == "color") { - var timeline = new spine.ColorTimeline(values.length); - timeline.slotIndex = slotIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - var color = valueMap["color"]; - var r = spine.SkeletonJson.toColor(color, 0); - var g = spine.SkeletonJson.toColor(color, 1); - var b = spine.SkeletonJson.toColor(color, 2); - var a = spine.SkeletonJson.toColor(color, 3); - timeline.setFrame(frameIndex, valueMap["time"], r, g, b, a); - spine.SkeletonJson.readCurve(timeline, frameIndex, valueMap); - frameIndex++; - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() * 5 - 5]); - - } else if (timelineName == "attachment") { - var timeline = new spine.AttachmentTimeline(values.length); - timeline.slotIndex = slotIndex; - - var frameIndex = 0; - for (var i = 0, n = values.length; i < n; i++) { - var valueMap = values[i]; - timeline.setFrame(frameIndex++, valueMap["time"], valueMap["name"]); - } - timelines.push(timeline); - duration = Math.max(duration, timeline.frames[timeline.getFrameCount() - 1]); - - } else - throw "Invalid timeline type for a slot: " + timelineName + " (" + slotName + ")"; - } - } - skeletonData.animations.push(new spine.Animation(name, timelines, duration)); - } -}; -spine.SkeletonJson.readCurve = function (timeline, frameIndex, valueMap) { - var curve = valueMap["curve"]; - if (!curve) return; - if (curve == "stepped") - timeline.curves.setStepped(frameIndex); - else if (curve instanceof Array) - timeline.curves.setCurve(frameIndex, curve[0], curve[1], curve[2], curve[3]); -}; -spine.SkeletonJson.toColor = function (hexString, colorIndex) { - if (hexString.length != 8) throw "Color hexidecimal length must be 8, recieved: " + hexString; - return parseInt(hexString.substring(colorIndex * 2, 2), 16) / 255; -}; - -spine.Atlas = function (atlasText, textureLoader) { - this.textureLoader = textureLoader; - this.pages = []; - this.regions = []; - - var reader = new spine.AtlasReader(atlasText); - var tuple = []; - tuple.length = 4; - var page = null; - while (true) { - var line = reader.readLine(); - if (line == null) break; - line = reader.trim(line); - if (line.length == 0) - page = null; - else if (!page) { - page = new spine.AtlasPage(); - page.name = line; - - page.format = spine.Atlas.Format[reader.readValue()]; - - reader.readTuple(tuple); - page.minFilter = spine.Atlas.TextureFilter[tuple[0]]; - page.magFilter = spine.Atlas.TextureFilter[tuple[1]]; - - var direction = reader.readValue(); - page.uWrap = spine.Atlas.TextureWrap.clampToEdge; - page.vWrap = spine.Atlas.TextureWrap.clampToEdge; - if (direction == "x") - page.uWrap = spine.Atlas.TextureWrap.repeat; - else if (direction == "y") - page.vWrap = spine.Atlas.TextureWrap.repeat; - else if (direction == "xy") - page.uWrap = page.vWrap = spine.Atlas.TextureWrap.repeat; - - textureLoader.load(page, line); - - this.pages.push(page); - - } else { - var region = new spine.AtlasRegion(); - region.name = line; - region.page = page; - - region.rotate = reader.readValue() == "true"; - - reader.readTuple(tuple); - var x = parseInt(tuple[0]); - var y = parseInt(tuple[1]); - - reader.readTuple(tuple); - var width = parseInt(tuple[0]); - var height = parseInt(tuple[1]); - - region.u = x / page.width; - region.v = y / page.height; - if (region.rotate) { - region.u2 = (x + height) / page.width; - region.v2 = (y + width) / page.height; - } else { - region.u2 = (x + width) / page.width; - region.v2 = (y + height) / page.height; - } - region.x = x; - region.y = y; - region.width = Math.abs(width); - region.height = Math.abs(height); - - if (reader.readTuple(tuple) == 4) { // split is optional - region.splits = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])]; - - if (reader.readTuple(tuple) == 4) { // pad is optional, but only present with splits - region.pads = [parseInt(tuple[0]), parseInt(tuple[1]), parseInt(tuple[2]), parseInt(tuple[3])]; - - reader.readTuple(tuple); - } - } - - region.originalWidth = parseInt(tuple[0]); - region.originalHeight = parseInt(tuple[1]); - - reader.readTuple(tuple); - region.offsetX = parseInt(tuple[0]); - region.offsetY = parseInt(tuple[1]); - - region.index = parseInt(reader.readValue()); - - this.regions.push(region); - } - } -}; -spine.Atlas.prototype = { - findRegion: function (name) { - var regions = this.regions; - for (var i = 0, n = regions.length; i < n; i++) - if (regions[i].name == name) return regions[i]; - return null; - }, - dispose: function () { - var pages = this.pages; - for (var i = 0, n = pages.length; i < n; i++) - this.textureLoader.unload(pages[i].rendererObject); - }, - updateUVs: function (page) { - var regions = this.regions; - for (var i = 0, n = regions.length; i < n; i++) { - var region = regions[i]; - if (region.page != page) continue; - region.u = region.x / page.width; - region.v = region.y / page.height; - if (region.rotate) { - region.u2 = (region.x + region.height) / page.width; - region.v2 = (region.y + region.width) / page.height; - } else { - region.u2 = (region.x + region.width) / page.width; - region.v2 = (region.y + region.height) / page.height; - } - } - } -}; - -spine.Atlas.Format = { - alpha: 0, - intensity: 1, - luminanceAlpha: 2, - rgb565: 3, - rgba4444: 4, - rgb888: 5, - rgba8888: 6 -}; - -spine.Atlas.TextureFilter = { - nearest: 0, - linear: 1, - mipMap: 2, - mipMapNearestNearest: 3, - mipMapLinearNearest: 4, - mipMapNearestLinear: 5, - mipMapLinearLinear: 6 -}; - -spine.Atlas.TextureWrap = { - mirroredRepeat: 0, - clampToEdge: 1, - repeat: 2 -}; - -spine.AtlasPage = function () {}; -spine.AtlasPage.prototype = { - name: null, - format: null, - minFilter: null, - magFilter: null, - uWrap: null, - vWrap: null, - rendererObject: null, - width: 0, - height: 0 -}; - -spine.AtlasRegion = function () {}; -spine.AtlasRegion.prototype = { - page: null, - name: null, - x: 0, y: 0, - width: 0, height: 0, - u: 0, v: 0, u2: 0, v2: 0, - offsetX: 0, offsetY: 0, - originalWidth: 0, originalHeight: 0, - index: 0, - rotate: false, - splits: null, - pads: null, -}; - -spine.AtlasReader = function (text) { - this.lines = text.split(/\r\n|\r|\n/); -}; -spine.AtlasReader.prototype = { - index: 0, - trim: function (value) { - return value.replace(/^\s+|\s+$/g, ""); - }, - readLine: function () { - if (this.index >= this.lines.length) return null; - return this.lines[this.index++]; - }, - readValue: function () { - var line = this.readLine(); - var colon = line.indexOf(":"); - if (colon == -1) throw "Invalid line: " + line; - return this.trim(line.substring(colon + 1)); - }, - /** Returns the number of tuple values read (2 or 4). */ - readTuple: function (tuple) { - var line = this.readLine(); - var colon = line.indexOf(":"); - if (colon == -1) throw "Invalid line: " + line; - var i = 0, lastMatch= colon + 1; - for (; i < 3; i++) { - var comma = line.indexOf(",", lastMatch); - if (comma == -1) { - if (i == 0) throw "Invalid line: " + line; - break; - } - tuple[i] = this.trim(line.substr(lastMatch, comma - lastMatch)); - lastMatch = comma + 1; - } - tuple[i] = this.trim(line.substring(lastMatch)); - return i + 1; - } -} - -spine.AtlasAttachmentLoader = function (atlas) { - this.atlas = atlas; -} -spine.AtlasAttachmentLoader.prototype = { - newAttachment: function (skin, type, name) { - switch (type) { - case spine.AttachmentType.region: - var region = this.atlas.findRegion(name); - if (!region) throw "Region not found in atlas: " + name + " (" + type + ")"; - var attachment = new spine.RegionAttachment(name); - attachment.rendererObject = region; - attachment.setUVs(region.u, region.v, region.u2, region.v2, region.rotate); - attachment.regionOffsetX = region.offsetX; - attachment.regionOffsetY = region.offsetY; - attachment.regionWidth = region.width; - attachment.regionHeight = region.height; - attachment.regionOriginalWidth = region.originalWidth; - attachment.regionOriginalHeight = region.originalHeight; - return attachment; - } - throw "Unknown attachment type: " + type; - } -} - -PIXI.AnimCache = {}; -spine.Bone.yDown = true; diff --git a/src/pixi/extras/Strip.js b/src/pixi/extras/Strip.js index 857e4129..e7e18c58 100644 --- a/src/pixi/extras/Strip.js +++ b/src/pixi/extras/Strip.js @@ -4,66 +4,66 @@ PIXI.Strip = function(texture, width, height) { - PIXI.DisplayObjectContainer.call( this ); - this.texture = texture; - this.blendMode = PIXI.blendModes.NORMAL; + PIXI.DisplayObjectContainer.call( this ); + this.texture = texture; + this.blendMode = PIXI.blendModes.NORMAL; - try - { - this.uvs = new Float32Array([0, 1, - 1, 1, - 1, 0, 0,1]); + try + { + this.uvs = new Float32Array([0, 1, + 1, 1, + 1, 0, 0,1]); - this.verticies = new Float32Array([0, 0, - 0,0, - 0,0, 0, - 0, 0]); + this.verticies = new Float32Array([0, 0, + 0,0, + 0,0, 0, + 0, 0]); - this.colors = new Float32Array([1, 1, 1, 1]); + this.colors = new Float32Array([1, 1, 1, 1]); - this.indices = new Uint16Array([0, 1, 2, 3]); - } - catch(error) - { - this.uvs = [0, 1, - 1, 1, - 1, 0, 0,1]; + this.indices = new Uint16Array([0, 1, 2, 3]); + } + catch(error) + { + this.uvs = [0, 1, + 1, 1, + 1, 0, 0,1]; - this.verticies = [0, 0, - 0,0, - 0,0, 0, - 0, 0]; + this.verticies = [0, 0, + 0,0, + 0,0, 0, + 0, 0]; - this.colors = [1, 1, 1, 1]; + this.colors = [1, 1, 1, 1]; - this.indices = [0, 1, 2, 3]; - } + this.indices = [0, 1, 2, 3]; + } - /* - this.uvs = new Float32Array() - this.verticies = new Float32Array() - this.colors = new Float32Array() - this.indices = new Uint16Array() -*/ - this.width = width; - this.height = height; + /* + this.uvs = new Float32Array() + this.verticies = new Float32Array() + this.colors = new Float32Array() + this.indices = new Uint16Array() + */ + this.width = width; + this.height = height; - // load the texture! - if(texture.baseTexture.hasLoaded) - { - this.width = this.texture.frame.width; - this.height = this.texture.frame.height; - this.updateFrame = true; - } - else - { - this.onTextureUpdateBind = this.onTextureUpdate.bind(this); - this.texture.addEventListener( 'update', this.onTextureUpdateBind ); - } + // load the texture! + if(texture.baseTexture.hasLoaded) + { + this.width = this.texture.frame.width; + this.height = this.texture.frame.height; + this.updateFrame = true; + } + else + { + this.onTextureUpdateBind = this.onTextureUpdate.bind(this); + this.texture.addEventListener( 'update', this.onTextureUpdateBind ); + } - this.renderable = true; -} + this.renderable = true; +}; // constructor PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); @@ -71,19 +71,18 @@ PIXI.Strip.prototype.constructor = PIXI.Strip; PIXI.Strip.prototype.setTexture = function(texture) { - //TODO SET THE TEXTURES - //TODO VISIBILITY + //TODO SET THE TEXTURES + //TODO VISIBILITY - // stop current texture - this.texture = texture; - this.width = texture.frame.width; - this.height = texture.frame.height; - this.updateFrame = true; -} + // stop current texture + this.texture = texture; + this.width = texture.frame.width; + this.height = texture.frame.height; + this.updateFrame = true; +}; -PIXI.Strip.prototype.onTextureUpdate = function(event) +PIXI.Strip.prototype.onTextureUpdate = function() { - this.updateFrame = true; -} + this.updateFrame = true; +}; // some helper functions.. - diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js index be2e93fa..821d7ca5 100644 --- a/src/pixi/extras/TilingSprite.js +++ b/src/pixi/extras/TilingSprite.js @@ -14,52 +14,52 @@ */ PIXI.TilingSprite = function(texture, width, height) { - PIXI.DisplayObjectContainer.call( this ); + PIXI.DisplayObjectContainer.call( this ); - /** - * The texture that the sprite is using - * - * @property texture - * @type Texture - */ - this.texture = texture; + /** + * The texture that the sprite is using + * + * @property texture + * @type Texture + */ + this.texture = texture; - /** - * The width of the tiling sprite - * - * @property width - * @type Number - */ - this.width = width; + /** + * The width of the tiling sprite + * + * @property width + * @type Number + */ + this.width = width; - /** - * The height of the tiling sprite - * - * @property height - * @type Number - */ - this.height = height; + /** + * The height of the tiling sprite + * + * @property height + * @type Number + */ + this.height = height; - /** - * The scaling of the image that is being tiled - * - * @property tileScale - * @type Point - */ - this.tileScale = new PIXI.Point(1,1); + /** + * The scaling of the image that is being tiled + * + * @property tileScale + * @type Point + */ + this.tileScale = new PIXI.Point(1,1); - /** - * The offset position of the image that is being tiled - * - * @property tilePosition - * @type Point - */ - this.tilePosition = new PIXI.Point(0,0); + /** + * The offset position of the image that is being tiled + * + * @property tilePosition + * @type Point + */ + this.tilePosition = new PIXI.Point(0,0); - this.renderable = true; + this.renderable = true; - this.blendMode = PIXI.blendModes.NORMAL -} + this.blendMode = PIXI.blendModes.NORMAL; +}; // constructor PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); @@ -73,13 +73,13 @@ PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite; */ PIXI.TilingSprite.prototype.setTexture = function(texture) { - //TODO SET THE TEXTURES - //TODO VISIBILITY + //TODO SET THE TEXTURES + //TODO VISIBILITY - // stop current texture - this.texture = texture; - this.updateFrame = true; -} + // stop current texture + this.texture = texture; + this.updateFrame = true; +}; /** * When the texture is updated, this event will fire to update the frame @@ -88,8 +88,7 @@ PIXI.TilingSprite.prototype.setTexture = function(texture) * @param event * @private */ -PIXI.TilingSprite.prototype.onTextureUpdate = function(event) +PIXI.TilingSprite.prototype.onTextureUpdate = function() { - this.updateFrame = true; -} - + this.updateFrame = true; +}; diff --git a/src/pixi/filters/AbstractFilter.js b/src/pixi/filters/AbstractFilter.js index 4e40c653..43665de4 100644 --- a/src/pixi/filters/AbstractFilter.js +++ b/src/pixi/filters/AbstractFilter.js @@ -2,36 +2,34 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** * This is the base class for creating a pixi.js filter. Currently only webGL supports filters. * If you want to make a custom filter this should be your base class. * @class AbstractFilter * @constructor * @param fragmentSrc - * @param uniforms + * @param uniforms */ PIXI.AbstractFilter = function(fragmentSrc, uniforms) { - /** - * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion. - * For example the blur filter has two passes blurX and blurY. - * @property passes - * @type Array an array of filter objects - * @private - */ - this.passes = [this]; + /** + * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion. + * For example the blur filter has two passes blurX and blurY. + * @property passes + * @type Array an array of filter objects + * @private + */ + this.passes = [this]; - this.dirty = true; - this.padding = 0; + this.dirty = true; + this.padding = 0; - /** - @property uniforms - @private - */ - this.uniforms = uniforms || {}; - - this.fragmentSrc = fragmentSrc || []; -} + /** + @property uniforms + @private + */ + this.uniforms = uniforms || {}; + this.fragmentSrc = fragmentSrc || []; +}; diff --git a/src/pixi/filters/BlurFilter.js b/src/pixi/filters/BlurFilter.js index 43caa0c4..5f89bff8 100644 --- a/src/pixi/filters/BlurFilter.js +++ b/src/pixi/filters/BlurFilter.js @@ -2,10 +2,9 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** - * - * The BlurFilter applies a Gaussian blur to an object. + * + * The BlurFilter applies a Gaussian blur to an object. * The strength of the blur can be set for x- and y-axis separately (always relative to the stage). * * @class BlurFilter @@ -13,13 +12,11 @@ */ PIXI.BlurFilter = function() { - - this.blurXFilter = new PIXI.BlurXFilter(); - this.blurYFilter = new PIXI.BlurYFilter(); + this.blurXFilter = new PIXI.BlurXFilter(); + this.blurYFilter = new PIXI.BlurYFilter(); - this.passes =[this.blurXFilter, this.blurYFilter]; - -} + this.passes =[this.blurXFilter, this.blurYFilter]; +}; /** * Sets the strength of both the blurX and blurY properties simultaneously @@ -33,7 +30,7 @@ Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', { return this.blurXFilter.blur; }, set: function(value) { - this.blurXFilter.blur = this.blurYFilter.blur = value; + this.blurXFilter.blur = this.blurYFilter.blur = value; } }); @@ -49,7 +46,7 @@ Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', { return this.blurXFilter.blur; }, set: function(value) { - this.blurXFilter.blur = value; + this.blurXFilter.blur = value; } }); @@ -65,6 +62,6 @@ Object.defineProperty(PIXI.BlurFilter.prototype, 'blurY', { return this.blurYFilter.blur; }, set: function(value) { - this.blurYFilter.blur = value; + this.blurYFilter.blur = value; } }); diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js index 38a99b46..6e7be332 100644 --- a/src/pixi/filters/BlurXFilter.js +++ b/src/pixi/filters/BlurXFilter.js @@ -2,55 +2,52 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - - PIXI.BlurXFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1/512}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float blur;", - "uniform sampler2D uSampler;", - "void main(void) {", - "vec4 sum = vec4(0.0);", + PIXI.AbstractFilter.call( this ); - "sum += texture2D(uSampler, vec2(vTextureCoord.x - 4.0*blur, vTextureCoord.y)) * 0.05;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x - 3.0*blur, vTextureCoord.y)) * 0.09;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x - 2.0*blur, vTextureCoord.y)) * 0.12;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x - blur, vTextureCoord.y)) * 0.15;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x + blur, vTextureCoord.y)) * 0.15;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x + 2.0*blur, vTextureCoord.y)) * 0.12;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x + 3.0*blur, vTextureCoord.y)) * 0.09;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x + 4.0*blur, vTextureCoord.y)) * 0.05;", - - "gl_FragColor = sum;", + this.passes = [this]; - "}" - ]; -} + // set the uniforms + this.uniforms = { + blur: {type: '1f', value: 1/512}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float blur;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' vec4 sum = vec4(0.0);', + + ' sum += texture2D(uSampler, vec2(vTextureCoord.x - 4.0*blur, vTextureCoord.y)) * 0.05;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x - 3.0*blur, vTextureCoord.y)) * 0.09;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x - 2.0*blur, vTextureCoord.y)) * 0.12;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x - blur, vTextureCoord.y)) * 0.15;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x + blur, vTextureCoord.y)) * 0.15;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x + 2.0*blur, vTextureCoord.y)) * 0.12;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x + 3.0*blur, vTextureCoord.y)) * 0.09;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x + 4.0*blur, vTextureCoord.y)) * 0.05;', + + ' gl_FragColor = sum;', + '}' + ]; +}; PIXI.BlurXFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.BlurXFilter.prototype.constructor = PIXI.BlurXFilter; - Object.defineProperty(PIXI.BlurXFilter.prototype, 'blur', { get: function() { return this.uniforms.blur.value / (1/7000); }, set: function(value) { - - this.dirty = true; - this.uniforms.blur.value = (1/7000) * value; + + this.dirty = true; + this.uniforms.blur.value = (1/7000) * value; } }); diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js index d472f79c..99829fb7 100644 --- a/src/pixi/filters/BlurYFilter.js +++ b/src/pixi/filters/BlurYFilter.js @@ -2,43 +2,41 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - - PIXI.BlurYFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1/512}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float blur;", - "uniform sampler2D uSampler;", - "void main(void) {", - "vec4 sum = vec4(0.0);", + PIXI.AbstractFilter.call( this ); - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09;", - "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05;", - - "gl_FragColor = sum;", + this.passes = [this]; - "}" - ]; -} + // set the uniforms + this.uniforms = { + blur: {type: '1f', value: 1/512}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float blur;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' vec4 sum = vec4(0.0);', + + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09;', + ' sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05;', + + ' gl_FragColor = sum;', + '}' + ]; +}; PIXI.BlurYFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.BlurYFilter.prototype.constructor = PIXI.BlurYFilter; @@ -48,7 +46,7 @@ Object.defineProperty(PIXI.BlurYFilter.prototype, 'blur', { return this.uniforms.blur.value / (1/7000); }, set: function(value) { - //this.padding = value; - this.uniforms.blur.value = (1/7000) * value; + //this.padding = value; + this.uniforms.blur.value = (1/7000) * value; } }); diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js index 1386f8b2..122b6fbd 100644 --- a/src/pixi/filters/ColorMatrixFilter.js +++ b/src/pixi/filters/ColorMatrixFilter.js @@ -3,41 +3,41 @@ */ /** - * - * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA - * color and alpha values of every pixel on your displayObject to produce a result + * + * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA + * color and alpha values of every pixel on your displayObject to produce a result * with a new set of RGBA color and alpha values. Its pretty powerful! * @class ColorMatrixFilter * @contructor */ PIXI.ColorMatrixFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - matrix: {type: 'mat4', value: [1,0,0,0, - 0,1,0,0, - 0,0,1,0, - 0,0,0,1]}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float invert;", - "uniform mat4 matrix;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;", - "gl_FragColor = gl_FragColor * vColor;", - "}" - ]; - -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + matrix: {type: 'mat4', value: [1,0,0,0, + 0,1,0,0, + 0,0,1,0, + 0,0,0,1]}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float invert;', + 'uniform mat4 matrix;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;', + ' gl_FragColor = gl_FragColor * vColor;', + '}' + ]; +}; PIXI.ColorMatrixFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.ColorMatrixFilter.prototype.constructor = PIXI.ColorMatrixFilter; @@ -54,6 +54,6 @@ Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', { return this.uniforms.matrix.value; }, set: function(value) { - this.uniforms.matrix.value = value; + this.uniforms.matrix.value = value; } }); \ No newline at end of file diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js index 8039af84..c83c887b 100644 --- a/src/pixi/filters/ColorStepFilter.js +++ b/src/pixi/filters/ColorStepFilter.js @@ -2,37 +2,37 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** - * + * * This turns your displayObjects to black and white. * @class ColorStepFilter * @contructor */ PIXI.ColorStepFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - step: {type: '1f', value: 5}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D uSampler;", - "uniform float step;", - "void main(void) {", - "vec4 color = texture2D(uSampler, vTextureCoord);", - "color = floor(color * step) / step;", - "gl_FragColor = color * vColor;", - "}" - ]; -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + step: {type: '1f', value: 5}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform sampler2D uSampler;', + 'uniform float step;', + + 'void main(void) {', + ' vec4 color = texture2D(uSampler, vTextureCoord);', + ' color = floor(color * step) / step;', + ' gl_FragColor = color * vColor;', + '}' + ]; +}; PIXI.ColorStepFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.ColorStepFilter.prototype.constructor = PIXI.ColorStepFilter; @@ -46,6 +46,6 @@ Object.defineProperty(PIXI.ColorStepFilter.prototype, 'step', { return this.uniforms.step.value; }, set: function(value) { - this.uniforms.step.value = value; + this.uniforms.step.value = value; } }); diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js index 2d26715e..43f3c261 100644 --- a/src/pixi/filters/CrossHatchFilter.js +++ b/src/pixi/filters/CrossHatchFilter.js @@ -2,58 +2,55 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - - PIXI.CrossHatchFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1/512}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float blur;", - "uniform sampler2D uSampler;", - "void main(void) {", - - - " float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);", - " ", - " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);", - " ", - " if (lum < 1.00) {", - " if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {", - " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", - " }", - " }", - " ", - " if (lum < 0.75) {", - " if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {", - " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", - " }", - " }", - " ", - " if (lum < 0.50) {", - " if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {", - " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", - " }", - " }", - " ", - " if (lum < 0.3) {", - " if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {", - " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);", - " }", - " }", - "}" - ]; -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + blur: {type: '1f', value: 1 / 512}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float blur;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);', + + ' gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);', + + ' if (lum < 1.00) {', + ' if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {', + ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', + ' }', + ' }', + + ' if (lum < 0.75) {', + ' if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {', + ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', + ' }', + ' }', + + ' if (lum < 0.50) {', + ' if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {', + ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', + ' }', + ' }', + + ' if (lum < 0.3) {', + ' if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {', + ' gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);', + ' }', + ' }', + '}' + ]; +}; PIXI.CrossHatchFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.CrossHatchFilter.prototype.constructor = PIXI.BlurYFilter; @@ -63,7 +60,7 @@ Object.defineProperty(PIXI.CrossHatchFilter.prototype, 'blur', { return this.uniforms.blur.value / (1/7000); }, set: function(value) { - //this.padding = value; - this.uniforms.blur.value = (1/7000) * value; + //this.padding = value; + this.uniforms.blur.value = (1/7000) * value; } }); diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js index 5662731f..40af8703 100644 --- a/src/pixi/filters/DisplacementFilter.js +++ b/src/pixi/filters/DisplacementFilter.js @@ -2,10 +2,9 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** - * - * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object. + * + * The DisplacementFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object. * You can use this filter to apply all manor of crazy warping effects * Currently the r property of the texture is used offset the x and the g propery of the texture is used to offset the y. * @class DisplacementFilter @@ -14,80 +13,75 @@ */ PIXI.DisplacementFilter = function(texture) { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - texture.baseTexture._powerOf2 = true; + PIXI.AbstractFilter.call( this ); - // set the uniforms - //console.log() - this.uniforms = { - displacementMap: {type: 'sampler2D', value:texture}, - scale: {type: '2f', value:{x:30, y:30}}, - offset: {type: '2f', value:{x:0, y:0}}, - mapDimensions: {type: '2f', value:{x:1, y:5112}}, - dimensions: {type: '4fv', value:[0,0,0,0]} - }; - + this.passes = [this]; + texture.baseTexture._powerOf2 = true; - if(texture.baseTexture.hasLoaded) - { - this.uniforms.mapDimensions.value.x = texture.width; - this.uniforms.mapDimensions.value.y = texture.height; - } - else - { - this.boundLoadedFunction = this.onTextureLoaded.bind(this); + // set the uniforms + //console.log() + this.uniforms = { + displacementMap: {type: 'sampler2D', value:texture}, + scale: {type: '2f', value:{x:30, y:30}}, + offset: {type: '2f', value:{x:0, y:0}}, + mapDimensions: {type: '2f', value:{x:1, y:5112}}, + dimensions: {type: '4fv', value:[0,0,0,0]} + }; - texture.baseTexture.on("loaded", this.boundLoadedFunction); - } + if(texture.baseTexture.hasLoaded) + { + this.uniforms.mapDimensions.value.x = texture.width; + this.uniforms.mapDimensions.value.y = texture.height; + } + else + { + this.boundLoadedFunction = this.onTextureLoaded.bind(this); - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D displacementMap;", - "uniform sampler2D uSampler;", - "uniform vec2 scale;", - "uniform vec2 offset;", - "uniform vec4 dimensions;", - "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);", - // "const vec2 textureDimensions = vec2(750.0, 750.0);", - - "void main(void) {", - "vec2 mapCords = vTextureCoord.xy;", -// "mapCords -= ;", - "mapCords += (dimensions.zw + offset)/ dimensions.xy ;", - "mapCords.y *= -1.0;", - "mapCords.y += 1.0;", - "vec2 matSample = texture2D(displacementMap, mapCords).xy;", - "matSample -= 0.5;", - "matSample *= scale;", - "matSample /= mapDimensions;", - "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + matSample.x, vTextureCoord.y + matSample.y));", - "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb, 1.0);", - "vec2 cord = vTextureCoord;", - - //"gl_FragColor = texture2D(displacementMap, cord);", - "gl_FragColor = gl_FragColor * vColor;", - - "}" - ]; - -} + texture.baseTexture.on('loaded', this.boundLoadedFunction); + } + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform sampler2D displacementMap;', + 'uniform sampler2D uSampler;', + 'uniform vec2 scale;', + 'uniform vec2 offset;', + 'uniform vec4 dimensions;', + 'uniform vec2 mapDimensions;',// = vec2(256.0, 256.0);', + // 'const vec2 textureDimensions = vec2(750.0, 750.0);', + + 'void main(void) {', + ' vec2 mapCords = vTextureCoord.xy;', + //' mapCords -= ;', + ' mapCords += (dimensions.zw + offset)/ dimensions.xy ;', + ' mapCords.y *= -1.0;', + ' mapCords.y += 1.0;', + ' vec2 matSample = texture2D(displacementMap, mapCords).xy;', + ' matSample -= 0.5;', + ' matSample *= scale;', + ' matSample /= mapDimensions;', + ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + matSample.x, vTextureCoord.y + matSample.y));', + ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb, 1.0);', + ' vec2 cord = vTextureCoord;', + + //' gl_FragColor = texture2D(displacementMap, cord);', + ' gl_FragColor = gl_FragColor * vColor;', + '}' + ]; +}; PIXI.DisplacementFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.DisplacementFilter.prototype.constructor = PIXI.DisplacementFilter; PIXI.DisplacementFilter.prototype.onTextureLoaded = function() { - - this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width; - this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height; + this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width; + this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height; - this.uniforms.displacementMap.value.baseTexture.off("loaded", this.boundLoadedFunction) - -} + this.uniforms.displacementMap.value.baseTexture.off('loaded', this.boundLoadedFunction); +}; /** * The texture used for the displacemtent map * must be power of 2 texture at the moment @@ -100,7 +94,7 @@ Object.defineProperty(PIXI.DisplacementFilter.prototype, 'map', { return this.uniforms.displacementMap.value; }, set: function(value) { - this.uniforms.displacementMap.value = value; + this.uniforms.displacementMap.value = value; } }); @@ -115,7 +109,7 @@ Object.defineProperty(PIXI.DisplacementFilter.prototype, 'scale', { return this.uniforms.scale.value; }, set: function(value) { - this.uniforms.scale.value = value; + this.uniforms.scale.value = value; } }); @@ -130,6 +124,6 @@ Object.defineProperty(PIXI.DisplacementFilter.prototype, 'offset', { return this.uniforms.offset.value; }, set: function(value) { - this.uniforms.offset.value = value; + this.uniforms.offset.value = value; } -}); \ No newline at end of file +}); diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js index 6c59d4c4..7a684a13 100644 --- a/src/pixi/filters/DotScreenFilter.js +++ b/src/pixi/filters/DotScreenFilter.js @@ -4,57 +4,57 @@ */ /** - * - * This filter applies a pixlate effect making display objects appear "blocky" + * + * This filter applies a pixlate effect making display objects appear 'blocky' * @class PixelateFilter * @contructor */ PIXI.DotScreenFilter = function() { - PIXI.AbstractFilter.call( this ); + PIXI.AbstractFilter.call( this ); - this.passes = [this]; - - // set the uniforms - this.uniforms = { - scale: {type: '1f', value:1}, - angle: {type: '1f', value:5}, - dimensions: {type: '4fv', value:[0,0,0,0]} - }; + this.passes = [this]; - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform vec4 dimensions;", - "uniform sampler2D uSampler;", + // set the uniforms + this.uniforms = { + scale: {type: '1f', value:1}, + angle: {type: '1f', value:5}, + dimensions: {type: '4fv', value:[0,0,0,0]} + }; - "uniform float angle;", - "uniform float scale;", + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform vec4 dimensions;', + 'uniform sampler2D uSampler;', - "float pattern() {", - "float s = sin(angle), c = cos(angle);", - "vec2 tex = vTextureCoord * dimensions.xy;", - "vec2 point = vec2(", - "c * tex.x - s * tex.y,", - "s * tex.x + c * tex.y", - ") * scale;", - "return (sin(point.x) * sin(point.y)) * 4.0;", - "}", + 'uniform float angle;', + 'uniform float scale;', - "void main() {", - "vec4 color = texture2D(uSampler, vTextureCoord);", - "float average = (color.r + color.g + color.b) / 3.0;", - "gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);", - "}", - ]; -} + 'float pattern() {', + ' float s = sin(angle), c = cos(angle);', + ' vec2 tex = vTextureCoord * dimensions.xy;', + ' vec2 point = vec2(', + ' c * tex.x - s * tex.y,', + ' s * tex.x + c * tex.y', + ' ) * scale;', + ' return (sin(point.x) * sin(point.y)) * 4.0;', + '}', + + 'void main() {', + ' vec4 color = texture2D(uSampler, vTextureCoord);', + ' float average = (color.r + color.g + color.b) / 3.0;', + ' gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);', + '}' + ]; +}; PIXI.DotScreenFilter.prototype = Object.create( PIXI.DotScreenFilter.prototype ); PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter; /** - * + * * This describes the the scale * @property scale * @type Number @@ -64,13 +64,13 @@ Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', { return this.uniforms.scale.value; }, set: function(value) { - this.dirty = true; - this.uniforms.scale.value = value; + this.dirty = true; + this.uniforms.scale.value = value; } }); /** - * + * * This radius describes angle * @property angle * @type Number @@ -80,7 +80,7 @@ Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', { return this.uniforms.angle.value; }, set: function(value) { - this.dirty = true; - this.uniforms.angle.value = value; + this.dirty = true; + this.uniforms.angle.value = value; } }); \ No newline at end of file diff --git a/src/pixi/filters/FilterBlock.js b/src/pixi/filters/FilterBlock.js index bfcfdb77..3b6ab520 100644 --- a/src/pixi/filters/FilterBlock.js +++ b/src/pixi/filters/FilterBlock.js @@ -6,6 +6,6 @@ PIXI.FilterBlock = function() { - this.visible = true; - this.renderable = true; -} \ No newline at end of file + this.visible = true; + this.renderable = true; +}; diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js index 9b6bb61d..5065834a 100644 --- a/src/pixi/filters/GrayFilter.js +++ b/src/pixi/filters/GrayFilter.js @@ -2,37 +2,37 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** - * + * * This turns your displayObjects to black and white. * @class GrayFilter * @contructor */ PIXI.GrayFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - gray: {type: '1f', value: 1}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D uSampler;", - "uniform float gray;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord);", - "gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);", - "gl_FragColor = gl_FragColor * vColor;", - "}" - ]; -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + gray: {type: '1f', value: 1}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform sampler2D uSampler;', + 'uniform float gray;', + + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vTextureCoord);', + ' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);', + ' gl_FragColor = gl_FragColor * vColor;', + '}' + ]; +}; PIXI.GrayFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.GrayFilter.prototype.constructor = PIXI.GrayFilter; @@ -46,6 +46,6 @@ Object.defineProperty(PIXI.GrayFilter.prototype, 'gray', { return this.uniforms.gray.value; }, set: function(value) { - this.uniforms.gray.value = value; + this.uniforms.gray.value = value; } }); diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js index afd196e1..ac4393f9 100644 --- a/src/pixi/filters/InvertFilter.js +++ b/src/pixi/filters/InvertFilter.js @@ -3,37 +3,37 @@ */ /** - * + * * This inverts your displayObjects colors. * @class InvertFilter * @contructor */ PIXI.InvertFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - invert: {type: '1f', value: 1}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float invert;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord);", - "gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);", - //"gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;", - "gl_FragColor = gl_FragColor * vColor;", - "}" - ]; - -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + invert: {type: '1f', value: 1}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float invert;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vTextureCoord);', + ' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);', + //' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;', + ' gl_FragColor = gl_FragColor * vColor;', + '}' + ]; +}; PIXI.InvertFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.InvertFilter.prototype.constructor = PIXI.InvertFilter; @@ -47,6 +47,6 @@ Object.defineProperty(PIXI.InvertFilter.prototype, 'invert', { return this.uniforms.invert.value; }, set: function(value) { - this.uniforms.invert.value = value; + this.uniforms.invert.value = value; } -}); \ No newline at end of file +}); diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js index d2680158..e4320ebf 100644 --- a/src/pixi/filters/PixelateFilter.js +++ b/src/pixi/filters/PixelateFilter.js @@ -3,50 +3,49 @@ */ /** - * - * This filter applies a pixlate effect making display objects appear "blocky" + * + * This filter applies a pixlate effect making display objects appear 'blocky' * @class PixelateFilter * @contructor */ PIXI.PixelateFilter = function() { - PIXI.AbstractFilter.call( this ); + PIXI.AbstractFilter.call( this ); - this.passes = [this]; - - // set the uniforms - this.uniforms = { - invert: {type: '1f', value: 0}, - dimensions: {type: '4fv', value:new Float32Array([10000, 100, 10, 10])}, - pixelSize: {type: '2f', value:{x:10, y:10}}, - }; + this.passes = [this]; - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform vec2 testDim;", - "uniform vec4 dimensions;", - "uniform vec2 pixelSize;", - "uniform sampler2D uSampler;", - "void main(void) {", - "vec2 coord = vTextureCoord;", + // set the uniforms + this.uniforms = { + invert: {type: '1f', value: 0}, + dimensions: {type: '4fv', value:new Float32Array([10000, 100, 10, 10])}, + pixelSize: {type: '2f', value:{x:10, y:10}}, + }; - "vec2 size = dimensions.xy/pixelSize;", + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform vec2 testDim;', + 'uniform vec4 dimensions;', + 'uniform vec2 pixelSize;', + 'uniform sampler2D uSampler;', - "vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;", - "gl_FragColor = texture2D(uSampler, color);", - "}" - ]; - + 'void main(void) {', + ' vec2 coord = vTextureCoord;', -} + ' vec2 size = dimensions.xy/pixelSize;', + + ' vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;', + ' gl_FragColor = texture2D(uSampler, color);', + '}' + ]; +}; PIXI.PixelateFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.PixelateFilter.prototype.constructor = PIXI.PixelateFilter; /** - * + * * This a point that describes the size of the blocs. x is the width of the block and y is the the height * @property size * @type Point @@ -56,7 +55,7 @@ Object.defineProperty(PIXI.PixelateFilter.prototype, 'size', { return this.uniforms.pixelSize.value; }, set: function(value) { - this.dirty = true; - this.uniforms.pixelSize.value = value; + this.dirty = true; + this.uniforms.pixelSize.value = value; } -}); \ No newline at end of file +}); diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js index 35a837eb..81439dd5 100644 --- a/src/pixi/filters/RGBSplitFilter.js +++ b/src/pixi/filters/RGBSplitFilter.js @@ -2,39 +2,38 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - - PIXI.RGBSplitFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - red: {type: '2f', value: {x:20, y:20}}, - green: {type: '2f', value: {x:-20, y:20}}, - blue: {type: '2f', value: {x:20, y:-20}}, - dimensions: {type: '4fv', value:[0,0,0,0]} - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform vec2 red;", - "uniform vec2 green;", - "uniform vec2 blue;", - "uniform vec4 dimensions;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;", - "gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;", - "gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;", - "gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;", - "}" - ]; -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + red: {type: '2f', value: {x:20, y:20}}, + green: {type: '2f', value: {x:-20, y:20}}, + blue: {type: '2f', value: {x:20, y:-20}}, + dimensions: {type: '4fv', value:[0,0,0,0]} + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform vec2 red;', + 'uniform vec2 green;', + 'uniform vec2 blue;', + 'uniform vec4 dimensions;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;', + ' gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;', + ' gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;', + ' gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;', + '}' + ]; +}; PIXI.RGBSplitFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.RGBSplitFilter.prototype.constructor = PIXI.RGBSplitFilter; @@ -44,7 +43,7 @@ Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'angle', { return this.uniforms.blur.value / (1/7000); }, set: function(value) { - //this.padding = value; - this.uniforms.blur.value = (1/7000) * value; + //this.padding = value; + this.uniforms.blur.value = (1/7000) * value; } }); diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js index 22f31a43..f114d761 100644 --- a/src/pixi/filters/SepiaFilter.js +++ b/src/pixi/filters/SepiaFilter.js @@ -1,42 +1,40 @@ -/** /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** - * + * * This applies a sepia effect to your displayObjects. * @class SepiaFilter * @contructor */ PIXI.SepiaFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - sepia: {type: '1f', value: 1}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float sepia;", - "uniform sampler2D uSampler;", - - "const mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord);", - "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);", - "gl_FragColor = gl_FragColor * vColor;", - "}" - ]; - -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + sepia: {type: '1f', value: 1}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float sepia;', + 'uniform sampler2D uSampler;', + + 'const mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);', + + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vTextureCoord);', + ' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);', + ' gl_FragColor = gl_FragColor * vColor;', + '}' + ]; +}; PIXI.SepiaFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.SepiaFilter.prototype.constructor = PIXI.SepiaFilter; @@ -50,6 +48,6 @@ Object.defineProperty(PIXI.SepiaFilter.prototype, 'sepia', { return this.uniforms.sepia.value; }, set: function(value) { - this.uniforms.sepia.value = value; + this.uniforms.sepia.value = value; } }); diff --git a/src/pixi/filters/SmartBlurFilter.js b/src/pixi/filters/SmartBlurFilter.js index 93567e85..1140a562 100644 --- a/src/pixi/filters/SmartBlurFilter.js +++ b/src/pixi/filters/SmartBlurFilter.js @@ -2,54 +2,51 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - - PIXI.SmartBlurFilter = function() { - PIXI.AbstractFilter.call( this ); - - this.passes = [this]; - - // set the uniforms - this.uniforms = { - blur: {type: '1f', value: 1/512}, - }; - - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "uniform sampler2D uSampler;", - // "uniform vec2 delta;", - "const vec2 delta = vec2(1.0/10.0, 0.0);", - // "uniform float darkness;", - - "float random(vec3 scale, float seed) {", - "return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);", - "}", - - - "void main(void) {", - - "vec4 color = vec4(0.0);", - "float total = 0.0;", - - "float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);", - - "for (float t = -30.0; t <= 30.0; t++) {", - "float percent = (t + offset - 0.5) / 30.0;", - "float weight = 1.0 - abs(percent);", - "vec4 sample = texture2D(uSampler, vTextureCoord + delta * percent);", - "sample.rgb *= sample.a;", - "color += sample * weight;", - "total += weight;", - "}", - - "gl_FragColor = color / total;", - "gl_FragColor.rgb /= gl_FragColor.a + 0.00001;", - // "gl_FragColor.rgb *= darkness;", - "}" - ]; -} + PIXI.AbstractFilter.call( this ); + + this.passes = [this]; + + // set the uniforms + this.uniforms = { + blur: {type: '1f', value: 1/512}, + }; + + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'uniform sampler2D uSampler;', + //'uniform vec2 delta;', + 'const vec2 delta = vec2(1.0/10.0, 0.0);', + //'uniform float darkness;', + + 'float random(vec3 scale, float seed) {', + ' return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);', + '}', + + + 'void main(void) {', + ' vec4 color = vec4(0.0);', + ' float total = 0.0;', + + ' float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);', + + ' for (float t = -30.0; t <= 30.0; t++) {', + ' float percent = (t + offset - 0.5) / 30.0;', + ' float weight = 1.0 - abs(percent);', + ' vec4 sample = texture2D(uSampler, vTextureCoord + delta * percent);', + ' sample.rgb *= sample.a;', + ' color += sample * weight;', + ' total += weight;', + ' }', + + ' gl_FragColor = color / total;', + ' gl_FragColor.rgb /= gl_FragColor.a + 0.00001;', + //' gl_FragColor.rgb *= darkness;', + '}' + ]; +}; PIXI.SmartBlurFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.SmartBlurFilter.prototype.constructor = PIXI.SmartBlurFilter; @@ -59,6 +56,6 @@ Object.defineProperty(PIXI.SmartBlurFilter.prototype, 'blur', { return this.uniforms.blur.value; }, set: function(value) { - this.uniforms.blur.value = value; + this.uniforms.blur.value = value; } }); diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js index 0dce008b..c529dd78 100644 --- a/src/pixi/filters/TwistFilter.js +++ b/src/pixi/filters/TwistFilter.js @@ -3,59 +3,57 @@ */ /** - * - * This filter applies a pixlate effect making display objects appear "blocky" + * + * This filter applies a pixlate effect making display objects appear 'blocky' * @class PixelateFilter * @contructor */ PIXI.TwistFilter = function() { - PIXI.AbstractFilter.call( this ); + PIXI.AbstractFilter.call( this ); - this.passes = [this]; - - // set the uniforms - this.uniforms = { - radius: {type: '1f', value:0.5}, - angle: {type: '1f', value:5}, - offset: {type: '2f', value:{x:0.5, y:0.5}}, - }; + this.passes = [this]; - this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform vec4 dimensions;", - "uniform sampler2D uSampler;", - - "uniform float radius;", - "uniform float angle;", - "uniform vec2 offset;", + // set the uniforms + this.uniforms = { + radius: {type: '1f', value:0.5}, + angle: {type: '1f', value:5}, + offset: {type: '2f', value:{x:0.5, y:0.5}}, + }; - "void main(void) {", - "vec2 coord = vTextureCoord - offset;", - "float distance = length(coord);", - - "if (distance < radius){", + this.fragmentSrc = [ + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform vec4 dimensions;', + 'uniform sampler2D uSampler;', - "float ratio = (radius - distance) / radius;", - "float angleMod = ratio * ratio * angle;", - "float s = sin(angleMod);", - "float c = cos(angleMod);", - "coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);", + 'uniform float radius;', + 'uniform float angle;', + 'uniform vec2 offset;', - "}", + 'void main(void) {', + ' vec2 coord = vTextureCoord - offset;', + ' float distance = length(coord);', - "gl_FragColor = texture2D(uSampler, coord+offset);", - "}" - ]; -} + ' if (distance < radius) {', + ' float ratio = (radius - distance) / radius;', + ' float angleMod = ratio * ratio * angle;', + ' float s = sin(angleMod);', + ' float c = cos(angleMod);', + ' coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);', + ' }', + + ' gl_FragColor = texture2D(uSampler, coord+offset);', + '}' + ]; +}; PIXI.TwistFilter.prototype = Object.create( PIXI.AbstractFilter.prototype ); PIXI.TwistFilter.prototype.constructor = PIXI.TwistFilter; /** - * + * * This point describes the the offset of the twist * @property size * @type Point @@ -65,13 +63,13 @@ Object.defineProperty(PIXI.TwistFilter.prototype, 'offset', { return this.uniforms.offset.value; }, set: function(value) { - this.dirty = true; - this.uniforms.offset.value = value; + this.dirty = true; + this.uniforms.offset.value = value; } }); /** - * + * * This radius describes size of the twist * @property size * @type Number @@ -81,13 +79,13 @@ Object.defineProperty(PIXI.TwistFilter.prototype, 'radius', { return this.uniforms.radius.value; }, set: function(value) { - this.dirty = true; - this.uniforms.radius.value = value; + this.dirty = true; + this.uniforms.radius.value = value; } }); /** - * + * * This radius describes angle of the twist * @property angle * @type Number @@ -97,7 +95,7 @@ Object.defineProperty(PIXI.TwistFilter.prototype, 'angle', { return this.uniforms.angle.value; }, set: function(value) { - this.dirty = true; - this.uniforms.angle.value = value; + this.dirty = true; + this.uniforms.angle.value = value; } }); \ No newline at end of file diff --git a/src/pixi/loaders/AssetLoader.js b/src/pixi/loaders/AssetLoader.js index 7aefa168..c2e8ef18 100644 --- a/src/pixi/loaders/AssetLoader.js +++ b/src/pixi/loaders/AssetLoader.js @@ -6,29 +6,29 @@ * A Class that loads a bunch of images / sprite sheet / bitmap font files. Once the * assets have been loaded they are added to the PIXI Texture cache and can be accessed * easily through PIXI.Texture.fromImage() and PIXI.Sprite.fromImage() - * When all items have been loaded this class will dispatch a "onLoaded" event - * As each individual item is loaded this class will dispatch a "onProgress" event + * When all items have been loaded this class will dispatch a 'onLoaded' event + * As each individual item is loaded this class will dispatch a 'onProgress' event * * @class AssetLoader * @constructor * @uses EventTarget * @param {Array} assetURLs an array of image/sprite sheet urls that you would like loaded - * supported. Supported image formats include "jpeg", "jpg", "png", "gif". Supported - * sprite sheet data formats only include "JSON" at this time. Supported bitmap font - * data formats include "xml" and "fnt". + * supported. Supported image formats include 'jpeg', 'jpg', 'png', 'gif'. Supported + * sprite sheet data formats only include 'JSON' at this time. Supported bitmap font + * data formats include 'xml' and 'fnt'. * @param crossorigin {Boolean} Whether requests should be treated as crossorigin */ PIXI.AssetLoader = function(assetURLs, crossorigin) { - PIXI.EventTarget.call(this); + PIXI.EventTarget.call(this); - /** - * The array of asset URLs that are going to be loaded + /** + * The array of asset URLs that are going to be loaded * - * @property assetURLs - * @type Array - */ - this.assetURLs = assetURLs; + * @property assetURLs + * @type Array + */ + this.assetURLs = assetURLs; /** * Whether the requests should be treated as cross origin @@ -36,7 +36,7 @@ PIXI.AssetLoader = function(assetURLs, crossorigin) * @property crossorigin * @type Boolean */ - this.crossorigin = crossorigin; + this.crossorigin = crossorigin; /** * Maps file extension to loader types @@ -45,17 +45,16 @@ PIXI.AssetLoader = function(assetURLs, crossorigin) * @type Object */ this.loadersByType = { - "jpg": PIXI.ImageLoader, - "jpeg": PIXI.ImageLoader, - "png": PIXI.ImageLoader, - "gif": PIXI.ImageLoader, - "json": PIXI.JsonLoader, - "anim": PIXI.SpineLoader, - "xml": PIXI.BitmapFontLoader, - "fnt": PIXI.BitmapFontLoader + 'jpg': PIXI.ImageLoader, + 'jpeg': PIXI.ImageLoader, + 'png': PIXI.ImageLoader, + 'gif': PIXI.ImageLoader, + 'json': PIXI.JsonLoader, + 'atlas': PIXI.AtlasLoader, + 'anim': PIXI.SpineLoader, + 'xml': PIXI.BitmapFontLoader, + 'fnt': PIXI.BitmapFontLoader }; - - }; /** @@ -72,31 +71,32 @@ PIXI.AssetLoader = function(assetURLs, crossorigin) PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader; -PIXI.AssetLoader.prototype._getDataType = function(str) +PIXI.AssetLoader.prototype._getDataType = function(str) { - var test = "data:"; + var test = 'data:'; //starts with 'data:' var start = str.slice(0, test.length).toLowerCase(); - if (start == test) { + if (start === test) { var data = str.slice(test.length); - + var sepIdx = data.indexOf(','); if (sepIdx === -1) //malformed data URI scheme return null; - //e.g. "image/gif;base64" => "image/gif" + //e.g. 'image/gif;base64' => 'image/gif' var info = data.slice(0, sepIdx).split(';')[0]; //We might need to handle some special cases here... - //standardize text/plain to "txt" file extension - if (!info || info.toLowerCase() == "text/plain") - return "txt" + //standardize text/plain to 'txt' file extension + if (!info || info.toLowerCase() === 'text/plain') + return 'txt'; //User specified mime type, try splitting it by '/' return info.split('/').pop().toLowerCase(); } + return null; -} +}; /** * Starts loading the assets sequentially @@ -107,30 +107,31 @@ PIXI.AssetLoader.prototype.load = function() { var scope = this; - this.loadCount = this.assetURLs.length; + function onLoad() { + scope.onAssetLoaded(); + } + + this.loadCount = this.assetURLs.length; for (var i=0; i < this.assetURLs.length; i++) - { - var fileName = this.assetURLs[i]; + { + var fileName = this.assetURLs[i]; //first see if we have a data URI scheme.. var fileType = this._getDataType(fileName); //if not, assume it's a file URI if (!fileType) - fileType = fileName.split("?").shift().split(".").pop().toLowerCase(); + fileType = fileName.split('?').shift().split('.').pop().toLowerCase(); - var loaderClass = this.loadersByType[fileType]; - if(!loaderClass) - throw new Error(fileType + " is an unsupported file type"); + var Constructor = this.loadersByType[fileType]; + if(!Constructor) + throw new Error(fileType + ' is an unsupported file type'); - var loader = new loaderClass(fileName, this.crossorigin); + var loader = new Constructor(fileName, this.crossorigin); - loader.addEventListener("loaded", function() - { - scope.onAssetLoaded(); - }); + loader.addEventListener('loaded', onLoad); loader.load(); - } + } }; /** @@ -142,13 +143,12 @@ PIXI.AssetLoader.prototype.load = function() PIXI.AssetLoader.prototype.onAssetLoaded = function() { this.loadCount--; - this.dispatchEvent({type: "onProgress", content: this}); - if(this.onProgress) this.onProgress(); + this.dispatchEvent({type: 'onProgress', content: this}); + if (this.onProgress) this.onProgress(); - if(this.loadCount == 0) - { - this.dispatchEvent({type: "onComplete", content: this}); - if(this.onComplete) this.onComplete(); - } + if (!this.loadCount) + { + this.dispatchEvent({type: 'onComplete', content: this}); + if(this.onComplete) this.onComplete(); + } }; - diff --git a/src/pixi/loaders/AtlasLoader.js b/src/pixi/loaders/AtlasLoader.js new file mode 100644 index 00000000..68300ebd --- /dev/null +++ b/src/pixi/loaders/AtlasLoader.js @@ -0,0 +1,184 @@ +/** + * @author Martin Kelm http://mkelm.github.com + */ + +/** + * The atlas file loader is used to load in Atlas data and parsing it + * When loaded this class will dispatch a 'loaded' event + * If load failed this class will dispatch a 'error' event + * @class AtlasLoader + * @extends EventTarget + * @constructor + * @param {String} url the url of the JSON file + * @param {Boolean} crossorigin + */ + +PIXI.AtlasLoader = function (url, crossorigin) { + PIXI.EventTarget.call(this); + this.url = url; + this.baseUrl = url.replace(/[^\/]*$/, ''); + this.crossorigin = crossorigin; + this.loaded = false; + +}; + +// constructor +PIXI.AtlasLoader.constructor = PIXI.AtlasLoader; + +/** + * This will begin loading the JSON file + */ +PIXI.AtlasLoader.prototype.load = function () { + this.ajaxRequest = new PIXI.AjaxRequest(); + this.ajaxRequest.onreadystatechange = this.onAtlasLoaded.bind(this); + + this.ajaxRequest.open('GET', this.url, true); + if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/json'); + this.ajaxRequest.send(null); +}; + +/** + * Invoke when JSON file is loaded + * @private + */ +PIXI.AtlasLoader.prototype.onAtlasLoaded = function () { + if (this.ajaxRequest.readyState === 4) { + if (this.ajaxRequest.status === 200 || window.location.href.indexOf('http') === -1) { + this.atlas = { + meta : { + image : [] + }, + frames : [] + }; + var result = this.ajaxRequest.responseText.split(/\r?\n/); + var lineCount = -3; + + var currentImageId = 0; + var currentFrame = null; + var nameInNextLine = false; + + var i = 0, + j = 0, + selfOnLoaded = this.onLoaded.bind(this); + + // parser without rotation support yet! + for (i = 0; i < result.length; i++) { + result[i] = result[i].replace(/^\s+|\s+$/g, ''); + if (result[i] === '') { + nameInNextLine = i+1; + } + if (result[i].length > 0) { + if (nameInNextLine === i) { + this.atlas.meta.image.push(result[i]); + currentImageId = this.atlas.meta.image.length - 1; + this.atlas.frames.push({}); + lineCount = -3; + } else if (lineCount > 0) { + if (lineCount % 7 === 1) { // frame name + if (currentFrame != null) { //jshint ignore:line + this.atlas.frames[currentImageId][currentFrame.name] = currentFrame; + } + currentFrame = { name: result[i], frame : {} }; + } else { + var text = result[i].split(' '); + if (lineCount % 7 === 3) { // position + currentFrame.frame.x = Number(text[1].replace(',', '')); + currentFrame.frame.y = Number(text[2]); + } else if (lineCount % 7 === 4) { // size + currentFrame.frame.w = Number(text[1].replace(',', '')); + currentFrame.frame.h = Number(text[2]); + } else if (lineCount % 7 === 5) { // real size + var realSize = { + x : 0, + y : 0, + w : Number(text[1].replace(',', '')), + h : Number(text[2]) + }; + + if (realSize.w > currentFrame.frame.w || realSize.h > currentFrame.frame.h) { + currentFrame.trimmed = true; + currentFrame.realSize = realSize; + } else { + currentFrame.trimmed = false; + } + } + } + } + lineCount++; + } + } + + if (currentFrame != null) { //jshint ignore:line + this.atlas.frames[currentImageId][currentFrame.name] = currentFrame; + } + + if (this.atlas.meta.image.length > 0) { + this.images = []; + for (j = 0; j < this.atlas.meta.image.length; j++) { + // sprite sheet + var textureUrl = this.baseUrl + this.atlas.meta.image[j]; + var frameData = this.atlas.frames[j]; + this.images.push(new PIXI.ImageLoader(textureUrl, this.crossorigin)); + + for (i in frameData) { + var rect = frameData[i].frame; + if (rect) { + PIXI.TextureCache[i] = new PIXI.Texture(this.images[j].texture.baseTexture, { + x: rect.x, + y: rect.y, + width: rect.w, + height: rect.h + }); + if (frameData[i].trimmed) { + PIXI.TextureCache[i].realSize = frameData[i].realSize; + // trim in pixi not supported yet, todo update trim properties if it is done ... + PIXI.TextureCache[i].trim.x = 0; + PIXI.TextureCache[i].trim.y = 0; + } + } + } + } + + this.currentImageId = 0; + for (j = 0; j < this.images.length; j++) { + this.images[j].addEventListener('loaded', selfOnLoaded); + } + this.images[this.currentImageId].load(); + + } else { + this.onLoaded(); + } + + } else { + this.onError(); + } + } +}; + +/** + * Invoke when json file loaded + * @private + */ +PIXI.AtlasLoader.prototype.onLoaded = function () { + if (this.images.length - 1 > this.currentImageId) { + this.currentImageId++; + this.images[this.currentImageId].load(); + } else { + this.loaded = true; + this.dispatchEvent({ + type: 'loaded', + content: this + }); + } +}; + +/** + * Invoke when error occured + * @private + */ +PIXI.AtlasLoader.prototype.onError = function () { + this.dispatchEvent({ + type: 'error', + content: this + }); +}; diff --git a/src/pixi/loaders/BitmapFontLoader.js b/src/pixi/loaders/BitmapFontLoader.js index ef050943..8421f90a 100644 --- a/src/pixi/loaders/BitmapFontLoader.js +++ b/src/pixi/loaders/BitmapFontLoader.js @@ -3,10 +3,10 @@ */ /** - * The xml loader is used to load in XML bitmap font data ("xml" or "fnt") + * The xml loader is used to load in XML bitmap font data ('xml' or 'fnt') * To generate the data you can use http://www.angelcode.com/products/bmfont/ * This loader will also load the image file as the data. - * When loaded this class will dispatch a "loaded" event + * When loaded this class will dispatch a 'loaded' event * * @class BitmapFontLoader * @uses EventTarget @@ -19,7 +19,7 @@ PIXI.BitmapFontLoader = function(url, crossorigin) /* * i use texture packer to load the assets.. * http://www.codeandweb.com/texturepacker - * make sure to set the format as "JSON" + * make sure to set the format as 'JSON' */ PIXI.EventTarget.call(this); @@ -46,7 +46,7 @@ PIXI.BitmapFontLoader = function(url, crossorigin) * @type String * @readOnly */ - this.baseUrl = url.replace(/[^\/]*$/, ""); + this.baseUrl = url.replace(/[^\/]*$/, ''); /** * [read-only] The texture of the bitmap font @@ -74,9 +74,9 @@ PIXI.BitmapFontLoader.prototype.load = function() scope.onXMLLoaded(); }; - this.ajaxRequest.open("GET", this.url, true); - if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType("application/xml"); - this.ajaxRequest.send(null) + this.ajaxRequest.open('GET', this.url, true); + if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/xml'); + this.ajaxRequest.send(null); }; /** @@ -87,40 +87,40 @@ PIXI.BitmapFontLoader.prototype.load = function() */ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function() { - if (this.ajaxRequest.readyState == 4) + if (this.ajaxRequest.readyState === 4) { - if (this.ajaxRequest.status == 200 || window.location.href.indexOf("http") == -1) + if (this.ajaxRequest.status === 200 || window.location.protocol.indexOf('http') === -1) { - var textureUrl = this.baseUrl + this.ajaxRequest.responseXML.getElementsByTagName("page")[0].attributes.getNamedItem("file").nodeValue; + var textureUrl = this.baseUrl + this.ajaxRequest.responseXML.getElementsByTagName('page')[0].attributes.getNamedItem('file').nodeValue; var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); this.texture = image.texture.baseTexture; var data = {}; - var info = this.ajaxRequest.responseXML.getElementsByTagName("info")[0]; - var common = this.ajaxRequest.responseXML.getElementsByTagName("common")[0]; - data.font = info.attributes.getNamedItem("face").nodeValue; - data.size = parseInt(info.attributes.getNamedItem("size").nodeValue, 10); - data.lineHeight = parseInt(common.attributes.getNamedItem("lineHeight").nodeValue, 10); + var info = this.ajaxRequest.responseXML.getElementsByTagName('info')[0]; + var common = this.ajaxRequest.responseXML.getElementsByTagName('common')[0]; + data.font = info.attributes.getNamedItem('face').nodeValue; + data.size = parseInt(info.attributes.getNamedItem('size').nodeValue, 10); + data.lineHeight = parseInt(common.attributes.getNamedItem('lineHeight').nodeValue, 10); data.chars = {}; //parse letters - var letters = this.ajaxRequest.responseXML.getElementsByTagName("char"); + var letters = this.ajaxRequest.responseXML.getElementsByTagName('char'); for (var i = 0; i < letters.length; i++) { - var charCode = parseInt(letters[i].attributes.getNamedItem("id").nodeValue, 10); + var charCode = parseInt(letters[i].attributes.getNamedItem('id').nodeValue, 10); var textureRect = new PIXI.Rectangle( - parseInt(letters[i].attributes.getNamedItem("x").nodeValue, 10), - parseInt(letters[i].attributes.getNamedItem("y").nodeValue, 10), - parseInt(letters[i].attributes.getNamedItem("width").nodeValue, 10), - parseInt(letters[i].attributes.getNamedItem("height").nodeValue, 10) + parseInt(letters[i].attributes.getNamedItem('x').nodeValue, 10), + parseInt(letters[i].attributes.getNamedItem('y').nodeValue, 10), + parseInt(letters[i].attributes.getNamedItem('width').nodeValue, 10), + parseInt(letters[i].attributes.getNamedItem('height').nodeValue, 10) ); data.chars[charCode] = { - xOffset: parseInt(letters[i].attributes.getNamedItem("xoffset").nodeValue, 10), - yOffset: parseInt(letters[i].attributes.getNamedItem("yoffset").nodeValue, 10), - xAdvance: parseInt(letters[i].attributes.getNamedItem("xadvance").nodeValue, 10), + xOffset: parseInt(letters[i].attributes.getNamedItem('xoffset').nodeValue, 10), + yOffset: parseInt(letters[i].attributes.getNamedItem('yoffset').nodeValue, 10), + xAdvance: parseInt(letters[i].attributes.getNamedItem('xadvance').nodeValue, 10), kerning: {}, texture: PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect) @@ -128,12 +128,12 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function() } //parse kernings - var kernings = this.ajaxRequest.responseXML.getElementsByTagName("kerning"); + var kernings = this.ajaxRequest.responseXML.getElementsByTagName('kerning'); for (i = 0; i < kernings.length; i++) { - var first = parseInt(kernings[i].attributes.getNamedItem("first").nodeValue, 10); - var second = parseInt(kernings[i].attributes.getNamedItem("second").nodeValue, 10); - var amount = parseInt(kernings[i].attributes.getNamedItem("amount").nodeValue, 10); + var first = parseInt(kernings[i].attributes.getNamedItem('first').nodeValue, 10); + var second = parseInt(kernings[i].attributes.getNamedItem('second').nodeValue, 10); + var amount = parseInt(kernings[i].attributes.getNamedItem('amount').nodeValue, 10); data.chars[second].kerning[first] = amount; @@ -142,7 +142,7 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function() PIXI.BitmapText.fonts[data.font] = data; var scope = this; - image.addEventListener("loaded", function() { + image.addEventListener('loaded', function() { scope.onLoaded(); }); image.load(); @@ -158,5 +158,5 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function() */ PIXI.BitmapFontLoader.prototype.onLoaded = function() { - this.dispatchEvent({type: "loaded", content: this}); + this.dispatchEvent({type: 'loaded', content: this}); }; diff --git a/src/pixi/loaders/ImageLoader.js b/src/pixi/loaders/ImageLoader.js index d8a41374..c73893f6 100644 --- a/src/pixi/loaders/ImageLoader.js +++ b/src/pixi/loaders/ImageLoader.js @@ -3,7 +3,7 @@ */ /** - * The image loader class is responsible for loading images file formats ("jpeg", "jpg", "png" and "gif") + * The image loader class is responsible for loading images file formats ('jpeg', 'jpg', 'png' and 'gif') * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId() * When loaded this class will dispatch a 'loaded' event * @@ -46,7 +46,7 @@ PIXI.ImageLoader.prototype.load = function() if(!this.texture.baseTexture.hasLoaded) { var scope = this; - this.texture.baseTexture.addEventListener("loaded", function() + this.texture.baseTexture.addEventListener('loaded', function() { scope.onLoaded(); }); @@ -65,7 +65,7 @@ PIXI.ImageLoader.prototype.load = function() */ PIXI.ImageLoader.prototype.onLoaded = function() { - this.dispatchEvent({type: "loaded", content: this}); + this.dispatchEvent({type: 'loaded', content: this}); }; /** @@ -75,7 +75,7 @@ PIXI.ImageLoader.prototype.onLoaded = function() * @method loadFramedSpriteSheet * @param frameWidth {Number} with of each frame * @param frameHeight {Number} height of each frame - * @param textureName {String} if given, the frames will be cached in - format + * @param textureName {String} if given, the frames will be cached in - format */ PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName) { @@ -96,14 +96,14 @@ PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHei }); this.frames.push(texture); - if (textureName) PIXI.TextureCache[textureName+'-'+i] = texture; + if (textureName) PIXI.TextureCache[textureName + '-' + i] = texture; } } if(!this.texture.baseTexture.hasLoaded) { var scope = this; - this.texture.baseTexture.addEventListener("loaded", function() { + this.texture.baseTexture.addEventListener('loaded', function() { scope.onLoaded(); }); } @@ -111,4 +111,4 @@ PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHei { this.onLoaded(); } -}; \ No newline at end of file +}; diff --git a/src/pixi/loaders/JsonLoader.js b/src/pixi/loaders/JsonLoader.js index 640ecbf0..127d8cf0 100644 --- a/src/pixi/loaders/JsonLoader.js +++ b/src/pixi/loaders/JsonLoader.js @@ -4,8 +4,8 @@ /** * The json file loader is used to load in JSON data and parsing it - * When loaded this class will dispatch a "loaded" event - * If load failed this class will dispatch a "error" event + * When loaded this class will dispatch a 'loaded' event + * If load failed this class will dispatch a 'error' event * * @class JsonLoader * @uses EventTarget @@ -14,41 +14,41 @@ * @param crossorigin {Boolean} Whether requests should be treated as crossorigin */ PIXI.JsonLoader = function (url, crossorigin) { - PIXI.EventTarget.call(this); + PIXI.EventTarget.call(this); - /** - * The url of the bitmap font data - * - * @property url - * @type String - */ - this.url = url; + /** + * The url of the bitmap font data + * + * @property url + * @type String + */ + this.url = url; - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; + /** + * Whether the requests should be treated as cross origin + * + * @property crossorigin + * @type Boolean + */ + this.crossorigin = crossorigin; - /** - * [read-only] The base url of the bitmap font data - * - * @property baseUrl - * @type String - * @readOnly - */ - this.baseUrl = url.replace(/[^\/]*$/, ""); + /** + * [read-only] The base url of the bitmap font data + * + * @property baseUrl + * @type String + * @readOnly + */ + this.baseUrl = url.replace(/[^\/]*$/, ''); - /** - * [read-only] Whether the data has loaded yet - * - * @property loaded - * @type Boolean - * @readOnly - */ - this.loaded = false; + /** + * [read-only] Whether the data has loaded yet + * + * @property loaded + * @type Boolean + * @readOnly + */ + this.loaded = false; }; @@ -61,15 +61,15 @@ PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader; * @method load */ PIXI.JsonLoader.prototype.load = function () { - this.ajaxRequest = new AjaxRequest(); - var scope = this; - this.ajaxRequest.onreadystatechange = function () { - scope.onJSONLoaded(); - }; + this.ajaxRequest = new PIXI.AjaxRequest(); + var scope = this; + this.ajaxRequest.onreadystatechange = function () { + scope.onJSONLoaded(); + }; - this.ajaxRequest.open("GET", this.url, true); - if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType("application/json"); - this.ajaxRequest.send(null); + this.ajaxRequest.open('GET', this.url, true); + if (this.ajaxRequest.overrideMimeType) this.ajaxRequest.overrideMimeType('application/json'); + this.ajaxRequest.send(null); }; /** @@ -79,62 +79,62 @@ PIXI.JsonLoader.prototype.load = function () { * @private */ PIXI.JsonLoader.prototype.onJSONLoaded = function () { - if (this.ajaxRequest.readyState == 4) { - if (this.ajaxRequest.status == 200 || window.location.href.indexOf("http") == -1) { - this.json = JSON.parse(this.ajaxRequest.responseText); + if (this.ajaxRequest.readyState === 4) { + if (this.ajaxRequest.status === 200 || window.location.protocol.indexOf('http') === -1) { + this.json = JSON.parse(this.ajaxRequest.responseText); - if(this.json.frames) - { - // sprite sheet - var scope = this; - var textureUrl = this.baseUrl + this.json.meta.image; - var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); - var frameData = this.json.frames; + if(this.json.frames) + { + // sprite sheet + var scope = this; + var textureUrl = this.baseUrl + this.json.meta.image; + var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); + var frameData = this.json.frames; - this.texture = image.texture.baseTexture; - image.addEventListener("loaded", function (event) { - scope.onLoaded(); - }); + this.texture = image.texture.baseTexture; + image.addEventListener('loaded', function() { + scope.onLoaded(); + }); - for (var i in frameData) { - var rect = frameData[i].frame; - if (rect) { - PIXI.TextureCache[i] = new PIXI.Texture(this.texture, { - x: rect.x, - y: rect.y, - width: rect.w, - height: rect.h - }); - if (frameData[i].trimmed) { - //var realSize = frameData[i].spriteSourceSize; - PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize; - PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w) - // calculate the offset! - } - } - } + for (var i in frameData) { + var rect = frameData[i].frame; + if (rect) { + PIXI.TextureCache[i] = new PIXI.Texture(this.texture, { + x: rect.x, + y: rect.y, + width: rect.w, + height: rect.h + }); + if (frameData[i].trimmed) { + //var realSize = frameData[i].spriteSourceSize; + PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize; + PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w) + // calculate the offset! + } + } + } - image.load(); + image.load(); - } - else if(this.json.bones) - { - // spine animation - var spineJsonParser = new spine.SkeletonJson(); - var skeletonData = spineJsonParser.readSkeletonData(this.json); - PIXI.AnimCache[this.url] = skeletonData; - this.onLoaded(); - } - else - { - this.onLoaded(); - } - } - else - { - this.onError(); - } - } + } + else if(this.json.bones) + { + // spine animation + var spineJsonParser = new spine.SkeletonJson(); + var skeletonData = spineJsonParser.readSkeletonData(this.json); + PIXI.AnimCache[this.url] = skeletonData; + this.onLoaded(); + } + else + { + this.onLoaded(); + } + } + else + { + this.onError(); + } + } }; /** @@ -144,11 +144,11 @@ PIXI.JsonLoader.prototype.onJSONLoaded = function () { * @private */ PIXI.JsonLoader.prototype.onLoaded = function () { - this.loaded = true; - this.dispatchEvent({ - type: "loaded", - content: this - }); + this.loaded = true; + this.dispatchEvent({ + type: 'loaded', + content: this + }); }; /** @@ -158,8 +158,8 @@ PIXI.JsonLoader.prototype.onLoaded = function () { * @private */ PIXI.JsonLoader.prototype.onError = function () { - this.dispatchEvent({ - type: "error", - content: this - }); + this.dispatchEvent({ + type: 'error', + content: this + }); }; \ No newline at end of file diff --git a/src/pixi/loaders/SpineLoader.js b/src/pixi/loaders/SpineLoader.js index 00360980..f0a38ca0 100644 --- a/src/pixi/loaders/SpineLoader.js +++ b/src/pixi/loaders/SpineLoader.js @@ -23,33 +23,33 @@ */ PIXI.SpineLoader = function(url, crossorigin) { - PIXI.EventTarget.call(this); + PIXI.EventTarget.call(this); - /** - * The url of the bitmap font data - * - * @property url - * @type String - */ - this.url = url; + /** + * The url of the bitmap font data + * + * @property url + * @type String + */ + this.url = url; - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; + /** + * Whether the requests should be treated as cross origin + * + * @property crossorigin + * @type Boolean + */ + this.crossorigin = crossorigin; - /** - * [read-only] Whether the data has loaded yet - * - * @property loaded - * @type Boolean - * @readOnly - */ - this.loaded = false; -} + /** + * [read-only] Whether the data has loaded yet + * + * @property loaded + * @type Boolean + * @readOnly + */ + this.loaded = false; +}; PIXI.SpineLoader.prototype.constructor = PIXI.SpineLoader; @@ -60,13 +60,13 @@ PIXI.SpineLoader.prototype.constructor = PIXI.SpineLoader; */ PIXI.SpineLoader.prototype.load = function () { - var scope = this; - var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); - jsonLoader.addEventListener("loaded", function (event) { - scope.json = event.content.json; - scope.onJSONLoaded(); - }); - jsonLoader.load(); + var scope = this; + var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); + jsonLoader.addEventListener("loaded", function (event) { + scope.json = event.content.json; + scope.onJSONLoaded(); + }); + jsonLoader.load(); }; /** @@ -75,13 +75,13 @@ PIXI.SpineLoader.prototype.load = function () { * @method onJSONLoaded * @private */ -PIXI.SpineLoader.prototype.onJSONLoaded = function (event) { - var spineJsonParser = new spine.SkeletonJson(); - var skeletonData = spineJsonParser.readSkeletonData(this.json); +PIXI.SpineLoader.prototype.onJSONLoaded = function () { + var spineJsonParser = new spine.SkeletonJson(); + var skeletonData = spineJsonParser.readSkeletonData(this.json); - PIXI.AnimCache[this.url] = skeletonData; + PIXI.AnimCache[this.url] = skeletonData; - this.onLoaded(); + this.onLoaded(); }; /** @@ -91,7 +91,7 @@ PIXI.SpineLoader.prototype.onJSONLoaded = function (event) { * @private */ PIXI.SpineLoader.prototype.onLoaded = function () { - this.loaded = true; + this.loaded = true; this.dispatchEvent({type: "loaded", content: this}); }; diff --git a/src/pixi/loaders/SpriteSheetLoader.js b/src/pixi/loaders/SpriteSheetLoader.js index 169fb70d..e9844cec 100644 --- a/src/pixi/loaders/SpriteSheetLoader.js +++ b/src/pixi/loaders/SpriteSheetLoader.js @@ -4,12 +4,12 @@ /** * The sprite sheet loader is used to load in JSON sprite sheet data - * To generate the data you can use http://www.codeandweb.com/texturepacker and publish the "JSON" format + * To generate the data you can use http://www.codeandweb.com/texturepacker and publish the 'JSON' format * There is a free version so thats nice, although the paid version is great value for money. - * It is highly recommended to use Sprite sheets (also know as texture atlas") as it means sprite"s can be batched and drawn together for highly increased rendering speed. + * It is highly recommended to use Sprite sheets (also know as texture atlas') as it means sprite's can be batched and drawn together for highly increased rendering speed. * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId() * This loader will also load the image file that the Spritesheet points to as well as the data. - * When loaded this class will dispatch a "loaded" event + * When loaded this class will dispatch a 'loaded' event * * @class SpriteSheetLoader * @uses EventTarget @@ -17,39 +17,38 @@ * @param url {String} The url of the sprite sheet JSON file * @param crossorigin {Boolean} Whether requests should be treated as crossorigin */ - PIXI.SpriteSheetLoader = function (url, crossorigin) { - /* - * i use texture packer to load the assets.. - * http://www.codeandweb.com/texturepacker - * make sure to set the format as "JSON" - */ - PIXI.EventTarget.call(this); + /* + * i use texture packer to load the assets.. + * http://www.codeandweb.com/texturepacker + * make sure to set the format as 'JSON' + */ + PIXI.EventTarget.call(this); - /** - * The url of the bitmap font data - * - * @property url - * @type String - */ - this.url = url; + /** + * The url of the bitmap font data + * + * @property url + * @type String + */ + this.url = url; - /** - * Whether the requests should be treated as cross origin - * - * @property crossorigin - * @type Boolean - */ - this.crossorigin = crossorigin; + /** + * Whether the requests should be treated as cross origin + * + * @property crossorigin + * @type Boolean + */ + this.crossorigin = crossorigin; - /** - * [read-only] The base url of the bitmap font data - * - * @property baseUrl - * @type String - * @readOnly - */ - this.baseUrl = url.replace(/[^\/]*$/, ""); + /** + * [read-only] The base url of the bitmap font data + * + * @property baseUrl + * @type String + * @readOnly + */ + this.baseUrl = url.replace(/[^\/]*$/, ''); /** * The texture being loaded @@ -65,7 +64,7 @@ PIXI.SpriteSheetLoader = function (url, crossorigin) { * @property frames * @type Object */ - this.frames = {}; + this.frames = {}; }; // constructor @@ -77,13 +76,13 @@ PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader; * @method load */ PIXI.SpriteSheetLoader.prototype.load = function () { - var scope = this; - var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); - jsonLoader.addEventListener("loaded", function (event) { - scope.json = event.content.json; - scope.onJSONLoaded(); - }); - jsonLoader.load(); + var scope = this; + var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin); + jsonLoader.addEventListener('loaded', function (event) { + scope.json = event.content.json; + scope.onJSONLoaded(); + }); + jsonLoader.load(); }; /** @@ -93,36 +92,37 @@ PIXI.SpriteSheetLoader.prototype.load = function () { * @private */ PIXI.SpriteSheetLoader.prototype.onJSONLoaded = function () { - var scope = this; - var textureUrl = this.baseUrl + this.json.meta.image; - var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); - var frameData = this.json.frames; + var scope = this; + var textureUrl = this.baseUrl + this.json.meta.image; + var image = new PIXI.ImageLoader(textureUrl, this.crossorigin); + var frameData = this.json.frames; - this.texture = image.texture.baseTexture; - image.addEventListener("loaded", function (event) { - scope.onLoaded(); - }); + this.texture = image.texture.baseTexture; + image.addEventListener('loaded', function () { + scope.onLoaded(); + }); - for (var i in frameData) { - var rect = frameData[i].frame; - if (rect) { - PIXI.TextureCache[i] = new PIXI.Texture(this.texture, { - x: rect.x, - y: rect.y, - width: rect.w, - height: rect.h - }); - if (frameData[i].trimmed) { - //var realSize = frameData[i].spriteSourceSize; - PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize; - PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w) - // calculate the offset! - } - } - } + for (var i in frameData) { + var rect = frameData[i].frame; + if (rect) { + PIXI.TextureCache[i] = new PIXI.Texture(this.texture, { + x: rect.x, + y: rect.y, + width: rect.w, + height: rect.h + }); + if (frameData[i].trimmed) { + //var realSize = frameData[i].spriteSourceSize; + PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize; + PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w) + // calculate the offset! + } + } + } - image.load(); + image.load(); }; + /** * Invoke when all files are loaded (json and texture) * @@ -130,8 +130,8 @@ PIXI.SpriteSheetLoader.prototype.onJSONLoaded = function () { * @private */ PIXI.SpriteSheetLoader.prototype.onLoaded = function () { - this.dispatchEvent({ - type: "loaded", - content: this - }); + this.dispatchEvent({ + type: 'loaded', + content: this + }); }; diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js index 8e8c3dd2..92dee1e2 100644 --- a/src/pixi/primitives/Graphics.js +++ b/src/pixi/primitives/Graphics.js @@ -14,9 +14,9 @@ */ PIXI.Graphics = function() { - PIXI.DisplayObjectContainer.call( this ); + PIXI.DisplayObjectContainer.call( this ); - this.renderable = true; + this.renderable = true; /** * The alpha of the fill of this graphics object @@ -24,7 +24,7 @@ PIXI.Graphics = function() * @property fillAlpha * @type Number */ - this.fillAlpha = 1; + this.fillAlpha = 1; /** * The width of any lines drawn @@ -32,7 +32,7 @@ PIXI.Graphics = function() * @property lineWidth * @type Number */ - this.lineWidth = 0; + this.lineWidth = 0; /** * The color of any lines drawn @@ -40,7 +40,7 @@ PIXI.Graphics = function() * @property lineColor * @type String */ - this.lineColor = "black"; + this.lineColor = "black"; /** * Graphics data @@ -49,7 +49,7 @@ PIXI.Graphics = function() * @type Array * @private */ - this.graphicsData = []; + this.graphicsData = []; /** * Current path @@ -58,8 +58,8 @@ PIXI.Graphics = function() * @type Object * @private */ - this.currentPath = {points:[]}; -} + this.currentPath = {points:[]}; +}; // constructor PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); @@ -75,17 +75,17 @@ PIXI.Graphics.prototype.constructor = PIXI.Graphics; */ PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha) { - if(this.currentPath.points.length == 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.lineWidth = lineWidth || 0; - this.lineColor = color || 0; - this.lineAlpha = (alpha == undefined) ? 1 : alpha; + this.lineWidth = lineWidth || 0; + this.lineColor = color || 0; + this.lineAlpha = (arguments.length < 3) ? 1 : alpha; - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; - this.graphicsData.push(this.currentPath); -} + this.graphicsData.push(this.currentPath); +}; /** * Moves the current drawing position to (x, y). @@ -96,15 +96,15 @@ PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha) */ PIXI.Graphics.prototype.moveTo = function(x, y) { - if(this.currentPath.points.length == 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; + this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; - this.currentPath.points.push(x, y); + this.currentPath.points.push(x, y); - this.graphicsData.push(this.currentPath); -} + this.graphicsData.push(this.currentPath); +}; /** * Draws a line using the current line style from the current drawing position to (x, y); @@ -116,9 +116,9 @@ PIXI.Graphics.prototype.moveTo = function(x, y) */ PIXI.Graphics.prototype.lineTo = function(x, y) { - this.currentPath.points.push(x, y); - this.dirty = true; -} + this.currentPath.points.push(x, y); + this.dirty = true; +}; /** * Specifies a simple one-color fill that subsequent calls to other Graphics methods @@ -130,10 +130,10 @@ PIXI.Graphics.prototype.lineTo = function(x, y) */ PIXI.Graphics.prototype.beginFill = function(color, alpha) { - this.filling = true; - this.fillColor = color || 0; - this.fillAlpha = (alpha == undefined) ? 1 : alpha; -} + this.filling = true; + this.fillColor = color || 0; + this.fillAlpha = (arguments.length < 2) ? 1 : alpha; +}; /** * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method. @@ -142,10 +142,10 @@ PIXI.Graphics.prototype.beginFill = function(color, alpha) */ PIXI.Graphics.prototype.endFill = function() { - this.filling = false; - this.fillColor = null; - this.fillAlpha = 1; -} + this.filling = false; + this.fillColor = null; + this.fillAlpha = 1; +}; /** * @method drawRect @@ -157,15 +157,15 @@ PIXI.Graphics.prototype.endFill = function() */ PIXI.Graphics.prototype.drawRect = function( x, y, width, height ) { - if(this.currentPath.points.length == 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, width, height], type:PIXI.Graphics.RECT}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, width, height], type:PIXI.Graphics.RECT}; - this.graphicsData.push(this.currentPath); - this.dirty = true; -} + this.graphicsData.push(this.currentPath); + this.dirty = true; +}; /** * Draws a circle. @@ -177,36 +177,36 @@ PIXI.Graphics.prototype.drawRect = function( x, y, width, height ) */ PIXI.Graphics.prototype.drawCircle = function( x, y, radius) { - if(this.currentPath.points.length == 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, radius, radius], type:PIXI.Graphics.CIRC}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, radius, radius], type:PIXI.Graphics.CIRC}; - this.graphicsData.push(this.currentPath); - this.dirty = true; -} + this.graphicsData.push(this.currentPath); + this.dirty = true; +}; /** - * Draws an elipse. + * Draws an ellipse. * - * @method drawElipse + * @method drawEllipse * @param x {Number} * @param y {Number} * @param width {Number} * @param height {Number} */ -PIXI.Graphics.prototype.drawElipse = function( x, y, width, height) +PIXI.Graphics.prototype.drawEllipse = function( x, y, width, height) { - if(this.currentPath.points.length == 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, width, height], type:PIXI.Graphics.ELIP}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, width, height], type:PIXI.Graphics.ELIP}; - this.graphicsData.push(this.currentPath); - this.dirty = true; -} + this.graphicsData.push(this.currentPath); + this.dirty = true; +}; /** * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. @@ -215,88 +215,83 @@ PIXI.Graphics.prototype.drawElipse = function( x, y, width, height) */ PIXI.Graphics.prototype.clear = function() { - this.lineWidth = 0; - this.filling = false; + this.lineWidth = 0; + this.filling = false; - this.dirty = true; - this.clearDirty = true; - this.graphicsData = []; + this.dirty = true; + this.clearDirty = true; + this.graphicsData = []; - this.bounds = null//new PIXI.Rectangle(); -} + this.bounds = null; //new PIXI.Rectangle(); +}; PIXI.Graphics.prototype.updateFilterBounds = function() { - if(!this.bounds) - { - var minX = Infinity; - var maxX = -Infinity; + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; - var minY = Infinity; - var maxY = -Infinity; + var minY = Infinity; + var maxY = -Infinity; - var points, x, y; + var points, x, y; - for (var i = 0; i < this.graphicsData.length; i++) { - + for (var i = 0; i < this.graphicsData.length; i++) { + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; - var data = this.graphicsData[i]; - var type = data.type; - var lineWidth = data.lineWidth; + points = data.points; - points = data.points; + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; - if(type === PIXI.Graphics.RECT) - { - x = points.x - lineWidth/2; - y = points.y - lineWidth/2; - var width = points.width + lineWidth; - var height = points.height + lineWidth; + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; - minX = x < minX ? x : minX; - maxX = x + width > maxX ? x + width : maxX; + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; - minY = y < minY ? x : minY; - maxY = y + height > maxY ? y + height : maxY; - } - else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) - { - x = points.x; - y = points.y; - var radius = points.radius + lineWidth/2; - - minX = x - radius < minX ? x - radius : minX; - maxX = x + radius > maxX ? x + radius : maxX; + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; - minY = y - radius < minY ? y - radius : minY; - maxY = y + radius > maxY ? y + radius : maxY; - } - else - { - // POLY - for (var j = 0; j < points.length; j+=2) - { - - x = points[j]; - y = points[j+1]; + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { - minX = x-lineWidth < minX ? x-lineWidth : minX; - maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + x = points[j]; + y = points[j+1]; - minY = y-lineWidth < minY ? y-lineWidth : minY; - maxY = y+lineWidth > maxY ? y+lineWidth : maxY; - }; - } + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; - }; + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + } + } + } - this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); - - } - -// console.log(this.bounds); -} + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + } +// console.log(this.bounds); +}; // SOME TYPES: PIXI.Graphics.POLY = 0; diff --git a/src/pixi/renderers/canvas/CanvasGraphics.js b/src/pixi/renderers/canvas/CanvasGraphics.js index f5352b9b..a34c4002 100644 --- a/src/pixi/renderers/canvas/CanvasGraphics.js +++ b/src/pixi/renderers/canvas/CanvasGraphics.js @@ -11,7 +11,7 @@ PIXI.CanvasGraphics = function() { -} +}; /* @@ -25,128 +25,128 @@ PIXI.CanvasGraphics = function() */ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) { - var worldAlpha = graphics.worldAlpha; + var worldAlpha = graphics.worldAlpha; + var color = ''; - for (var i=0; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - var points = data.points; + for (var i = 0; i < graphics.graphicsData.length; i++) + { + var data = graphics.graphicsData[i]; + var points = data.points; - context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6); + context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6); - context.lineWidth = data.lineWidth; + context.lineWidth = data.lineWidth; - if(data.type == PIXI.Graphics.POLY) - { - context.beginPath(); + if(data.type === PIXI.Graphics.POLY) + { + context.beginPath(); - context.moveTo(points[0], points[1]); + context.moveTo(points[0], points[1]); - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } + for (var j=1; j < points.length/2; j++) + { + context.lineTo(points[j * 2], points[j * 2 + 1]); + } - // if the first and last point are the same close the path - much neater :) - if(points[0] == points[points.length-2] && points[1] == points[points.length-1]) - { - context.closePath(); - } + // if the first and last point are the same close the path - much neater :) + if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) + { + context.closePath(); + } - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - else if(data.type == PIXI.Graphics.RECT) - { + if(data.fill) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fill(); + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.stroke(); + } + } + else if(data.type === PIXI.Graphics.RECT) + { - if(data.fillColor || data.fillColor === 0) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fillRect(points[0], points[1], points[2], points[3]); + if(data.fillColor || data.fillColor === 0) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fillRect(points[0], points[1], points[2], points[3]); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeRect(points[0], points[1], points[2], points[3]); - } + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.strokeRect(points[0], points[1], points[2], points[3]); + } - } - else if(data.type == PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(points[0], points[1], points[2],0,2*Math.PI); - context.closePath(); + } + else if(data.type === PIXI.Graphics.CIRC) + { + // TODO - need to be Undefined! + context.beginPath(); + context.arc(points[0], points[1], points[2],0,2*Math.PI); + context.closePath(); - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - else if(data.type == PIXI.Graphics.ELIP) - { + if(data.fill) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fill(); + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.stroke(); + } + } + else if(data.type === PIXI.Graphics.ELIP) + { - // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas + // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - var elipseData = data.points; + var ellipseData = data.points; - var w = elipseData[2] * 2; - var h = elipseData[3] * 2; + var w = ellipseData[2] * 2; + var h = ellipseData[3] * 2; - var x = elipseData[0] - w/2; - var y = elipseData[1] - h/2; + var x = ellipseData[0] - w/2; + var y = ellipseData[1] - h/2; - context.beginPath(); + context.beginPath(); - var kappa = .5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle + var kappa = 0.5522848, + ox = (w / 2) * kappa, // control point offset horizontal + oy = (h / 2) * kappa, // control point offset vertical + xe = x + w, // x-end + ye = y + h, // y-end + xm = x + w / 2, // x-middle + ym = y + h / 2; // y-middle - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); + context.moveTo(x, ym); + context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); + context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); + context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); + context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - context.closePath(); + context.closePath(); - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - - }; -} + if(data.fill) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fill(); + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.stroke(); + } + } + } +}; /* * Renders a graphics mask @@ -159,82 +159,79 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) */ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) { - var worldAlpha = graphics.worldAlpha; + var len = graphics.graphicsData.length; - var len = graphics.graphicsData.length; - if(len === 0)return; + if(len === 0) return; - if(len > 1) - { - len = 1; - console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object") - } + if(len > 1) + { + len = 1; + window.console.log('Pixi.js warning: masks in canvas can only mask using the first path in the graphics object'); + } - for (var i=0; i < 1; i++) - { - var data = graphics.graphicsData[i]; - var points = data.points; + for (var i = 0; i < 1; i++) + { + var data = graphics.graphicsData[i]; + var points = data.points; - if(data.type == PIXI.Graphics.POLY) - { - context.beginPath(); - context.moveTo(points[0], points[1]); + if(data.type === PIXI.Graphics.POLY) + { + context.beginPath(); + context.moveTo(points[0], points[1]); - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } + for (var j=1; j < points.length/2; j++) + { + context.lineTo(points[j * 2], points[j * 2 + 1]); + } - // if the first and last point are the same close the path - much neater :) - if(points[0] == points[points.length-2] && points[1] == points[points.length-1]) - { - context.closePath(); - } + // if the first and last point are the same close the path - much neater :) + if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) + { + context.closePath(); + } - } - else if(data.type == PIXI.Graphics.RECT) - { - context.beginPath(); - context.rect(points[0], points[1], points[2], points[3]); - context.closePath(); - } - else if(data.type == PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(points[0], points[1], points[2],0,2*Math.PI); - context.closePath(); - } - else if(data.type == PIXI.Graphics.ELIP) - { + } + else if(data.type === PIXI.Graphics.RECT) + { + context.beginPath(); + context.rect(points[0], points[1], points[2], points[3]); + context.closePath(); + } + else if(data.type === PIXI.Graphics.CIRC) + { + // TODO - need to be Undefined! + context.beginPath(); + context.arc(points[0], points[1], points[2],0,2*Math.PI); + context.closePath(); + } + else if(data.type === PIXI.Graphics.ELIP) + { - // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - var elipseData = data.points; + // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas + var ellipseData = data.points; - var w = elipseData[2] * 2; - var h = elipseData[3] * 2; + var w = ellipseData[2] * 2; + var h = ellipseData[3] * 2; - var x = elipseData[0] - w/2; - var y = elipseData[1] - h/2; + var x = ellipseData[0] - w/2; + var y = ellipseData[1] - h/2; - context.beginPath(); + context.beginPath(); - var kappa = .5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle + var kappa = 0.5522848, + ox = (w / 2) * kappa, // control point offset horizontal + oy = (h / 2) * kappa, // control point offset vertical + xe = x + w, // x-end + ye = y + h, // y-end + xm = x + w / 2, // x-middle + ym = y + h / 2; // y-middle - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - context.closePath(); - } - - - }; -} + context.moveTo(x, ym); + context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); + context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); + context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); + context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); + context.closePath(); + } + } +}; diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js index aa15b4fe..8062a6eb 100644 --- a/src/pixi/renderers/canvas/CanvasRenderer.js +++ b/src/pixi/renderers/canvas/CanvasRenderer.js @@ -2,7 +2,6 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** * the CanvasRenderer draws the stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. * Dont forget to add the view to your DOM or you will not see anything :) @@ -16,49 +15,63 @@ */ PIXI.CanvasRenderer = function(width, height, view, transparent) { - this.transparent = transparent; + this.transparent = transparent; - /** - * The width of the canvas view - * - * @property width - * @type Number - * @default 800 - */ - this.width = width || 800; + /** + * The width of the canvas view + * + * @property width + * @type Number + * @default 800 + */ + this.width = width || 800; - /** - * The height of the canvas view - * - * @property height - * @type Number - * @default 600 - */ - this.height = height || 600; + /** + * The height of the canvas view + * + * @property height + * @type Number + * @default 600 + */ + this.height = height || 600; - /** - * The canvas element that the everything is drawn to - * - * @property view - * @type Canvas - */ - this.view = view || document.createElement( 'canvas' ); + /** + * The canvas element that the everything is drawn to + * + * @property view + * @type Canvas + */ + this.view = view || document.createElement( 'canvas' ); - /** - * The canvas context that the everything is drawn to - * @property context - * @type Canvas 2d Context - */ - this.context = this.view.getContext("2d"); + /** + * The canvas context that the everything is drawn to + * @property context + * @type Canvas 2d Context + */ + this.context = this.view.getContext( '2d' ); + + //some filter variables + this.smoothProperty = null; + + if('imageSmoothingEnabled' in this.context) + this.smoothProperty = 'imageSmoothingEnabled'; + else if('webkitImageSmoothingEnabled' in this.context) + this.smoothProperty = 'webkitImageSmoothingEnabled'; + else if('mozImageSmoothingEnabled' in this.context) + this.smoothProperty = 'mozImageSmoothingEnabled'; + else if('oImageSmoothingEnabled' in this.context) + this.smoothProperty = 'oImageSmoothingEnabled'; + + this.scaleMode = null; + + this.refresh = true; + // hack to enable some hardware acceleration! + //this.view.style["transform"] = "translatez(0)"; - this.refresh = true; - // hack to enable some hardware acceleration! - //this.view.style["transform"] = "translatez(0)"; - this.view.width = this.width; - this.view.height = this.height; - this.count = 0; -} + this.view.height = this.height; + this.count = 0; +}; // constructor PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; @@ -71,44 +84,42 @@ PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; */ PIXI.CanvasRenderer.prototype.render = function(stage) { - - //stage.__childrenAdded = []; - //stage.__childrenRemoved = []; - - // update textures if need be - PIXI.texturesToUpdate = []; - PIXI.texturesToDestroy = []; - - PIXI.visibleCount++; - stage.updateTransform(); - - // update the background color - if(this.view.style.backgroundColor!=stage.backgroundColorString && !this.transparent)this.view.style.backgroundColor = stage.backgroundColorString; + //stage.__childrenAdded = []; + //stage.__childrenRemoved = []; - this.context.setTransform(1,0,0,1,0,0); - this.context.clearRect(0, 0, this.width, this.height) + // update textures if need be + PIXI.texturesToUpdate = []; + PIXI.texturesToDestroy = []; + + PIXI.visibleCount++; + stage.updateTransform(); + + // update the background color + if(this.view.style.backgroundColor !== stage.backgroundColorString && !this.transparent) + this.view.style.backgroundColor = stage.backgroundColorString; + + this.context.setTransform(1,0,0,1,0,0); + this.context.clearRect(0, 0, this.width, this.height); this.renderDisplayObject(stage); //as - + // run interaction! - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } - - // remove frame updates.. - if(PIXI.Texture.frameUpdates.length > 0) - { - PIXI.Texture.frameUpdates = []; - } - - -} + if(stage.interactive) + { + //need to add some events! + if(!stage._interactiveEventsAdded) + { + stage._interactiveEventsAdded = true; + stage.interactionManager.setTarget(this); + } + } + + // remove frame updates.. + if(PIXI.Texture.frameUpdates.length > 0) + { + PIXI.Texture.frameUpdates = []; + } +}; /** * resizes the canvas view to the specified width and height @@ -119,12 +130,12 @@ PIXI.CanvasRenderer.prototype.render = function(stage) */ PIXI.CanvasRenderer.prototype.resize = function(width, height) { - this.width = width; - this.height = height; - - this.view.width = width; - this.view.height = height; -} + this.width = width; + this.height = height; + + this.view.width = width; + this.view.height = height; +}; /** * Renders a display object @@ -135,118 +146,116 @@ PIXI.CanvasRenderer.prototype.resize = function(width, height) */ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) { - // no loger recurrsive! - var transform; - var context = this.context; - - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - var testObject = displayObject.last._iNext; - displayObject = displayObject.first; - - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { + // no loger recurrsive! + var transform; + var context = this.context; - var frame = displayObject.texture.frame; + context.globalCompositeOperation = 'source-over'; - //ignore null sources - if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; + // one the display object hits this. we can break the loop + var testObject = displayObject.last._iNext; + displayObject = displayObject.first; - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]) - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - else - { - // only masks supported right now! - } - } - // count++ - displayObject = displayObject._iNext; - - - } - while(displayObject != testObject) + do + { + transform = displayObject.worldTransform; - -} + if(!displayObject.visible) + { + displayObject = displayObject.last._iNext; + continue; + } + + if(!displayObject.renderable) + { + displayObject = displayObject._iNext; + continue; + } + + if(displayObject instanceof PIXI.Sprite) + { + + var frame = displayObject.texture.frame; + + //ignore null sources + if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) + { + context.globalAlpha = displayObject.worldAlpha; + + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + + //if smoothingEnabled is supported and we need to change the smoothing property for this texture + if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { + this.scaleMode = displayObject.texture.baseTexture.scaleMode; + context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); + } + + context.drawImage(displayObject.texture.baseTexture.source, + frame.x, + frame.y, + frame.width, + frame.height, + (displayObject.anchor.x) * -frame.width, + (displayObject.anchor.y) * -frame.height, + frame.width, + frame.height); + } + } + else if(displayObject instanceof PIXI.Strip) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + this.renderStrip(displayObject); + } + else if(displayObject instanceof PIXI.TilingSprite) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + this.renderTilingSprite(displayObject); + } + else if(displayObject instanceof PIXI.CustomRenderable) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + displayObject.renderCanvas(this); + } + else if(displayObject instanceof PIXI.Graphics) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + PIXI.CanvasGraphics.renderGraphics(displayObject, context); + } + else if(displayObject instanceof PIXI.FilterBlock) + { + if(displayObject.data instanceof PIXI.Graphics) + { + var mask = displayObject.data; + + if(displayObject.open) + { + context.save(); + + var cacheAlpha = mask.alpha; + var maskTransform = mask.worldTransform; + + context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); + + mask.worldAlpha = 0.5; + + context.worldAlpha = 0; + + PIXI.CanvasGraphics.renderGraphicsMask(mask, context); + context.clip(); + + mask.worldAlpha = cacheAlpha; + } + else + { + context.restore(); + } + } + } + //count++ + displayObject = displayObject._iNext; + } + while(displayObject !== testObject); +}; /** * Renders a flat strip @@ -257,33 +266,30 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) */ PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip) { - var context = this.context; - var verticies = strip.verticies; - var uvs = strip.uvs; - - var length = verticies.length/2; - this.count++; - - context.beginPath(); - for (var i=1; i < length-2; i++) - { - - // draw some triangles! - var index = i*2; - - var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; - var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - - }; - - context.fillStyle = "#FF0000"; - context.fill(); - context.closePath(); -} + var context = this.context; + var verticies = strip.verticies; + + var length = verticies.length/2; + this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + } + + context.fillStyle = '#FF0000'; + context.fill(); + context.closePath(); +}; /** * Renders a tiling sprite @@ -294,29 +300,30 @@ PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip) */ PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) { - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, "repeat"); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - + var context = this.context; + + context.globalAlpha = sprite.worldAlpha; + + if(!sprite.__tilePattern) + sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); + + context.beginPath(); + + var tilePosition = sprite.tilePosition; + var tileScale = sprite.tileScale; + // offset context.scale(tileScale.x,tileScale.y); context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); + + context.fillStyle = sprite.__tilePattern; + context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); + + context.scale(1/tileScale.x, 1/tileScale.y); context.translate(-tilePosition.x, -tilePosition.y); - + context.closePath(); -} +}; /** * Renders a strip @@ -327,55 +334,49 @@ PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) */ PIXI.CanvasRenderer.prototype.renderStrip = function(strip) { - var context = this.context; + var context = this.context; - // draw triangles!! - var verticies = strip.verticies; - var uvs = strip.uvs; - - var length = verticies.length/2; - this.count++; - for (var i=1; i < length-2; i++) - { - - // draw some triangles! - var index = i*2; - - var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; - var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; - - var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width; - var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height; + // draw triangles!! + var verticies = strip.verticies; + var uvs = strip.uvs; + var length = verticies.length/2; + this.count++; + + for (var i = 1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width; + var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height; + + context.save(); + context.beginPath(); + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + context.closePath(); + + context.clip(); - context.save(); - context.beginPath(); - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - context.closePath(); - - context.clip(); - - // Compute matrix transform var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2; - var delta_a = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; - var delta_b = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; - var delta_c = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; - var delta_d = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; - var delta_e = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; - var delta_f = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; - - - - - context.transform(delta_a/delta, delta_d/delta, - delta_b/delta, delta_e/delta, - delta_c/delta, delta_f/delta); - - context.drawImage(strip.texture.baseTexture.source, 0, 0); - context.restore(); - }; - -} + var deltaA = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; + var deltaB = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; + var deltaC = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; + var deltaD = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; + var deltaE = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; + var deltaF = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(strip.texture.baseTexture.source, 0, 0); + context.restore(); + } +}; diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js index f7fbf850..01721c07 100644 --- a/src/pixi/renderers/webgl/PixiShader.js +++ b/src/pixi/renderers/webgl/PixiShader.js @@ -12,26 +12,25 @@ PIXI.PixiShader = function() /** * @property {any} program - The WebGL program. */ - this.program; - + this.program = null; + /** * @property {array} fragmentSrc - The fragment shader. */ this.fragmentSrc = [ - "precision lowp float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;", - "}" + 'precision lowp float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform sampler2D uSampler;', + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + '}' ]; /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ this.textureCount = 0; - }; /** @@ -39,23 +38,23 @@ PIXI.PixiShader = function() */ PIXI.PixiShader.prototype.init = function() { - var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc) - + var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc); + var gl = PIXI.gl; gl.useProgram(program); - + // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, "uSampler"); - this.projectionVector = gl.getUniformLocation(program, "projectionVector"); - this.offsetVector = gl.getUniformLocation(program, "offsetVector"); - this.dimensions = gl.getUniformLocation(program, "dimensions"); - + this.uSampler = gl.getUniformLocation(program, 'uSampler'); + this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); + this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.dimensions = gl.getUniformLocation(program, 'dimensions'); + // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); - this.colorAttribute = gl.getAttribLocation(program, "aColor"); - this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); - + this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); + this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); + // add those custom shaders! for (var key in this.uniforms) { @@ -64,7 +63,7 @@ PIXI.PixiShader.prototype.init = function() } this.initUniforms(); - + this.program = program; }; @@ -80,13 +79,14 @@ PIXI.PixiShader.prototype.initUniforms = function() this.textureCount = 1; var uniform; - - for (var key in this.uniforms) + + for (var key in this.uniforms) { - var uniform = this.uniforms[key]; + uniform = this.uniforms[key]; + var type = uniform.type; - if (type == 'sampler2D') + if (type === 'sampler2D') { uniform._init = false; @@ -95,21 +95,21 @@ PIXI.PixiShader.prototype.initUniforms = function() this.initSampler2D(uniform); } } - else if (type == 'mat2' || type == 'mat3' || type == 'mat4') + else if (type === 'mat2' || type === 'mat3' || type === 'mat4') { // These require special handling uniform.glMatrix = true; uniform.glValueLength = 1; - if (type == 'mat2') + if (type === 'mat2') { uniform.glFunc = PIXI.gl.uniformMatrix2fv; } - else if (type == 'mat3') + else if (type === 'mat3') { uniform.glFunc = PIXI.gl.uniformMatrix3fv; } - else if (type == 'mat4') + else if (type === 'mat4') { uniform.glFunc = PIXI.gl.uniformMatrix4fv; } @@ -119,15 +119,15 @@ PIXI.PixiShader.prototype.initUniforms = function() // GL function reference uniform.glFunc = PIXI.gl['uniform' + type]; - if (type == '2f' || type == '2i') + if (type === '2f' || type === '2i') { uniform.glValueLength = 2; } - else if (type == '3f' || type == '3i') + else if (type === '3f' || type === '3i') { uniform.glValueLength = 3; } - else if (type == '4f' || type == '4i') + else if (type === '4f' || type === '4i') { uniform.glValueLength = 4; } @@ -137,7 +137,7 @@ PIXI.PixiShader.prototype.initUniforms = function() } } } - + }; /** @@ -224,12 +224,12 @@ PIXI.PixiShader.prototype.syncUniforms = function() var uniform; // This would probably be faster in an array and it would guarantee key order - for (var key in this.uniforms) + for (var key in this.uniforms) { uniform = this.uniforms[key]; - if (uniform.glValueLength == 1) + if (uniform.glValueLength === 1) { if (uniform.glMatrix === true) { @@ -240,19 +240,19 @@ PIXI.PixiShader.prototype.syncUniforms = function() uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value); } } - else if (uniform.glValueLength == 2) + else if (uniform.glValueLength === 2) { uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y); } - else if (uniform.glValueLength == 3) + else if (uniform.glValueLength === 3) { uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z); } - else if (uniform.glValueLength == 4) + else if (uniform.glValueLength === 4) { uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w); } - else if (uniform.type == 'sampler2D') + else if (uniform.type === 'sampler2D') { if (uniform._init) { @@ -267,26 +267,25 @@ PIXI.PixiShader.prototype.syncUniforms = function() } } } - + }; PIXI.PixiShader.defaultVertexSrc = [ - - "attribute vec2 aVertexPosition;", - "attribute vec2 aTextureCoord;", - "attribute float aColor;", + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute float aColor;', - "uniform vec2 projectionVector;", - "uniform vec2 offsetVector;", - "varying vec2 vTextureCoord;", + 'uniform vec2 projectionVector;', + 'uniform vec2 offsetVector;', + 'varying vec2 vTextureCoord;', - "varying float vColor;", + 'varying float vColor;', - "const vec2 center = vec2(-1.0, 1.0);", - - "void main(void) {", - "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", - "vTextureCoord = aTextureCoord;", - "vColor = aColor;", - "}" + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void) {', + ' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = aColor;', + '}' ]; diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js index 1089d84d..b206e79a 100644 --- a/src/pixi/renderers/webgl/PrimitiveShader.js +++ b/src/pixi/renderers/webgl/PrimitiveShader.js @@ -5,53 +5,54 @@ PIXI.PrimitiveShader = function() { - // the webGL program.. - this.program; - + // the webGL program.. + this.program = null; + this.fragmentSrc = [ - "precision mediump float;", - "varying vec4 vColor;", - "void main(void) {", - "gl_FragColor = vColor;", - "}" + 'precision mediump float;', + 'varying vec4 vColor;', + + 'void main(void) {', + ' gl_FragColor = vColor;', + '}' ]; this.vertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec4 aColor;", - "uniform mat3 translationMatrix;", - "uniform vec2 projectionVector;", - "uniform vec2 offsetVector;", - "uniform float alpha;", - "varying vec4 vColor;", - "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);", - "v -= offsetVector.xyx;", - "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", - "vColor = aColor * alpha;", - "}" + 'attribute vec2 aVertexPosition;', + 'attribute vec4 aColor;', + 'uniform mat3 translationMatrix;', + 'uniform vec2 projectionVector;', + 'uniform vec2 offsetVector;', + 'uniform float alpha;', + 'varying vec4 vColor;', + + 'void main(void) {', + ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', + ' v -= offsetVector.xyx;', + ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);', + ' vColor = aColor * alpha;', + '}' ]; - -} +}; PIXI.PrimitiveShader.prototype.init = function() { - var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); - - var gl = PIXI.gl; - - gl.useProgram(program); - - // get and store the uniforms for the shader - this.projectionVector = gl.getUniformLocation(program, "projectionVector"); - this.offsetVector = gl.getUniformLocation(program, "offsetVector"); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); - this.colorAttribute = gl.getAttribLocation(program, "aColor"); - - this.translationMatrix = gl.getUniformLocation(program, "translationMatrix"); - this.alpha = gl.getUniformLocation(program, "alpha"); + var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); - this.program = program; -} + var gl = PIXI.gl; + + gl.useProgram(program); + + // get and store the uniforms for the shader + this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); + this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); + this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + + this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); + this.alpha = gl.getUniformLocation(program, 'alpha'); + + this.program = program; +}; diff --git a/src/pixi/renderers/webgl/StripShader.js b/src/pixi/renderers/webgl/StripShader.js index 80d8394c..e82f33ad 100644 --- a/src/pixi/renderers/webgl/StripShader.js +++ b/src/pixi/renderers/webgl/StripShader.js @@ -5,61 +5,63 @@ PIXI.StripShader = function() { - // the webGL program.. - this.program; - + // the webGL program.. + this.program = null; + this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float alpha;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));", - "gl_FragColor = gl_FragColor * alpha;", - "}" + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float alpha;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));', + ' gl_FragColor = gl_FragColor * alpha;', + '}' ]; this.vertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec2 aTextureCoord;", - "attribute float aColor;", - "uniform mat3 translationMatrix;", - "uniform vec2 projectionVector;", - "varying vec2 vTextureCoord;", - "varying vec2 offsetVector;", - "varying float vColor;", - "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", - "v -= offsetVector.xyx;", - "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);", - "vTextureCoord = aTextureCoord;", - "vColor = aColor;", - "}" + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute float aColor;', + 'uniform mat3 translationMatrix;', + 'uniform vec2 projectionVector;', + 'varying vec2 vTextureCoord;', + 'varying vec2 offsetVector;', + 'varying float vColor;', + + 'void main(void) {', + ' vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);', + ' v -= offsetVector.xyx;', + ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = aColor;', + '}' ]; -} +}; PIXI.StripShader.prototype.init = function() { - var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc) - - var gl = PIXI.gl; - + var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); + + var gl = PIXI.gl; + gl.useProgram(program); - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, "uSampler"); - this.projectionVector = gl.getUniformLocation(program, "projectionVector"); - this.offsetVector = gl.getUniformLocation(program, "offsetVector"); - this.colorAttribute = gl.getAttribLocation(program, "aColor"); - //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); - this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); - - this.translationMatrix = gl.getUniformLocation(program, "translationMatrix"); - this.alpha = gl.getUniformLocation(program, "alpha"); - - this.program = program; -} + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, 'uSampler'); + this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); + this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + //this.dimensions = gl.getUniformLocation(this.program, 'dimensions'); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); + this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); + + this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); + this.alpha = gl.getUniformLocation(program, 'alpha'); + + this.program = program; +}; diff --git a/src/pixi/renderers/webgl/WebGLBatch.js b/src/pixi/renderers/webgl/WebGLBatch.js index fa09fc43..ba719b36 100644 --- a/src/pixi/renderers/webgl/WebGLBatch.js +++ b/src/pixi/renderers/webgl/WebGLBatch.js @@ -9,35 +9,35 @@ PIXI._batchs = []; */ PIXI._getBatch = function(gl) { - if(PIXI._batchs.length == 0) - { - return new PIXI.WebGLBatch(gl); - } - else - { - return PIXI._batchs.pop(); - } -} + if(PIXI._batchs.length === 0) + { + return new PIXI.WebGLBatch(gl); + } + else + { + return PIXI._batchs.pop(); + } +}; /** * @private */ PIXI._returnBatch = function(batch) { - batch.clean(); - PIXI._batchs.push(batch); -} + batch.clean(); + PIXI._batchs.push(batch); +}; /** * @private */ PIXI._restoreBatchs = function(gl) { - for (var i=0; i < PIXI._batchs.length; i++) - { - PIXI._batchs[i].restoreLostContext(gl); - }; -} + for (var i=0; i < PIXI._batchs.length; i++) + { + PIXI._batchs[i].restoreLostContext(gl); + } +}; /** * A WebGLBatch Enables a group of sprites to be drawn using the same settings. @@ -53,17 +53,17 @@ PIXI._restoreBatchs = function(gl) */ PIXI.WebGLBatch = function(gl) { - this.gl = gl; - - this.size = 0; + this.gl = gl; - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.blendMode = PIXI.blendModes.NORMAL; - this.dynamicSize = 1; -} + this.size = 0; + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.colorBuffer = gl.createBuffer(); + this.blendMode = PIXI.blendModes.NORMAL; + this.dynamicSize = 1; +}; // constructor PIXI.WebGLBatch.prototype.constructor = PIXI.WebGLBatch; @@ -75,17 +75,17 @@ PIXI.WebGLBatch.prototype.constructor = PIXI.WebGLBatch; */ PIXI.WebGLBatch.prototype.clean = function() { - this.verticies = []; - this.uvs = []; - this.indices = []; - this.colors = []; - this.dynamicSize = 1; - this.texture = null; - this.last = null; - this.size = 0; - this.head; - this.tail; -} + this.verticies = []; + this.uvs = []; + this.indices = []; + this.colors = []; + this.dynamicSize = 1; + this.texture = null; + this.last = null; + this.size = 0; + this.head = null; + this.tail = null; +}; /** * Recreates the buffers in the event of a context loss @@ -95,32 +95,32 @@ PIXI.WebGLBatch.prototype.clean = function() */ PIXI.WebGLBatch.prototype.restoreLostContext = function(gl) { - this.gl = gl; - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); -} + this.gl = gl; + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.colorBuffer = gl.createBuffer(); +}; /** * inits the batch's texture and blend mode based if the supplied sprite * * @method init * @param sprite {Sprite} the first sprite to be added to the batch. Only sprites with - * the same base texture and blend mode will be allowed to be added to this batch - */ + * the same base texture and blend mode will be allowed to be added to this batch + */ PIXI.WebGLBatch.prototype.init = function(sprite) { - sprite.batch = this; - this.dirty = true; - this.blendMode = sprite.blendMode; - this.texture = sprite.texture.baseTexture; - this.head = sprite; - this.tail = sprite; - this.size = 1; + sprite.batch = this; + this.dirty = true; + this.blendMode = sprite.blendMode; + this.texture = sprite.texture.baseTexture; + this.head = sprite; + this.tail = sprite; + this.size = 1; - this.growBatch(); -} + this.growBatch(); +}; /** * inserts a sprite before the specified sprite @@ -128,27 +128,27 @@ PIXI.WebGLBatch.prototype.init = function(sprite) * @method insertBefore * @param sprite {Sprite} the sprite to be added * @param nextSprite {nextSprite} the first sprite will be inserted before this sprite - */ + */ PIXI.WebGLBatch.prototype.insertBefore = function(sprite, nextSprite) { - this.size++; + this.size++; - sprite.batch = this; - this.dirty = true; - var tempPrev = nextSprite.__prev; - nextSprite.__prev = sprite; - sprite.__next = nextSprite; + sprite.batch = this; + this.dirty = true; + var tempPrev = nextSprite.__prev; + nextSprite.__prev = sprite; + sprite.__next = nextSprite; - if(tempPrev) - { - sprite.__prev = tempPrev; - tempPrev.__next = sprite; - } - else - { - this.head = sprite; - } -} + if(tempPrev) + { + sprite.__prev = tempPrev; + tempPrev.__next = sprite; + } + else + { + this.head = sprite; + } +}; /** * inserts a sprite after the specified sprite @@ -156,72 +156,72 @@ PIXI.WebGLBatch.prototype.insertBefore = function(sprite, nextSprite) * @method insertAfter * @param sprite {Sprite} the sprite to be added * @param previousSprite {Sprite} the first sprite will be inserted after this sprite - */ + */ PIXI.WebGLBatch.prototype.insertAfter = function(sprite, previousSprite) { - this.size++; + this.size++; - sprite.batch = this; - this.dirty = true; + sprite.batch = this; + this.dirty = true; - var tempNext = previousSprite.__next; - previousSprite.__next = sprite; - sprite.__prev = previousSprite; + var tempNext = previousSprite.__next; + previousSprite.__next = sprite; + sprite.__prev = previousSprite; - if(tempNext) - { - sprite.__next = tempNext; - tempNext.__prev = sprite; - } - else - { - this.tail = sprite - } -} + if(tempNext) + { + sprite.__next = tempNext; + tempNext.__prev = sprite; + } + else + { + this.tail = sprite; + } +}; /** * removes a sprite from the batch * * @method remove * @param sprite {Sprite} the sprite to be removed - */ + */ PIXI.WebGLBatch.prototype.remove = function(sprite) { - this.size--; + this.size--; - if(this.size == 0) - { - sprite.batch = null; - sprite.__prev = null; - sprite.__next = null; - return; - } + if(this.size === 0) + { + sprite.batch = null; + sprite.__prev = null; + sprite.__next = null; + return; + } - if(sprite.__prev) - { - sprite.__prev.__next = sprite.__next; - } - else - { - this.head = sprite.__next; - this.head.__prev = null; - } + if(sprite.__prev) + { + sprite.__prev.__next = sprite.__next; + } + else + { + this.head = sprite.__next; + this.head.__prev = null; + } - if(sprite.__next) - { - sprite.__next.__prev = sprite.__prev; - } - else - { - this.tail = sprite.__prev; - this.tail.__next = null - } + if(sprite.__next) + { + sprite.__next.__prev = sprite.__prev; + } + else + { + this.tail = sprite.__prev; + this.tail.__next = null; + } - sprite.batch = null; - sprite.__next = null; - sprite.__prev = null; - this.dirty = true; -} + sprite.batch = null; + sprite.__next = null; + sprite.__prev = null; + this.dirty = true; +}; /** * Splits the batch into two with the specified sprite being the start of the new batch. @@ -232,62 +232,62 @@ PIXI.WebGLBatch.prototype.remove = function(sprite) */ PIXI.WebGLBatch.prototype.split = function(sprite) { - this.dirty = true; + this.dirty = true; - var batch = new PIXI.WebGLBatch(this.gl); - batch.init(sprite); - batch.texture = this.texture; - batch.tail = this.tail; + var batch = new PIXI.WebGLBatch(this.gl); + batch.init(sprite); + batch.texture = this.texture; + batch.tail = this.tail; - this.tail = sprite.__prev; - this.tail.__next = null; + this.tail = sprite.__prev; + this.tail.__next = null; - sprite.__prev = null; - // return a splite batch! + sprite.__prev = null; + // return a splite batch! - // TODO this size is wrong! - // need to recalculate :/ problem with a linked list! - // unless it gets calculated in the "clean"? + // TODO this size is wrong! + // need to recalculate :/ problem with a linked list! + // unless it gets calculated in the "clean"? - // need to loop through items as there is no way to know the length on a linked list :/ - var tempSize = 0; - while(sprite) - { - tempSize++; - sprite.batch = batch; - sprite = sprite.__next; - } + // need to loop through items as there is no way to know the length on a linked list :/ + var tempSize = 0; + while(sprite) + { + tempSize++; + sprite.batch = batch; + sprite = sprite.__next; + } - batch.size = tempSize; - this.size -= tempSize; + batch.size = tempSize; + this.size -= tempSize; - return batch; -} + return batch; +}; /** * Merges two batchs together * * @method merge - * @param batch {WebGLBatch} the batch that will be merged + * @param batch {WebGLBatch} the batch that will be merged */ PIXI.WebGLBatch.prototype.merge = function(batch) { - this.dirty = true; + this.dirty = true; - this.tail.__next = batch.head; - batch.head.__prev = this.tail; + this.tail.__next = batch.head; + batch.head.__prev = this.tail; - this.size += batch.size; + this.size += batch.size; - this.tail = batch.tail; + this.tail = batch.tail; - var sprite = batch.head; - while(sprite) - { - sprite.batch = this; - sprite = sprite.__next; - } -} + var sprite = batch.head; + while(sprite) + { + sprite.batch = this; + sprite = sprite.__next; + } +}; /** * Grows the size of the batch. As the elements in the batch cannot have a dynamic size this @@ -298,51 +298,52 @@ PIXI.WebGLBatch.prototype.merge = function(batch) */ PIXI.WebGLBatch.prototype.growBatch = function() { - var gl = this.gl; - if( this.size == 1) - { - this.dynamicSize = 1; - } - else - { - this.dynamicSize = this.size * 1.5 - } - // grow verts - this.verticies = new Float32Array(this.dynamicSize * 8); + var gl = this.gl; + if( this.size === 1) + { + this.dynamicSize = 1; + } + else + { + this.dynamicSize = this.size * 1.5; + } - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW); + // grow verts + this.verticies = new Float32Array(this.dynamicSize * 8); - this.uvs = new Float32Array( this.dynamicSize * 8 ); - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvs , gl.DYNAMIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW); - this.dirtyUVS = true; + this.uvs = new Float32Array( this.dynamicSize * 8 ); + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.uvs , gl.DYNAMIC_DRAW); - this.colors = new Float32Array( this.dynamicSize * 4 ); - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colors , gl.DYNAMIC_DRAW); + this.dirtyUVS = true; - this.dirtyColors = true; + this.colors = new Float32Array( this.dynamicSize * 4 ); + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.colors , gl.DYNAMIC_DRAW); - this.indices = new Uint16Array(this.dynamicSize * 6); - var length = this.indices.length/6; + this.dirtyColors = true; - for (var i=0; i < length; i++) - { - var index2 = i * 6; - var index3 = i * 4; - this.indices[index2 + 0] = index3 + 0; - this.indices[index2 + 1] = index3 + 1; - this.indices[index2 + 2] = index3 + 2; - this.indices[index2 + 3] = index3 + 0; - this.indices[index2 + 4] = index3 + 2; - this.indices[index2 + 5] = index3 + 3; - }; + this.indices = new Uint16Array(this.dynamicSize * 6); + var length = this.indices.length/6; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + for (var i = 0; i < length; i++) + { + var index2 = i * 6; + var index3 = i * 4; + this.indices[index2 + 0] = index3 + 0; + this.indices[index2 + 1] = index3 + 1; + this.indices[index2 + 2] = index3 + 2; + this.indices[index2 + 3] = index3 + 0; + this.indices[index2 + 4] = index3 + 2; + this.indices[index2 + 5] = index3 + 3; + } + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); -} +}; /** * Refresh's all the data in the batch and sync's it with the webGL buffers @@ -351,54 +352,51 @@ PIXI.WebGLBatch.prototype.growBatch = function() */ PIXI.WebGLBatch.prototype.refresh = function() { - var gl = this.gl; + if (this.dynamicSize < this.size) + { + this.growBatch(); + } - if (this.dynamicSize < this.size) - { - this.growBatch(); - } + var indexRun = 0; + var index, colorIndex; - var indexRun = 0; - var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index; - var a, b, c, d, tx, ty; + var displayObject = this.head; - var displayObject = this.head; + while(displayObject) + { + index = indexRun * 8; - while(displayObject) - { - index = indexRun * 8; + var texture = displayObject.texture; - var texture = displayObject.texture; + var frame = texture.frame; + var tw = texture.baseTexture.width; + var th = texture.baseTexture.height; - var frame = texture.frame; - var tw = texture.baseTexture.width; - var th = texture.baseTexture.height; + this.uvs[index + 0] = frame.x / tw; + this.uvs[index +1] = frame.y / th; - this.uvs[index + 0] = frame.x / tw; - this.uvs[index +1] = frame.y / th; + this.uvs[index +2] = (frame.x + frame.width) / tw; + this.uvs[index +3] = frame.y / th; - this.uvs[index +2] = (frame.x + frame.width) / tw; - this.uvs[index +3] = frame.y / th; + this.uvs[index +4] = (frame.x + frame.width) / tw; + this.uvs[index +5] = (frame.y + frame.height) / th; - this.uvs[index +4] = (frame.x + frame.width) / tw; - this.uvs[index +5] = (frame.y + frame.height) / th; + this.uvs[index +6] = frame.x / tw; + this.uvs[index +7] = (frame.y + frame.height) / th; - this.uvs[index +6] = frame.x / tw; - this.uvs[index +7] = (frame.y + frame.height) / th; + displayObject.updateFrame = false; - displayObject.updateFrame = false; + colorIndex = indexRun * 4; + this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha; - colorIndex = indexRun * 4; - this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha; + displayObject = displayObject.__next; - displayObject = displayObject.__next; + indexRun++; + } - indexRun ++; - } - - this.dirtyUVS = true; - this.dirtyColors = true; -} + this.dirtyUVS = true; + this.dirtyColors = true; +}; /** * Updates all the relevant geometry and uploads the data to the GPU @@ -407,103 +405,102 @@ PIXI.WebGLBatch.prototype.refresh = function() */ PIXI.WebGLBatch.prototype.update = function() { - var gl = this.gl; - var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3 + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index; - var a, b, c, d, tx, ty; + var a, b, c, d, tx, ty; - var indexRun = 0; + var indexRun = 0; - var displayObject = this.head; - var verticies = this.verticies; - var uvs = this.uvs; - var colors = this.colors; - - while(displayObject) - { - if(displayObject.vcount === PIXI.visibleCount) - { - width = displayObject.texture.frame.width; - height = displayObject.texture.frame.height; + var displayObject = this.head; + var verticies = this.verticies; + var uvs = this.uvs; + var colors = this.colors; - // TODO trim?? - aX = displayObject.anchor.x;// - displayObject.texture.trim.x - aY = displayObject.anchor.y; //- displayObject.texture.trim.y - w0 = width * (1-aX); - w1 = width * -aX; + while(displayObject) + { + if(displayObject.vcount === PIXI.visibleCount) + { + width = displayObject.texture.frame.width; + height = displayObject.texture.frame.height; - h0 = height * (1-aY); - h1 = height * -aY; + // TODO trim?? + aX = displayObject.anchor.x;// - displayObject.texture.trim.x + aY = displayObject.anchor.y; //- displayObject.texture.trim.y + w0 = width * (1-aX); + w1 = width * -aX; - index = indexRun * 8; + h0 = height * (1-aY); + h1 = height * -aY; - worldTransform = displayObject.worldTransform; + index = indexRun * 8; - a = worldTransform[0]; - b = worldTransform[3]; - c = worldTransform[1]; - d = worldTransform[4]; - tx = worldTransform[2]; - ty = worldTransform[5]; + worldTransform = displayObject.worldTransform; - verticies[index + 0 ] = a * w1 + c * h1 + tx; - verticies[index + 1 ] = d * h1 + b * w1 + ty; + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; - verticies[index + 2 ] = a * w0 + c * h1 + tx; - verticies[index + 3 ] = d * h1 + b * w0 + ty; + verticies[index + 0 ] = a * w1 + c * h1 + tx; + verticies[index + 1 ] = d * h1 + b * w1 + ty; - verticies[index + 4 ] = a * w0 + c * h0 + tx; - verticies[index + 5 ] = d * h0 + b * w0 + ty; + verticies[index + 2 ] = a * w0 + c * h1 + tx; + verticies[index + 3 ] = d * h1 + b * w0 + ty; - verticies[index + 6] = a * w1 + c * h0 + tx; - verticies[index + 7] = d * h0 + b * w1 + ty; + verticies[index + 4 ] = a * w0 + c * h0 + tx; + verticies[index + 5 ] = d * h0 + b * w0 + ty; - if(displayObject.updateFrame || displayObject.texture.updateFrame) - { - this.dirtyUVS = true; + verticies[index + 6] = a * w1 + c * h0 + tx; + verticies[index + 7] = d * h0 + b * w1 + ty; - var texture = displayObject.texture; + if(displayObject.updateFrame || displayObject.texture.updateFrame) + { + this.dirtyUVS = true; - var frame = texture.frame; - var tw = texture.baseTexture.width; - var th = texture.baseTexture.height; + var texture = displayObject.texture; - uvs[index + 0] = frame.x / tw; - uvs[index +1] = frame.y / th; + var frame = texture.frame; + var tw = texture.baseTexture.width; + var th = texture.baseTexture.height; - uvs[index +2] = (frame.x + frame.width) / tw; - uvs[index +3] = frame.y / th; + uvs[index + 0] = frame.x / tw; + uvs[index +1] = frame.y / th; - uvs[index +4] = (frame.x + frame.width) / tw; - uvs[index +5] = (frame.y + frame.height) / th; + uvs[index +2] = (frame.x + frame.width) / tw; + uvs[index +3] = frame.y / th; - uvs[index +6] = frame.x / tw; - uvs[index +7] = (frame.y + frame.height) / th; + uvs[index +4] = (frame.x + frame.width) / tw; + uvs[index +5] = (frame.y + frame.height) / th; - displayObject.updateFrame = false; - } + uvs[index +6] = frame.x / tw; + uvs[index +7] = (frame.y + frame.height) / th; - // TODO this probably could do with some optimisation.... - if(displayObject.cacheAlpha != displayObject.worldAlpha) - { - displayObject.cacheAlpha = displayObject.worldAlpha; + displayObject.updateFrame = false; + } - var colorIndex = indexRun * 4; - colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha; - this.dirtyColors = true; - } - } - else - { - index = indexRun * 8; + // TODO this probably could do with some optimisation.... + if(displayObject.cacheAlpha !== displayObject.worldAlpha) + { + displayObject.cacheAlpha = displayObject.worldAlpha; - verticies[index + 0 ] = verticies[index + 1 ] = verticies[index + 2 ] = verticies[index + 3 ] = verticies[index + 4 ] = verticies[index + 5 ] = verticies[index + 6] = verticies[index + 7] = 0; - } + var colorIndex = indexRun * 4; + colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha; + this.dirtyColors = true; + } + } + else + { + index = indexRun * 8; - indexRun++; - displayObject = displayObject.__next; - } -} + verticies[index + 0 ] = verticies[index + 1 ] = verticies[index + 2 ] = verticies[index + 3 ] = verticies[index + 4 ] = verticies[index + 5 ] = verticies[index + 6] = verticies[index + 7] = 0; + } + + indexRun++; + displayObject = displayObject.__next; + } +}; /** * Draws the batch to the frame buffer @@ -512,41 +509,42 @@ PIXI.WebGLBatch.prototype.update = function() */ PIXI.WebGLBatch.prototype.render = function(start, end) { - start = start || 0; + start = start || 0; - if(end == undefined)end = this.size; - - if(this.dirty) - { - this.refresh(); - this.dirty = false; - } + if(end === undefined) + end = this.size; - if (this.size == 0)return; + if(this.dirty) + { + this.refresh(); + this.dirty = false; + } - this.update(); - var gl = this.gl; + if (this.size === 0)return; - //TODO optimize this! + this.update(); + var gl = this.gl; - var shaderProgram = PIXI.defaultShader; - - //gl.useProgram(shaderProgram); + //TODO optimize this! - // update the verts.. - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - // ok.. - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies) + var shaderProgram = PIXI.defaultShader; + + //gl.useProgram(shaderProgram); + + // update the verts.. + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + // ok.. + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies); gl.vertexAttribPointer(shaderProgram.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - // update the uvs - //var isDefault = (shaderProgram == PIXI.shaderProgram) + // update the uvs + //var isDefault = (shaderProgram == PIXI.shaderProgram) - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); if(this.dirtyUVS) { - this.dirtyUVS = false; - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs); + this.dirtyUVS = false; + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs); } gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0); @@ -554,21 +552,21 @@ PIXI.WebGLBatch.prototype.render = function(start, end) gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture); - // update color! - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); + // update color! + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - if(this.dirtyColors) + if(this.dirtyColors) { - this.dirtyColors = false; - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.colors); - } + this.dirtyColors = false; + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.colors); + } gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); - // dont need to upload! + // dont need to upload! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - var len = end - start; + var len = end - start; // DRAW THAT this! gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 ); -} +}; diff --git a/src/pixi/renderers/webgl/WebGLFilterManager.js b/src/pixi/renderers/webgl/WebGLFilterManager.js index a98afb45..2dd4b759 100644 --- a/src/pixi/renderers/webgl/WebGLFilterManager.js +++ b/src/pixi/renderers/webgl/WebGLFilterManager.js @@ -5,524 +5,507 @@ PIXI.WebGLFilterManager = function(transparent) { - this.transparent = transparent; - - this.filterStack = []; - this.texturePool = []; - - this.offsetX = 0; - this.offsetY = 0; - - this.initShaderBuffers(); -} + this.transparent = transparent; + + this.filterStack = []; + this.texturePool = []; + + this.offsetX = 0; + this.offsetY = 0; + + this.initShaderBuffers(); +}; // API PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer) { - this.width = projection.x * 2; - this.height = -projection.y * 2; - this.buffer = buffer; -} + this.width = projection.x * 2; + this.height = -projection.y * 2; + this.buffer = buffer; +}; PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) { - var gl = PIXI.gl; + var gl = PIXI.gl; - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); + // filter program + // OPTIMISATION - the first filter is free if its a simple color change? + this.filterStack.push(filterBlock); - var filter = filterBlock.filterPasses[0]; + var filter = filterBlock.filterPasses[0]; - + this.offsetX += filterBlock.target.filterArea.x; + this.offsetY += filterBlock.target.filterArea.y; - this.offsetX += filterBlock.target.filterArea.x; - this.offsetY += filterBlock.target.filterArea.y; - - - - - - var texture = this.texturePool.pop(); - if(!texture) - { - texture = new PIXI.FilterTexture(this.width, this.height); - } - else - { - texture.resize(this.width, this.height); - } + var texture = this.texturePool.pop(); + if(!texture) + { + texture = new PIXI.FilterTexture(this.width, this.height); + } + else + { + texture.resize(this.width, this.height); + } - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - this.getBounds(filterBlock.target); - - // addpadding? - //displayObject.filterArea.x + gl.bindTexture(gl.TEXTURE_2D, texture.texture); - var filterArea = filterBlock.target.filterArea; + this.getBounds(filterBlock.target); - var padidng = filter.padding; - filterArea.x -= padidng; - filterArea.y -= padidng; - filterArea.width += padidng * 2; - filterArea.height += padidng * 2; + // addpadding? + //displayObject.filterArea.x - // cap filter to screen size.. - if(filterArea.x < 0)filterArea.x = 0; - if(filterArea.width > this.width)filterArea.width = this.width; - if(filterArea.y < 0)filterArea.y = 0; - if(filterArea.height > this.height)filterArea.height = this.height; + var filterArea = filterBlock.target.filterArea; + var padidng = filter.padding; + filterArea.x -= padidng; + filterArea.y -= padidng; + filterArea.width += padidng * 2; + filterArea.height += padidng * 2; - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // console.log(filterArea) - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - PIXI.projection.x = filterArea.width/2; - PIXI.projection.y = -filterArea.height/2; - - PIXI.offset.x = -filterArea.x; - PIXI.offset.y = -filterArea.y; + // cap filter to screen size.. + if(filterArea.x < 0)filterArea.x = 0; + if(filterArea.width > this.width)filterArea.width = this.width; + if(filterArea.y < 0)filterArea.y = 0; + if(filterArea.height > this.height)filterArea.height = this.height; - //console.log(PIXI.defaultShader.projectionVector) - // update projection - gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - //PIXI.primitiveProgram + //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - //filter.texture = texture; - filterBlock._glFilterTexture = texture; + //console.log(filterArea) + // set view port + gl.viewport(0, 0, filterArea.width, filterArea.height); - //console.log("PUSH") -} + PIXI.projection.x = filterArea.width/2; + PIXI.projection.y = -filterArea.height/2; + + PIXI.offset.x = -filterArea.x; + PIXI.offset.y = -filterArea.y; + + //console.log(PIXI.defaultShader.projectionVector) + // update projection + gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y); + //PIXI.primitiveProgram + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + //filter.texture = texture; + filterBlock._glFilterTexture = texture; + + //console.log("PUSH") +}; PIXI.WebGLFilterManager.prototype.popFilter = function() { - - var gl = PIXI.gl; - - var filterBlock = this.filterStack.pop(); + var gl = PIXI.gl; + var filterBlock = this.filterStack.pop(); + var filterArea = filterBlock.target.filterArea; + var texture = filterBlock._glFilterTexture; + + if(filterBlock.filterPasses.length > 1) + { + gl.viewport(0, 0, filterArea.width, filterArea.height); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + + this.vertexArray[0] = 0; + this.vertexArray[1] = filterArea.height; + + this.vertexArray[2] = filterArea.width; + this.vertexArray[3] = filterArea.height; + + this.vertexArray[4] = 0; + this.vertexArray[5] = 0; + + this.vertexArray[6] = filterArea.width; + this.vertexArray[7] = 0; + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + // nnow set the uvs.. + this.uvArray[2] = filterArea.width/this.width; + this.uvArray[5] = filterArea.height/this.height; + this.uvArray[6] = filterArea.width/this.width; + this.uvArray[7] = filterArea.height/this.height; + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); + + var inputTexture = texture; + var outputTexture = this.texturePool.pop(); + if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height); + + // need to clear this FBO as it may have some left over elements from a prvious filter. + gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.disable(gl.BLEND); + + for (var i = 0; i < filterBlock.filterPasses.length-1; i++) + { + var filterPass = filterBlock.filterPasses[i]; + + gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); + + // draw texture.. + //filterPass.applyFilterPass(filterArea.width, filterArea.height); + this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); + + // swap the textures.. + var temp = inputTexture; + inputTexture = outputTexture; + outputTexture = temp; + } + + gl.enable(gl.BLEND); + + texture = inputTexture; + this.texturePool.push(outputTexture); + } + + var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; + + this.offsetX -= filterArea.x; + this.offsetY -= filterArea.y; + + + var sizeX = this.width; + var sizeY = this.height; + + var offsetX = 0; + var offsetY = 0; + + var buffer = this.buffer; + + // time to render the filters texture to the previous scene + if(this.filterStack.length === 0) + { + gl.colorMask(true, true, true, this.transparent); + } + else + { + var currentFilter = this.filterStack[this.filterStack.length-1]; + filterArea = currentFilter.target.filterArea; + + sizeX = filterArea.width; + sizeY = filterArea.height; + + offsetX = filterArea.x; + offsetY = filterArea.y; + + buffer = currentFilter._glFilterTexture.frameBuffer; + } - var filterArea = filterBlock.target.filterArea; + // TODO need toremove thease global elements.. + PIXI.projection.x = sizeX/2; + PIXI.projection.y = -sizeY/2; - var texture = filterBlock._glFilterTexture; + PIXI.offset.x = offsetX; + PIXI.offset.y = offsetY; - if(filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); + filterArea = filterBlock.target.filterArea; - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; + var x = filterArea.x-offsetX; + var y = filterArea.y-offsetY; + // update the buffers.. + // make sure to flip the y! + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); + this.vertexArray[0] = x; + this.vertexArray[1] = y + filterArea.height; - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // nnow set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); + this.vertexArray[2] = x + filterArea.width; + this.vertexArray[3] = y + filterArea.height; - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a prvious filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); + this.vertexArray[4] = x; + this.vertexArray[5] = y; - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - - }; + this.vertexArray[6] = x + filterArea.width; + this.vertexArray[7] = y; - gl.enable(gl.BLEND); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - texture = inputTexture; - this.texturePool.push(outputTexture); - } + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; + this.uvArray[2] = filterArea.width/this.width; + this.uvArray[5] = filterArea.height/this.height; + this.uvArray[6] = filterArea.width/this.width; + this.uvArray[7] = filterArea.height/this.height; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if(this.filterStack.length === 0) - { - gl.colorMask(true, true, true, this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - var filterArea = currentFilter.target.filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - // TODO need toremove thease global elements.. - PIXI.projection.x = sizeX/2; - PIXI.projection.y = -sizeY/2; + gl.viewport(0, 0, sizeX, sizeY); + // bind the buffer + gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - PIXI.offset.x = offsetX; - PIXI.offset.y = offsetY; - - - var filterArea = filterBlock.target.filterArea; - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set texture + // set texture gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - //filter.applyFilterPass(sizeX, sizeY); - this.applyFilterPass(filter, filterArea, sizeX, sizeY); + gl.bindTexture(gl.TEXTURE_2D, texture.texture); - // now restore the regular shader.. + // apply! + //filter.applyFilterPass(sizeX, sizeY); + this.applyFilterPass(filter, filterArea, sizeX, sizeY); + + // now restore the regular shader.. gl.useProgram(PIXI.defaultShader.program); - gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2); - gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY); + gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY); - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -} + // return the texture to the pool + this.texturePool.push(texture); + filterBlock._glFilterTexture = null; +}; PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height) { - // use program - var gl = PIXI.gl; + // use program + var gl = PIXI.gl; + var shader = filter.shader; - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader; - } + if(!shader) + { + shader = new PIXI.PixiShader(); - var shader = filter.shader; - - // set the shader - gl.useProgram(shader.program); + shader.fragmentSrc = filter.fragmentSrc; + shader.uniforms = filter.uniforms; + shader.init(); - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0) + filter.shader = shader; + } - if(filter.uniforms.dimensions) - { - //console.log(filter.uniforms.dimensions) - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - // console.log(this.vertexArray[5]) - } + // set the shader + gl.useProgram(shader.program); - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.uniform2f(shader.projectionVector, width/2, -height/2); + gl.uniform2f(shader.offsetVector, 0,0); + + if(filter.uniforms.dimensions) + { + //console.log(filter.uniforms.dimensions) + filter.uniforms.dimensions.value[0] = this.width;//width; + filter.uniforms.dimensions.value[1] = this.height;//height; + filter.uniforms.dimensions.value[2] = this.vertexArray[0]; + filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; + // console.log(this.vertexArray[5]) + } + + shader.syncUniforms(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... + + // draw the filter... gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); -} +}; PIXI.WebGLFilterManager.prototype.initShaderBuffers = function() { - var gl = PIXI.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a refferance to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData( - gl.ARRAY_BUFFER, - this.vertexArray, + var gl = PIXI.gl; + + // create some buffers + this.vertexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + // bind and upload the vertexs.. + // keep a refferance to the vertexFloatData.. + this.vertexArray = new Float32Array([0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0]); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + this.vertexArray, gl.STATIC_DRAW); - - + + // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData( - gl.ARRAY_BUFFER, - this.uvArray, + this.uvArray = new Float32Array([0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0]); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + this.uvArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData( - gl.ELEMENT_ARRAY_BUFFER, - new Uint16Array([0, 1, 2, 1, 3, 2]), + + // bind and upload the index + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); -} +}; PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject) { - // time to get the width and height of the object! - var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest; - var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4; + // time to get the width and height of the object! + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, doTest; + var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4; - var tempObject = displayObject.first; - var testObject = displayObject.last._iNext; - - var maxX = -Infinity; - var maxY = -Infinity; - - var minX = Infinity; - var minY = Infinity; - - do - { - // TODO can be optimized! - what if there is no scale / rotation? - - if(tempObject.visible) - { - if(tempObject instanceof PIXI.Sprite) - { - width = tempObject.texture.frame.width; - height = tempObject.texture.frame.height; + var tempObject = displayObject.first; + var testObject = displayObject.last._iNext; - // TODO trim?? - aX = tempObject.anchor.x; - aY = tempObject.anchor.y; - w0 = width * (1-aX); - w1 = width * -aX; + var maxX = -Infinity; + var maxY = -Infinity; - h0 = height * (1-aY); - h1 = height * -aY; + var minX = Infinity; + var minY = Infinity; - doTest = true; - } - else if(tempObject instanceof PIXI.Graphics) - { - tempObject.updateFilterBounds(); + do + { + // TODO can be optimized! - what if there is no scale / rotation? - var bounds = tempObject.bounds; + if(tempObject.visible) + { + if(tempObject instanceof PIXI.Sprite) + { + width = tempObject.texture.frame.width; + height = tempObject.texture.frame.height; - width = bounds.width; - height = bounds.height; + // TODO trim?? + aX = tempObject.anchor.x; + aY = tempObject.anchor.y; + w0 = width * (1-aX); + w1 = width * -aX; - w0 = bounds.x - w1 = bounds.x + bounds.width; + h0 = height * (1-aY); + h1 = height * -aY; - h0 = bounds.y - h1 = bounds.y + bounds.height; + doTest = true; + } + else if(tempObject instanceof PIXI.Graphics) + { + tempObject.updateFilterBounds(); - doTest = true; - } - } - - if(doTest) - { - worldTransform = tempObject.worldTransform; + var bounds = tempObject.bounds; - a = worldTransform[0]; - b = worldTransform[3]; - c = worldTransform[1]; - d = worldTransform[4]; - tx = worldTransform[2]; - ty = worldTransform[5]; + width = bounds.width; + height = bounds.height; - x1 = a * w1 + c * h1 + tx; - y1 = d * h1 + b * w1 + ty; + w0 = bounds.x; + w1 = bounds.x + bounds.width; - x2 = a * w0 + c * h1 + tx; - y2 = d * h1 + b * w0 + ty; + h0 = bounds.y; + h1 = bounds.y + bounds.height; - x3 = a * w0 + c * h0 + tx; - y3 = d * h0 + b * w0 + ty; + doTest = true; + } + } - x4 = a * w1 + c * h0 + tx; - y4 = d * h0 + b * w1 + ty; + if(doTest) + { + worldTransform = tempObject.worldTransform; - minX = x1 < minX ? x1 : minX; - minX = x2 < minX ? x2 : minX; - minX = x3 < minX ? x3 : minX; - minX = x4 < minX ? x4 : minX; - - minY = y1 < minY ? y1 : minY; - minY = y2 < minY ? y2 : minY; - minY = y3 < minY ? y3 : minY; - minY = y4 < minY ? y4 : minY; - - maxX = x1 > maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - } + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; - doTest = false; - tempObject = tempObject._iNext; + x1 = a * w1 + c * h1 + tx; + y1 = d * h1 + b * w1 + ty; - } - while(tempObject != testObject) - - // maximum bounds is the size of the screen.. - //minX = minX > 0 ? minX : 0; - //minY = minY > 0 ? minY : 0; + x2 = a * w0 + c * h1 + tx; + y2 = d * h1 + b * w0 + ty; - displayObject.filterArea.x = minX; - displayObject.filterArea.y = minY; + x3 = a * w0 + c * h0 + tx; + y3 = d * h0 + b * w0 + ty; -// console.log(maxX+ " : " + minX) - displayObject.filterArea.width = maxX - minX; - displayObject.filterArea.height = maxY - minY; -} + x4 = a * w1 + c * h0 + tx; + y4 = d * h0 + b * w1 + ty; + + minX = x1 < minX ? x1 : minX; + minX = x2 < minX ? x2 : minX; + minX = x3 < minX ? x3 : minX; + minX = x4 < minX ? x4 : minX; + + minY = y1 < minY ? y1 : minY; + minY = y2 < minY ? y2 : minY; + minY = y3 < minY ? y3 : minY; + minY = y4 < minY ? y4 : minY; + + maxX = x1 > maxX ? x1 : maxX; + maxX = x2 > maxX ? x2 : maxX; + maxX = x3 > maxX ? x3 : maxX; + maxX = x4 > maxX ? x4 : maxX; + + maxY = y1 > maxY ? y1 : maxY; + maxY = y2 > maxY ? y2 : maxY; + maxY = y3 > maxY ? y3 : maxY; + maxY = y4 > maxY ? y4 : maxY; + } + + doTest = false; + tempObject = tempObject._iNext; + + } + while(tempObject !== testObject); + + // maximum bounds is the size of the screen.. + //minX = minX > 0 ? minX : 0; + //minY = minY > 0 ? minY : 0; + + displayObject.filterArea.x = minX; + displayObject.filterArea.y = minY; + +// console.log(maxX+ " : " + minX) + displayObject.filterArea.width = maxX - minX; + displayObject.filterArea.height = maxY - minY; +}; PIXI.FilterTexture = function(width, height) { - var gl = PIXI.gl; - + var gl = PIXI.gl; + // next time to create a frame buffer and texture - this.frameBuffer = gl.createFramebuffer(); + this.frameBuffer = gl.createFramebuffer(); this.texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, this.texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); - - this.resize(width, height); -} + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); + + this.resize(width, height); +}; PIXI.FilterTexture.prototype.resize = function(width, height) { - if(this.width == width && this.height == height)return; + if(this.width === width && this.height === height) return; - this.width = width; - this.height = height; + this.width = width; + this.height = height; - var gl = PIXI.gl; + var gl = PIXI.gl; - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - -} \ No newline at end of file + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + +}; diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js index 1d949853..50ba4482 100644 --- a/src/pixi/renderers/webgl/WebGLGraphics.js +++ b/src/pixi/renderers/webgl/WebGLGraphics.js @@ -9,8 +9,8 @@ */ PIXI.WebGLGraphics = function() { - -} + +}; /** * Renders the graphics object @@ -23,62 +23,61 @@ PIXI.WebGLGraphics = function() */ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection) { - var gl = PIXI.gl; - - if(!graphics._webGL)graphics._webGL = {points:[], indices:[], lastIndex:0, - buffer:gl.createBuffer(), - indexBuffer:gl.createBuffer()}; - - if(graphics.dirty) - { - graphics.dirty = false; - - if(graphics.clearDirty) - { - graphics.clearDirty = false; - - graphics._webGL.lastIndex = 0; - graphics._webGL.points = []; - graphics._webGL.indices = []; - - } - - PIXI.WebGLGraphics.updateGraphics(graphics); - } - - PIXI.activatePrimitiveShader(); - - // This could be speeded up fo sure! - var m = PIXI.mat3.clone(graphics.worldTransform); - - PIXI.mat3.transpose(m); - - // set the matrix transform for the - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + var gl = PIXI.gl; - gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m); - - gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); - gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); - - gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); - gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); - - gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); - - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - + if(!graphics._webGL)graphics._webGL = {points:[], indices:[], lastIndex:0, + buffer:gl.createBuffer(), + indexBuffer:gl.createBuffer()}; - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); - - PIXI.deactivatePrimitiveShader(); - - - // return to default shader... -// PIXI.activateShader(PIXI.defaultShader); -} + if(graphics.dirty) + { + graphics.dirty = false; + + if(graphics.clearDirty) + { + graphics.clearDirty = false; + + graphics._webGL.lastIndex = 0; + graphics._webGL.points = []; + graphics._webGL.indices = []; + + } + + PIXI.WebGLGraphics.updateGraphics(graphics); + } + + PIXI.activatePrimitiveShader(); + + // This could be speeded up fo sure! + var m = PIXI.mat3.clone(graphics.worldTransform); + + PIXI.mat3.transpose(m); + + // set the matrix transform for the + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m); + + gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); + gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); + + gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); + gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); + + // set the index buffer! + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); + + + gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); + + PIXI.deactivatePrimitiveShader(); + + // return to default shader... +// PIXI.activateShader(PIXI.defaultShader); +}; /** * Updates the graphics object @@ -90,47 +89,47 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection) */ PIXI.WebGLGraphics.updateGraphics = function(graphics) { - for (var i=graphics._webGL.lastIndex; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - - if(data.type == PIXI.Graphics.POLY) - { - if(data.fill) - { - if(data.points.length>3) - PIXI.WebGLGraphics.buildPoly(data, graphics._webGL); - } - - if(data.lineWidth > 0) - { - PIXI.WebGLGraphics.buildLine(data, graphics._webGL); - } - } - else if(data.type == PIXI.Graphics.RECT) - { - PIXI.WebGLGraphics.buildRectangle(data, graphics._webGL); - } - else if(data.type == PIXI.Graphics.CIRC || data.type == PIXI.Graphics.ELIP) - { - PIXI.WebGLGraphics.buildCircle(data, graphics._webGL); - } - }; - - graphics._webGL.lastIndex = graphics.graphicsData.length; - - var gl = PIXI.gl; + for (var i = graphics._webGL.lastIndex; i < graphics.graphicsData.length; i++) + { + var data = graphics.graphicsData[i]; - graphics._webGL.glPoints = new Float32Array(graphics._webGL.points); - - gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); - gl.bufferData(gl.ARRAY_BUFFER, graphics._webGL.glPoints, gl.STATIC_DRAW); - - graphics._webGL.glIndicies = new Uint16Array(graphics._webGL.indices); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); + if(data.type === PIXI.Graphics.POLY) + { + if(data.fill) + { + if(data.points.length>3) + PIXI.WebGLGraphics.buildPoly(data, graphics._webGL); + } + + if(data.lineWidth > 0) + { + PIXI.WebGLGraphics.buildLine(data, graphics._webGL); + } + } + else if(data.type === PIXI.Graphics.RECT) + { + PIXI.WebGLGraphics.buildRectangle(data, graphics._webGL); + } + else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP); + { + PIXI.WebGLGraphics.buildCircle(data, graphics._webGL); + } + } + + graphics._webGL.lastIndex = graphics.graphicsData.length; + + var gl = PIXI.gl; + + graphics._webGL.glPoints = new Float32Array(graphics._webGL.points); + + gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); + gl.bufferData(gl.ARRAY_BUFFER, graphics._webGL.glPoints, gl.STATIC_DRAW); + + graphics._webGL.glIndicies = new Uint16Array(graphics._webGL.indices); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.glIndicies, gl.STATIC_DRAW); -} +}; /** * Builds a rectangle to draw @@ -143,59 +142,58 @@ PIXI.WebGLGraphics.updateGraphics = function(graphics) */ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) { - // --- // - // need to convert points to a nice regular data - // - var rectData = graphicsData.points; - var x = rectData[0]; - var y = rectData[1]; - var width = rectData[2]; - var height = rectData[3]; - - - if(graphicsData.fill) - { - var color = HEXtoRGB(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vertPos = verts.length/6; - - // start - verts.push(x, y); - verts.push(r, g, b, alpha); - - verts.push(x + width, y); - verts.push(r, g, b, alpha); - - verts.push(x , y + height); - verts.push(r, g, b, alpha); - - verts.push(x + width, y + height); - verts.push(r, g, b, alpha); - - // insert 2 dead triangles.. - indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3) - } - - if(graphicsData.lineWidth) - { - graphicsData.points = [x, y, - x + width, y, - x + width, y + height, - x, y + height, - x, y]; - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - } - -} + // --- // + // need to convert points to a nice regular data + // + var rectData = graphicsData.points; + var x = rectData[0]; + var y = rectData[1]; + var width = rectData[2]; + var height = rectData[3]; + + + if(graphicsData.fill) + { + var color = PIXI.hex2rgb(graphicsData.fillColor); + var alpha = graphicsData.fillAlpha; + + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + + var verts = webGLData.points; + var indices = webGLData.indices; + + var vertPos = verts.length/6; + + // start + verts.push(x, y); + verts.push(r, g, b, alpha); + + verts.push(x + width, y); + verts.push(r, g, b, alpha); + + verts.push(x , y + height); + verts.push(r, g, b, alpha); + + verts.push(x + width, y + height); + verts.push(r, g, b, alpha); + + // insert 2 dead triangles.. + indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3); + } + + if(graphicsData.lineWidth) + { + graphicsData.points = [x, y, + x + width, y, + x + width, y + height, + x, y + height, + x, y]; + + PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); + } +}; /** * Builds a circle to draw @@ -208,62 +206,63 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) */ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData) { - // --- // - // need to convert points to a nice regular data - // - var rectData = graphicsData.points; - var x = rectData[0]; - var y = rectData[1]; - var width = rectData[2]; - var height = rectData[3]; - - var totalSegs = 40; - var seg = (Math.PI * 2) / totalSegs ; - - if(graphicsData.fill) - { - var color = HEXtoRGB(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; + // --- // + // need to convert points to a nice regular data + // + var rectData = graphicsData.points; + var x = rectData[0]; + var y = rectData[1]; + var width = rectData[2]; + var height = rectData[3]; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vecPos = verts.length/6; - - indices.push(vecPos); - - for (var i=0; i < totalSegs + 1 ; i++) - { - verts.push(x,y, r, g, b, alpha); - - verts.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height, - r, g, b, alpha); - - indices.push(vecPos++, vecPos++); - }; - - indices.push(vecPos-1); - } - - if(graphicsData.lineWidth) - { - graphicsData.points = []; - - for (var i=0; i < totalSegs + 1; i++) - { - graphicsData.points.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height) - }; - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - } - -} + var totalSegs = 40; + var seg = (Math.PI * 2) / totalSegs ; + + var i = 0; + + if(graphicsData.fill) + { + var color = PIXI.hex2rgb(graphicsData.fillColor); + var alpha = graphicsData.fillAlpha; + + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + + var verts = webGLData.points; + var indices = webGLData.indices; + + var vecPos = verts.length/6; + + indices.push(vecPos); + + for (i = 0; i < totalSegs + 1 ; i++) + { + verts.push(x,y, r, g, b, alpha); + + verts.push(x + Math.sin(seg * i) * width, + y + Math.cos(seg * i) * height, + r, g, b, alpha); + + indices.push(vecPos++, vecPos++); + } + + indices.push(vecPos-1); + } + + if(graphicsData.lineWidth) + { + graphicsData.points = []; + + for (i = 0; i < totalSegs + 1; i++) + { + graphicsData.points.push(x + Math.sin(seg * i) * width, + y + Math.cos(seg * i) * height); + } + + PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); + } +}; /** * Builds a line to draw @@ -276,205 +275,204 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData) */ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) { - // TODO OPTIMISE! - - var wrap = true; - var points = graphicsData.points; - if(points.length == 0)return; - - // if the line width is an odd number add 0.5 to align to a whole pixel - if(graphicsData.lineWidth%2) - { - for (var i = 0; i < points.length; i++) { - points[i] += 0.5; - }; - } + // TODO OPTIMISE! + var i = 0; - // get first and last point.. figure out the middle! - var firstPoint = new PIXI.Point( points[0], points[1] ); - var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - // if the first point is the last point - goona have issues :) - if(firstPoint.x == lastPoint.x && firstPoint.y == lastPoint.y) - { - points.pop(); - points.pop(); - - lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5; - var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5; - - points.unshift(midPointX, midPointY); - points.push(midPointX, midPointY) - } - - var verts = webGLData.points; - var indices = webGLData.indices; - var length = points.length / 2; - var indexCount = points.length; - var indexStart = verts.length/6; - - // DRAW the Line - var width = graphicsData.lineWidth / 2; - - // sort color - var color = HEXtoRGB(graphicsData.lineColor); - var alpha = graphicsData.lineAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var p1x, p1y, p2x, p2y, p3x, p3y; - var perpx, perpy, perp2x, perp2y, perp3x, perp3y; - var ipx, ipy; - var a1, b1, c1, a2, b2, c2; - var denom, pdist, dist; - - p1x = points[0]; - p1y = points[1]; - - p2x = points[2]; - p2y = points[3]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - // start - verts.push(p1x - perpx , p1y - perpy, - r, g, b, alpha); - - verts.push(p1x + perpx , p1y + perpy, - r, g, b, alpha); - - for (var i = 1; i < length-1; i++) - { - p1x = points[(i-1)*2]; - p1y = points[(i-1)*2 + 1]; - - p2x = points[(i)*2] - p2y = points[(i)*2 + 1] - - p3x = points[(i+1)*2]; - p3y = points[(i+1)*2 + 1]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; + var points = graphicsData.points; + if(points.length === 0)return; - perp2x = -(p2y - p3y); - perp2y = p2x - p3x; - - dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y); - perp2x /= dist; - perp2y /= dist; - perp2x *= width; - perp2y *= width; - - a1 = (-perpy + p1y) - (-perpy + p2y); - b1 = (-perpx + p2x) - (-perpx + p1x); - c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y); - a2 = (-perp2y + p3y) - (-perp2y + p2y); - b2 = (-perp2x + p2x) - (-perp2x + p3x); - c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); - - denom = a1*b2 - a2*b1; + // if the line width is an odd number add 0.5 to align to a whole pixel + if(graphicsData.lineWidth%2) + { + for (i = 0; i < points.length; i++) { + points[i] += 0.5; + } + } - if(Math.abs(denom) < 0.1 ) - { - - denom+=10.1; - verts.push(p2x - perpx , p2y - perpy, - r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy, - r, g, b, alpha); - - continue; - } - - px = (b1*c2 - b2*c1)/denom; - py = (a2*c1 - a1*c2)/denom; - - - pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y); - + // get first and last point.. figure out the middle! + var firstPoint = new PIXI.Point( points[0], points[1] ); + var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - if(pdist > 140 * 140) - { - perp3x = perpx - perp2x; - perp3y = perpy - perp2y; - - dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y); - perp3x /= dist; - perp3y /= dist; - perp3x *= width; - perp3y *= width; - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x + perp3x, p2y +perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - indexCount++; - } - else - { + // if the first point is the last point - goona have issues :) + if(firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) + { + points.pop(); + points.pop(); - verts.push(px , py); - verts.push(r, g, b, alpha); - - verts.push(p2x - (px-p2x), p2y - (py - p2y)); - verts.push(r, g, b, alpha); - } - } - - p1x = points[(length-2)*2] - p1y = points[(length-2)*2 + 1] - - p2x = points[(length-1)*2] - p2y = points[(length-1)*2 + 1] - - perpx = -(p1y - p2y) - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - verts.push(p2x - perpx , p2y - perpy) - verts.push(r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy) - verts.push(r, g, b, alpha); - - indices.push(indexStart); - - for (var i=0; i < indexCount; i++) - { - indices.push(indexStart++); - }; - - indices.push(indexStart-1); -} + lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); + + var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5; + var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5; + + points.unshift(midPointX, midPointY); + points.push(midPointX, midPointY); + } + + var verts = webGLData.points; + var indices = webGLData.indices; + var length = points.length / 2; + var indexCount = points.length; + var indexStart = verts.length/6; + + // DRAW the Line + var width = graphicsData.lineWidth / 2; + + // sort color + var color = PIXI.hex2rgb(graphicsData.lineColor); + var alpha = graphicsData.lineAlpha; + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + + var px, py, p1x, p1y, p2x, p2y, p3x, p3y; + var perpx, perpy, perp2x, perp2y, perp3x, perp3y; + var a1, b1, c1, a2, b2, c2; + var denom, pdist, dist; + + p1x = points[0]; + p1y = points[1]; + + p2x = points[2]; + p2y = points[3]; + + perpx = -(p1y - p2y); + perpy = p1x - p2x; + + dist = Math.sqrt(perpx*perpx + perpy*perpy); + + perpx /= dist; + perpy /= dist; + perpx *= width; + perpy *= width; + + // start + verts.push(p1x - perpx , p1y - perpy, + r, g, b, alpha); + + verts.push(p1x + perpx , p1y + perpy, + r, g, b, alpha); + + for (i = 1; i < length-1; i++) + { + p1x = points[(i-1)*2]; + p1y = points[(i-1)*2 + 1]; + + p2x = points[(i)*2]; + p2y = points[(i)*2 + 1]; + + p3x = points[(i+1)*2]; + p3y = points[(i+1)*2 + 1]; + + perpx = -(p1y - p2y); + perpy = p1x - p2x; + + dist = Math.sqrt(perpx*perpx + perpy*perpy); + perpx /= dist; + perpy /= dist; + perpx *= width; + perpy *= width; + + perp2x = -(p2y - p3y); + perp2y = p2x - p3x; + + dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y); + perp2x /= dist; + perp2y /= dist; + perp2x *= width; + perp2y *= width; + + a1 = (-perpy + p1y) - (-perpy + p2y); + b1 = (-perpx + p2x) - (-perpx + p1x); + c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y); + a2 = (-perp2y + p3y) - (-perp2y + p2y); + b2 = (-perp2x + p2x) - (-perp2x + p3x); + c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); + + denom = a1*b2 - a2*b1; + + if(Math.abs(denom) < 0.1 ) + { + + denom+=10.1; + verts.push(p2x - perpx , p2y - perpy, + r, g, b, alpha); + + verts.push(p2x + perpx , p2y + perpy, + r, g, b, alpha); + + continue; + } + + px = (b1*c2 - b2*c1)/denom; + py = (a2*c1 - a1*c2)/denom; + + + pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y); + + + if(pdist > 140 * 140) + { + perp3x = perpx - perp2x; + perp3y = perpy - perp2y; + + dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y); + perp3x /= dist; + perp3y /= dist; + perp3x *= width; + perp3y *= width; + + verts.push(p2x - perp3x, p2y -perp3y); + verts.push(r, g, b, alpha); + + verts.push(p2x + perp3x, p2y +perp3y); + verts.push(r, g, b, alpha); + + verts.push(p2x - perp3x, p2y -perp3y); + verts.push(r, g, b, alpha); + + indexCount++; + } + else + { + + verts.push(px , py); + verts.push(r, g, b, alpha); + + verts.push(p2x - (px-p2x), p2y - (py - p2y)); + verts.push(r, g, b, alpha); + } + } + + p1x = points[(length-2)*2]; + p1y = points[(length-2)*2 + 1]; + + p2x = points[(length-1)*2]; + p2y = points[(length-1)*2 + 1]; + + perpx = -(p1y - p2y); + perpy = p1x - p2x; + + dist = Math.sqrt(perpx*perpx + perpy*perpy); + perpx /= dist; + perpy /= dist; + perpx *= width; + perpy *= width; + + verts.push(p2x - perpx , p2y - perpy); + verts.push(r, g, b, alpha); + + verts.push(p2x + perpx , p2y + perpy); + verts.push(r, g, b, alpha); + + indices.push(indexStart); + + for (i = 0; i < indexCount; i++) + { + indices.push(indexStart++); + } + + indices.push(indexStart-1); +}; /** * Builds a polygon to draw @@ -487,46 +485,40 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) */ PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData) { - var points = graphicsData.points; - if(points.length < 6)return; - - // get first and last point.. figure out the middle! - var verts = webGLData.points; - var indices = webGLData.indices; - - var length = points.length / 2; - - // sort color - var color = HEXtoRGB(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var triangles = PIXI.PolyK.Triangulate(points); - - var vertPos = verts.length / 6; - - for (var i=0; i < triangles.length; i+=3) - { - indices.push(triangles[i] + vertPos); - indices.push(triangles[i] + vertPos); - indices.push(triangles[i+1] + vertPos); - indices.push(triangles[i+2] +vertPos); - indices.push(triangles[i+2] + vertPos); - }; - - for (var i = 0; i < length; i++) - { - verts.push(points[i * 2], points[i * 2 + 1], - r, g, b, alpha); - }; -} + var points = graphicsData.points; + if(points.length < 6)return; -function HEXtoRGB(hex) { - return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; -} + // get first and last point.. figure out the middle! + var verts = webGLData.points; + var indices = webGLData.indices; + var length = points.length / 2; + // sort color + var color = PIXI.hex2rgb(graphicsData.fillColor); + var alpha = graphicsData.fillAlpha; + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + var triangles = PIXI.PolyK.Triangulate(points); + var vertPos = verts.length / 6; + + var i = 0; + + for (i = 0; i < triangles.length; i+=3) + { + indices.push(triangles[i] + vertPos); + indices.push(triangles[i] + vertPos); + indices.push(triangles[i+1] + vertPos); + indices.push(triangles[i+2] +vertPos); + indices.push(triangles[i+2] + vertPos); + } + + for (i = 0; i < length; i++) + { + verts.push(points[i * 2], points[i * 2 + 1], + r, g, b, alpha); + } +}; diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js index 0cdf18a0..b0f2da76 100644 --- a/src/pixi/renderers/webgl/WebGLRenderGroup.js +++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js @@ -25,6 +25,7 @@ PIXI.WebGLRenderGroup = function(gl, transparent) this.batchs = []; this.toRemove = []; + // console.log(this.transparent) this.filterManager = new PIXI.WebGLFilterManager(this.transparent); } diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js index e11cd44f..4d83833b 100644 --- a/src/pixi/renderers/webgl/WebGLRenderer.js +++ b/src/pixi/renderers/webgl/WebGLRenderer.js @@ -6,7 +6,7 @@ PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1); // an instance of the gl context.. // only one at the moment :/ -PIXI.gl; +PIXI.gl = null; /** * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer @@ -21,68 +21,68 @@ PIXI.gl; * @param view {Canvas} the canvas to use as a view, optional * @param transparent=false {Boolean} the transparency of the render view, default false * @param antialias=false {Boolean} sets antialias (only applicable in chrome at the moment) - * + * */ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) { - // do a catch.. only 1 webGL renderer.. + // do a catch.. only 1 webGL renderer.. - this.transparent = !!transparent; + this.transparent = !!transparent; - this.width = width || 800; - this.height = height || 600; + this.width = width || 800; + this.height = height || 600; - this.view = view || document.createElement( 'canvas' ); + this.view = view || document.createElement( 'canvas' ); this.view.width = this.width; - this.view.height = this.height; + this.view.height = this.height; - // deal with losing context.. + // deal with losing context.. var scope = this; - this.view.addEventListener('webglcontextlost', function(event) { scope.handleContextLost(event); }, false) - this.view.addEventListener('webglcontextrestored', function(event) { scope.handleContextRestored(event); }, false) + this.view.addEventListener('webglcontextlost', function(event) { scope.handleContextLost(event); }, false); + this.view.addEventListener('webglcontextrestored', function(event) { scope.handleContextRestored(event); }, false); - this.batchs = []; + this.batchs = []; - var options = { - alpha: this.transparent, - antialias:!!antialias, // SPEED UP?? - premultipliedAlpha:false, - stencil:true - } + var options = { + alpha: this.transparent, + antialias:!!antialias, // SPEED UP?? + premultipliedAlpha:false, + stencil:true + }; - //try 'experimental-webgl' - try { - PIXI.gl = this.gl = this.view.getContext("experimental-webgl", options); - } catch (e) { - //try 'webgl' - try { - PIXI.gl = this.gl = this.view.getContext("webgl", options); - } catch (e) { - // fail, not able to get a context - throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this); - } - } + //try 'experimental-webgl' + try { + PIXI.gl = this.gl = this.view.getContext('experimental-webgl', options); + } catch (e) { + //try 'webgl' + try { + PIXI.gl = this.gl = this.view.getContext('webgl', options); + } catch (e2) { + // fail, not able to get a context + throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this); + } + } PIXI.initDefaultShaders(); - - + + // PIXI.activateDefaultShader(); var gl = this.gl; - + gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; this.batch = new PIXI.WebGLBatch(gl); - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.CULL_FACE); gl.enable(gl.BLEND); - gl.colorMask(true, true, true, this.transparent); + gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); PIXI.offset = new PIXI.Point(0, 0); @@ -92,11 +92,11 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) this.resize(this.width, this.height); this.contextLost = false; - //PIXI.pushShader(PIXI.defaultShader); + //PIXI.pushShader(PIXI.defaultShader); this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent); // this.stageRenderGroup. = this.transparent -} +}; // constructor PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer; @@ -107,19 +107,19 @@ PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer; * @static * @method getBatch * @return {WebGLBatch} - * @private + * @private */ PIXI.WebGLRenderer.getBatch = function() { - if(PIXI._batchs.length == 0) - { - return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl); - } - else - { - return PIXI._batchs.pop(); - } -} + if(PIXI._batchs.length === 0) + { + return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl); + } + else + { + return PIXI._batchs.pop(); + } +}; /** * Puts a batch back into the pool @@ -131,9 +131,9 @@ PIXI.WebGLRenderer.getBatch = function() */ PIXI.WebGLRenderer.returnBatch = function(batch) { - batch.clean(); - PIXI._batchs.push(batch); -} + batch.clean(); + PIXI._batchs.push(batch); +}; /** * Renders the stage to its webGL view @@ -143,68 +143,68 @@ PIXI.WebGLRenderer.returnBatch = function(batch) */ PIXI.WebGLRenderer.prototype.render = function(stage) { - if(this.contextLost)return; - - - // if rendering a new stage clear the batchs.. - if(this.__stage !== stage) - { - // TODO make this work - // dont think this is needed any more? - this.__stage = stage; - this.stageRenderGroup.setRenderable(stage); - } + if(this.contextLost)return; - // update any textures - PIXI.WebGLRenderer.updateTextures(); - - // update the scene graph - PIXI.visibleCount++; - stage.updateTransform(); - - var gl = this.gl; - - // -- Does this need to be set every frame? -- // - gl.colorMask(true, true, true, this.transparent); - gl.viewport(0, 0, this.width, this.height); - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - - gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); - gl.clear(gl.COLOR_BUFFER_BIT); - // HACK TO TEST - - this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; - - PIXI.projection.x = this.width/2; - PIXI.projection.y = -this.height/2; - - this.stageRenderGroup.render(PIXI.projection); - - // interaction - // run interaction! - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } - - // after rendering lets confirm all frames that have been uodated.. - if(PIXI.Texture.frameUpdates.length > 0) - { - for (var i=0; i < PIXI.Texture.frameUpdates.length; i++) - { - PIXI.Texture.frameUpdates[i].updateFrame = false; - }; - - PIXI.Texture.frameUpdates = []; - } -} + // if rendering a new stage clear the batchs.. + if(this.__stage !== stage) + { + // TODO make this work + // dont think this is needed any more? + this.__stage = stage; + this.stageRenderGroup.setRenderable(stage); + } + + // update any textures + PIXI.WebGLRenderer.updateTextures(); + + // update the scene graph + PIXI.visibleCount++; + stage.updateTransform(); + + var gl = this.gl; + + // -- Does this need to be set every frame? -- // + gl.colorMask(true, true, true, this.transparent); + gl.viewport(0, 0, this.width, this.height); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); + gl.clear(gl.COLOR_BUFFER_BIT); + + // HACK TO TEST + + this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + + this.stageRenderGroup.render(PIXI.projection); + + // interaction + // run interaction! + if(stage.interactive) + { + //need to add some events! + if(!stage._interactiveEventsAdded) + { + stage._interactiveEventsAdded = true; + stage.interactionManager.setTarget(this); + } + } + + // after rendering lets confirm all frames that have been uodated.. + if(PIXI.Texture.frameUpdates.length > 0) + { + for (var i=0; i < PIXI.Texture.frameUpdates.length; i++) + { + PIXI.Texture.frameUpdates[i].updateFrame = false; + } + + PIXI.Texture.frameUpdates = []; + } +}; /** * Updates the textures loaded into this webgl renderer @@ -215,12 +215,18 @@ PIXI.WebGLRenderer.prototype.render = function(stage) */ PIXI.WebGLRenderer.updateTextures = function() { - //TODO break this out into a texture manager... - for (var i=0; i < PIXI.texturesToUpdate.length; i++) PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]); - for (var i=0; i < PIXI.texturesToDestroy.length; i++) PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]); - PIXI.texturesToUpdate = []; - PIXI.texturesToDestroy = []; -} + var i = 0; + + //TODO break this out into a texture manager... + for (i = 0; i < PIXI.texturesToUpdate.length; i++) + PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]); + + for (i = 0; i < PIXI.texturesToDestroy.length; i++) + PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]); + + PIXI.texturesToUpdate = []; + PIXI.texturesToDestroy = []; +}; /** * Updates a loaded webgl texture @@ -232,39 +238,39 @@ PIXI.WebGLRenderer.updateTextures = function() */ PIXI.WebGLRenderer.updateTexture = function(texture) { - //TODO break this out into a texture manager... - var gl = PIXI.gl; - - if(!texture._glTexture) - { - texture._glTexture = gl.createTexture(); - } + //TODO break this out into a texture manager... + var gl = PIXI.gl; - if(texture.hasLoaded) - { - gl.bindTexture(gl.TEXTURE_2D, texture._glTexture); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + if(!texture._glTexture) + { + texture._glTexture = gl.createTexture(); + } - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + if(texture.hasLoaded) + { + gl.bindTexture(gl.TEXTURE_2D, texture._glTexture); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); - // reguler... + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR ? gl.LINEAR : gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR ? gl.LINEAR : gl.NEAREST); - if(!texture._powerOf2) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } - else - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - } + // reguler... - gl.bindTexture(gl.TEXTURE_2D, null); - } -} + if(!texture._powerOf2) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + + gl.bindTexture(gl.TEXTURE_2D, null); + } +}; /** * Destroys a loaded webgl texture @@ -275,15 +281,15 @@ PIXI.WebGLRenderer.updateTexture = function(texture) */ PIXI.WebGLRenderer.destroyTexture = function(texture) { - //TODO break this out into a texture manager... - var gl = PIXI.gl; + //TODO break this out into a texture manager... + var gl = PIXI.gl; - if(texture._glTexture) - { - texture._glTexture = gl.createTexture(); - gl.deleteTexture(gl.TEXTURE_2D, texture._glTexture); - } -} + if(texture._glTexture) + { + texture._glTexture = gl.createTexture(); + gl.deleteTexture(gl.TEXTURE_2D, texture._glTexture); + } +}; /** * resizes the webGL view to the specified width and height @@ -294,27 +300,27 @@ PIXI.WebGLRenderer.destroyTexture = function(texture) */ PIXI.WebGLRenderer.prototype.resize = function(width, height) { - this.width = width; - this.height = height; + this.width = width; + this.height = height; - this.view.width = width; - this.view.height = height; + this.view.width = width; + this.view.height = height; - this.gl.viewport(0, 0, this.width, this.height); + this.gl.viewport(0, 0, this.width, this.height); - //var projectionMatrix = this.projectionMatrix; + //var projectionMatrix = this.projectionMatrix; - PIXI.projection.x = this.width/2; - PIXI.projection.y = -this.height/2; - - //PIXI.size.x = this.width/2; - //PIXI.size.y = -this.height/2; + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; -// projectionMatrix[0] = 2/this.width; -// projectionMatrix[5] = -2/this.height; -// projectionMatrix[12] = -1; -// projectionMatrix[13] = 1; -} + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; + +// projectionMatrix[0] = 2/this.width; +// projectionMatrix[5] = -2/this.height; +// projectionMatrix[12] = -1; +// projectionMatrix[13] = 1; +}; /** * Handles a lost webgl context @@ -325,9 +331,9 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height) */ PIXI.WebGLRenderer.prototype.handleContextLost = function(event) { - event.preventDefault(); - this.contextLost = true; -} + event.preventDefault(); + this.contextLost = true; +}; /** * Handles a restored webgl context @@ -336,28 +342,28 @@ PIXI.WebGLRenderer.prototype.handleContextLost = function(event) * @param event {Event} * @private */ -PIXI.WebGLRenderer.prototype.handleContextRestored = function(event) +PIXI.WebGLRenderer.prototype.handleContextRestored = function() { - this.gl = this.view.getContext("experimental-webgl", { - alpha: true + this.gl = this.view.getContext('experimental-webgl', { + alpha: true }); - this.initShaders(); + this.initShaders(); - for(var key in PIXI.TextureCache) - { - var texture = PIXI.TextureCache[key].baseTexture; - texture._glTexture = null; - PIXI.WebGLRenderer.updateTexture(texture); - }; + for(var key in PIXI.TextureCache) + { + var texture = PIXI.TextureCache[key].baseTexture; + texture._glTexture = null; + PIXI.WebGLRenderer.updateTexture(texture); + } - for (var i=0; i < this.batchs.length; i++) - { - this.batchs[i].restoreLostContext(this.gl)// - this.batchs[i].dirty = true; - }; + for (var i=0; i < this.batchs.length; i++) + { + this.batchs[i].restoreLostContext(this.gl); + this.batchs[i].dirty = true; + } - PIXI._restoreBatchs(this.gl); + PIXI._restoreBatchs(this.gl); - this.contextLost = false; -} + this.contextLost = false; +}; diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js index 44123d27..b6b66b7e 100644 --- a/src/pixi/renderers/webgl/WebGLShaders.js +++ b/src/pixi/renderers/webgl/WebGLShaders.js @@ -2,73 +2,70 @@ * @author Mat Groves http://matgroves.com/ @Doormat23 */ - -PIXI.initDefaultShaders = function() +PIXI.initDefaultShaders = function() { - PIXI.primitiveShader = new PIXI.PrimitiveShader(); - PIXI.primitiveShader.init(); + PIXI.primitiveShader = new PIXI.PrimitiveShader(); + PIXI.primitiveShader.init(); - PIXI.stripShader = new PIXI.StripShader(); - PIXI.stripShader.init(); + PIXI.stripShader = new PIXI.StripShader(); + PIXI.stripShader.init(); - PIXI.defaultShader = new PIXI.PixiShader(); - PIXI.defaultShader.init(); + PIXI.defaultShader = new PIXI.PixiShader(); + PIXI.defaultShader.init(); - var gl = PIXI.gl; - var shaderProgram = PIXI.defaultShader.program; - + var gl = PIXI.gl; + var shaderProgram = PIXI.defaultShader.program; - gl.useProgram(shaderProgram); - - gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); - gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); - gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); -} + gl.useProgram(shaderProgram); + + gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +}; PIXI.activatePrimitiveShader = function() { - var gl = PIXI.gl; - - gl.useProgram(PIXI.primitiveShader.program); - - gl.disableVertexAttribArray(PIXI.defaultShader.aVertexPosition); - gl.disableVertexAttribArray(PIXI.defaultShader.colorAttribute); - gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + var gl = PIXI.gl; - gl.enableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); - gl.enableVertexAttribArray(PIXI.primitiveShader.colorAttribute); -} + gl.useProgram(PIXI.primitiveShader.program); + + gl.disableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.disableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + + gl.enableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.primitiveShader.colorAttribute); +}; PIXI.deactivatePrimitiveShader = function() { - var gl = PIXI.gl; + var gl = PIXI.gl; - gl.useProgram(PIXI.defaultShader.program); - - gl.disableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); - gl.disableVertexAttribArray(PIXI.primitiveShader.colorAttribute); + gl.useProgram(PIXI.defaultShader.program); - gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); - gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); - gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + gl.disableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); + gl.disableVertexAttribArray(PIXI.primitiveShader.colorAttribute); -} + gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +}; PIXI.activateStripShader = function() { - var gl = PIXI.gl; - - gl.useProgram(PIXI.stripShader.program); + var gl = PIXI.gl; + + gl.useProgram(PIXI.stripShader.program); // gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); -} +}; PIXI.deactivateStripShader = function() { - var gl = PIXI.gl; + var gl = PIXI.gl; - gl.useProgram(PIXI.defaultShader.program); - //gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); -} + gl.useProgram(PIXI.defaultShader.program); + //gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +}; /* @@ -77,45 +74,44 @@ SHADER COMPILER HELPERS PIXI.CompileVertexShader = function(gl, shaderSrc) { - return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER); -} + return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER); +}; PIXI.CompileFragmentShader = function(gl, shaderSrc) { - return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER); -} + return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER); +}; PIXI._CompileShader = function(gl, shaderSrc, shaderType) { - var src = shaderSrc.join("\n"); - var shader = gl.createShader(shaderType); - gl.shaderSource(shader, src); - gl.compileShader(shader); + var src = shaderSrc.join("\n"); + var shader = gl.createShader(shaderType); + gl.shaderSource(shader, src); + gl.compileShader(shader); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - console.log(gl.getShaderInfoLog(shader)); - return null; - } - - return shader; -} + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + window.console.log(gl.getShaderInfoLog(shader)); + return null; + } + return shader; +}; PIXI.compileProgram = function(vertexSrc, fragmentSrc) { - var gl = PIXI.gl; - var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc); - var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc); - - var shaderProgram = gl.createProgram(); - + var gl = PIXI.gl; + var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc); + var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc); + + var shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - console.log("Could not initialise shaders"); + window.console.log("Could not initialise shaders"); } - return shaderProgram; -} + return shaderProgram; +}; diff --git a/src/pixi/text/BitmapText.js b/src/pixi/text/BitmapText.js index 7dd15ee3..fb5fb8cc 100644 --- a/src/pixi/text/BitmapText.js +++ b/src/pixi/text/BitmapText.js @@ -3,7 +3,7 @@ */ /** - * A Text Object will create a line(s) of text using bitmap font. To split a line you can use "\n", "\r" or "\r\n" + * A Text Object will create a line(s) of text using bitmap font. To split a line you can use '\n', '\r' or '\r\n' * You can generate the fnt files using * http://www.angelcode.com/products/bmfont/ for windows or * http://www.bmglyph.com/ for mac. @@ -13,8 +13,8 @@ * @constructor * @param text {String} The copy that you would like the text to display * @param style {Object} The style parameters - * @param style.font {String} The size (optional) and bitmap font id (required) eq "Arial" or "20px Arial" (must have loaded previously) - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") + * @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') */ PIXI.BitmapText = function(text, style) { @@ -23,8 +23,7 @@ PIXI.BitmapText = function(text, style) this.setText(text); this.setStyle(style); this.updateText(); - this.dirty = false - + this.dirty = false; }; // constructor @@ -39,7 +38,7 @@ PIXI.BitmapText.prototype.constructor = PIXI.BitmapText; */ PIXI.BitmapText.prototype.setText = function(text) { - this.text = text || " "; + this.text = text || ' '; this.dirty = true; }; @@ -48,16 +47,16 @@ PIXI.BitmapText.prototype.setText = function(text) * * @method setStyle * @param style {Object} The style parameters - * @param style.font {String} The size (optional) and bitmap font id (required) eq "Arial" or "20px Arial" (must have loaded previously) - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") + * @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') */ PIXI.BitmapText.prototype.setStyle = function(style) { style = style || {}; - style.align = style.align || "left"; + style.align = style.align || 'left'; this.style = style; - var font = style.font.split(" "); + var font = style.font.split(' '); this.fontName = font[font.length - 1]; this.fontSize = font.length >= 2 ? parseInt(font[font.length - 2], 10) : PIXI.BitmapText.fonts[this.fontName].size; @@ -100,7 +99,7 @@ PIXI.BitmapText.prototype.updateText = function() if(prevCharCode && charData[prevCharCode]) { - pos.x += charData.kerning[prevCharCode]; + pos.x += charData.kerning[prevCharCode]; } chars.push({texture:charData.texture, line: line, charCode: charCode, position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)}); pos.x += charData.xAdvance; @@ -115,11 +114,11 @@ PIXI.BitmapText.prototype.updateText = function() for(i = 0; i <= line; i++) { var alignOffset = 0; - if(this.style.align == "right") + if(this.style.align === 'right') { alignOffset = maxLineWidth - lineWidths[i]; } - else if(this.style.align == "center") + else if(this.style.align === 'center') { alignOffset = (maxLineWidth - lineWidths[i]) / 2; } @@ -128,7 +127,7 @@ PIXI.BitmapText.prototype.updateText = function() for(i = 0; i < chars.length; i++) { - var c = new PIXI.Sprite(chars[i].texture)//PIXI.Sprite.fromFrame(chars[i].charCode); + var c = new PIXI.Sprite(chars[i].texture); //PIXI.Sprite.fromFrame(chars[i].charCode); c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale; c.position.y = chars[i].position.y * scale; c.scale.x = c.scale.y = scale; @@ -147,8 +146,8 @@ PIXI.BitmapText.prototype.updateText = function() */ PIXI.BitmapText.prototype.updateTransform = function() { - if(this.dirty) - { + if(this.dirty) + { while(this.children.length > 0) { this.removeChild(this.getChildAt(0)); @@ -156,9 +155,9 @@ PIXI.BitmapText.prototype.updateTransform = function() this.updateText(); this.dirty = false; - } + } - PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); + PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); }; PIXI.BitmapText.fonts = {}; diff --git a/src/pixi/text/Text.js b/src/pixi/text/Text.js index a2acdd6d..75d50d05 100644 --- a/src/pixi/text/Text.js +++ b/src/pixi/text/Text.js @@ -3,25 +3,25 @@ */ /** - * A Text Object will create a line(s) of text to split a line you can use "\n" + * A Text Object will create a line(s) of text to split a line you can use '\n' * * @class Text * @extends Sprite * @constructor * @param text {String} The copy that you would like the text to display * @param [style] {Object} The style parameters - * @param [style.font] {String} default "bold 20pt Arial" The style and size of the font - * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00" - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") - * @param [style.stroke] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00" + * @param [style.font] {String} default 'bold 20pt Arial' The style and size of the font + * @param [style.fill='black'] {Object} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') + * @param [style.stroke] {String} 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 */ PIXI.Text = function(text, style) { - this.canvas = document.createElement("canvas"); - this.context = this.canvas.getContext("2d"); + this.canvas = document.createElement('canvas'); + this.context = this.canvas.getContext('2d'); PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas)); this.setText(text); @@ -40,10 +40,10 @@ PIXI.Text.prototype.constructor = PIXI.Text; * * @method setStyle * @param [style] {Object} The style parameters - * @param [style.font="bold 20pt Arial"] {String} The style and size of the font - * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00" - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") - * @param [style.stroke="black"] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00" + * @param [style.font='bold 20pt Arial'] {String} The style and size of the font + * @param [style.fill='black'] {Object} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') + * @param [style.stroke='black'] {String} 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 @@ -51,10 +51,10 @@ PIXI.Text.prototype.constructor = PIXI.Text; PIXI.Text.prototype.setStyle = function(style) { style = style || {}; - 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/GoodBoyDigital/pixi.js/issues/136 + 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/GoodBoyDigital/pixi.js/issues/136 style.strokeThickness = style.strokeThickness || 0; style.wordWrap = style.wordWrap || false; style.wordWrapWidth = style.wordWrapWidth || 100; @@ -63,14 +63,14 @@ PIXI.Text.prototype.setStyle = function(style) }; /** - * Set the copy for the text object. To split a line you can use "\n" + * Set the copy for the text object. To split a line you can use '\n' * * @method setText * @param {String} text The copy that you would like the text to display */ PIXI.Text.prototype.setText = function(text) { - this.text = text.toString() || " "; + this.text = text.toString() || ' '; this.dirty = true; }; @@ -82,65 +82,65 @@ PIXI.Text.prototype.setText = function(text) */ PIXI.Text.prototype.updateText = function() { - this.context.font = this.style.font; + this.context.font = this.style.font; - var outputText = this.text; + var outputText = this.text; - // word wrap - // preserve original text - if(this.style.wordWrap)outputText = this.wordWrap(this.text); + // word wrap + // preserve original text + if(this.style.wordWrap)outputText = this.wordWrap(this.text); - //split text into lines - var lines = outputText.split(/(?:\r\n|\r|\n)/); + //split text into lines + var lines = outputText.split(/(?:\r\n|\r|\n)/); - //calculate text width - var lineWidths = []; - var maxLineWidth = 0; - for (var i = 0; i < lines.length; i++) - { - var lineWidth = this.context.measureText(lines[i]).width; - lineWidths[i] = lineWidth; - maxLineWidth = Math.max(maxLineWidth, lineWidth); - } - this.canvas.width = maxLineWidth + this.style.strokeThickness; + //calculate text width + var lineWidths = []; + var maxLineWidth = 0; + for (var i = 0; i < lines.length; i++) + { + var lineWidth = this.context.measureText(lines[i]).width; + lineWidths[i] = lineWidth; + maxLineWidth = Math.max(maxLineWidth, lineWidth); + } + this.canvas.width = maxLineWidth + this.style.strokeThickness; - //calculate text height - var lineHeight = this.determineFontHeight("font: " + this.style.font + ";") + this.style.strokeThickness; - this.canvas.height = lineHeight * lines.length; + //calculate text height + var lineHeight = this.determineFontHeight('font: ' + this.style.font + ';') + this.style.strokeThickness; + this.canvas.height = lineHeight * lines.length; - //set canvas text styles - this.context.fillStyle = this.style.fill; - this.context.font = this.style.font; + //set canvas text styles + this.context.fillStyle = this.style.fill; + this.context.font = this.style.font; - this.context.strokeStyle = this.style.stroke; - this.context.lineWidth = this.style.strokeThickness; + this.context.strokeStyle = this.style.stroke; + this.context.lineWidth = this.style.strokeThickness; - this.context.textBaseline = "top"; + this.context.textBaseline = 'top'; - //draw lines line by line - for (i = 0; i < lines.length; i++) - { - var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight); + //draw lines line by line + for (i = 0; i < lines.length; i++) + { + var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight); - if(this.style.align == "right") - { - linePosition.x += maxLineWidth - lineWidths[i]; - } - else if(this.style.align == "center") - { - linePosition.x += (maxLineWidth - lineWidths[i]) / 2; - } + if(this.style.align === 'right') + { + linePosition.x += maxLineWidth - lineWidths[i]; + } + else if(this.style.align === 'center') + { + linePosition.x += (maxLineWidth - lineWidths[i]) / 2; + } - if(this.style.stroke && this.style.strokeThickness) - { - this.context.strokeText(lines[i], linePosition.x, linePosition.y); - } + if(this.style.stroke && this.style.strokeThickness) + { + this.context.strokeText(lines[i], linePosition.x, linePosition.y); + } - if(this.style.fill) - { - this.context.fillText(lines[i], linePosition.x, linePosition.y); - } - } + if(this.style.fill) + { + this.context.fillText(lines[i], linePosition.x, linePosition.y); + } + } this.updateTexture(); }; @@ -158,7 +158,7 @@ PIXI.Text.prototype.updateTexture = function() this.texture.frame.width = this.canvas.width; this.texture.frame.height = this.canvas.height; - this._width = this.canvas.width; + this._width = this.canvas.width; this._height = this.canvas.height; PIXI.texturesToUpdate.push(this.texture.baseTexture); @@ -172,13 +172,13 @@ PIXI.Text.prototype.updateTexture = function() */ PIXI.Text.prototype.updateTransform = function() { - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } + if(this.dirty) + { + this.updateText(); + this.dirty = false; + } - PIXI.Sprite.prototype.updateTransform.call(this); + PIXI.Sprite.prototype.updateTransform.call(this); }; /* @@ -191,26 +191,26 @@ PIXI.Text.prototype.updateTransform = function() */ PIXI.Text.prototype.determineFontHeight = function(fontStyle) { - // build a little reference dictionary so if the font style has been used return a - // cached version... - var result = PIXI.Text.heightCache[fontStyle]; + // build a little reference dictionary so if the font style has been used return a + // cached version... + var result = PIXI.Text.heightCache[fontStyle]; - if(!result) - { - var body = document.getElementsByTagName("body")[0]; - var dummy = document.createElement("div"); - var dummyText = document.createTextNode("M"); - dummy.appendChild(dummyText); - dummy.setAttribute("style", fontStyle + ';position:absolute;top:0;left:0'); - body.appendChild(dummy); + if(!result) + { + var body = document.getElementsByTagName('body')[0]; + var dummy = document.createElement('div'); + var dummyText = document.createTextNode('M'); + dummy.appendChild(dummyText); + dummy.setAttribute('style', fontStyle + ';position:absolute;top:0;left:0'); + body.appendChild(dummy); - result = dummy.offsetHeight; - PIXI.Text.heightCache[fontStyle] = result; + result = dummy.offsetHeight; + PIXI.Text.heightCache[fontStyle] = result; - body.removeChild(dummy); - } + body.removeChild(dummy); + } - return result; + return result; }; /** @@ -223,38 +223,38 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle) */ PIXI.Text.prototype.wordWrap = function(text) { - // Greedy wrapping algorithm that will wrap words as the line grows longer - // than its horizontal bounds. - var result = ""; - var lines = text.split("\n"); - for (var i = 0; i < lines.length; i++) - { - var spaceLeft = this.style.wordWrapWidth; - var words = lines[i].split(" "); - for (var j = 0; j < words.length; j++) - { - var wordWidth = this.context.measureText(words[j]).width; - var wordWidthWithSpace = wordWidth + this.context.measureText(" ").width; - if(wordWidthWithSpace > spaceLeft) - { - // Skip printing the newline if it's the first word of the line that is - // greater than the word wrap width. - if(j > 0) - { - result += "\n"; - } - result += words[j] + " "; - spaceLeft = this.style.wordWrapWidth - wordWidth; - } - else - { - spaceLeft -= wordWidthWithSpace; - result += words[j] + " "; - } - } - result += "\n"; - } - return result; + // Greedy wrapping algorithm that will wrap words as the line grows longer + // than its horizontal bounds. + var result = ''; + var lines = text.split('\n'); + for (var i = 0; i < lines.length; i++) + { + var spaceLeft = this.style.wordWrapWidth; + var words = lines[i].split(' '); + for (var j = 0; j < words.length; j++) + { + var wordWidth = this.context.measureText(words[j]).width; + var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; + if(wordWidthWithSpace > spaceLeft) + { + // Skip printing the newline if it's the first word of the line that is + // greater than the word wrap width. + if(j > 0) + { + result += '\n'; + } + result += words[j] + ' '; + spaceLeft = this.style.wordWrapWidth - wordWidth; + } + else + { + spaceLeft -= wordWidthWithSpace; + result += words[j] + ' '; + } + } + result += '\n'; + } + return result; }; /** @@ -265,10 +265,10 @@ PIXI.Text.prototype.wordWrap = function(text) */ PIXI.Text.prototype.destroy = function(destroyTexture) { - if(destroyTexture) - { - this.texture.destroy(); - } + if(destroyTexture) + { + this.texture.destroy(); + } }; diff --git a/src/pixi/textures/BaseTexture.js b/src/pixi/textures/BaseTexture.js index 099f2275..1c78656d 100644 --- a/src/pixi/textures/BaseTexture.js +++ b/src/pixi/textures/BaseTexture.js @@ -14,86 +14,94 @@ PIXI.texturesToDestroy = []; * @constructor * @param source {String} the source object (image or canvas) */ -PIXI.BaseTexture = function(source) +PIXI.BaseTexture = function(source, scaleMode) { - PIXI.EventTarget.call( this ); + PIXI.EventTarget.call( this ); - /** - * [read-only] The width of the base texture set when the image has loaded - * - * @property width - * @type Number - * @readOnly - */ - this.width = 100; + /** + * [read-only] The width of the base texture set when the image has loaded + * + * @property width + * @type Number + * @readOnly + */ + this.width = 100; - /** - * [read-only] The height of the base texture set when the image has loaded - * - * @property height - * @type Number - * @readOnly - */ - this.height = 100; + /** + * [read-only] The height of the base texture set when the image has loaded + * + * @property height + * @type Number + * @readOnly + */ + this.height = 100; - /** - * [read-only] Describes if the base texture has loaded or not - * - * @property hasLoaded - * @type Boolean - * @readOnly - */ - this.hasLoaded = false; + /** + * The scale mode to apply when scaling this texture + * @property scaleMode + * @type PIXI.BaseTexture.SCALE_MODE + * @default PIXI.BaseTexture.SCALE_MODE.LINEAR + */ + this.scaleMode = scaleMode || PIXI.BaseTexture.SCALE_MODE.DEFAULT; - /** - * The source that is loaded to create the texture - * - * @property source - * @type Image - */ - this.source = source; + /** + * [read-only] Describes if the base texture has loaded or not + * + * @property hasLoaded + * @type Boolean + * @readOnly + */ + this.hasLoaded = false; - if(!source)return; + /** + * The source that is loaded to create the texture + * + * @property source + * @type Image + */ + this.source = source; - if(this.source instanceof Image || this.source instanceof HTMLImageElement) - { - if(this.source.complete) - { - this.hasLoaded = true; - this.width = this.source.width; - this.height = this.source.height; + if(!source)return; - PIXI.texturesToUpdate.push(this); - } - else - { + if(this.source instanceof Image || this.source instanceof HTMLImageElement) + { + if(this.source.complete) + { + this.hasLoaded = true; + this.width = this.source.width; + this.height = this.source.height; - var scope = this; - this.source.onload = function(){ + PIXI.texturesToUpdate.push(this); + } + else + { - scope.hasLoaded = true; - scope.width = scope.source.width; - scope.height = scope.source.height; + var scope = this; + this.source.onload = function() { - // add it to somewhere... - PIXI.texturesToUpdate.push(scope); - scope.dispatchEvent( { type: 'loaded', content: scope } ); - } - // this.image.src = imageUrl; - } - } - else - { - this.hasLoaded = true; - this.width = this.source.width; - this.height = this.source.height; + scope.hasLoaded = true; + scope.width = scope.source.width; + scope.height = scope.source.height; - PIXI.texturesToUpdate.push(this); - } + // add it to somewhere... + PIXI.texturesToUpdate.push(scope); + scope.dispatchEvent( { type: 'loaded', content: scope } ); + }; + //this.image.src = imageUrl; + } + } + else + { + this.hasLoaded = true; + this.width = this.source.width; + this.height = this.source.height; - this.imageUrl = null; - this._powerOf2 = false; -} + PIXI.texturesToUpdate.push(this); + } + + this.imageUrl = null; + this._powerOf2 = false; +}; PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture; @@ -104,29 +112,29 @@ PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture; */ PIXI.BaseTexture.prototype.destroy = function() { - if(this.source instanceof Image) - { - if (this.imageUrl in PIXI.BaseTextureCache) - delete PIXI.BaseTextureCache[this.imageUrl]; - this.imageUrl = null; - this.source.src = null; - } - this.source = null; - PIXI.texturesToDestroy.push(this); -} + if(this.source instanceof Image) + { + if (this.imageUrl in PIXI.BaseTextureCache) + delete PIXI.BaseTextureCache[this.imageUrl]; + this.imageUrl = null; + this.source.src = null; + } + this.source = null; + PIXI.texturesToDestroy.push(this); +}; /** - * + * * * @method destroy */ PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc) { - this.hasLoaded = false; - this.source.src = null; - this.source.src = newSrc; -} + this.hasLoaded = false; + this.source.src = null; + this.source.src = newSrc; +}; /** * Helper function that returns a base texture based on an image url @@ -137,23 +145,29 @@ PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc) * @param imageUrl {String} The image url of the texture * @return BaseTexture */ -PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin) +PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode) { - var baseTexture = PIXI.BaseTextureCache[imageUrl]; - if(!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - var image = new Image();//document.createElement('img'); - if (crossorigin) - { - image.crossOrigin = ''; - } - image.src = imageUrl; - baseTexture = new PIXI.BaseTexture(image); - baseTexture.imageUrl = imageUrl; - PIXI.BaseTextureCache[imageUrl] = baseTexture; - } + var baseTexture = PIXI.BaseTextureCache[imageUrl]; + if(!baseTexture) + { + // new Image() breaks tex loading in some versions of Chrome. + // See https://code.google.com/p/chromium/issues/detail?id=238071 + var image = new Image();//document.createElement('img'); + if (crossorigin) + { + image.crossOrigin = ''; + } + image.src = imageUrl; + baseTexture = new PIXI.BaseTexture(image, scaleMode); + baseTexture.imageUrl = imageUrl; + PIXI.BaseTextureCache[imageUrl] = baseTexture; + } - return baseTexture; -} + return baseTexture; +}; + +PIXI.BaseTexture.SCALE_MODE = { + DEFAULT: 0, //default to LINEAR + LINEAR: 0, + NEAREST: 1 +}; \ No newline at end of file diff --git a/src/pixi/textures/RenderTexture.js b/src/pixi/textures/RenderTexture.js index ec35c189..fe1df380 100644 --- a/src/pixi/textures/RenderTexture.js +++ b/src/pixi/textures/RenderTexture.js @@ -5,24 +5,24 @@ /** A RenderTexture is a special texture that allows any pixi displayObject to be rendered to it. - __Hint__: All DisplayObjects (exmpl. Sprites) that renders on RenderTexture should be preloaded. - Otherwise black rectangles will be drawn instead. - + __Hint__: All DisplayObjects (exmpl. Sprites) that renders on RenderTexture should be preloaded. + Otherwise black rectangles will be drawn instead. + RenderTexture takes snapshot of DisplayObject passed to render method. If DisplayObject is passed to render method, position and rotation of it will be ignored. For example: - - var renderTexture = new PIXI.RenderTexture(800, 600); - var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); - sprite.position.x = 800/2; - sprite.position.y = 600/2; - sprite.anchor.x = 0.5; - sprite.anchor.y = 0.5; - renderTexture.render(sprite); + + var renderTexture = new PIXI.RenderTexture(800, 600); + var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); + sprite.position.x = 800/2; + sprite.position.y = 600/2; + sprite.anchor.x = 0.5; + sprite.anchor.y = 0.5; + renderTexture.render(sprite); Sprite in this case will be rendered to 0,0 position. To render this sprite at center DisplayObjectContainer should be used: - var doc = new PIXI.DisplayObjectContainer(); - doc.addChild(sprite); - renderTexture.render(doc); // Renders to center of renderTexture + var doc = new PIXI.DisplayObjectContainer(); + doc.addChild(sprite); + renderTexture.render(doc); // Renders to center of renderTexture @class RenderTexture @extends Texture @@ -32,24 +32,24 @@ */ PIXI.RenderTexture = function(width, height) { - PIXI.EventTarget.call( this ); + PIXI.EventTarget.call( this ); - this.width = width || 100; - this.height = height || 100; + this.width = width || 100; + this.height = height || 100; - this.indetityMatrix = PIXI.mat3.create(); + this.indetityMatrix = PIXI.mat3.create(); - this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); + this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); - if(PIXI.gl) - { - this.initWebGL(); - } - else - { - this.initCanvas(); - } -} + if(PIXI.gl) + { + this.initWebGL(); + } + else + { + this.initCanvas(); + } +}; PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype ); PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture; @@ -62,65 +62,65 @@ PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture; */ PIXI.RenderTexture.prototype.initWebGL = function() { - var gl = PIXI.gl; - this.glFramebuffer = gl.createFramebuffer(); + var gl = PIXI.gl; + this.glFramebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); this.glFramebuffer.width = this.width; - this.glFramebuffer.height = this.height; + this.glFramebuffer.height = this.height; - this.baseTexture = new PIXI.BaseTexture(); + this.baseTexture = new PIXI.BaseTexture(); - this.baseTexture.width = this.width; - this.baseTexture.height = this.height; + this.baseTexture.width = this.width; + this.baseTexture.height = this.height; this.baseTexture._glTexture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - this.baseTexture.isRender = true; + this.baseTexture.isRender = true; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.baseTexture._glTexture, 0); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.baseTexture._glTexture, 0); - // create a projection matrix.. - this.projection = new PIXI.Point(this.width/2 , -this.height/2); + // create a projection matrix.. + this.projection = new PIXI.Point(this.width/2 , -this.height/2); - // set the correct render function.. - this.render = this.renderWebGL; -} + // set the correct render function.. + this.render = this.renderWebGL; +}; PIXI.RenderTexture.prototype.resize = function(width, height) { - this.width = width; - this.height = height; - - if(PIXI.gl) - { - this.projection.x = this.width/2 - this.projection.y = -this.height/2; - - var gl = PIXI.gl; - gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - else - { - - this.frame.width = this.width - this.frame.height = this.height; - this.renderer.resize(this.width, this.height); - } -} + this.width = width; + this.height = height; + + if(PIXI.gl) + { + this.projection.x = this.width / 2; + this.projection.y = -this.height / 2; + + var gl = PIXI.gl; + gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + else + { + + this.frame.width = this.width; + this.frame.height = this.height; + this.renderer.resize(this.width, this.height); + } +}; /** * Initializes the canvas data for this texture @@ -130,13 +130,13 @@ PIXI.RenderTexture.prototype.resize = function(width, height) */ PIXI.RenderTexture.prototype.initCanvas = function() { - this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0); + this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0); - this.baseTexture = new PIXI.BaseTexture(this.renderer.view); - this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); + this.baseTexture = new PIXI.BaseTexture(this.renderer.view); + this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); - this.render = this.renderCanvas; -} + this.render = this.renderCanvas; +}; /** * This function will draw the display object to the texture. @@ -148,67 +148,67 @@ PIXI.RenderTexture.prototype.initCanvas = function() */ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear) { - var gl = PIXI.gl; + var gl = PIXI.gl; - // enable the alpha color mask.. - gl.colorMask(true, true, true, true); + // enable the alpha color mask.. + gl.colorMask(true, true, true, true); - gl.viewport(0, 0, this.width, this.height); + gl.viewport(0, 0, this.width, this.height); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); - if(clear) - { - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - } + if(clear) + { + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + } - // THIS WILL MESS WITH HIT TESTING! - var children = displayObject.children; + // THIS WILL MESS WITH HIT TESTING! + var children = displayObject.children; - //TODO -? create a new one??? dont think so! - var originalWorldTransform = displayObject.worldTransform; - displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix; - // modify to flip... - displayObject.worldTransform[4] = -1; - displayObject.worldTransform[5] = this.projection.y * -2; + //TODO -? create a new one??? dont think so! + var originalWorldTransform = displayObject.worldTransform; + displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix; + // modify to flip... + displayObject.worldTransform[4] = -1; + displayObject.worldTransform[5] = this.projection.y * -2; - if(position) - { - displayObject.worldTransform[2] = position.x; - displayObject.worldTransform[5] -= position.y; - } - - PIXI.visibleCount++; - displayObject.vcount = PIXI.visibleCount; - - for(var i=0,j=children.length; i this.baseTexture.width || frame.y + frame.height > this.baseTexture.height) - { - throw new Error("Texture Error: frame does not fit inside the base Texture dimensions " + this); - } + if(frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height) + { + throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this); + } - this.updateFrame = true; + this.updateFrame = true; - PIXI.Texture.frameUpdates.push(this); - //this.dispatchEvent( { type: 'update', content: this } ); -} + PIXI.Texture.frameUpdates.push(this); + //this.dispatchEvent( { type: 'update', content: this } ); +}; /** * Helper function that returns a texture based on an image url @@ -134,18 +134,18 @@ PIXI.Texture.prototype.setFrame = function(frame) * @param crossorigin {Boolean} Whether requests should be treated as crossorigin * @return Texture */ -PIXI.Texture.fromImage = function(imageUrl, crossorigin) +PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode) { - var texture = PIXI.TextureCache[imageUrl]; + var texture = PIXI.TextureCache[imageUrl]; - if(!texture) - { - texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin)); - PIXI.TextureCache[imageUrl] = texture; - } + if(!texture) + { + texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin, scaleMode)); + PIXI.TextureCache[imageUrl] = texture; + } - return texture; -} + return texture; +}; /** * Helper function that returns a texture based on a frame id @@ -158,10 +158,10 @@ PIXI.Texture.fromImage = function(imageUrl, crossorigin) */ PIXI.Texture.fromFrame = function(frameId) { - var texture = PIXI.TextureCache[frameId]; - if(!texture)throw new Error("The frameId '"+ frameId +"' does not exist in the texture cache " + this); - return texture; -} + var texture = PIXI.TextureCache[frameId]; + if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this); + return texture; +}; /** * Helper function that returns a texture based on a canvas element @@ -172,11 +172,11 @@ PIXI.Texture.fromFrame = function(frameId) * @param canvas {Canvas} The canvas element source of the texture * @return Texture */ -PIXI.Texture.fromCanvas = function(canvas) +PIXI.Texture.fromCanvas = function(canvas, scaleMode) { - var baseTexture = new PIXI.BaseTexture(canvas); - return new PIXI.Texture(baseTexture); -} + var baseTexture = new PIXI.BaseTexture(canvas, scaleMode); + return new PIXI.Texture(baseTexture); +}; /** @@ -189,8 +189,8 @@ PIXI.Texture.fromCanvas = function(canvas) */ PIXI.Texture.addTextureToCache = function(texture, id) { - PIXI.TextureCache[id] = texture; -} + PIXI.TextureCache[id] = texture; +}; /** * Remove a texture from the textureCache. @@ -202,11 +202,12 @@ PIXI.Texture.addTextureToCache = function(texture, id) */ PIXI.Texture.removeTextureFromCache = function(id) { - var texture = PIXI.TextureCache[id] - PIXI.TextureCache[id] = null; - return texture; -} + var texture = PIXI.TextureCache[id]; + PIXI.TextureCache[id] = null; + return texture; +}; // this is more for webGL.. it contains updated frames.. PIXI.Texture.frameUpdates = []; +PIXI.Texture.SCALE_MODE = PIXI.BaseTexture.SCALE_MODE; diff --git a/src/pixi/utils/Detector.js b/src/pixi/utils/Detector.js index 250f609d..d6046a38 100644 --- a/src/pixi/utils/Detector.js +++ b/src/pixi/utils/Detector.js @@ -19,25 +19,29 @@ */ PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias) { - if(!width)width = 800; - if(!height)height = 600; + if(!width)width = 800; + if(!height)height = 600; - // BORROWED from Mr Doob (mrdoob.com) - var webgl = ( function () { try { var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); } catch( e ) { return false; } } )(); + // BORROWED from Mr Doob (mrdoob.com) + var webgl = ( function () { try { + var canvas = document.createElement( 'canvas' ); + return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); + } catch( e ) { + return false; + } + } )(); - if(webgl) - { - var ie = (navigator.userAgent.toLowerCase().indexOf('trident') != -1); - webgl = !ie; - } - - //console.log(webgl); - if( webgl ) - { - return new PIXI.WebGLRenderer(width, height, view, transparent, antialias); - } + if(webgl) + { + var ie = (navigator.userAgent.toLowerCase().indexOf('trident') !== -1); + webgl = !ie; + } - return new PIXI.CanvasRenderer(width, height, view, transparent); + //console.log(webgl); + if( webgl ) + { + return new PIXI.WebGLRenderer(width, height, view, transparent, antialias); + } + + return new PIXI.CanvasRenderer(width, height, view, transparent); }; - - diff --git a/src/pixi/utils/EventTarget.js b/src/pixi/utils/EventTarget.js index 3ee5fc28..ce7d7a2c 100644 --- a/src/pixi/utils/EventTarget.js +++ b/src/pixi/utils/EventTarget.js @@ -8,60 +8,60 @@ * * @class EventTarget * @example - * function MyEmitter() { - * PIXI.EventTarget.call(this); //mixes in event target stuff - * } + * function MyEmitter() { + * PIXI.EventTarget.call(this); //mixes in event target stuff + * } * - * var em = new MyEmitter(); - * em.emit({ type: 'eventName', data: 'some data' }); + * var em = new MyEmitter(); + * em.emit({ type: 'eventName', data: 'some data' }); */ PIXI.EventTarget = function () { - var listeners = {}; + var listeners = {}; - this.addEventListener = this.on = function ( type, listener ) { + this.addEventListener = this.on = function ( type, listener ) { - if ( listeners[ type ] === undefined ) { + if ( listeners[ type ] === undefined ) { - listeners[ type ] = []; + listeners[ type ] = []; - } + } - if ( listeners[ type ].indexOf( listener ) === - 1 ) { + if ( listeners[ type ].indexOf( listener ) === - 1 ) { - listeners[ type ].push( listener ); - } + listeners[ type ].push( listener ); + } - }; + }; - this.dispatchEvent = this.emit = function ( event ) { + this.dispatchEvent = this.emit = function ( event ) { - if ( !listeners[ event.type ] || !listeners[ event.type ].length ) { + if ( !listeners[ event.type ] || !listeners[ event.type ].length ) { - return; + return; - } + } - for(var i = 0, l = listeners[ event.type ].length; i < l; i++) { + for(var i = 0, l = listeners[ event.type ].length; i < l; i++) { - listeners[ event.type ][ i ]( event ); + listeners[ event.type ][ i ]( event ); - } + } - }; + }; - this.removeEventListener = this.off = function ( type, listener ) { + this.removeEventListener = this.off = function ( type, listener ) { - var index = listeners[ type ].indexOf( listener ); + var index = listeners[ type ].indexOf( listener ); - if ( index !== - 1 ) { + if ( index !== - 1 ) { - listeners[ type ].splice( index, 1 ); + listeners[ type ].splice( index, 1 ); - } + } - }; + }; this.removeAllEventListeners = function( type ) { var a = listeners[type]; diff --git a/src/pixi/utils/Polyk.js b/src/pixi/utils/Polyk.js index e29d77da..8c5d30e5 100644 --- a/src/pixi/utils/Polyk.js +++ b/src/pixi/utils/Polyk.js @@ -1,34 +1,34 @@ /* - PolyK library - url: http://polyk.ivank.net - Released under MIT licence. + PolyK library + url: http://polyk.ivank.net + Released under MIT licence. - Copyright (c) 2012 Ivan Kuckir + Copyright (c) 2012 Ivan Kuckir - Permission is hereby granted, free of charge, to any person - obtaining a copy of this software and associated documentation - files (the "Software"), to deal in the Software without - restriction, including without limitation the rights to use, - copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the - Software is furnished to do so, subject to the following - conditions: + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, + copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following + conditions: - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. - This is an amazing lib! + This is an amazing lib! - slightly modified by mat groves (matgroves.com); + slightly modified by mat groves (matgroves.com); */ PIXI.PolyK = {}; @@ -42,69 +42,76 @@ PIXI.PolyK = {}; */ PIXI.PolyK.Triangulate = function(p) { - var sign = true; + var sign = true; - var n = p.length>>1; - if(n<3) return []; - var tgs = []; - var avl = []; - for(var i=0; i> 1; + if(n < 3) return []; - var i = 0; - var al = n; - while(al > 3) - { - var i0 = avl[(i+0)%al]; - var i1 = avl[(i+1)%al]; - var i2 = avl[(i+2)%al]; + var tgs = []; + var avl = []; + for(var i = 0; i < n; i++) avl.push(i); - var ax = p[2*i0], ay = p[2*i0+1]; - var bx = p[2*i1], by = p[2*i1+1]; - var cx = p[2*i2], cy = p[2*i2+1]; + i = 0; + var al = n; + while(al > 3) + { + var i0 = avl[(i+0)%al]; + var i1 = avl[(i+1)%al]; + var i2 = avl[(i+2)%al]; - var earFound = false; - if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign)) - { - earFound = true; - for(var j=0; j 3*al) - { - // need to flip flip reverse it! - // reset! - if(sign) - { - var tgs = []; - avl = []; - for(var i=0; i 3*al) + { + // need to flip flip reverse it! + // reset! + if(sign) + { + tgs = []; + avl = []; + for(i = 0; i < n; i++) avl.push(i); + + i = 0; + al = n; + + sign = false; + } + else + { + window.console.log("PIXI Warning: shape too complex to fill"); + return []; + } + } + } + + tgs.push(avl[0], avl[1], avl[2]); + return tgs; +}; /** * Checks if a point is within a triangle @@ -115,26 +122,26 @@ PIXI.PolyK.Triangulate = function(p) */ PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) { - var v0x = cx-ax; - var v0y = cy-ay; - var v1x = bx-ax; - var v1y = by-ay; - var v2x = px-ax; - var v2y = py-ay; + var v0x = cx-ax; + var v0y = cy-ay; + var v1x = bx-ax; + var v1y = by-ay; + var v2x = px-ax; + var v2y = py-ay; - var dot00 = v0x*v0x+v0y*v0y; - var dot01 = v0x*v1x+v0y*v1y; - var dot02 = v0x*v2x+v0y*v2y; - var dot11 = v1x*v1x+v1y*v1y; - var dot12 = v1x*v2x+v1y*v2y; + var dot00 = v0x*v0x+v0y*v0y; + var dot01 = v0x*v1x+v0y*v1y; + var dot02 = v0x*v2x+v0y*v2y; + var dot11 = v1x*v1x+v1y*v1y; + var dot12 = v1x*v2x+v1y*v2y; - var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - var u = (dot11 * dot02 - dot01 * dot12) * invDenom; - var v = (dot00 * dot12 - dot01 * dot02) * invDenom; + var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + var u = (dot11 * dot02 - dot01 * dot12) * invDenom; + var v = (dot00 * dot12 - dot01 * dot02) * invDenom; - // Check if point is in triangle - return (u >= 0) && (v >= 0) && (u + v < 1); -} + // Check if point is in triangle + return (u >= 0) && (v >= 0) && (u + v < 1); +}; /** * Checks if a shape is convex @@ -145,5 +152,5 @@ PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) */ PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign) { - return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign; -} + return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) === sign; +}; diff --git a/src/pixi/utils/Utils.js b/src/pixi/utils/Utils.js index 71d7a65b..4551722f 100644 --- a/src/pixi/utils/Utils.js +++ b/src/pixi/utils/Utils.js @@ -18,13 +18,13 @@ var lastTime = 0; var vendors = ['ms', 'moz', 'webkit', 'o']; for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { - window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; - window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame'] - || window[vendors[x]+'CancelRequestAnimationFrame']; + window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame']; + window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] || + window[vendors[x] + 'CancelRequestAnimationFrame']; } -if (!window.requestAnimationFrame) - window.requestAnimationFrame = function(callback, element) { +if (!window.requestAnimationFrame) { + window.requestAnimationFrame = function(callback) { var currTime = new Date().getTime(); var timeToCall = Math.max(0, 16 - (currTime - lastTime)); var id = window.setTimeout(function() { callback(currTime + timeToCall); }, @@ -32,50 +32,52 @@ if (!window.requestAnimationFrame) lastTime = currTime + timeToCall; return id; }; +} -if (!window.cancelAnimationFrame) +if (!window.cancelAnimationFrame) { window.cancelAnimationFrame = function(id) { clearTimeout(id); }; +} window.requestAnimFrame = window.requestAnimationFrame; /** * Converts a hex color number to an [R, G, B] array * - * @method HEXtoRGB + * @method hex2rgb * @param hex {Number} */ -function HEXtoRGB(hex) { - return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; -} +PIXI.hex2rgb = function hex2rgb(hex) { + return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; +}; /** * A polyfill for Function.prototype.bind * * @method bind */ -if (typeof Function.prototype.bind != 'function') { - Function.prototype.bind = (function () { - var slice = Array.prototype.slice; - return function (thisArg) { - var target = this, boundArgs = slice.call(arguments, 1); +if (typeof Function.prototype.bind !== 'function') { + Function.prototype.bind = (function () { + var slice = Array.prototype.slice; + return function (thisArg) { + var target = this, boundArgs = slice.call(arguments, 1); - if (typeof target != 'function') throw new TypeError(); + if (typeof target !== 'function') throw new TypeError(); - function bound() { - var args = boundArgs.concat(slice.call(arguments)); - target.apply(this instanceof bound ? this : thisArg, args); - } + function bound() { + var args = boundArgs.concat(slice.call(arguments)); + target.apply(this instanceof bound ? this : thisArg, args); + } - bound.prototype = (function F(proto) { - proto && (F.prototype = proto); - if (!(this instanceof F)) return new F; - })(target.prototype); + bound.prototype = (function F(proto) { + if (proto) F.prototype = proto; + if (!(this instanceof F)) return new F(); + })(target.prototype); - return bound; - }; - })(); + return bound; + }; + })(); } /** @@ -84,57 +86,57 @@ if (typeof Function.prototype.bind != 'function') { * @class AjaxRequest * @constructor */ -var AjaxRequest = PIXI.AjaxRequest = function() +PIXI.AjaxRequest = function AjaxRequest() { - var activexmodes = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Microsoft.XMLHTTP"] //activeX versions to check for in IE + var activexmodes = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0', 'Microsoft.XMLHTTP']; //activeX versions to check for in IE - if (window.ActiveXObject) - { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken) - for (var i=0; i>>>>>>>>") - console.log("_") - var safe = 0; - var tmp = item.first; - console.log(tmp); + window.console.log('>>>>>>>>>'); + window.console.log('_'); + var safe = 0; + var tmp = item.first; + window.console.log(tmp); - while(tmp._iNext) - { - safe++; - tmp = tmp._iNext; - console.log(tmp); - // console.log(tmp); + while(tmp._iNext) + { + safe++; + tmp = tmp._iNext; + window.console.log(tmp); + // console.log(tmp); - if(safe > 100) - { - console.log("BREAK") - break - } - } -} + if(safe > 100) + { + window.console.log('BREAK'); + break; + } + } +}; diff --git a/src/tilemap/Tilemap.js b/src/tilemap/Tilemap.js index 75f02fd2..098c0ae8 100644 --- a/src/tilemap/Tilemap.js +++ b/src/tilemap/Tilemap.js @@ -197,6 +197,7 @@ Phaser.Tilemap.prototype = { * Sprite is created. You could also give it a value like: body.velocity.x: 100 to set it moving automatically. * * @method Phaser.Tileset#createFromObjects + * @param {string} name - The name of the Object Group to create Sprites from. * @param {number} gid - The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents. * @param {string} key - The Game.cache key of the image that this Sprite will use. * @param {number|string} [frame] - If the Sprite image contains multiple frames you can specify which one to use here. @@ -204,28 +205,34 @@ Phaser.Tilemap.prototype = { * @param {boolean} [autoCull=true] - The default autoCull state of the Sprite. Sprites that are autoCulled are culled from the camera if out of its range. * @param {Phaser.Group} [group] - Optional Group to add the Sprite to. If not specified it will be added to the World group. */ - createFromObjects: function (gid, key, frame, exists, autoCull, group) { + createFromObjects: function (name, gid, key, frame, exists, autoCull, group) { if (typeof exists === 'undefined') { exists = true; } if (typeof autoCull === 'undefined') { autoCull = true; } if (typeof group === 'undefined') { group = this.game.world; } + if (!this.objects[name]) + { + console.warn('Tilemap.createFromObjects: Invalid objectgroup name given: ' + name); + return; + } + var sprite; - for (var i = 0; i < this.objects.length; i++) + for (var i = 0, len = this.objects[name].length; i < len; i++) { - if (this.objects[i].gid === gid) + if (this.objects[name][i].gid === gid) { - sprite = group.create(this.objects[i].x, this.objects[i].y, key, frame, exists); + sprite = group.create(this.objects[name][i].x, this.objects[name][i].y, key, frame, exists); sprite.anchor.setTo(0, 1); - sprite.name = this.objects[i].name; - sprite.visible = this.objects[i].visible; + sprite.name = this.objects[name][i].name; + sprite.visible = this.objects[name][i].visible; sprite.autoCull = autoCull; - for (property in this.objects[i].properties) + for (property in this.objects[name][i].properties) { - group.set(sprite, property, this.objects[i].properties[property], false, false, 0); + group.set(sprite, property, this.objects[name][i].properties[property], false, false, 0); } } } diff --git a/src/tilemap/TilemapParser.js b/src/tilemap/TilemapParser.js index 08844ef0..b5fb2370 100644 --- a/src/tilemap/TilemapParser.js +++ b/src/tilemap/TilemapParser.js @@ -265,7 +265,7 @@ Phaser.TilemapParser = { map.images = images; // Objects - var objects = []; + var objects = {}; for (var i = 0; i < json.layers.length; i++) { @@ -274,7 +274,9 @@ Phaser.TilemapParser = { continue; } - for (var v = 0; v < json.layers[i].objects.length; v++) + objects[json.layers[i].name] = []; + + for (var v = 0, len = json.layers[i].objects.length; v < len; v++) { // For now we'll just support object tiles if (json.layers[i].objects[v].gid) @@ -290,7 +292,7 @@ Phaser.TilemapParser = { }; - objects.push(object); + objects[json.layers[i].name].push(object); } } diff --git a/src/utils/Utils.js b/src/utils/Utils.js index 8619f78b..b7f3faf8 100644 --- a/src/utils/Utils.js +++ b/src/utils/Utils.js @@ -244,6 +244,16 @@ function HEXtoRGB(hex) { return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; } +/** + * Converts a hex color number to an [R, G, B] array + * + * @method hex2rgb + * @param hex {Number} + */ +PIXI.hex2rgb = function hex2rgb(hex) { + return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; +}; + /** * A polyfill for Function.prototype.bind */