diff --git a/Gruntfile.js b/Gruntfile.js
index 77b347e..f7d524b 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,10 +1,12 @@
module.exports = function(grunt) {
+ grunt.loadNpmTasks('grunt-concat-sourcemap');
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-jshint');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-contrib-qunit');
grunt.loadNpmTasks('grunt-contrib-yuidoc');
+ grunt.loadNpmTasks('grunt-contrib-watch');
var root = 'src/pixi/',
debug = 'bin/pixi.dev.js',
@@ -79,7 +81,6 @@ module.exports = function(grunt) {
dirs: {
build: 'bin',
docs: 'docs',
- examples: 'examples',
src: 'src/pixi',
test: 'test'
},
@@ -98,6 +99,16 @@ module.exports = function(grunt) {
dest: '<%= files.build %>'
}
},
+ concat_sourcemap: {
+ dev: {
+ files: {
+ '<%= files.build %>': srcFiles
+ },
+ options: {
+ sourceRoot: '../'
+ }
+ }
+ },
jshint: {
beforeconcat: srcFiles,
test: ['<%= files.testBlob %>'],
@@ -115,26 +126,6 @@ module.exports = function(grunt) {
dest: '<%= files.buildMin %>'
}
},
- distribute: {
- examples: [
- 'examples/example 1 - Basics',
- 'examples/example 2 - SpriteSheet',
- 'examples/example 3 - MovieClip',
- 'examples/example 4 - Balls',
- 'examples/example 5 - Morph',
- 'examples/example 6 - Interactivity',
- 'examples/example 7 - Transparent Background',
- 'examples/example 8 - Dragging',
- 'examples/example 9 - Tiling Texture',
- 'examples/example 10 - Text',
- 'examples/example 11 - RenderTexture',
- 'examples/example 12 - Spine',
- 'examples/example 13 - Graphics',
- 'examples/example 14 - Masking',
- 'examples/example 15 - Filters',
- 'examples/example 16 - Displacement'
- ]
- },
connect: {
qunit: {
options: {
@@ -169,29 +160,23 @@ module.exports = function(grunt) {
outdir: '<%= dirs.docs %>'
}
}
+ },
+ watch: {
+ dev: {
+ files: ['Gruntfile.js', 'src/**/*.js', 'examples/**/*.html'],
+ tasks: ['build-debug'],
+
+ // We would need to inject
+
diff --git a/examples/example 1 - Basics/pixi.js b/examples/example 1 - Basics/pixi.js
deleted file mode 100644
index 6d567a2..0000000
--- a/examples/example 1 - Basics/pixi.js
+++ /dev/null
@@ -1,10649 +0,0 @@
-/**
- * @license
- * Pixi.JS - v1.3.0
- * Copyright (c) 2012, Mat Groves
- * http://goodboydigital.com/
- *
- * Compiled: 2013-09-30
- *
- * Pixi.JS is licensed under the MIT License.
- * http://www.opensource.org/licenses/mit-license.php
- */
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-(function(){
-
- var root = this;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * @module PIXI
- */
-var PIXI = PIXI || {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
- *
- * @class Point
- * @constructor
- * @param x {Number} position of the point
- * @param y {Number} position of the point
- */
-PIXI.Point = function(x, y)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-}
-
-/**
- * Creates a clone of this point
- *
- * @method clone
- * @return {Point} a copy of the point
- */
-PIXI.Point.prototype.clone = function()
-{
- return new PIXI.Point(this.x, this.y);
-}
-
-// constructor
-PIXI.Point.prototype.constructor = PIXI.Point;
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
- *
- * @class Rectangle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the rectangle
- * @param y {Number} The Y coord of the upper-left corner of the rectangle
- * @param width {Number} The overall width of this rectangle
- * @param height {Number} The overall height of this rectangle
- */
-PIXI.Rectangle = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Rectangle
- *
- * @method clone
- * @return {Rectangle} a copy of the rectangle
- */
-PIXI.Rectangle.prototype.clone = function()
-{
- 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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this Rectangle
- */
-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;
-
- if(y >= y1 && y <= y1 + this.height)
- {
- return true;
- }
- }
-
- return false;
-}
-
-// constructor
-PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
-
-
-/**
- * @author Adrien Brault
- */
-
-/**
- * @class Polygon
- * @constructor
- * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
- * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
- * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
- * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
- * Numbers.
- */
-PIXI.Polygon = function(points)
-{
- //if points isn't an array, use arguments as the array
- if(!(points instanceof Array))
- points = Array.prototype.slice.call(arguments);
-
- //if this is a flat array of numbers, convert it to points
- if(typeof points[0] === 'number') {
- var p = [];
- for(var i = 0, il = points.length; i < il; i+=2) {
- p.push(
- new PIXI.Point(points[i], points[i + 1])
- );
- }
-
- points = p;
- }
-
- this.points = points;
-}
-
-/**
- * Creates a clone of this polygon
- *
- * @method clone
- * @return {Polygon} a copy of the polygon
- */
-PIXI.Polygon.prototype.clone = function()
-{
- var points = [];
- for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
-
- if(intersect) inside = !inside;
- }
-
- return inside;
-}
-
-// constructor
-PIXI.Polygon.prototype.constructor = PIXI.Polygon;
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Circle object can be used to specify a hit area for displayobjects
- *
- * @class Circle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Circle = function(x, y, radius)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property radius
- * @type Number
- * @default 0
- */
- this.radius = radius || 0;
-}
-
-/**
- * Creates a clone of this Circle instance
- *
- * @method clone
- * @return {Circle} a copy of the polygon
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
- */
-PIXI.Circle.prototype.contains = function(x, y)
-{
- if(this.radius <= 0)
- return false;
-
- var dx = (this.x - x),
- dy = (this.y - y),
- r2 = this.radius * this.radius;
-
- dx *= dx;
- dy *= dy;
-
- return (dx + dy <= r2);
-}
-
-// constructor
-PIXI.Circle.prototype.constructor = PIXI.Circle;
-
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Ellipse object can be used to specify a hit area for displayobjects
- *
- * @class Ellipse
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
- * @param width {Number} The overall width of this ellipse
- * @param height {Number} The overall height of this ellipse
- */
-PIXI.Ellipse = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Ellipse instance
- *
- * @method clone
- * @return {Ellipse} a copy of the ellipse
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this ellipse
- */
-PIXI.Ellipse.prototype.contains = function(x, y)
-{
- if(this.width <= 0 || this.height <= 0)
- return false;
-
- //normalize the coords to an ellipse with center 0,0
- //and a radius of 0.5
- var normx = ((x - this.x) / this.width) - 0.5,
- normy = ((y - this.y) / this.height) - 0.5;
-
- normx *= normx;
- normy *= normy;
-
- return (normx + normy < 0.25);
-}
-
-PIXI.Ellipse.getBounds = function()
-{
- return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
-}
-
-// constructor
-PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
-
-
-
-/*
- * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
- * you both rock!
- */
-
-function determineMatrixArrayType() {
- PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return PIXI.Matrix;
-}
-
-determineMatrixArrayType();
-
-PIXI.mat3 = {};
-
-PIXI.mat3.create = function()
-{
- 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;
-
- 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;
-
- return matrix;
-}
-
-
-PIXI.mat4 = {};
-
-PIXI.mat4.create = function()
-{
- 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;
-
- return matrix;
-}
-
-PIXI.mat3.multiply = function (mat, mat2, dest)
-{
- 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],
-
- 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[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;
-
- return dest;
-}
-
-PIXI.mat3.clone = function(mat)
-{
- 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];
-
- 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 (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
-}
-
-PIXI.mat3.toMat4 = function (mat, dest)
-{
- if (!dest) { dest = PIXI.mat4.create(); }
-
- 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[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];
-
- return dest;
-}
-
-
-/////
-
-
-PIXI.mat4.create = function()
-{
- 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;
-
- 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];
-
- 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;
-}
-
-PIXI.mat4.multiply = function (mat, mat2, dest)
-{
- 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 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;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The base class for all objects that are rendered on the screen.
- *
- * @class DisplayObject
- * @constructor
- */
-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();
-
- /**
- * 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 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 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 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;
-
- /**
- * [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 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] Current transform of the object based on world (parent) factors
- *
- * @property worldTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.worldTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [read-only] Current transform of the object locally
- *
- * @property localTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.localTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [NYI] Unkown
- *
- * @property color
- * @type Array<>
- * @private
- */
- this.color = [];
-
- /**
- * [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;
-
- /*
- * MOUSE Callbacks
- */
-
- /**
- * 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 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
- * 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 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 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
- */
-
- /**
- * 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 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}
- */
-}
-
-// constructor
-PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
-
-/**
- * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default
- * Instead of using this function you can now simply set the interactive property to true or false
- *
- * @method setInteractive
- * @param interactive {Boolean}
- * @deprecated Simply set the `interactive` property directly
- */
-PIXI.DisplayObject.prototype.setInteractive = function(interactive)
-{
- this.interactive = interactive;
-}
-
-/**
- * Indicates if the sprite will have touch and mouse interactivity. It is false by default
- *
- * @property interactive
- * @type Boolean
- * @default false
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
- get: function() {
- 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;
- }
-});
-
-/**
- * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
- * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
- * To remove a mask, set this property to null.
- *
- * @property mask
- * @type Graphics
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
- get: function() {
- 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;
- }
- }
- else
- {
- this.removeFilter(this._mask);
- this._mask.renderable = true;
- }
-
- this._mask = value;
- }
-});
-
-/**
- * Sets the filters for the displayObject. Currently there's a few limitations.
- * 1: At the moment only one filter can be applied at a time..
- * 2: They cannot be nested.
- * 3: There's no padding yet.
- * 4: this is a webGL only feature.
- * @property filters
- * @type Array
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
- get: function() {
- return this._filters;
- },
- set: function(value) {
-
- //if(value == )
- if(value)
- {
- if(this._filters)this.removeFilter(this._filters);
- this.addFilter(value)
- }
- else
- {
- if(this._filters)this.removeFilter(this._filters);
- }
-
- this._filters = value;
- }
-});
-
-/*
- * Adds a filter to this displayObject
- *
- * @method addFilter
- * @param mask {Graphics} the graphics object to use as a filter
- * @private
- */
-PIXI.DisplayObject.prototype.addFilter = function(data)
-{
- //if(this.filter)return;
- //this.filter = true;
-
- // 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;
-
- /*
- * 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);
- }
-
-}
-
-/*
- * Removes the filter to this displayObject
- *
- * @method removeFilter
- * @private
- */
-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);
- }
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-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;
-
- // 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],
-
- b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
- b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
-
- 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;
-
- worldTransform[3] = b10 * a00 + b11 * a10;
- 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;
-
-}
-
-PIXI.visibleCount = 0;
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * 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
- * @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 = [];
-}
-
-// constructor
-PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-
-/**
- * Adds a child to the container.
- *
- * @method addChild
- * @param child {DisplayObject} The DisplayObject to add to the container
- */
-PIXI.DisplayObjectContainer.prototype.addChild = function(child)
-{
- if(child.parent != undefined)
- {
-
- //// 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)
- {
- 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
- *
- * @method addChildAt
- * @param child {DisplayObject} The child to add
- * @param index {Number} The index to place the child in
- */
-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;
-
- 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
- *
- * @method swapChildren
- * @param child {DisplayObject}
- * @param child2 {DisplayObject}
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
-{
- /*
- * this funtion needs to be recoded..
- * can be done a lot faster..
- */
- return;
-
- // need to fix this function :/
- /*
- // TODO I already know this??
- var index = this.children.indexOf( child );
- var index2 = this.children.indexOf( child2 );
-
- if ( index !== -1 && index2 !== -1 )
- {
- // cool
-
- /*
- if(this.stage)
- {
- // this is to satisfy the webGL batching..
- // TODO sure there is a nicer way to achieve this!
- this.stage.__removeChild(child);
- this.stage.__removeChild(child2);
-
- this.stage.__addChild(child);
- this.stage.__addChild(child2);
- }
-
- // swap the positions..
- this.children[index] = child2;
- this.children[index2] = child;
-
- }
- else
- {
- throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
- }*/
-}
-
-/**
- * Returns the Child at the specified index
- *
- * @method getChildAt
- * @param index {Number} The index to get the child from
- */
-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);
- }
-}
-
-/**
- * Removes a child from the container.
- *
- * @method removeChild
- * @param child {DisplayObject} The DisplayObject to remove
- */
-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 tempLast = childFirst._iPrev;
- // need to make sure the parents last is updated too
- var updateLast = this;
- while(updateLast.last == childLast.last)
- {
- 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
- *
- * @method updateTransform
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.updateTransform = function()
-{
- if(!this.visible)return;
-
- PIXI.DisplayObject.prototype.updateTransform.call( this );
-
- for(var i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation
- */
-PIXI.MovieClip = function(textures)
-{
- PIXI.Sprite.call(this, textures[0]);
-
- /**
- * The array of textures that make up the animation
- *
- * @property textures
- * @type Array
- */
- this.textures = textures;
-
- /**
- * The speed that the MovieClip will play at. Higher is faster, lower is slower
- *
- * @property animationSpeed
- * @type Number
- * @default 1
- */
- this.animationSpeed = 1;
-
- /**
- * Whether or not the movie clip repeats after playing.
- *
- * @property loop
- * @type Boolean
- * @default true
- */
- this.loop = true;
-
- /**
- * Function to call when a MovieClip finishes playing
- *
- * @property onComplete
- * @type Function
- */
- this.onComplete = null;
-
- /**
- * [read-only] The index MovieClips current frame (this may not have to be a whole number)
- *
- * @property currentFrame
- * @type Number
- * @default 0
- * @readOnly
- */
- this.currentFrame = 0;
-
- /**
- * [read-only] Indicates if the MovieClip is currently playing
- *
- * @property playing
- * @type Boolean
- * @readOnly
- */
- this.playing = false;
-}
-
-// constructor
-PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
-PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
-
-/**
-* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
-* assigned to the MovieClip.
-*
-* @property totalFrames
-* @type Number
-* @default 0
-* @readOnly
-*/
-Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
- get: function() {
-
- return this.textures.length;
- }
-});
-
-
-/**
- * Stops the MovieClip
- *
- * @method stop
- */
-PIXI.MovieClip.prototype.stop = function()
-{
- this.playing = false;
-}
-
-/**
- * Plays the MovieClip
- *
- * @method play
- */
-PIXI.MovieClip.prototype.play = function()
-{
- this.playing = true;
-}
-
-/**
- * Stops the MovieClip and goes to a specific frame
- *
- * @method gotoAndStop
- * @param frameNumber {Number} frame index to stop at
- */
-PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
-{
- this.playing = false;
- this.currentFrame = frameNumber;
- var round = (this.currentFrame + 0.5) | 0;
- this.setTexture(this.textures[round % this.textures.length]);
-}
-
-/**
- * Goes to a specific frame and begins playing the MovieClip
- *
- * @method gotoAndPlay
- * @param frameNumber {Number} frame index to start at
- */
-PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
-{
- this.currentFrame = frameNumber;
- this.playing = true;
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.MovieClip.prototype.updateTransform = function()
-{
- PIXI.Sprite.prototype.updateTransform.call(this);
-
- if(!this.playing)return;
-
- this.currentFrame += this.animationSpeed;
-
- var round = (this.currentFrame + 0.5) | 0;
-
- 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();
- }
- }
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.FilterBlock = function()
-{
- this.visible = true;
- this.renderable = true;
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.ColorMatrixFilter = function()
-{
- // 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;",
- "}"
- ];
-
-}
-
-
-Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
- get: function() {
- return this.uniforms.matrix.value;
- },
- set: function(value) {
- this.uniforms.matrix.value = value;
- }
-});
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.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");
- PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
-
- this.setText(text);
- this.setStyle(style);
-
- this.updateText();
- this.dirty = false;
-};
-
-// constructor
-PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype);
-PIXI.Text.prototype.constructor = PIXI.Text;
-
-/**
- * Set the style of the 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.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.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.strokeThickness = style.strokeThickness || 0;
- style.wordWrap = style.wordWrap || false;
- style.wordWrapWidth = style.wordWrapWidth || 100;
- this.style = style;
- this.dirty = true;
-};
-
-/**
- * Set the copy for the text object. To split a line you can use "\n"
- *
- * @methos 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.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.Text.prototype.updateText = function()
-{
- this.context.font = this.style.font;
-
- var outputText = 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)/);
-
- //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;
-
- //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.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);
-
- 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.fill)
- {
- this.context.fillText(lines[i], linePosition.x, linePosition.y);
- }
- }
-
- this.updateTexture();
-};
-
-/**
- * Updates texture size based on canvas size
- *
- * @method updateTexture
- * @private
- */
-PIXI.Text.prototype.updateTexture = function()
-{
- this.texture.baseTexture.width = this.canvas.width;
- this.texture.baseTexture.height = this.canvas.height;
- this.texture.frame.width = this.canvas.width;
- this.texture.frame.height = this.canvas.height;
-
- this._width = this.canvas.width;
- this._height = this.canvas.height;
-
- PIXI.texturesToUpdate.push(this.texture.baseTexture);
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.Text.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- this.updateText();
- this.dirty = false;
- }
-
- PIXI.Sprite.prototype.updateTransform.call(this);
-};
-
-/*
- * http://stackoverflow.com/users/34441/ellisbben
- * great solution to the problem!
- *
- * @method determineFontHeight
- * @param fontStyle {Object}
- * @private
- */
-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];
-
- 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;
-
- body.removeChild(dummy);
- }
-
- return result;
-};
-
-/**
- * A Text Object will apply wordwrap
- *
- * @method wordWrap
- * @param text {String}
- * @private
- */
-PIXI.Text.prototype.wordWrap = function(text)
-{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
- var result = "";
- var lines = text.split("\n");
- for (var i = 0; i < lines.length; i++)
- {
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
- }
-
- return result;
-};
-
-/**
- * Destroys this text object
- *
- * @method destroy
- * @param destroyTexture {Boolean}
- */
-PIXI.Text.prototype.destroy = function(destroyTexture)
-{
- if(destroyTexture)
- {
- this.texture.destroy();
- }
-
-};
-
-PIXI.Text.heightCache = {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.
- *
- * @class BitmapText
- * @extends DisplayObjectContainer
- * @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")
- */
-PIXI.BitmapText = function(text, style)
-{
- PIXI.DisplayObjectContainer.call(this);
-
- this.setText(text);
- this.setStyle(style);
- this.updateText();
- this.dirty = false
-
-};
-
-// constructor
-PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
-
-/**
- * Set the copy for the text object
- *
- * @method setText
- * @param text {String} The copy that you would like the text to display
- */
-PIXI.BitmapText.prototype.setText = function(text)
-{
- this.text = text || " ";
- this.dirty = true;
-};
-
-/**
- * Set the style of the 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")
- */
-PIXI.BitmapText.prototype.setStyle = function(style)
-{
- style = style || {};
- style.align = style.align || "left";
- this.style = style;
-
- 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;
-
- this.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.BitmapText.prototype.updateText = function()
-{
- var data = PIXI.BitmapText.fonts[this.fontName];
- var pos = new PIXI.Point();
- var prevCharCode = null;
- var chars = [];
- var maxLineWidth = 0;
- var lineWidths = [];
- var line = 0;
- var scale = this.fontSize / data.size;
- for(var i = 0; i < this.text.length; i++)
- {
- var charCode = this.text.charCodeAt(i);
- if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
- {
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
- line++;
-
- pos.x = 0;
- pos.y += data.lineHeight;
- prevCharCode = null;
- continue;
- }
-
- var charData = data.chars[charCode];
- if(!charData) continue;
-
- if(prevCharCode && charData[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;
-
- prevCharCode = charCode;
- }
-
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
-
- var lineAlignOffsets = [];
- for(i = 0; i <= line; i++)
- {
- var alignOffset = 0;
- if(this.style.align == "right")
- {
- alignOffset = maxLineWidth - lineWidths[i];
- }
- else if(this.style.align == "center")
- {
- alignOffset = (maxLineWidth - lineWidths[i]) / 2;
- }
- lineAlignOffsets.push(alignOffset);
- }
-
- for(i = 0; i < chars.length; i++)
- {
- 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;
- this.addChild(c);
- }
-
- this.width = pos.x * scale;
- this.height = (pos.y + data.lineHeight) * scale;
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.BitmapText.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- while(this.children.length > 0)
- {
- this.removeChild(this.getChildAt(0));
- }
- this.updateText();
-
- this.dirty = false;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
-};
-
-PIXI.BitmapText.fonts = {};
-
-/**
- * @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.
- *
- * @class InteractionManager
- * @constructor
- * @param stage {Stage} The stage to handle interactions
- */
-PIXI.InteractionManager = function(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();
-
- /**
- * 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();
-
- this.mouseoverEnabled = true;
-
- //tiny little interactiveData pool!
- this.pool = [];
-
- 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.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;
-
-/**
- * Collects an interactive sprite recursively to have their interactions managed
- *
- * @method collectInteractiveSprite
- * @param displayObject {DisplayObject} the displayObject to collect
- * @param iParent {DisplayObject}
- * @private
- */
-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);
-
- 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
- *
- * @method setTarget
- * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to
- * @private
- */
-PIXI.InteractionManager.prototype.setTarget = function(target)
-{
- this.target = target;
-
- //check if the dom element has been set. If it has don't do anything
- if( this.interactionDOMElement === null ) {
-
- this.setTargetDomElement( target.view );
- }
-
- document.body.addEventListener('mouseup', this.onMouseUp, true);
-}
-
-
-/**
- * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
- * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
- * to receive those events
- *
- * @method setTargetDomElement
- * @param domElement {DOMElement} the dom element which will receive mouse and touch events
- * @private
- */
-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'] = '';
-
- 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);
- }
-
-
- 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!
- }
-
- this.interactionDOMElement = domElement;
-
- 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
- *
- * @method update
- * @private
- */
-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 = "default";
-
- 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 = "pointer";
-
- 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
- *
- * @method onMouseMove
- * @param event {Event} The DOM event of the mouse moving
- * @private
- */
-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);
- }
- }
-}
-
-/**
- * Is called when the mouse button is pressed down on the renderer element
- *
- * @method onMouseDown
- * @param event {Event} The DOM event of a mouse button being pressed down
- * @private
- */
-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;
- }
- }
- }
-}
-
-
-PIXI.InteractionManager.prototype.onMouseOut = function(event)
-{
- var length = this.interactiveItems.length;
-
- this.interactionDOMElement.style.cursor = "default";
-
- 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
- *
- * @method onMouseUp
- * @param event {Event} The DOM event of a mouse button being released
- * @private
- */
-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;
- }
- }
-}
-
-/**
- * Tests if the current mouse coords hit a sprite
- *
- * @method hitTest
- * @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
- * @private
- */
-PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
-{
- var global = interactionData.global;
-
- if(item.vcount !== PIXI.visibleCount)return false;
-
- 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;
-
- 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;
-
- 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
- *
- * @method onTouchMove
- * @param event {Event} The DOM event of a touch moving accross the renderer view
- * @private
- */
-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);
- }
-}
-
-/**
- * Is called when a touch is started on the renderer element
- *
- * @method onTouchStart
- * @param event {Event} The DOM event of a touch starting on the renderer view
- * @private
- */
-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;
- }
- }
- }
- }
-}
-
-/**
- * Is called when a touch is ended on the renderer element
- *
- * @method onTouchEnd
- * @param event {Event} The DOM event of a touch ending on the renderer view
- * @private
- */
-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;
- }
-}
-
-/**
- * Holds all information related to an Interaction event
- *
- * @class InteractionData
- * @constructor
- */
-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();
-
- /**
- * The target Sprite that was interacted with
- *
- * @property target
- * @type Sprite
- */
- this.target;
-
- /**
- * When passed to an event handler, this will be the original DOM Event that was captured
- *
- * @property originalEvent
- * @type Event
- */
- this.originalEvent;
-}
-
-/**
- * This will return the local coords of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
- */
-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],
- 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)
-}
-
-// constructor
-PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A Stage represents the root of the display tree. Everything connected to the stage is rendered
- *
- * @class Stage
- * @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
- */
-PIXI.Stage = function(backgroundColor)
-{
- 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();
-
- /**
- * 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);
-
- /**
- * Whether the stage is dirty and needs to have interactions updated
- *
- * @property dirty
- * @type Boolean
- * @private
- */
- this.dirty = true;
-
- this.__childrenAdded = [];
- this.__childrenRemoved = [];
-
- //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);
-
- this.setBackgroundColor(backgroundColor);
- this.worldVisible = true;
-}
-
-// constructor
-PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Stage.prototype.constructor = PIXI.Stage;
-
-/**
- * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
- * This is useful for when you have other DOM elements ontop of the Canvas element.
- *
- * @method setInteractionDelegate
- * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
- */
-PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
-{
- this.interactionManager.setTargetDomElement( domElement );
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.Stage.prototype.updateTransform = function()
-{
- this.worldAlpha = 1;
- this.vcount = PIXI.visibleCount;
-
- for(var i=0,j=this.children.length; i> 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 target != 'function') throw new TypeError();
-
- 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);
-
- return bound;
- };
- })();
-}
-
-/**
- * A wrapper for ajax requests to be handled cross browser
- *
- * @class AjaxRequest
- * @constructor
- */
-var AjaxRequest = PIXI.AjaxRequest = function()
-{
- 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);
-
- while(tmp._iNext)
- {
- safe++;
- tmp = tmp._iNext;
- console.log(tmp);
- // console.log(tmp);
-
- if(safe > 100)
- {
- console.log("BREAK")
- break
- }
- }
-}
-
-
-
-
-
-
-/**
- * https://github.com/mrdoob/eventtarget.js/
- * THankS mr DOob!
- */
-
-/**
- * Adds event emitter functionality to a class
- *
- * @class EventTarget
- * @example
- * function MyEmitter() {
- * PIXI.EventTarget.call(this); //mixes in event target stuff
- * }
- *
- * var em = new MyEmitter();
- * em.emit({ type: 'eventName', data: 'some data' });
- */
-PIXI.EventTarget = function () {
-
- var listeners = {};
-
- this.addEventListener = this.on = function ( type, listener ) {
-
-
- if ( listeners[ type ] === undefined ) {
-
- listeners[ type ] = [];
-
- }
-
- if ( listeners[ type ].indexOf( listener ) === - 1 ) {
-
- listeners[ type ].push( listener );
- }
-
- };
-
- this.dispatchEvent = this.emit = function ( event ) {
-
- if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
-
- return;
-
- }
-
- for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
-
- listeners[ event.type ][ i ]( event );
-
- }
-
- };
-
- this.removeEventListener = this.off = function ( type, listener ) {
-
- var index = listeners[ type ].indexOf( listener );
-
- if ( index !== - 1 ) {
-
- listeners[ type ].splice( index, 1 );
-
- }
-
- };
-
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * This helper function will automatically detect which renderer you should be using.
- * WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
- * the browser then this function will return a canvas renderer
- *
- * @method autoDetectRenderer
- * @static
- * @param width {Number} the width of the renderers view
- * @param height {Number} the height of the renderers view
- * @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 webGL chrome at the moment)
- *
- * antialias
- */
-PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
-{
- if(!width)width = 800;
- if(!height)height = 600;
-
- // BORROWED from Mr Doob (mrdoob.com)
- var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )();
-
- //console.log(webgl);
- if( webgl )
- {
- return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
- }
-
- return new PIXI.CanvasRenderer(width, height, view, transparent);
-};
-
-
-
-/*
- PolyK library
- url: http://polyk.ivank.net
- Released under MIT licence.
-
- 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:
-
- 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.
-
- This is an amazing lib!
-
- slightly modified by mat groves (matgroves.com);
-*/
-
-PIXI.PolyK = {};
-
-/**
- * Triangulates shapes for webGL graphic fills
- *
- * @method Triangulate
- * @namespace PolyK
- * @constructor
- */
-PIXI.PolyK.Triangulate = function(p)
-{
- var sign = true;
-
- var n = p.length>>1;
- if(n<3) return [];
- var tgs = [];
- var avl = [];
- for(var i=0; i 3)
- {
- var i0 = avl[(i+0)%al];
- var i1 = avl[(i+1)%al];
- var i2 = avl[(i+2)%al];
-
- 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];
-
- 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= 0) && (v >= 0) && (u + v < 1);
-}
-
-/**
- * Checks if a shape is convex
- *
- * @class _convex
- * @namespace PolyK
- * @private
- */
-PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
-{
- return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/*
- * the default suoer fast shader!
- */
-
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
-
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
-
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * the triangle strip shader..
- */
-
-PIXI.stripShaderFragmentSrc = [
- "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;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.shaderStack = [];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
-
- //gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-//gl.enableVertexAttribArray(program.textureCoordAttribute);
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-
-
-}
-
-PIXI.initDefaultShader = function()
-{
- PIXI.defaultShader = new PIXI.PixiShader();
- PIXI.defaultShader.init();
- PIXI.activateShader(PIXI.defaultShader);
- /*
- PIXI.shaderStack.push(PIXI.defaultShader);
- PIXI.current*/
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
-
-PIXI.CompileVertexShader = function(gl, shaderSrc)
-{
- return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
-}
-
-PIXI.CompileFragmentShader = function(gl, shaderSrc)
-{
- 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);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(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();
-
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
-
- return shaderProgram;
-}
-
-PIXI.activateShader = function(shader)
-{
- PIXI.shaderStack.push(shader);
-
- //console.log(">>>")
- var gl = PIXI.gl;
-
- var shaderProgram = shader.program;
-
- // map uniforms..
- gl.useProgram(shaderProgram);
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
-
- shader.syncUniforms();
-
- PIXI.currentShader = shaderProgram;
-}
-
-
-PIXI.popShader = function()
-{
- var gl = PIXI.gl;
- // activate last program..
- var lastProgram = PIXI.shaderStack.pop();
-
- var shaderProgram = PIXI.shaderStack[ PIXI.shaderStack.length-1 ].program;
-
- gl.useProgram(shaderProgram);
-
- PIXI.currentShader = shaderProgram;
-}
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.primitiveProgram);
-
- //gl.disableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.disableVertexAttribArray(PIXI.currentShader.colorAttribute);
- gl.disableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
-
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute);
-}
-
-PIXI.deactivatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.currentShader);
-
- gl.enableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.colorAttribute);
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-PIXI.PixiShader = function()
-{
- // the webGL program..
- this.program;
-
- this.fragmentSrc = [
- "precision lowp float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
- "}"
- ];
-
-}
-
-PIXI.PixiShader.prototype.init = function()
-{
- var program = PIXI.compileProgram(this.vertexSrc || PIXI.shaderVertexSrc, this.fragmentSrc)
-
- var gl = PIXI.gl;
-
- gl.useProgram(program);
-
- // get the default shader bits!
- program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
- program.colorAttribute = gl.getAttribLocation(program, "aColor");
- program.textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
-
- program.projectionVector = gl.getUniformLocation(program, "projectionVector");
- program.samplerUniform = gl.getUniformLocation(program, "uSampler");
-
- // add those custom shaders!
- for (var key in this.uniforms)
- {
- // get the uniform locations..
- program[key] = gl.getUniformLocation(program, key);
- }
-
- this.program = program;
-}
-
-PIXI.PixiShader.prototype.syncUniforms = function()
-{
- var gl = PIXI.gl;
-
- for (var key in this.uniforms)
- {
- //var
- var type = this.uniforms[key].type;
-
- // need to grow this!
- if(type == "f")
- {
- gl.uniform1f(this.program[key], this.uniforms[key].value);
- }
- else if(type == "mat4")
- {
- gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- }
- }
-
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A set of functions used by the webGL renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.WebGLGraphics = function()
-{
-
-}
-
-/**
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param projection {Object}
- */
-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);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
-
- // WHY DOES THIS LINE NEED TO BE THERE???
- //gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.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
- *
- * @static
- * @private
- * @method updateGraphics
- * @param graphics {Graphics}
- */
-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;
-
- 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
- *
- * @static
- * @private
- * @method buildRectangle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- }
-
-}
-
-/**
- * Builds a circle to draw
- *
- * @static
- * @private
- * @method buildCircle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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;
-
- 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);
- }
-
-}
-
-/**
- * Builds a line to draw
- *
- * @static
- * @private
- * @method buildLine
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
-{
- // TODO OPTIMISE!
-
- var wrap = true;
- var points = graphicsData.points;
- if(points.length == 0)return;
-
- // 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;
-
- 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 (denom == 0) {
- denom+=1;
- }
-
- 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 (var i=0; i < indexCount; i++)
- {
- indices.push(indexStart++);
- };
-
- indices.push(indexStart-1);
-}
-
-/**
- * Builds a polygon to draw
- *
- * @static
- * @private
- * @method buildPoly
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- };
-}
-
-function HEXtoRGB(hex) {
- return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
-
-// an instance of the gl context..
-// only one at the moment :/
-PIXI.gl;
-
-/**
- * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
- * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
- * So no need for Sprite Batch's or Sprite Cloud's
- * Dont forget to add the view to your DOM or you will not see anything :)
- *
- * @class WebGLRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @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..
-
- this.transparent = !!transparent;
-
- this.width = width || 800;
- this.height = height || 600;
-
- this.view = view || document.createElement( 'canvas' );
- this.view.width = this.width;
- this.view.height = this.height;
-
- // 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.batchs = [];
-
- try
- {
- PIXI.gl = this.gl = this.view.getContext("experimental-webgl", {
- alpha: this.transparent,
- antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
- stencil:true
- });
- }
- catch (e)
- {
- throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
- }
-
- PIXI.initDefaultShader();
- PIXI.initPrimitiveShader();
- PIXI.initDefaultStripShader();
-
-
-// PIXI.activateDefaultShader();
-
- var gl = this.gl;
- PIXI.WebGLRenderer.gl = gl;
-
- this.batch = new PIXI.WebGLBatch(gl);
- gl.disable(gl.DEPTH_TEST);
- gl.disable(gl.CULL_FACE);
-
- gl.enable(gl.BLEND);
- gl.colorMask(true, true, true, this.transparent);
-
- PIXI.projection = new PIXI.Point(400, 300);
-
- this.resize(this.width, this.height);
- this.contextLost = false;
-
- PIXI.activateShader(PIXI.defaultShader);
-
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
-
-}
-
-// constructor
-PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
-
-/**
- * Gets a new WebGLBatch from the pool
- *
- * @static
- * @method getBatch
- * @return {WebGLBatch}
- * @private
- */
-PIXI.WebGLRenderer.getBatch = function()
-{
- if(PIXI._batchs.length == 0)
- {
- return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
- }
- else
- {
- return PIXI._batchs.pop();
- }
-}
-
-/**
- * Puts a batch back into the pool
- *
- * @static
- * @method returnBatch
- * @param batch {WebGLBatch} The batch to return
- * @private
- */
-PIXI.WebGLRenderer.returnBatch = function(batch)
-{
- batch.clean();
- PIXI._batchs.push(batch);
-}
-
-/**
- * Renders the stage to its webGL view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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);
- }
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
-
- // 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;
- 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
- *
- * @static
- * @method updateTextures
- * @private
- */
-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 = [];
-}
-
-/**
- * Updates a loaded webgl texture
- *
- * @static
- * @method updateTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.updateTexture = function(texture)
-{
- //TODO break this out into a texture manager...
- var gl = PIXI.gl;
-
- if(!texture._glTexture)
- {
- texture._glTexture = gl.createTexture();
- }
-
- if(texture.hasLoaded)
- {
- gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
-
- 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);
-
- // reguler...
-
- 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
- *
- * @method destroyTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.destroyTexture = function(texture)
-{
- //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);
- }
-}
-
-/**
- * resizes the webGL view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the webGL view
- * @param height {Number} the new height of the webGL view
- */
-PIXI.WebGLRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-
- this.gl.viewport(0, 0, this.width, this.height);
-
- //var projectionMatrix = this.projectionMatrix;
-
- 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;
-}
-
-/**
- * Handles a lost webgl context
- *
- * @method handleContextLost
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
-{
- event.preventDefault();
- this.contextLost = true;
-}
-
-/**
- * Handles a restored webgl context
- *
- * @method handleContextRestored
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
-{
- this.gl = this.view.getContext("experimental-webgl", {
- alpha: true
- });
-
- this.initShaders();
-
- 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;
- };
-
- PIXI._restoreBatchs(this.gl);
-
- this.contextLost = false;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._batchs = [];
-
-/**
- * @private
- */
-PIXI._getBatch = function(gl)
-{
- 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);
-}
-
-/**
- * @private
- */
-PIXI._restoreBatchs = function(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.
- * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
- * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
- * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
- * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @constructor
- * @param gl {WebGLContext} an instance of the webGL context
- */
-PIXI.WebGLBatch = function(gl)
-{
- this.gl = gl;
-
- 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;
-
-/**
- * Cleans the batch so that is can be returned to an object pool and reused
- *
- * @method clean
- */
-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;
-}
-
-/**
- * Recreates the buffers in the event of a context loss
- *
- * @method restoreLostContext
- * @param gl {WebGLContext}
- */
-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();
-}
-
-/**
- * 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
- */
-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;
-
- this.growBatch();
-}
-
-/**
- * inserts a sprite before the specified 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++;
-
- 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;
- }
-}
-
-/**
- * inserts a sprite after the specified sprite
- *
- * @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++;
-
- sprite.batch = this;
- this.dirty = true;
-
- var tempNext = previousSprite.__next;
- previousSprite.__next = sprite;
- sprite.__prev = previousSprite;
-
- 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--;
-
- 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.__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;
-}
-
-/**
- * Splits the batch into two with the specified sprite being the start of the new batch.
- *
- * @method split
- * @param sprite {Sprite} the sprite that indicates where the batch should be split
- * @return {WebGLBatch} the new batch
- */
-PIXI.WebGLBatch.prototype.split = function(sprite)
-{
- this.dirty = true;
-
- 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;
-
- 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"?
-
- // 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;
-
- return batch;
-}
-
-/**
- * Merges two batchs together
- *
- * @method merge
- * @param batch {WebGLBatch} the batch that will be merged
- */
-PIXI.WebGLBatch.prototype.merge = function(batch)
-{
- this.dirty = true;
-
- this.tail.__next = batch.head;
- batch.head.__prev = this.tail;
-
- this.size += batch.size;
-
- this.tail = batch.tail;
-
- 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
- * function is used to increase the size of the batch. It also creates a little extra room so
- * that the batch does not need to be resized every time a sprite is added
- *
- * @method growBatch
- */
-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);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
-
- 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.dirtyUVS = 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.dirtyColors = true;
-
- this.indices = new Uint16Array(this.dynamicSize * 6);
- var length = this.indices.length/6;
-
- 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
- *
- * @method refresh
- */
-PIXI.WebGLBatch.prototype.refresh = function()
-{
- var gl = this.gl;
-
- if (this.dynamicSize < this.size)
- {
- this.growBatch();
- }
-
- 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;
-
- while(displayObject)
- {
- index = indexRun * 8;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
-
- colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
-
- displayObject = displayObject.__next;
-
- indexRun ++;
- }
-
- this.dirtyUVS = true;
- this.dirtyColors = true;
-}
-
-/**
- * Updates all the relevant geometry and uploads the data to the GPU
- *
- * @method update
- */
-PIXI.WebGLBatch.prototype.update = function()
-{
- var gl = this.gl;
- var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3
-
- var a, b, c, d, tx, ty;
-
- var indexRun = 0;
-
- var displayObject = this.head;
-
- while(displayObject)
- {
- if(displayObject.vcount === PIXI.visibleCount)
- {
- width = displayObject.texture.frame.width;
- height = displayObject.texture.frame.height;
-
- // 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;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- index = indexRun * 8;
-
- worldTransform = displayObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- this.verticies[index + 0 ] = a * w1 + c * h1 + tx;
- this.verticies[index + 1 ] = d * h1 + b * w1 + ty;
-
- this.verticies[index + 2 ] = a * w0 + c * h1 + tx;
- this.verticies[index + 3 ] = d * h1 + b * w0 + ty;
-
- this.verticies[index + 4 ] = a * w0 + c * h0 + tx;
- this.verticies[index + 5 ] = d * h0 + b * w0 + ty;
-
- this.verticies[index + 6] = a * w1 + c * h0 + tx;
- this.verticies[index + 7] = d * h0 + b * w1 + ty;
-
- if(displayObject.updateFrame || displayObject.texture.updateFrame)
- {
- this.dirtyUVS = true;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
- }
-
- // TODO this probably could do with some optimisation....
- if(displayObject.cacheAlpha != displayObject.worldAlpha)
- {
- displayObject.cacheAlpha = displayObject.worldAlpha;
-
- var colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
- this.dirtyColors = true;
- }
- }
- else
- {
- index = indexRun * 8;
-
- this.verticies[index + 0 ] = 0;
- this.verticies[index + 1 ] = 0;
-
- this.verticies[index + 2 ] = 0;
- this.verticies[index + 3 ] = 0;
-
- this.verticies[index + 4 ] = 0;
- this.verticies[index + 5 ] = 0;
-
- this.verticies[index + 6] = 0;
- this.verticies[index + 7] = 0;
- }
-
- indexRun++;
- displayObject = displayObject.__next;
- }
-}
-
-/**
- * Draws the batch to the frame buffer
- *
- * @method render
- */
-PIXI.WebGLBatch.prototype.render = function(start, end)
-{
- start = start || 0;
-
- if(end == undefined)end = this.size;
-
- if(this.dirty)
- {
- this.refresh();
- this.dirty = false;
- }
-
- if (this.size == 0)return;
-
- this.update();
- var gl = this.gl;
-
- //TODO optimize this!
-
- var shaderProgram = PIXI.currentShader;
-
- //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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // update the uvs
- var isDefault = (shaderProgram == PIXI.shaderProgram)
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
-
- if(this.dirtyUVS)
- {
- this.dirtyUVS = false;
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
- }
-
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
-
- // update color!
- gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
-
- if(this.dirtyColors)
- {
- 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!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
-
- var len = end - start;
-
- // DRAW THAT this!
- gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
- * if a group of sprites all have the same baseTexture and blendMode then they can be
- * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
- * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
- * even if the batch only contains one sprite. Batching is handled automatically by the
- * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @contructor
- * @param gl {WebGLContext} An instance of the webGL context
- */
-PIXI.WebGLRenderGroup = function(gl)
-{
- this.gl = gl;
- this.root;
-
- this.backgroundColor;
- this.batchs = [];
- this.toRemove = [];
-}
-
-// constructor
-PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
-
-/**
- * Add a display object to the webgl renderer
- *
- * @method setRenderable
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
-{
- // has this changed??
- if(this.root)this.removeDisplayObjectAndChildren(this.root);
-
- displayObject.worldVisible = displayObject.visible;
-
- // soooooo //
- // to check if any batchs exist already??
-
- // TODO what if its already has an object? should remove it
- this.root = displayObject;
- this.addDisplayObjectAndChildren(displayObject);
-}
-
-/**
- * Renders the stage to its webgl view
- *
- * @method render
- * @param projection {Object}
- */
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
-
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- // will render all the elements in the group
- var renderable;
- for (var i=0; i < this.batchs.length; i++)
- {
-
- renderable = this.batchs[i];
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- continue;
- }
-
- // non sprite batch..
- var worldVisible = renderable.vcount === PIXI.visibleCount;
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
- }
-
-}
-
-/**
- * Renders a specific displayObject
- *
- * @method renderSpecific
- * @param displayObject {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- // to do!
- // render part of the scene...
-
- var startIndex;
- var startBatchIndex;
-
- var endIndex;
- var endBatchIndex;
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.first;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
- var startBatch = nextRenderable.batch;
-
- if(nextRenderable instanceof PIXI.Sprite)
- {
- startBatch = nextRenderable.batch;
-
- var head = startBatch.head;
- var next = head;
-
- // ok now we have the batch.. need to find the start index!
- if(head == nextRenderable)
- {
- startIndex = 0;
- }
- else
- {
- startIndex = 1;
-
- while(head.__next != nextRenderable)
- {
- startIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- startBatch = nextRenderable;
- }
-
- // Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
- {
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem.last;
- }
-
- if(lastRenderable instanceof PIXI.Sprite)
- {
- endBatch = lastRenderable.batch;
-
- var head = endBatch.head;
-
- if(head == lastRenderable)
- {
- endIndex = 0;
- }
- else
- {
- endIndex = 1;
-
- while(head.__next != lastRenderable)
- {
- endIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- endBatch = lastRenderable;
- }
-
- // TODO - need to fold this up a bit!
-
- if(startBatch == endBatch)
- {
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex, endIndex+1);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
- return;
- }
-
- // now we have first and last!
- startBatchIndex = this.batchs.indexOf(startBatch);
- endBatchIndex = this.batchs.indexOf(endBatch);
-
- // DO the first batch
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
-
- // DO the middle batchs..
- for (var i=startBatchIndex+1; i < endBatchIndex; i++)
- {
- renderable = this.batchs[i];
-
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- }
- else
- {
- this.renderSpecial(renderable, projection);
- }
- }
-
- // DO the last batch..
- if(endBatch instanceof PIXI.WebGLBatch)
- {
- endBatch.render(0, endIndex+1);
- }
- else
- {
- this.renderSpecial(endBatch, projection);
- }
-}
-
-/**
- * Renders a specific renderable
- *
- * @method renderSpecial
- * @param renderable {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
-{
- var sta = PIXI.shaderStack.length;
-
- var worldVisible = renderable.vcount === PIXI.visibleCount
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.CustomRenderable)
- {
- if(worldVisible) renderable.renderWebGL(this, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
-}
-
-PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection)
-{
- /*
- * for now only masks are supported..
- */
- var gl = PIXI.gl;
-
- if(renderable.open)
- {
- if(renderable.data instanceof Array)
- {
- var filter = renderable.data[0];
-
- if(!filter.shader)
- {
- var shader = new PIXI.PixiShader();
-
- shader.fragmentSrc = filter.fragmentSrc;
- shader.uniforms = filter.uniforms;
- shader.init();
-
- filter.shader = shader
- }
-
- PIXI.activateShader(filter.shader);
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
- PIXI.WebGLGraphics.renderGraphics(renderable.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- }
- else
- {
- if(renderable.data instanceof Array)
- {
- PIXI.popShader();
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
-}
-
-/**
- * Updates a webgl texture
- *
- * @method updateTexture
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
-{
-
- // TODO definitely can optimse this function..
-
- this.removeObject(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- this.insertObject(displayObject, previousRenderable, nextRenderable);
-}
-
-/**
- * Adds filter blocks
- *
- * @method addFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
-{
- start.__renderGroup = this;
- end.__renderGroup = this;
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = start;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
- this.insertAfter(start, previousRenderable);
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var previousRenderable2 = end;
- while(previousRenderable2 != this.root.first)
- {
- previousRenderable2 = previousRenderable2._iPrev;
- if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
- }
- this.insertAfter(end, previousRenderable2);
-}
-
-/**
- * Remove filter blocks
- *
- * @method removeFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
-{
- this.removeObject(start);
- this.removeObject(end);
-}
-
-/**
- * Adds a display object and children to the webgl context
- *
- * @method addDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
-
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- // one the display object hits this. we can break the loop
-
- var tempObject = displayObject.first;
- var testObject = displayObject.last._iNext;
- do
- {
- tempObject.__renderGroup = this;
-
- if(tempObject.renderable)
- {
-
- this.insertObject(tempObject, previousRenderable, nextRenderable);
- previousRenderable = tempObject;
- }
-
- tempObject = tempObject._iNext;
- }
- while(tempObject != testObject)
-}
-
-/**
- * Removes a display object and children to the webgl context
- *
- * @method removeDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup != this)return;
-
-// var displayObject = displayObject.first;
- var lastObject = displayObject.last;
- do
- {
- displayObject.__renderGroup = null;
- if(displayObject.renderable)this.removeObject(displayObject);
- displayObject = displayObject._iNext;
- }
- while(displayObject)
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertObject
- * @param displayObject {DisplayObject}
- * @param previousObject {DisplayObject}
- * @param nextObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
-{
- // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
- var previousSprite = previousObject;
- var nextSprite = nextObject;
-
- /*
- * so now we have the next renderable and the previous renderable
- *
- */
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch
- var nextBatch
-
- if(previousSprite instanceof PIXI.Sprite)
- {
- previousBatch = previousSprite.batch;
- if(previousBatch)
- {
- if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
- {
- previousBatch.insertAfter(displayObject, previousSprite);
- return;
- }
- }
- }
- else
- {
- // TODO reword!
- previousBatch = previousSprite;
- }
-
- if(nextSprite)
- {
- if(nextSprite instanceof PIXI.Sprite)
- {
- nextBatch = nextSprite.batch;
-
- //batch may not exist if item was added to the display list but not to the webGL
- if(nextBatch)
- {
- if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
- {
- nextBatch.insertBefore(displayObject, nextSprite);
- return;
- }
- else
- {
- if(nextBatch == previousBatch)
- {
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(nextSprite);
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var batch = PIXI.WebGLRenderer.getBatch();
-
- var index = this.batchs.indexOf( previousBatch );
- batch.init(displayObject);
- this.batchs.splice(index+1, 0, batch, splitBatch);
-
- return;
- }
- }
- }
- }
- else
- {
- // TODO re-word!
-
- nextBatch = nextSprite;
- }
- }
-
- /*
- * looks like it does not belong to any batch!
- * but is also not intersecting one..
- * time to create anew one!
- */
-
- var batch = PIXI.WebGLRenderer.getBatch();
- batch.init(displayObject);
-
- if(previousBatch) // if this is invalid it means
- {
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, batch);
- }
- else
- {
- this.batchs.push(batch);
- }
-
- return;
- }
- else if(displayObject instanceof PIXI.TilingSprite)
- {
-
- // add to a batch!!
- this.initTilingSprite(displayObject);
- // this.batchs.push(displayObject);
-
- }
- else if(displayObject instanceof PIXI.Strip)
- {
- // add to a batch!!
- this.initStrip(displayObject);
- // this.batchs.push(displayObject);
- }
- else if(displayObject)// instanceof PIXI.Graphics)
- {
- //displayObject.initWebGL(this);
-
- // add to a batch!!
- //this.initStrip(displayObject);
- //this.batchs.push(displayObject);
- }
-
- this.insertAfter(displayObject, previousSprite);
-
- // insert and SPLIT!
-
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertAfter
- * @param item {DisplayObject}
- * @param displayObject {DisplayObject} The object to insert
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
-{
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch = displayObject.batch;
-
- if(previousBatch)
- {
- // so this object is in a batch!
-
- // is it not? need to split the batch
- if(previousBatch.tail == displayObject)
- {
- // is it tail? insert in to batchs
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item);
- }
- else
- {
- // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
-
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(displayObject.__next);
-
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item, splitBatch);
- }
- }
- else
- {
- this.batchs.push(item);
- }
- }
- else
- {
- var index = this.batchs.indexOf( displayObject );
- this.batchs.splice(index+1, 0, item);
- }
-}
-
-/**
- * Removes a displayObject from the linked list
- *
- * @method removeObject
- * @param displayObject {DisplayObject} The object to remove
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
-{
- // loop through children..
- // display object //
-
- // add a child from the render group..
- // remove it and all its children!
- //displayObject.cacheVisible = false;//displayObject.visible;
-
- /*
- * removing is a lot quicker..
- *
- */
- var batchToRemove;
-
- if(displayObject instanceof PIXI.Sprite)
- {
- // should always have a batch!
- var batch = displayObject.batch;
- if(!batch)return; // this means the display list has been altered befre rendering
-
- batch.remove(displayObject);
-
- if(batch.size==0)
- {
- batchToRemove = batch;
- }
- }
- else
- {
- batchToRemove = displayObject;
- }
-
- /*
- * Looks like there is somthing that needs removing!
- */
- if(batchToRemove)
- {
- var index = this.batchs.indexOf( batchToRemove );
- if(index == -1)return;// this means it was added then removed before rendered
-
- // ok so.. check to see if you adjacent batchs should be joined.
- // TODO may optimise?
- if(index == 0 || index == this.batchs.length-1)
- {
- // wha - eva! just get of the empty batch!
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
-
- return;
- }
-
- if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
- {
- if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
- {
- //console.log("MERGE")
- this.batchs[index-1].merge(this.batchs[index+1]);
-
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
- this.batchs.splice(index, 2);
- return;
- }
- }
-
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- }
-}
-
-
-/**
- * Initializes a tiling sprite
- *
- * @method initTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
-{
- var gl = this.gl;
-
- // make the texture tilable..
-
- sprite.verticies = new Float32Array([0, 0,
- sprite.width, 0,
- sprite.width, sprite.height,
- 0, sprite.height]);
-
- sprite.uvs = new Float32Array([0, 0,
- 1, 0,
- 1, 1,
- 0, 1]);
-
- sprite.colors = new Float32Array([1,1,1,1]);
-
- sprite.indices = new Uint16Array([0, 1, 3,2])//, 2]);
-
- sprite._vertexBuffer = gl.createBuffer();
- sprite._indexBuffer = gl.createBuffer();
- sprite._uvBuffer = gl.createBuffer();
- sprite._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.uvs, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW);
-
-// return ( (x > 0) && ((x & (x - 1)) == 0) );
-
- if(sprite.texture.baseTexture._glTexture)
- {
- gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- sprite.texture.baseTexture._powerOf2 = true;
- }
- else
- {
- sprite.texture.baseTexture._powerOf2 = true;
- }
-}
-
-/**
- * Renders a Strip
- *
- * @method renderStrip
- * @param strip {Strip} The strip to render
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.stripShaderProgram;
-
-
- gl.useProgram(shaderProgram);
-
- var m = PIXI.mat3.clone(strip.worldTransform);
-
- PIXI.mat3.transpose(m);
-
- // set the matrix transform for the
- gl.uniformMatrix3fv(shaderProgram.translationMatrix, false, m);
- gl.uniform2f(shaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(shaderProgram.alpha, strip.worldAlpha);
-
-/*
- if(strip.blendMode == PIXI.blendModes.NORMAL)
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
- }
- */
-
-
- if(!strip.dirty)
- {
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- }
- else
- {
- strip.dirty = false;
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-
- }
-
- gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
-
- gl.useProgram(PIXI.currentProgram);
-}
-
-/**
- * Renders a TilingSprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to render
- * @param projectionMatrix {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- var tilePosition = sprite.tilePosition;
- var tileScale = sprite.tileScale;
-
- var offsetX = tilePosition.x/sprite.texture.baseTexture.width;
- var offsetY = tilePosition.y/sprite.texture.baseTexture.height;
-
- var scaleX = (sprite.width / sprite.texture.baseTexture.width) / tileScale.x;
- var scaleY = (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
-
- sprite.uvs[0] = 0 - offsetX;
- sprite.uvs[1] = 0 - offsetY;
-
- sprite.uvs[2] = (1 * scaleX) -offsetX;
- sprite.uvs[3] = 0 - offsetY;
-
- sprite.uvs[4] = (1 *scaleX) - offsetX;
- sprite.uvs[5] = (1 *scaleY) - offsetY;
-
- sprite.uvs[6] = 0 - offsetX;
- sprite.uvs[7] = (1 *scaleY) - offsetY;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
-
- this.renderStrip(sprite, projectionMatrix);
-}
-
-/**
- * Initializes a strip to be rendered
- *
- * @method initStrip
- * @param strip {Strip} The strip to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
-{
- // build the strip!
- var gl = this.gl;
- var shaderProgram = this.shaderProgram;
-
- strip._vertexBuffer = gl.createBuffer();
- strip._indexBuffer = gl.createBuffer();
- strip._uvBuffer = gl.createBuffer();
- strip._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-}
-
-
-/**
- * @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 :)
- *
- * @class CanvasRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
- */
-PIXI.CanvasRenderer = function(width, height, view, transparent)
-{
- this.transparent = transparent;
-
- /**
- * 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 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");
-
- 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;
-}
-
-// constructor
-PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
-
-/**
- * Renders the stage to its canvas view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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;
-
- 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 = [];
- }
-
-
-}
-
-/**
- * resizes the canvas view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the canvas view
- * @param height {Number} the new height of the canvas view
- */
-PIXI.CanvasRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-}
-
-/**
- * Renders a display object
- *
- * @method renderDisplayObject
- * @param displayObject {DisplayObject} The displayObject to render
- * @private
- */
-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)
- {
-
- var frame = displayObject.texture.frame;
-
- if(frame && frame.width && frame.height)
- {
- 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)
- {
- 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(PIXI.FilterBlock.data instanceof PIXI.Graphics)
- {
- if(displayObject.open)
- {
- context.save();
-
- var cacheAlpha = displayObject.mask.alpha;
- var maskTransform = displayObject.mask.worldTransform;
-
- context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
-
- displayObject.mask.worldAlpha = 0.5;
-
- context.worldAlpha = 0;
-
- PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context);
- context.clip();
-
- displayObject.mask.worldAlpha = cacheAlpha;
- }
- else
- {
- context.restore();
- }
- }
- else
- {
- // only masks supported right now!
- }
- }
- // count++
- displayObject = displayObject._iNext;
-
-
- }
- while(displayObject != testObject)
-
-
-}
-
-/**
- * Renders a flat strip
- *
- * @method renderStripFlat
- * @param strip {Strip} The Strip to render
- * @private
- */
-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();
-}
-
-/**
- * Renders a tiling sprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tilingsprite to render
- * @private
- */
-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;
-
- // 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.translate(-tilePosition.x, -tilePosition.y);
-
- context.closePath();
-}
-
-/**
- * Renders a strip
- *
- * @method renderStrip
- * @param strip {Strip} The Strip to render
- * @private
- */
-PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
-{
- 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;
-
-
- 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();
- };
-
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * A set of functions used by the canvas renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.CanvasGraphics = function()
-{
-
-}
-
-
-/*
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- 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.lineWidth = data.lineWidth;
-
- 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]);
- }
-
- // 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.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]);
- }
-
- }
- 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
-
- 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
- *
- * @static
- * @private
- * @method renderGraphicsMask
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- var len = graphics.graphicsData.length;
- if(len > 1)
- {
- len = 1;
- 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;
-
- 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]);
- }
-
- // 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
- }
-
-
- };
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
- * It is important to know that with the webGL renderer only simple polys can be filled at this stage
- * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
- *
- * @class Graphics
- * @extends DisplayObjectContainer
- * @constructor
- */
-PIXI.Graphics = function()
-{
- PIXI.DisplayObjectContainer.call( this );
-
- this.renderable = true;
-
- /**
- * The alpha of the fill of this graphics object
- *
- * @property fillAlpha
- * @type Number
- */
- this.fillAlpha = 1;
-
- /**
- * The width of any lines drawn
- *
- * @property lineWidth
- * @type Number
- */
- this.lineWidth = 0;
-
- /**
- * The color of any lines drawn
- *
- * @property lineColor
- * @type String
- */
- this.lineColor = "black";
-
- /**
- * Graphics data
- *
- * @property graphicsData
- * @type Array
- * @private
- */
- this.graphicsData = [];
-
- /**
- * Current path
- *
- * @property currentPath
- * @type Object
- * @private
- */
- this.currentPath = {points:[]};
-}
-
-// constructor
-PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Graphics.prototype.constructor = PIXI.Graphics;
-
-/**
- * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
- *
- * @method lineStyle
- * @param lineWidth {Number} width of the line to draw, will update the object's stored style
- * @param color {Number} color of the line to draw, will update the object's stored style
- * @param alpha {Number} alpha of the line to draw, will update the object's stored style
- */
-PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
-{
- if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.lineWidth = lineWidth || 0;
- this.lineColor = color || 0;
- this.lineAlpha = (alpha == undefined) ? 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.graphicsData.push(this.currentPath);
-}
-
-/**
- * Moves the current drawing position to (x, y).
- *
- * @method moveTo
- * @param x {Number} the X coord to move to
- * @param y {Number} the Y coord to move to
- */
-PIXI.Graphics.prototype.moveTo = function(x, y)
-{
- if(this.currentPath.points.length == 0)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.points.push(x, y);
-
- this.graphicsData.push(this.currentPath);
-}
-
-/**
- * Draws a line using the current line style from the current drawing position to (x, y);
- * the current drawing position is then set to (x, y).
- *
- * @method lineTo
- * @param x {Number} the X coord to draw to
- * @param y {Number} the Y coord to draw to
- */
-PIXI.Graphics.prototype.lineTo = function(x, y)
-{
- this.currentPath.points.push(x, y);
- this.dirty = true;
-}
-
-/**
- * Specifies a simple one-color fill that subsequent calls to other Graphics methods
- * (such as lineTo() or drawCircle()) use when drawing.
- *
- * @method beginFill
- * @param color {uint} the color of the fill
- * @param alpha {Number} the alpha
- */
-PIXI.Graphics.prototype.beginFill = function(color, alpha)
-{
- this.filling = true;
- this.fillColor = color || 0;
- this.fillAlpha = (alpha == undefined) ? 1 : alpha;
-}
-
-/**
- * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
- *
- * @method endFill
- */
-PIXI.Graphics.prototype.endFill = function()
-{
- this.filling = false;
- this.fillColor = null;
- this.fillAlpha = 1;
-}
-
-/**
- * @method drawRect
- *
- * @param x {Number} The X coord of the top-left of the rectangle
- * @param y {Number} The Y coord of the top-left of the rectangle
- * @param width {Number} The width of the rectangle
- * @param height {Number} The height of the rectangle
- */
-PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws a circle.
- *
- * @method drawCircle
- * @param x {Number} The X coord of the center of the circle
- * @param y {Number} The Y coord of the center of the circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws an elipse.
- *
- * @method drawElipse
- * @param x {Number}
- * @param y {Number}
- * @param width {Number}
- * @param height {Number}
- */
-PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
- *
- * @method clear
- */
-PIXI.Graphics.prototype.clear = function()
-{
- this.lineWidth = 0;
- this.filling = false;
-
- this.dirty = true;
- this.clearDirty = true;
- this.graphicsData = [];
-}
-
-// SOME TYPES:
-PIXI.Graphics.POLY = 0;
-PIXI.Graphics.RECT = 1;
-PIXI.Graphics.CIRC = 2;
-PIXI.Graphics.ELIP = 3;
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-PIXI.Strip = function(texture, width, height)
-{
- 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]);
-
- this.verticies = new Float32Array([0, 0,
- 0,0,
- 0,0, 0,
- 0, 0]);
-
- 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.verticies = [0, 0,
- 0,0,
- 0,0, 0,
- 0, 0];
-
- this.colors = [1, 1, 1, 1];
-
- 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;
-
- // 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;
-}
-
-// constructor
-PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Strip.prototype.constructor = PIXI.Strip;
-
-PIXI.Strip.prototype.setTexture = function(texture)
-{
- //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;
-}
-
-PIXI.Strip.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-// some helper functions..
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-
-PIXI.Rope = function(texture, points)
-{
- PIXI.Strip.call( this, texture );
- this.points = points;
-
- try
- {
- this.verticies = new Float32Array( points.length * 4);
- this.uvs = new Float32Array( points.length * 4);
- this.colors = new Float32Array( points.length * 2);
- this.indices = new Uint16Array( points.length * 2);
- }
- catch(error)
- {
- this.verticies = verticies
-
- this.uvs = uvs
- this.colors = colors
- this.indices = indices
- }
-
- this.refresh();
-}
-
-
-// constructor
-PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
-PIXI.Rope.prototype.constructor = PIXI.Rope;
-
-PIXI.Rope.prototype.refresh = function()
-{
- var points = this.points;
- if(points.length < 1)return;
-
- var uvs = this.uvs
- var indices = this.indices;
- var colors = this.colors;
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
-
- uvs[0] = 0
- uvs[1] = 1
- uvs[2] = 0
- uvs[3] = 1
-
- colors[0] = 1;
- colors[1] = 1;
-
- indices[0] = 0;
- indices[1] = 1;
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
- // time to do some smart drawing!
- var amount = i/(total-1)
-
- if(i%2)
- {
- uvs[index] = amount;
- uvs[index+1] = 0;
-
- uvs[index+2] = amount
- uvs[index+3] = 1
-
- }
- else
- {
- uvs[index] = amount
- uvs[index+1] = 0
-
- uvs[index+2] = amount
- uvs[index+3] = 1
- }
-
- index = i * 2;
- colors[index] = 1;
- colors[index+1] = 1;
-
- index = i * 2;
- indices[index] = index;
- indices[index + 1] = index + 1;
-
- lastPoint = point;
- }
-}
-
-PIXI.Rope.prototype.updateTransform = function()
-{
-
- var points = this.points;
- if(points.length < 1)return;
-
- var verticies = this.verticies
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
- verticies[0] = point.x + perp.x
- verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
- verticies[3] = point.y - perp.y//+200
- // time to do some smart drawing!
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
-
- if(i < points.length-1)
- {
- nextPoint = points[i+1];
- }
- else
- {
- nextPoint = point
- }
-
- perp.y = -(nextPoint.x - lastPoint.x);
- perp.x = nextPoint.y - lastPoint.y;
-
- var ratio = (1 - (i / (total-1))) * 10;
- if(ratio > 1)ratio = 1;
-
- 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;
-
- 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;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
-}
-
-PIXI.Rope.prototype.setTexture = function(texture)
-{
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * A tiling sprite is a fast way of rendering a tiling image
- *
- * @class TilingSprite
- * @extends DisplayObjectContainer
- * @constructor
- * @param texture {Texture} the texture of the tiling sprite
- * @param width {Number} the width of the tiling sprite
- * @param height {Number} the height of the tiling sprite
- */
-PIXI.TilingSprite = function(texture, width, height)
-{
- PIXI.DisplayObjectContainer.call( this );
-
- /**
- * 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 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 offset position of the image that is being tiled
- *
- * @property tilePosition
- * @type Point
- */
- this.tilePosition = new PIXI.Point(0,0);
-
- this.renderable = true;
-
- this.blendMode = PIXI.blendModes.NORMAL
-}
-
-// constructor
-PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
-
-/**
- * Sets the texture of the tiling sprite
- *
- * @method setTexture
- * @param texture {Texture} The PIXI texture that is displayed by the sprite
- */
-PIXI.TilingSprite.prototype.setTexture = function(texture)
-{
- //TODO SET THE TEXTURES
- //TODO VISIBILITY
-
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-/**
- * When the texture is updated, this event will fire to update the frame
- *
- * @method onTextureUpdate
- * @param event
- * @private
- */
-PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
- *
- * Awesome JS run time provided by EsotericSoftware
- * https://github.com/EsotericSoftware/spine-runtimes
- *
- */
-
-/**
- * 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
- * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
- *
- * @class Spine
- * @extends DisplayObjectContainer
- * @constructor
- * @param url {String} The url of the spine anim file to be used
- */
-PIXI.Spine = function (url) {
- PIXI.DisplayObjectContainer.call(this);
-
- this.spineData = PIXI.AnimCache[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.stateData = new spine.AnimationStateData(this.spineData);
- this.state = new spine.AnimationState(this.stateData);
-
- 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);
- }
-};
-
-PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.Spine.prototype.constructor = PIXI.Spine;
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @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();
-
- 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;
-
- 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.rotation = -(slot.bone.worldRotation * Math.PI / 180);
- }
-
- 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;
-
- 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;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * This object is one that will allow you to specify custom rendering functions based on render type
- *
- * @class CustomRenderable
- * @extends DisplayObject
- * @constructor
- */
-PIXI.CustomRenderable = function()
-{
- PIXI.DisplayObject.call( this );
-
-}
-
-// constructor
-PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
-
-/**
- * If this object is being rendered by a CanvasRenderer it will call this callback
- *
- * @method renderCanvas
- * @param renderer {CanvasRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderCanvas = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback to initialize
- *
- * @method initWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.initWebGL = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback
- *
- * @method renderWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderWebGL = function(renderGroup, projectionMatrix)
-{
- // not sure if both needed? but ya have for now!
- // override!
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.BaseTextureCache = {};
-PIXI.texturesToUpdate = [];
-PIXI.texturesToDestroy = [];
-
-/**
- * A texture stores the information that represents an image. All textures have a base texture
- *
- * @class BaseTexture
- * @uses EventTarget
- * @constructor
- * @param source {String} the source object (image or canvas)
- */
-PIXI.BaseTexture = function(source)
-{
- 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 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 source that is loaded to create the texture
- *
- * @property source
- * @type Image
- */
- this.source = source;
-
- if(!source)return;
-
- 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;
-
- PIXI.texturesToUpdate.push(this);
- }
- else
- {
-
- var scope = this;
- this.source.onload = function(){
-
- scope.hasLoaded = true;
- scope.width = scope.source.width;
- scope.height = scope.source.height;
-
- // 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;
-
- PIXI.texturesToUpdate.push(this);
- }
-
- this._powerOf2 = false;
-}
-
-PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
-
-/**
- * Destroys this base texture
- *
- * @method destroy
- */
-PIXI.BaseTexture.prototype.destroy = function()
-{
- if(this.source instanceof Image)
- {
- this.source.src = null;
- }
- this.source = null;
- PIXI.texturesToDestroy.push(this);
-}
-
-/**
- * Helper function that returns a base texture based on an image url
- * If the image is not in the base texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @return BaseTexture
- */
-PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
-{
- 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);
- PIXI.BaseTextureCache[imageUrl] = baseTexture;
- }
-
- return baseTexture;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.TextureCache = {};
-PIXI.FrameCache = {};
-
-/**
- * A texture stores the information that represents an image or part of an image. It cannot be added
- * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
- *
- * @class Texture
- * @uses EventTarget
- * @constructor
- * @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frame {Rectangle} The rectangle frame of the texture to show
- */
-PIXI.Texture = function(baseTexture, frame)
-{
- PIXI.EventTarget.call( this );
-
- if(!frame)
- {
- this.noFrame = true;
- frame = new PIXI.Rectangle(0,0,1,1);
- }
-
- if(baseTexture instanceof PIXI.Texture)
- baseTexture = baseTexture.baseTexture;
-
- /**
- * The base texture of this texture
- *
- * @property baseTexture
- * @type BaseTexture
- */
- this.baseTexture = baseTexture;
-
- /**
- * The frame specifies the region of the base texture that this texture uses
- *
- * @property frame
- * @type Rectangle
- */
- this.frame = frame;
-
- /**
- * The trim point
- *
- * @property trim
- * @type Point
- */
- this.trim = new PIXI.Point();
-
- this.scope = this;
-
- if(baseTexture.hasLoaded)
- {
- if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- //console.log(frame)
-
- this.setFrame(frame);
- }
- else
- {
- var scope = this;
- baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} );
- }
-}
-
-PIXI.Texture.prototype.constructor = PIXI.Texture;
-
-/**
- * Called when the base texture is loaded
- *
- * @method onBaseTextureLoaded
- * @param event
- * @private
- */
-PIXI.Texture.prototype.onBaseTextureLoaded = function(event)
-{
- var baseTexture = this.baseTexture;
- baseTexture.removeEventListener( 'loaded', this.onLoaded );
-
- if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- this.noFrame = false;
- this.width = this.frame.width;
- this.height = this.frame.height;
-
- this.scope.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Destroys this texture
- *
- * @method destroy
- * @param destroyBase {Boolean} Whether to destroy the base texture as well
- */
-PIXI.Texture.prototype.destroy = function(destroyBase)
-{
- if(destroyBase)this.baseTexture.destroy();
-}
-
-/**
- * Specifies the rectangle region of the baseTexture
- *
- * @method setFrame
- * @param frame {Rectangle} The frame of the texture to set it to
- */
-PIXI.Texture.prototype.setFrame = function(frame)
-{
- this.frame = frame;
- this.width = frame.width;
- this.height = frame.height;
-
- 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;
-
- PIXI.Texture.frameUpdates.push(this);
- //this.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Helper function that returns a texture based on an image url
- * If the image is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- * @return Texture
- */
-PIXI.Texture.fromImage = function(imageUrl, crossorigin)
-{
- var texture = PIXI.TextureCache[imageUrl];
-
- if(!texture)
- {
- texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
- PIXI.TextureCache[imageUrl] = texture;
- }
-
- return texture;
-}
-
-/**
- * Helper function that returns a texture based on a frame id
- * If the frame id is not in the texture cache an error will be thrown
- *
- * @static
- * @method fromFrame
- * @param frameId {String} The frame id of the texture
- * @return Texture
- */
-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;
-}
-
-/**
- * Helper function that returns a texture based on a canvas element
- * If the canvas is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromCanvas
- * @param canvas {Canvas} The canvas element source of the texture
- * @return Texture
- */
-PIXI.Texture.fromCanvas = function(canvas)
-{
- var baseTexture = new PIXI.BaseTexture(canvas);
- return new PIXI.Texture(baseTexture);
-}
-
-
-/**
- * Adds a texture to the textureCache.
- *
- * @static
- * @method addTextureToCache
- * @param texture {Texture}
- * @param id {String} the id that the texture will be stored against.
- */
-PIXI.Texture.addTextureToCache = function(texture, id)
-{
- PIXI.TextureCache[id] = texture;
-}
-
-/**
- * Remove a texture from the textureCache.
- *
- * @static
- * @method removeTextureFromCache
- * @param id {String} the id of the texture to be removed
- * @return {Texture} the texture that was removed
- */
-PIXI.Texture.removeTextureFromCache = function(id)
-{
- var texture = PIXI.TextureCache[id]
- PIXI.TextureCache[id] = null;
- return texture;
-}
-
-// this is more for webGL.. it contains updated frames..
-PIXI.Texture.frameUpdates = [];
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- 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.
-
- 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);
-
- 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
-
- @class RenderTexture
- @extends Texture
- @constructor
- @param width {Number} The width of the render texture
- @param height {Number} The height of the render texture
- */
-PIXI.RenderTexture = function(width, height)
-{
- PIXI.EventTarget.call( this );
-
- this.width = width || 100;
- this.height = height || 100;
-
- this.indetityMatrix = PIXI.mat3.create();
-
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
-
- if(PIXI.gl)
- {
- this.initWebGL();
- }
- else
- {
- this.initCanvas();
- }
-}
-
-PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
-PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
-
-/**
- * Initializes the webgl data for this texture
- *
- * @method initWebGL
- * @private
- */
-PIXI.RenderTexture.prototype.initWebGL = function()
-{
- var gl = PIXI.gl;
- this.glFramebuffer = gl.createFramebuffer();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // 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);
- }
-}
-
-/**
- * Initializes the canvas data for this texture
- *
- * @method initCanvas
- * @private
- */
-PIXI.RenderTexture.prototype.initCanvas = function()
-{
- 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.render = this.renderCanvas;
-}
-
-/**
- * This function will draw the display object to the texture.
- *
- * @method renderWebGL
- * @param displayObject {DisplayObject} The display object to render this texture on
- * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
- * @private
- */
-PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
-{
- var gl = PIXI.gl;
-
- // enable the alpha color mask..
- gl.colorMask(true, true, true, true);
-
- gl.viewport(0, 0, this.width, this.height);
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- if(clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
-
- // 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;
-
-
- 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} 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".
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.AssetLoader = function(assetURLs, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The array of asset URLs that are going to be loaded
- *
- * @property assetURLs
- * @type Array
- */
- this.assetURLs = assetURLs;
-
- /**
- * Whether the requests should be treated as cross origin
- *
- * @property crossorigin
- * @type Boolean
- */
- this.crossorigin = crossorigin;
-
- /**
- * Maps file extension to loader types
- *
- * @property loadersByType
- * @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
- };
-
-
-};
-
-/**
- * Fired when an item has loaded
- * @event onProgress
- */
-
-/**
- * Fired when all the assets have loaded
- * @event onComplete
- */
-
-// constructor
-PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
-
-/**
- * Starts loading the assets sequentially
- *
- * @method load
- */
-PIXI.AssetLoader.prototype.load = function()
-{
- var scope = this;
-
- this.loadCount = this.assetURLs.length;
-
- for (var i=0; i < this.assetURLs.length; i++)
- {
- var fileName = this.assetURLs[i];
- var fileType = fileName.split(".").pop().toLowerCase();
-
- var loaderClass = this.loadersByType[fileType];
- if(!loaderClass)
- throw new Error(fileType + " is an unsupported file type");
-
- var loader = new loaderClass(fileName, this.crossorigin);
-
- loader.addEventListener("loaded", function()
- {
- scope.onAssetLoaded();
- });
- loader.load();
- }
-};
-
-/**
- * Invoked after each file is loaded
- *
- * @method onAssetLoaded
- * @private
- */
-PIXI.AssetLoader.prototype.onAssetLoaded = function()
-{
- this.loadCount--;
- 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();
- }
-};
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class JsonLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the JSON file
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.JsonLoader = function (url, crossorigin) {
- PIXI.EventTarget.call(this);
-
- /**
- * 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;
-
- /**
- * [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;
-
-};
-
-// constructor
-PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
-
-/**
- * Loads the JSON data
- *
- * @method load
- */
-PIXI.JsonLoader.prototype.load = function () {
- this.ajaxRequest = new 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);
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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.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();
- });
-
- 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();
-
- }
- 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();
- }
- }
-};
-
-/**
- * Invoke when json file loaded
- *
- * @method onLoaded
- * @private
- */
-PIXI.JsonLoader.prototype.onLoaded = function () {
- this.loaded = true;
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * Invoke when error occured
- *
- * @method onError
- * @private
- */
-PIXI.JsonLoader.prototype.onError = function () {
- this.dispatchEvent({
- type: "error",
- content: this
- });
-};
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- * 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.
- * 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
- *
- * @class SpriteSheetLoader
- * @uses EventTarget
- * @constructor
- * @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);
-
- /**
- * 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;
-
- /**
- * [read-only] The base url of the bitmap font data
- *
- * @property baseUrl
- * @type String
- * @readOnly
- */
- this.baseUrl = url.replace(/[^\/]*$/, "");
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = null;
-
- /**
- * The frames of the sprite sheet
- *
- * @property frames
- * @type Object
- */
- this.frames = {};
-};
-
-// constructor
-PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader;
-
-/**
- * This will begin loading the JSON file
- *
- * @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();
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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;
-
- this.texture = image.texture.baseTexture;
- image.addEventListener("loaded", function (event) {
- 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!
- }
- }
- }
-
- image.load();
-};
-/**
- * Invoke when all files are loaded (json and texture)
- *
- * @method onLoaded
- * @private
- */
-PIXI.SpriteSheetLoader.prototype.onLoaded = function () {
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class ImageLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the image
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.ImageLoader = function(url, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = PIXI.Texture.fromImage(url, crossorigin);
-
- /**
- * if the image is loaded with loadFramedSpriteSheet
- * frames will contain the sprite sheet frames
- *
- */
- this.frames = [];
-};
-
-// constructor
-PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader;
-
-/**
- * Loads image or takes it from cache
- *
- * @method load
- */
-PIXI.ImageLoader.prototype.load = function()
-{
- if(!this.texture.baseTexture.hasLoaded)
- {
- var scope = this;
- this.texture.baseTexture.addEventListener("loaded", function()
- {
- scope.onLoaded();
- });
- }
- else
- {
- this.onLoaded();
- }
-};
-
-/**
- * Invoked when image file is loaded or it is already cached and ready to use
- *
- * @method onLoaded
- * @private
- */
-PIXI.ImageLoader.prototype.onLoaded = function()
-{
- this.dispatchEvent({type: "loaded", content: this});
-};
-
-/**
- * Loads image and split it to uniform sized frames
- *
- *
- * @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
- */
-PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
-{
- this.frames = [];
- var cols = Math.floor(this.texture.width / frameWidth);
- var rows = Math.floor(this.texture.height / frameHeight);
-
- var i=0;
- for (var y=0; y
-
+
+
+
+
diff --git a/examples/example 12 - Spine/index_goblins.html b/examples/example 12 - Spine/index_goblins.html
index 550187d..4010633 100644
--- a/examples/example 12 - Spine/index_goblins.html
+++ b/examples/example 12 - Spine/index_goblins.html
@@ -11,7 +11,7 @@
-
+
+
+
diff --git a/examples/example 13 - Graphics/pixi.js b/examples/example 13 - Graphics/pixi.js
deleted file mode 100644
index 6d567a2..0000000
--- a/examples/example 13 - Graphics/pixi.js
+++ /dev/null
@@ -1,10649 +0,0 @@
-/**
- * @license
- * Pixi.JS - v1.3.0
- * Copyright (c) 2012, Mat Groves
- * http://goodboydigital.com/
- *
- * Compiled: 2013-09-30
- *
- * Pixi.JS is licensed under the MIT License.
- * http://www.opensource.org/licenses/mit-license.php
- */
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-(function(){
-
- var root = this;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * @module PIXI
- */
-var PIXI = PIXI || {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
- *
- * @class Point
- * @constructor
- * @param x {Number} position of the point
- * @param y {Number} position of the point
- */
-PIXI.Point = function(x, y)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-}
-
-/**
- * Creates a clone of this point
- *
- * @method clone
- * @return {Point} a copy of the point
- */
-PIXI.Point.prototype.clone = function()
-{
- return new PIXI.Point(this.x, this.y);
-}
-
-// constructor
-PIXI.Point.prototype.constructor = PIXI.Point;
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
- *
- * @class Rectangle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the rectangle
- * @param y {Number} The Y coord of the upper-left corner of the rectangle
- * @param width {Number} The overall width of this rectangle
- * @param height {Number} The overall height of this rectangle
- */
-PIXI.Rectangle = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Rectangle
- *
- * @method clone
- * @return {Rectangle} a copy of the rectangle
- */
-PIXI.Rectangle.prototype.clone = function()
-{
- 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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this Rectangle
- */
-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;
-
- if(y >= y1 && y <= y1 + this.height)
- {
- return true;
- }
- }
-
- return false;
-}
-
-// constructor
-PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
-
-
-/**
- * @author Adrien Brault
- */
-
-/**
- * @class Polygon
- * @constructor
- * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
- * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
- * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
- * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
- * Numbers.
- */
-PIXI.Polygon = function(points)
-{
- //if points isn't an array, use arguments as the array
- if(!(points instanceof Array))
- points = Array.prototype.slice.call(arguments);
-
- //if this is a flat array of numbers, convert it to points
- if(typeof points[0] === 'number') {
- var p = [];
- for(var i = 0, il = points.length; i < il; i+=2) {
- p.push(
- new PIXI.Point(points[i], points[i + 1])
- );
- }
-
- points = p;
- }
-
- this.points = points;
-}
-
-/**
- * Creates a clone of this polygon
- *
- * @method clone
- * @return {Polygon} a copy of the polygon
- */
-PIXI.Polygon.prototype.clone = function()
-{
- var points = [];
- for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
-
- if(intersect) inside = !inside;
- }
-
- return inside;
-}
-
-// constructor
-PIXI.Polygon.prototype.constructor = PIXI.Polygon;
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Circle object can be used to specify a hit area for displayobjects
- *
- * @class Circle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Circle = function(x, y, radius)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property radius
- * @type Number
- * @default 0
- */
- this.radius = radius || 0;
-}
-
-/**
- * Creates a clone of this Circle instance
- *
- * @method clone
- * @return {Circle} a copy of the polygon
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
- */
-PIXI.Circle.prototype.contains = function(x, y)
-{
- if(this.radius <= 0)
- return false;
-
- var dx = (this.x - x),
- dy = (this.y - y),
- r2 = this.radius * this.radius;
-
- dx *= dx;
- dy *= dy;
-
- return (dx + dy <= r2);
-}
-
-// constructor
-PIXI.Circle.prototype.constructor = PIXI.Circle;
-
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Ellipse object can be used to specify a hit area for displayobjects
- *
- * @class Ellipse
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
- * @param width {Number} The overall width of this ellipse
- * @param height {Number} The overall height of this ellipse
- */
-PIXI.Ellipse = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Ellipse instance
- *
- * @method clone
- * @return {Ellipse} a copy of the ellipse
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this ellipse
- */
-PIXI.Ellipse.prototype.contains = function(x, y)
-{
- if(this.width <= 0 || this.height <= 0)
- return false;
-
- //normalize the coords to an ellipse with center 0,0
- //and a radius of 0.5
- var normx = ((x - this.x) / this.width) - 0.5,
- normy = ((y - this.y) / this.height) - 0.5;
-
- normx *= normx;
- normy *= normy;
-
- return (normx + normy < 0.25);
-}
-
-PIXI.Ellipse.getBounds = function()
-{
- return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
-}
-
-// constructor
-PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
-
-
-
-/*
- * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
- * you both rock!
- */
-
-function determineMatrixArrayType() {
- PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return PIXI.Matrix;
-}
-
-determineMatrixArrayType();
-
-PIXI.mat3 = {};
-
-PIXI.mat3.create = function()
-{
- 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;
-
- 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;
-
- return matrix;
-}
-
-
-PIXI.mat4 = {};
-
-PIXI.mat4.create = function()
-{
- 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;
-
- return matrix;
-}
-
-PIXI.mat3.multiply = function (mat, mat2, dest)
-{
- 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],
-
- 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[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;
-
- return dest;
-}
-
-PIXI.mat3.clone = function(mat)
-{
- 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];
-
- 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 (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
-}
-
-PIXI.mat3.toMat4 = function (mat, dest)
-{
- if (!dest) { dest = PIXI.mat4.create(); }
-
- 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[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];
-
- return dest;
-}
-
-
-/////
-
-
-PIXI.mat4.create = function()
-{
- 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;
-
- 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];
-
- 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;
-}
-
-PIXI.mat4.multiply = function (mat, mat2, dest)
-{
- 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 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;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The base class for all objects that are rendered on the screen.
- *
- * @class DisplayObject
- * @constructor
- */
-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();
-
- /**
- * 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 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 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 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;
-
- /**
- * [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 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] Current transform of the object based on world (parent) factors
- *
- * @property worldTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.worldTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [read-only] Current transform of the object locally
- *
- * @property localTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.localTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [NYI] Unkown
- *
- * @property color
- * @type Array<>
- * @private
- */
- this.color = [];
-
- /**
- * [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;
-
- /*
- * MOUSE Callbacks
- */
-
- /**
- * 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 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
- * 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 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 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
- */
-
- /**
- * 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 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}
- */
-}
-
-// constructor
-PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
-
-/**
- * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default
- * Instead of using this function you can now simply set the interactive property to true or false
- *
- * @method setInteractive
- * @param interactive {Boolean}
- * @deprecated Simply set the `interactive` property directly
- */
-PIXI.DisplayObject.prototype.setInteractive = function(interactive)
-{
- this.interactive = interactive;
-}
-
-/**
- * Indicates if the sprite will have touch and mouse interactivity. It is false by default
- *
- * @property interactive
- * @type Boolean
- * @default false
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
- get: function() {
- 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;
- }
-});
-
-/**
- * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
- * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
- * To remove a mask, set this property to null.
- *
- * @property mask
- * @type Graphics
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
- get: function() {
- 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;
- }
- }
- else
- {
- this.removeFilter(this._mask);
- this._mask.renderable = true;
- }
-
- this._mask = value;
- }
-});
-
-/**
- * Sets the filters for the displayObject. Currently there's a few limitations.
- * 1: At the moment only one filter can be applied at a time..
- * 2: They cannot be nested.
- * 3: There's no padding yet.
- * 4: this is a webGL only feature.
- * @property filters
- * @type Array
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
- get: function() {
- return this._filters;
- },
- set: function(value) {
-
- //if(value == )
- if(value)
- {
- if(this._filters)this.removeFilter(this._filters);
- this.addFilter(value)
- }
- else
- {
- if(this._filters)this.removeFilter(this._filters);
- }
-
- this._filters = value;
- }
-});
-
-/*
- * Adds a filter to this displayObject
- *
- * @method addFilter
- * @param mask {Graphics} the graphics object to use as a filter
- * @private
- */
-PIXI.DisplayObject.prototype.addFilter = function(data)
-{
- //if(this.filter)return;
- //this.filter = true;
-
- // 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;
-
- /*
- * 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);
- }
-
-}
-
-/*
- * Removes the filter to this displayObject
- *
- * @method removeFilter
- * @private
- */
-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);
- }
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-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;
-
- // 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],
-
- b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
- b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
-
- 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;
-
- worldTransform[3] = b10 * a00 + b11 * a10;
- 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;
-
-}
-
-PIXI.visibleCount = 0;
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * 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
- * @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 = [];
-}
-
-// constructor
-PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-
-/**
- * Adds a child to the container.
- *
- * @method addChild
- * @param child {DisplayObject} The DisplayObject to add to the container
- */
-PIXI.DisplayObjectContainer.prototype.addChild = function(child)
-{
- if(child.parent != undefined)
- {
-
- //// 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)
- {
- 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
- *
- * @method addChildAt
- * @param child {DisplayObject} The child to add
- * @param index {Number} The index to place the child in
- */
-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;
-
- 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
- *
- * @method swapChildren
- * @param child {DisplayObject}
- * @param child2 {DisplayObject}
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
-{
- /*
- * this funtion needs to be recoded..
- * can be done a lot faster..
- */
- return;
-
- // need to fix this function :/
- /*
- // TODO I already know this??
- var index = this.children.indexOf( child );
- var index2 = this.children.indexOf( child2 );
-
- if ( index !== -1 && index2 !== -1 )
- {
- // cool
-
- /*
- if(this.stage)
- {
- // this is to satisfy the webGL batching..
- // TODO sure there is a nicer way to achieve this!
- this.stage.__removeChild(child);
- this.stage.__removeChild(child2);
-
- this.stage.__addChild(child);
- this.stage.__addChild(child2);
- }
-
- // swap the positions..
- this.children[index] = child2;
- this.children[index2] = child;
-
- }
- else
- {
- throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
- }*/
-}
-
-/**
- * Returns the Child at the specified index
- *
- * @method getChildAt
- * @param index {Number} The index to get the child from
- */
-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);
- }
-}
-
-/**
- * Removes a child from the container.
- *
- * @method removeChild
- * @param child {DisplayObject} The DisplayObject to remove
- */
-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 tempLast = childFirst._iPrev;
- // need to make sure the parents last is updated too
- var updateLast = this;
- while(updateLast.last == childLast.last)
- {
- 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
- *
- * @method updateTransform
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.updateTransform = function()
-{
- if(!this.visible)return;
-
- PIXI.DisplayObject.prototype.updateTransform.call( this );
-
- for(var i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation
- */
-PIXI.MovieClip = function(textures)
-{
- PIXI.Sprite.call(this, textures[0]);
-
- /**
- * The array of textures that make up the animation
- *
- * @property textures
- * @type Array
- */
- this.textures = textures;
-
- /**
- * The speed that the MovieClip will play at. Higher is faster, lower is slower
- *
- * @property animationSpeed
- * @type Number
- * @default 1
- */
- this.animationSpeed = 1;
-
- /**
- * Whether or not the movie clip repeats after playing.
- *
- * @property loop
- * @type Boolean
- * @default true
- */
- this.loop = true;
-
- /**
- * Function to call when a MovieClip finishes playing
- *
- * @property onComplete
- * @type Function
- */
- this.onComplete = null;
-
- /**
- * [read-only] The index MovieClips current frame (this may not have to be a whole number)
- *
- * @property currentFrame
- * @type Number
- * @default 0
- * @readOnly
- */
- this.currentFrame = 0;
-
- /**
- * [read-only] Indicates if the MovieClip is currently playing
- *
- * @property playing
- * @type Boolean
- * @readOnly
- */
- this.playing = false;
-}
-
-// constructor
-PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
-PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
-
-/**
-* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
-* assigned to the MovieClip.
-*
-* @property totalFrames
-* @type Number
-* @default 0
-* @readOnly
-*/
-Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
- get: function() {
-
- return this.textures.length;
- }
-});
-
-
-/**
- * Stops the MovieClip
- *
- * @method stop
- */
-PIXI.MovieClip.prototype.stop = function()
-{
- this.playing = false;
-}
-
-/**
- * Plays the MovieClip
- *
- * @method play
- */
-PIXI.MovieClip.prototype.play = function()
-{
- this.playing = true;
-}
-
-/**
- * Stops the MovieClip and goes to a specific frame
- *
- * @method gotoAndStop
- * @param frameNumber {Number} frame index to stop at
- */
-PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
-{
- this.playing = false;
- this.currentFrame = frameNumber;
- var round = (this.currentFrame + 0.5) | 0;
- this.setTexture(this.textures[round % this.textures.length]);
-}
-
-/**
- * Goes to a specific frame and begins playing the MovieClip
- *
- * @method gotoAndPlay
- * @param frameNumber {Number} frame index to start at
- */
-PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
-{
- this.currentFrame = frameNumber;
- this.playing = true;
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.MovieClip.prototype.updateTransform = function()
-{
- PIXI.Sprite.prototype.updateTransform.call(this);
-
- if(!this.playing)return;
-
- this.currentFrame += this.animationSpeed;
-
- var round = (this.currentFrame + 0.5) | 0;
-
- 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();
- }
- }
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.FilterBlock = function()
-{
- this.visible = true;
- this.renderable = true;
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.ColorMatrixFilter = function()
-{
- // 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;",
- "}"
- ];
-
-}
-
-
-Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
- get: function() {
- return this.uniforms.matrix.value;
- },
- set: function(value) {
- this.uniforms.matrix.value = value;
- }
-});
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.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");
- PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
-
- this.setText(text);
- this.setStyle(style);
-
- this.updateText();
- this.dirty = false;
-};
-
-// constructor
-PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype);
-PIXI.Text.prototype.constructor = PIXI.Text;
-
-/**
- * Set the style of the 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.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.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.strokeThickness = style.strokeThickness || 0;
- style.wordWrap = style.wordWrap || false;
- style.wordWrapWidth = style.wordWrapWidth || 100;
- this.style = style;
- this.dirty = true;
-};
-
-/**
- * Set the copy for the text object. To split a line you can use "\n"
- *
- * @methos 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.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.Text.prototype.updateText = function()
-{
- this.context.font = this.style.font;
-
- var outputText = 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)/);
-
- //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;
-
- //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.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);
-
- 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.fill)
- {
- this.context.fillText(lines[i], linePosition.x, linePosition.y);
- }
- }
-
- this.updateTexture();
-};
-
-/**
- * Updates texture size based on canvas size
- *
- * @method updateTexture
- * @private
- */
-PIXI.Text.prototype.updateTexture = function()
-{
- this.texture.baseTexture.width = this.canvas.width;
- this.texture.baseTexture.height = this.canvas.height;
- this.texture.frame.width = this.canvas.width;
- this.texture.frame.height = this.canvas.height;
-
- this._width = this.canvas.width;
- this._height = this.canvas.height;
-
- PIXI.texturesToUpdate.push(this.texture.baseTexture);
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.Text.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- this.updateText();
- this.dirty = false;
- }
-
- PIXI.Sprite.prototype.updateTransform.call(this);
-};
-
-/*
- * http://stackoverflow.com/users/34441/ellisbben
- * great solution to the problem!
- *
- * @method determineFontHeight
- * @param fontStyle {Object}
- * @private
- */
-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];
-
- 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;
-
- body.removeChild(dummy);
- }
-
- return result;
-};
-
-/**
- * A Text Object will apply wordwrap
- *
- * @method wordWrap
- * @param text {String}
- * @private
- */
-PIXI.Text.prototype.wordWrap = function(text)
-{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
- var result = "";
- var lines = text.split("\n");
- for (var i = 0; i < lines.length; i++)
- {
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
- }
-
- return result;
-};
-
-/**
- * Destroys this text object
- *
- * @method destroy
- * @param destroyTexture {Boolean}
- */
-PIXI.Text.prototype.destroy = function(destroyTexture)
-{
- if(destroyTexture)
- {
- this.texture.destroy();
- }
-
-};
-
-PIXI.Text.heightCache = {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.
- *
- * @class BitmapText
- * @extends DisplayObjectContainer
- * @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")
- */
-PIXI.BitmapText = function(text, style)
-{
- PIXI.DisplayObjectContainer.call(this);
-
- this.setText(text);
- this.setStyle(style);
- this.updateText();
- this.dirty = false
-
-};
-
-// constructor
-PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
-
-/**
- * Set the copy for the text object
- *
- * @method setText
- * @param text {String} The copy that you would like the text to display
- */
-PIXI.BitmapText.prototype.setText = function(text)
-{
- this.text = text || " ";
- this.dirty = true;
-};
-
-/**
- * Set the style of the 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")
- */
-PIXI.BitmapText.prototype.setStyle = function(style)
-{
- style = style || {};
- style.align = style.align || "left";
- this.style = style;
-
- 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;
-
- this.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.BitmapText.prototype.updateText = function()
-{
- var data = PIXI.BitmapText.fonts[this.fontName];
- var pos = new PIXI.Point();
- var prevCharCode = null;
- var chars = [];
- var maxLineWidth = 0;
- var lineWidths = [];
- var line = 0;
- var scale = this.fontSize / data.size;
- for(var i = 0; i < this.text.length; i++)
- {
- var charCode = this.text.charCodeAt(i);
- if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
- {
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
- line++;
-
- pos.x = 0;
- pos.y += data.lineHeight;
- prevCharCode = null;
- continue;
- }
-
- var charData = data.chars[charCode];
- if(!charData) continue;
-
- if(prevCharCode && charData[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;
-
- prevCharCode = charCode;
- }
-
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
-
- var lineAlignOffsets = [];
- for(i = 0; i <= line; i++)
- {
- var alignOffset = 0;
- if(this.style.align == "right")
- {
- alignOffset = maxLineWidth - lineWidths[i];
- }
- else if(this.style.align == "center")
- {
- alignOffset = (maxLineWidth - lineWidths[i]) / 2;
- }
- lineAlignOffsets.push(alignOffset);
- }
-
- for(i = 0; i < chars.length; i++)
- {
- 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;
- this.addChild(c);
- }
-
- this.width = pos.x * scale;
- this.height = (pos.y + data.lineHeight) * scale;
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.BitmapText.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- while(this.children.length > 0)
- {
- this.removeChild(this.getChildAt(0));
- }
- this.updateText();
-
- this.dirty = false;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
-};
-
-PIXI.BitmapText.fonts = {};
-
-/**
- * @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.
- *
- * @class InteractionManager
- * @constructor
- * @param stage {Stage} The stage to handle interactions
- */
-PIXI.InteractionManager = function(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();
-
- /**
- * 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();
-
- this.mouseoverEnabled = true;
-
- //tiny little interactiveData pool!
- this.pool = [];
-
- 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.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;
-
-/**
- * Collects an interactive sprite recursively to have their interactions managed
- *
- * @method collectInteractiveSprite
- * @param displayObject {DisplayObject} the displayObject to collect
- * @param iParent {DisplayObject}
- * @private
- */
-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);
-
- 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
- *
- * @method setTarget
- * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to
- * @private
- */
-PIXI.InteractionManager.prototype.setTarget = function(target)
-{
- this.target = target;
-
- //check if the dom element has been set. If it has don't do anything
- if( this.interactionDOMElement === null ) {
-
- this.setTargetDomElement( target.view );
- }
-
- document.body.addEventListener('mouseup', this.onMouseUp, true);
-}
-
-
-/**
- * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
- * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
- * to receive those events
- *
- * @method setTargetDomElement
- * @param domElement {DOMElement} the dom element which will receive mouse and touch events
- * @private
- */
-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'] = '';
-
- 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);
- }
-
-
- 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!
- }
-
- this.interactionDOMElement = domElement;
-
- 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
- *
- * @method update
- * @private
- */
-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 = "default";
-
- 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 = "pointer";
-
- 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
- *
- * @method onMouseMove
- * @param event {Event} The DOM event of the mouse moving
- * @private
- */
-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);
- }
- }
-}
-
-/**
- * Is called when the mouse button is pressed down on the renderer element
- *
- * @method onMouseDown
- * @param event {Event} The DOM event of a mouse button being pressed down
- * @private
- */
-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;
- }
- }
- }
-}
-
-
-PIXI.InteractionManager.prototype.onMouseOut = function(event)
-{
- var length = this.interactiveItems.length;
-
- this.interactionDOMElement.style.cursor = "default";
-
- 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
- *
- * @method onMouseUp
- * @param event {Event} The DOM event of a mouse button being released
- * @private
- */
-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;
- }
- }
-}
-
-/**
- * Tests if the current mouse coords hit a sprite
- *
- * @method hitTest
- * @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
- * @private
- */
-PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
-{
- var global = interactionData.global;
-
- if(item.vcount !== PIXI.visibleCount)return false;
-
- 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;
-
- 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;
-
- 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
- *
- * @method onTouchMove
- * @param event {Event} The DOM event of a touch moving accross the renderer view
- * @private
- */
-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);
- }
-}
-
-/**
- * Is called when a touch is started on the renderer element
- *
- * @method onTouchStart
- * @param event {Event} The DOM event of a touch starting on the renderer view
- * @private
- */
-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;
- }
- }
- }
- }
-}
-
-/**
- * Is called when a touch is ended on the renderer element
- *
- * @method onTouchEnd
- * @param event {Event} The DOM event of a touch ending on the renderer view
- * @private
- */
-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;
- }
-}
-
-/**
- * Holds all information related to an Interaction event
- *
- * @class InteractionData
- * @constructor
- */
-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();
-
- /**
- * The target Sprite that was interacted with
- *
- * @property target
- * @type Sprite
- */
- this.target;
-
- /**
- * When passed to an event handler, this will be the original DOM Event that was captured
- *
- * @property originalEvent
- * @type Event
- */
- this.originalEvent;
-}
-
-/**
- * This will return the local coords of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
- */
-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],
- 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)
-}
-
-// constructor
-PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A Stage represents the root of the display tree. Everything connected to the stage is rendered
- *
- * @class Stage
- * @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
- */
-PIXI.Stage = function(backgroundColor)
-{
- 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();
-
- /**
- * 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);
-
- /**
- * Whether the stage is dirty and needs to have interactions updated
- *
- * @property dirty
- * @type Boolean
- * @private
- */
- this.dirty = true;
-
- this.__childrenAdded = [];
- this.__childrenRemoved = [];
-
- //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);
-
- this.setBackgroundColor(backgroundColor);
- this.worldVisible = true;
-}
-
-// constructor
-PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Stage.prototype.constructor = PIXI.Stage;
-
-/**
- * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
- * This is useful for when you have other DOM elements ontop of the Canvas element.
- *
- * @method setInteractionDelegate
- * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
- */
-PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
-{
- this.interactionManager.setTargetDomElement( domElement );
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.Stage.prototype.updateTransform = function()
-{
- this.worldAlpha = 1;
- this.vcount = PIXI.visibleCount;
-
- for(var i=0,j=this.children.length; i> 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 target != 'function') throw new TypeError();
-
- 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);
-
- return bound;
- };
- })();
-}
-
-/**
- * A wrapper for ajax requests to be handled cross browser
- *
- * @class AjaxRequest
- * @constructor
- */
-var AjaxRequest = PIXI.AjaxRequest = function()
-{
- 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);
-
- while(tmp._iNext)
- {
- safe++;
- tmp = tmp._iNext;
- console.log(tmp);
- // console.log(tmp);
-
- if(safe > 100)
- {
- console.log("BREAK")
- break
- }
- }
-}
-
-
-
-
-
-
-/**
- * https://github.com/mrdoob/eventtarget.js/
- * THankS mr DOob!
- */
-
-/**
- * Adds event emitter functionality to a class
- *
- * @class EventTarget
- * @example
- * function MyEmitter() {
- * PIXI.EventTarget.call(this); //mixes in event target stuff
- * }
- *
- * var em = new MyEmitter();
- * em.emit({ type: 'eventName', data: 'some data' });
- */
-PIXI.EventTarget = function () {
-
- var listeners = {};
-
- this.addEventListener = this.on = function ( type, listener ) {
-
-
- if ( listeners[ type ] === undefined ) {
-
- listeners[ type ] = [];
-
- }
-
- if ( listeners[ type ].indexOf( listener ) === - 1 ) {
-
- listeners[ type ].push( listener );
- }
-
- };
-
- this.dispatchEvent = this.emit = function ( event ) {
-
- if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
-
- return;
-
- }
-
- for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
-
- listeners[ event.type ][ i ]( event );
-
- }
-
- };
-
- this.removeEventListener = this.off = function ( type, listener ) {
-
- var index = listeners[ type ].indexOf( listener );
-
- if ( index !== - 1 ) {
-
- listeners[ type ].splice( index, 1 );
-
- }
-
- };
-
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * This helper function will automatically detect which renderer you should be using.
- * WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
- * the browser then this function will return a canvas renderer
- *
- * @method autoDetectRenderer
- * @static
- * @param width {Number} the width of the renderers view
- * @param height {Number} the height of the renderers view
- * @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 webGL chrome at the moment)
- *
- * antialias
- */
-PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
-{
- if(!width)width = 800;
- if(!height)height = 600;
-
- // BORROWED from Mr Doob (mrdoob.com)
- var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )();
-
- //console.log(webgl);
- if( webgl )
- {
- return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
- }
-
- return new PIXI.CanvasRenderer(width, height, view, transparent);
-};
-
-
-
-/*
- PolyK library
- url: http://polyk.ivank.net
- Released under MIT licence.
-
- 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:
-
- 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.
-
- This is an amazing lib!
-
- slightly modified by mat groves (matgroves.com);
-*/
-
-PIXI.PolyK = {};
-
-/**
- * Triangulates shapes for webGL graphic fills
- *
- * @method Triangulate
- * @namespace PolyK
- * @constructor
- */
-PIXI.PolyK.Triangulate = function(p)
-{
- var sign = true;
-
- var n = p.length>>1;
- if(n<3) return [];
- var tgs = [];
- var avl = [];
- for(var i=0; i 3)
- {
- var i0 = avl[(i+0)%al];
- var i1 = avl[(i+1)%al];
- var i2 = avl[(i+2)%al];
-
- 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];
-
- 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= 0) && (v >= 0) && (u + v < 1);
-}
-
-/**
- * Checks if a shape is convex
- *
- * @class _convex
- * @namespace PolyK
- * @private
- */
-PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
-{
- return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/*
- * the default suoer fast shader!
- */
-
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
-
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
-
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * the triangle strip shader..
- */
-
-PIXI.stripShaderFragmentSrc = [
- "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;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.shaderStack = [];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
-
- //gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-//gl.enableVertexAttribArray(program.textureCoordAttribute);
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-
-
-}
-
-PIXI.initDefaultShader = function()
-{
- PIXI.defaultShader = new PIXI.PixiShader();
- PIXI.defaultShader.init();
- PIXI.activateShader(PIXI.defaultShader);
- /*
- PIXI.shaderStack.push(PIXI.defaultShader);
- PIXI.current*/
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
-
-PIXI.CompileVertexShader = function(gl, shaderSrc)
-{
- return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
-}
-
-PIXI.CompileFragmentShader = function(gl, shaderSrc)
-{
- 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);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(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();
-
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
-
- return shaderProgram;
-}
-
-PIXI.activateShader = function(shader)
-{
- PIXI.shaderStack.push(shader);
-
- //console.log(">>>")
- var gl = PIXI.gl;
-
- var shaderProgram = shader.program;
-
- // map uniforms..
- gl.useProgram(shaderProgram);
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
-
- shader.syncUniforms();
-
- PIXI.currentShader = shaderProgram;
-}
-
-
-PIXI.popShader = function()
-{
- var gl = PIXI.gl;
- // activate last program..
- var lastProgram = PIXI.shaderStack.pop();
-
- var shaderProgram = PIXI.shaderStack[ PIXI.shaderStack.length-1 ].program;
-
- gl.useProgram(shaderProgram);
-
- PIXI.currentShader = shaderProgram;
-}
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.primitiveProgram);
-
- //gl.disableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.disableVertexAttribArray(PIXI.currentShader.colorAttribute);
- gl.disableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
-
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute);
-}
-
-PIXI.deactivatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.currentShader);
-
- gl.enableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.colorAttribute);
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-PIXI.PixiShader = function()
-{
- // the webGL program..
- this.program;
-
- this.fragmentSrc = [
- "precision lowp float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
- "}"
- ];
-
-}
-
-PIXI.PixiShader.prototype.init = function()
-{
- var program = PIXI.compileProgram(this.vertexSrc || PIXI.shaderVertexSrc, this.fragmentSrc)
-
- var gl = PIXI.gl;
-
- gl.useProgram(program);
-
- // get the default shader bits!
- program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
- program.colorAttribute = gl.getAttribLocation(program, "aColor");
- program.textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
-
- program.projectionVector = gl.getUniformLocation(program, "projectionVector");
- program.samplerUniform = gl.getUniformLocation(program, "uSampler");
-
- // add those custom shaders!
- for (var key in this.uniforms)
- {
- // get the uniform locations..
- program[key] = gl.getUniformLocation(program, key);
- }
-
- this.program = program;
-}
-
-PIXI.PixiShader.prototype.syncUniforms = function()
-{
- var gl = PIXI.gl;
-
- for (var key in this.uniforms)
- {
- //var
- var type = this.uniforms[key].type;
-
- // need to grow this!
- if(type == "f")
- {
- gl.uniform1f(this.program[key], this.uniforms[key].value);
- }
- else if(type == "mat4")
- {
- gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- }
- }
-
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A set of functions used by the webGL renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.WebGLGraphics = function()
-{
-
-}
-
-/**
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param projection {Object}
- */
-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);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
-
- // WHY DOES THIS LINE NEED TO BE THERE???
- //gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.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
- *
- * @static
- * @private
- * @method updateGraphics
- * @param graphics {Graphics}
- */
-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;
-
- 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
- *
- * @static
- * @private
- * @method buildRectangle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- }
-
-}
-
-/**
- * Builds a circle to draw
- *
- * @static
- * @private
- * @method buildCircle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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;
-
- 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);
- }
-
-}
-
-/**
- * Builds a line to draw
- *
- * @static
- * @private
- * @method buildLine
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
-{
- // TODO OPTIMISE!
-
- var wrap = true;
- var points = graphicsData.points;
- if(points.length == 0)return;
-
- // 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;
-
- 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 (denom == 0) {
- denom+=1;
- }
-
- 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 (var i=0; i < indexCount; i++)
- {
- indices.push(indexStart++);
- };
-
- indices.push(indexStart-1);
-}
-
-/**
- * Builds a polygon to draw
- *
- * @static
- * @private
- * @method buildPoly
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- };
-}
-
-function HEXtoRGB(hex) {
- return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
-
-// an instance of the gl context..
-// only one at the moment :/
-PIXI.gl;
-
-/**
- * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
- * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
- * So no need for Sprite Batch's or Sprite Cloud's
- * Dont forget to add the view to your DOM or you will not see anything :)
- *
- * @class WebGLRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @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..
-
- this.transparent = !!transparent;
-
- this.width = width || 800;
- this.height = height || 600;
-
- this.view = view || document.createElement( 'canvas' );
- this.view.width = this.width;
- this.view.height = this.height;
-
- // 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.batchs = [];
-
- try
- {
- PIXI.gl = this.gl = this.view.getContext("experimental-webgl", {
- alpha: this.transparent,
- antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
- stencil:true
- });
- }
- catch (e)
- {
- throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
- }
-
- PIXI.initDefaultShader();
- PIXI.initPrimitiveShader();
- PIXI.initDefaultStripShader();
-
-
-// PIXI.activateDefaultShader();
-
- var gl = this.gl;
- PIXI.WebGLRenderer.gl = gl;
-
- this.batch = new PIXI.WebGLBatch(gl);
- gl.disable(gl.DEPTH_TEST);
- gl.disable(gl.CULL_FACE);
-
- gl.enable(gl.BLEND);
- gl.colorMask(true, true, true, this.transparent);
-
- PIXI.projection = new PIXI.Point(400, 300);
-
- this.resize(this.width, this.height);
- this.contextLost = false;
-
- PIXI.activateShader(PIXI.defaultShader);
-
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
-
-}
-
-// constructor
-PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
-
-/**
- * Gets a new WebGLBatch from the pool
- *
- * @static
- * @method getBatch
- * @return {WebGLBatch}
- * @private
- */
-PIXI.WebGLRenderer.getBatch = function()
-{
- if(PIXI._batchs.length == 0)
- {
- return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
- }
- else
- {
- return PIXI._batchs.pop();
- }
-}
-
-/**
- * Puts a batch back into the pool
- *
- * @static
- * @method returnBatch
- * @param batch {WebGLBatch} The batch to return
- * @private
- */
-PIXI.WebGLRenderer.returnBatch = function(batch)
-{
- batch.clean();
- PIXI._batchs.push(batch);
-}
-
-/**
- * Renders the stage to its webGL view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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);
- }
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
-
- // 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;
- 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
- *
- * @static
- * @method updateTextures
- * @private
- */
-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 = [];
-}
-
-/**
- * Updates a loaded webgl texture
- *
- * @static
- * @method updateTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.updateTexture = function(texture)
-{
- //TODO break this out into a texture manager...
- var gl = PIXI.gl;
-
- if(!texture._glTexture)
- {
- texture._glTexture = gl.createTexture();
- }
-
- if(texture.hasLoaded)
- {
- gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
-
- 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);
-
- // reguler...
-
- 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
- *
- * @method destroyTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.destroyTexture = function(texture)
-{
- //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);
- }
-}
-
-/**
- * resizes the webGL view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the webGL view
- * @param height {Number} the new height of the webGL view
- */
-PIXI.WebGLRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-
- this.gl.viewport(0, 0, this.width, this.height);
-
- //var projectionMatrix = this.projectionMatrix;
-
- 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;
-}
-
-/**
- * Handles a lost webgl context
- *
- * @method handleContextLost
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
-{
- event.preventDefault();
- this.contextLost = true;
-}
-
-/**
- * Handles a restored webgl context
- *
- * @method handleContextRestored
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
-{
- this.gl = this.view.getContext("experimental-webgl", {
- alpha: true
- });
-
- this.initShaders();
-
- 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;
- };
-
- PIXI._restoreBatchs(this.gl);
-
- this.contextLost = false;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._batchs = [];
-
-/**
- * @private
- */
-PIXI._getBatch = function(gl)
-{
- 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);
-}
-
-/**
- * @private
- */
-PIXI._restoreBatchs = function(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.
- * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
- * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
- * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
- * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @constructor
- * @param gl {WebGLContext} an instance of the webGL context
- */
-PIXI.WebGLBatch = function(gl)
-{
- this.gl = gl;
-
- 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;
-
-/**
- * Cleans the batch so that is can be returned to an object pool and reused
- *
- * @method clean
- */
-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;
-}
-
-/**
- * Recreates the buffers in the event of a context loss
- *
- * @method restoreLostContext
- * @param gl {WebGLContext}
- */
-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();
-}
-
-/**
- * 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
- */
-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;
-
- this.growBatch();
-}
-
-/**
- * inserts a sprite before the specified 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++;
-
- 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;
- }
-}
-
-/**
- * inserts a sprite after the specified sprite
- *
- * @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++;
-
- sprite.batch = this;
- this.dirty = true;
-
- var tempNext = previousSprite.__next;
- previousSprite.__next = sprite;
- sprite.__prev = previousSprite;
-
- 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--;
-
- 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.__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;
-}
-
-/**
- * Splits the batch into two with the specified sprite being the start of the new batch.
- *
- * @method split
- * @param sprite {Sprite} the sprite that indicates where the batch should be split
- * @return {WebGLBatch} the new batch
- */
-PIXI.WebGLBatch.prototype.split = function(sprite)
-{
- this.dirty = true;
-
- 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;
-
- 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"?
-
- // 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;
-
- return batch;
-}
-
-/**
- * Merges two batchs together
- *
- * @method merge
- * @param batch {WebGLBatch} the batch that will be merged
- */
-PIXI.WebGLBatch.prototype.merge = function(batch)
-{
- this.dirty = true;
-
- this.tail.__next = batch.head;
- batch.head.__prev = this.tail;
-
- this.size += batch.size;
-
- this.tail = batch.tail;
-
- 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
- * function is used to increase the size of the batch. It also creates a little extra room so
- * that the batch does not need to be resized every time a sprite is added
- *
- * @method growBatch
- */
-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);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
-
- 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.dirtyUVS = 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.dirtyColors = true;
-
- this.indices = new Uint16Array(this.dynamicSize * 6);
- var length = this.indices.length/6;
-
- 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
- *
- * @method refresh
- */
-PIXI.WebGLBatch.prototype.refresh = function()
-{
- var gl = this.gl;
-
- if (this.dynamicSize < this.size)
- {
- this.growBatch();
- }
-
- 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;
-
- while(displayObject)
- {
- index = indexRun * 8;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
-
- colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
-
- displayObject = displayObject.__next;
-
- indexRun ++;
- }
-
- this.dirtyUVS = true;
- this.dirtyColors = true;
-}
-
-/**
- * Updates all the relevant geometry and uploads the data to the GPU
- *
- * @method update
- */
-PIXI.WebGLBatch.prototype.update = function()
-{
- var gl = this.gl;
- var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3
-
- var a, b, c, d, tx, ty;
-
- var indexRun = 0;
-
- var displayObject = this.head;
-
- while(displayObject)
- {
- if(displayObject.vcount === PIXI.visibleCount)
- {
- width = displayObject.texture.frame.width;
- height = displayObject.texture.frame.height;
-
- // 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;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- index = indexRun * 8;
-
- worldTransform = displayObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- this.verticies[index + 0 ] = a * w1 + c * h1 + tx;
- this.verticies[index + 1 ] = d * h1 + b * w1 + ty;
-
- this.verticies[index + 2 ] = a * w0 + c * h1 + tx;
- this.verticies[index + 3 ] = d * h1 + b * w0 + ty;
-
- this.verticies[index + 4 ] = a * w0 + c * h0 + tx;
- this.verticies[index + 5 ] = d * h0 + b * w0 + ty;
-
- this.verticies[index + 6] = a * w1 + c * h0 + tx;
- this.verticies[index + 7] = d * h0 + b * w1 + ty;
-
- if(displayObject.updateFrame || displayObject.texture.updateFrame)
- {
- this.dirtyUVS = true;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
- }
-
- // TODO this probably could do with some optimisation....
- if(displayObject.cacheAlpha != displayObject.worldAlpha)
- {
- displayObject.cacheAlpha = displayObject.worldAlpha;
-
- var colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
- this.dirtyColors = true;
- }
- }
- else
- {
- index = indexRun * 8;
-
- this.verticies[index + 0 ] = 0;
- this.verticies[index + 1 ] = 0;
-
- this.verticies[index + 2 ] = 0;
- this.verticies[index + 3 ] = 0;
-
- this.verticies[index + 4 ] = 0;
- this.verticies[index + 5 ] = 0;
-
- this.verticies[index + 6] = 0;
- this.verticies[index + 7] = 0;
- }
-
- indexRun++;
- displayObject = displayObject.__next;
- }
-}
-
-/**
- * Draws the batch to the frame buffer
- *
- * @method render
- */
-PIXI.WebGLBatch.prototype.render = function(start, end)
-{
- start = start || 0;
-
- if(end == undefined)end = this.size;
-
- if(this.dirty)
- {
- this.refresh();
- this.dirty = false;
- }
-
- if (this.size == 0)return;
-
- this.update();
- var gl = this.gl;
-
- //TODO optimize this!
-
- var shaderProgram = PIXI.currentShader;
-
- //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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // update the uvs
- var isDefault = (shaderProgram == PIXI.shaderProgram)
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
-
- if(this.dirtyUVS)
- {
- this.dirtyUVS = false;
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
- }
-
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
-
- // update color!
- gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
-
- if(this.dirtyColors)
- {
- 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!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
-
- var len = end - start;
-
- // DRAW THAT this!
- gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
- * if a group of sprites all have the same baseTexture and blendMode then they can be
- * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
- * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
- * even if the batch only contains one sprite. Batching is handled automatically by the
- * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @contructor
- * @param gl {WebGLContext} An instance of the webGL context
- */
-PIXI.WebGLRenderGroup = function(gl)
-{
- this.gl = gl;
- this.root;
-
- this.backgroundColor;
- this.batchs = [];
- this.toRemove = [];
-}
-
-// constructor
-PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
-
-/**
- * Add a display object to the webgl renderer
- *
- * @method setRenderable
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
-{
- // has this changed??
- if(this.root)this.removeDisplayObjectAndChildren(this.root);
-
- displayObject.worldVisible = displayObject.visible;
-
- // soooooo //
- // to check if any batchs exist already??
-
- // TODO what if its already has an object? should remove it
- this.root = displayObject;
- this.addDisplayObjectAndChildren(displayObject);
-}
-
-/**
- * Renders the stage to its webgl view
- *
- * @method render
- * @param projection {Object}
- */
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
-
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- // will render all the elements in the group
- var renderable;
- for (var i=0; i < this.batchs.length; i++)
- {
-
- renderable = this.batchs[i];
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- continue;
- }
-
- // non sprite batch..
- var worldVisible = renderable.vcount === PIXI.visibleCount;
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
- }
-
-}
-
-/**
- * Renders a specific displayObject
- *
- * @method renderSpecific
- * @param displayObject {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- // to do!
- // render part of the scene...
-
- var startIndex;
- var startBatchIndex;
-
- var endIndex;
- var endBatchIndex;
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.first;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
- var startBatch = nextRenderable.batch;
-
- if(nextRenderable instanceof PIXI.Sprite)
- {
- startBatch = nextRenderable.batch;
-
- var head = startBatch.head;
- var next = head;
-
- // ok now we have the batch.. need to find the start index!
- if(head == nextRenderable)
- {
- startIndex = 0;
- }
- else
- {
- startIndex = 1;
-
- while(head.__next != nextRenderable)
- {
- startIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- startBatch = nextRenderable;
- }
-
- // Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
- {
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem.last;
- }
-
- if(lastRenderable instanceof PIXI.Sprite)
- {
- endBatch = lastRenderable.batch;
-
- var head = endBatch.head;
-
- if(head == lastRenderable)
- {
- endIndex = 0;
- }
- else
- {
- endIndex = 1;
-
- while(head.__next != lastRenderable)
- {
- endIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- endBatch = lastRenderable;
- }
-
- // TODO - need to fold this up a bit!
-
- if(startBatch == endBatch)
- {
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex, endIndex+1);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
- return;
- }
-
- // now we have first and last!
- startBatchIndex = this.batchs.indexOf(startBatch);
- endBatchIndex = this.batchs.indexOf(endBatch);
-
- // DO the first batch
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
-
- // DO the middle batchs..
- for (var i=startBatchIndex+1; i < endBatchIndex; i++)
- {
- renderable = this.batchs[i];
-
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- }
- else
- {
- this.renderSpecial(renderable, projection);
- }
- }
-
- // DO the last batch..
- if(endBatch instanceof PIXI.WebGLBatch)
- {
- endBatch.render(0, endIndex+1);
- }
- else
- {
- this.renderSpecial(endBatch, projection);
- }
-}
-
-/**
- * Renders a specific renderable
- *
- * @method renderSpecial
- * @param renderable {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
-{
- var sta = PIXI.shaderStack.length;
-
- var worldVisible = renderable.vcount === PIXI.visibleCount
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.CustomRenderable)
- {
- if(worldVisible) renderable.renderWebGL(this, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
-}
-
-PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection)
-{
- /*
- * for now only masks are supported..
- */
- var gl = PIXI.gl;
-
- if(renderable.open)
- {
- if(renderable.data instanceof Array)
- {
- var filter = renderable.data[0];
-
- if(!filter.shader)
- {
- var shader = new PIXI.PixiShader();
-
- shader.fragmentSrc = filter.fragmentSrc;
- shader.uniforms = filter.uniforms;
- shader.init();
-
- filter.shader = shader
- }
-
- PIXI.activateShader(filter.shader);
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
- PIXI.WebGLGraphics.renderGraphics(renderable.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- }
- else
- {
- if(renderable.data instanceof Array)
- {
- PIXI.popShader();
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
-}
-
-/**
- * Updates a webgl texture
- *
- * @method updateTexture
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
-{
-
- // TODO definitely can optimse this function..
-
- this.removeObject(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- this.insertObject(displayObject, previousRenderable, nextRenderable);
-}
-
-/**
- * Adds filter blocks
- *
- * @method addFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
-{
- start.__renderGroup = this;
- end.__renderGroup = this;
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = start;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
- this.insertAfter(start, previousRenderable);
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var previousRenderable2 = end;
- while(previousRenderable2 != this.root.first)
- {
- previousRenderable2 = previousRenderable2._iPrev;
- if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
- }
- this.insertAfter(end, previousRenderable2);
-}
-
-/**
- * Remove filter blocks
- *
- * @method removeFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
-{
- this.removeObject(start);
- this.removeObject(end);
-}
-
-/**
- * Adds a display object and children to the webgl context
- *
- * @method addDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
-
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- // one the display object hits this. we can break the loop
-
- var tempObject = displayObject.first;
- var testObject = displayObject.last._iNext;
- do
- {
- tempObject.__renderGroup = this;
-
- if(tempObject.renderable)
- {
-
- this.insertObject(tempObject, previousRenderable, nextRenderable);
- previousRenderable = tempObject;
- }
-
- tempObject = tempObject._iNext;
- }
- while(tempObject != testObject)
-}
-
-/**
- * Removes a display object and children to the webgl context
- *
- * @method removeDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup != this)return;
-
-// var displayObject = displayObject.first;
- var lastObject = displayObject.last;
- do
- {
- displayObject.__renderGroup = null;
- if(displayObject.renderable)this.removeObject(displayObject);
- displayObject = displayObject._iNext;
- }
- while(displayObject)
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertObject
- * @param displayObject {DisplayObject}
- * @param previousObject {DisplayObject}
- * @param nextObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
-{
- // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
- var previousSprite = previousObject;
- var nextSprite = nextObject;
-
- /*
- * so now we have the next renderable and the previous renderable
- *
- */
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch
- var nextBatch
-
- if(previousSprite instanceof PIXI.Sprite)
- {
- previousBatch = previousSprite.batch;
- if(previousBatch)
- {
- if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
- {
- previousBatch.insertAfter(displayObject, previousSprite);
- return;
- }
- }
- }
- else
- {
- // TODO reword!
- previousBatch = previousSprite;
- }
-
- if(nextSprite)
- {
- if(nextSprite instanceof PIXI.Sprite)
- {
- nextBatch = nextSprite.batch;
-
- //batch may not exist if item was added to the display list but not to the webGL
- if(nextBatch)
- {
- if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
- {
- nextBatch.insertBefore(displayObject, nextSprite);
- return;
- }
- else
- {
- if(nextBatch == previousBatch)
- {
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(nextSprite);
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var batch = PIXI.WebGLRenderer.getBatch();
-
- var index = this.batchs.indexOf( previousBatch );
- batch.init(displayObject);
- this.batchs.splice(index+1, 0, batch, splitBatch);
-
- return;
- }
- }
- }
- }
- else
- {
- // TODO re-word!
-
- nextBatch = nextSprite;
- }
- }
-
- /*
- * looks like it does not belong to any batch!
- * but is also not intersecting one..
- * time to create anew one!
- */
-
- var batch = PIXI.WebGLRenderer.getBatch();
- batch.init(displayObject);
-
- if(previousBatch) // if this is invalid it means
- {
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, batch);
- }
- else
- {
- this.batchs.push(batch);
- }
-
- return;
- }
- else if(displayObject instanceof PIXI.TilingSprite)
- {
-
- // add to a batch!!
- this.initTilingSprite(displayObject);
- // this.batchs.push(displayObject);
-
- }
- else if(displayObject instanceof PIXI.Strip)
- {
- // add to a batch!!
- this.initStrip(displayObject);
- // this.batchs.push(displayObject);
- }
- else if(displayObject)// instanceof PIXI.Graphics)
- {
- //displayObject.initWebGL(this);
-
- // add to a batch!!
- //this.initStrip(displayObject);
- //this.batchs.push(displayObject);
- }
-
- this.insertAfter(displayObject, previousSprite);
-
- // insert and SPLIT!
-
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertAfter
- * @param item {DisplayObject}
- * @param displayObject {DisplayObject} The object to insert
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
-{
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch = displayObject.batch;
-
- if(previousBatch)
- {
- // so this object is in a batch!
-
- // is it not? need to split the batch
- if(previousBatch.tail == displayObject)
- {
- // is it tail? insert in to batchs
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item);
- }
- else
- {
- // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
-
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(displayObject.__next);
-
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item, splitBatch);
- }
- }
- else
- {
- this.batchs.push(item);
- }
- }
- else
- {
- var index = this.batchs.indexOf( displayObject );
- this.batchs.splice(index+1, 0, item);
- }
-}
-
-/**
- * Removes a displayObject from the linked list
- *
- * @method removeObject
- * @param displayObject {DisplayObject} The object to remove
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
-{
- // loop through children..
- // display object //
-
- // add a child from the render group..
- // remove it and all its children!
- //displayObject.cacheVisible = false;//displayObject.visible;
-
- /*
- * removing is a lot quicker..
- *
- */
- var batchToRemove;
-
- if(displayObject instanceof PIXI.Sprite)
- {
- // should always have a batch!
- var batch = displayObject.batch;
- if(!batch)return; // this means the display list has been altered befre rendering
-
- batch.remove(displayObject);
-
- if(batch.size==0)
- {
- batchToRemove = batch;
- }
- }
- else
- {
- batchToRemove = displayObject;
- }
-
- /*
- * Looks like there is somthing that needs removing!
- */
- if(batchToRemove)
- {
- var index = this.batchs.indexOf( batchToRemove );
- if(index == -1)return;// this means it was added then removed before rendered
-
- // ok so.. check to see if you adjacent batchs should be joined.
- // TODO may optimise?
- if(index == 0 || index == this.batchs.length-1)
- {
- // wha - eva! just get of the empty batch!
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
-
- return;
- }
-
- if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
- {
- if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
- {
- //console.log("MERGE")
- this.batchs[index-1].merge(this.batchs[index+1]);
-
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
- this.batchs.splice(index, 2);
- return;
- }
- }
-
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- }
-}
-
-
-/**
- * Initializes a tiling sprite
- *
- * @method initTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
-{
- var gl = this.gl;
-
- // make the texture tilable..
-
- sprite.verticies = new Float32Array([0, 0,
- sprite.width, 0,
- sprite.width, sprite.height,
- 0, sprite.height]);
-
- sprite.uvs = new Float32Array([0, 0,
- 1, 0,
- 1, 1,
- 0, 1]);
-
- sprite.colors = new Float32Array([1,1,1,1]);
-
- sprite.indices = new Uint16Array([0, 1, 3,2])//, 2]);
-
- sprite._vertexBuffer = gl.createBuffer();
- sprite._indexBuffer = gl.createBuffer();
- sprite._uvBuffer = gl.createBuffer();
- sprite._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.uvs, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW);
-
-// return ( (x > 0) && ((x & (x - 1)) == 0) );
-
- if(sprite.texture.baseTexture._glTexture)
- {
- gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- sprite.texture.baseTexture._powerOf2 = true;
- }
- else
- {
- sprite.texture.baseTexture._powerOf2 = true;
- }
-}
-
-/**
- * Renders a Strip
- *
- * @method renderStrip
- * @param strip {Strip} The strip to render
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.stripShaderProgram;
-
-
- gl.useProgram(shaderProgram);
-
- var m = PIXI.mat3.clone(strip.worldTransform);
-
- PIXI.mat3.transpose(m);
-
- // set the matrix transform for the
- gl.uniformMatrix3fv(shaderProgram.translationMatrix, false, m);
- gl.uniform2f(shaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(shaderProgram.alpha, strip.worldAlpha);
-
-/*
- if(strip.blendMode == PIXI.blendModes.NORMAL)
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
- }
- */
-
-
- if(!strip.dirty)
- {
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- }
- else
- {
- strip.dirty = false;
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-
- }
-
- gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
-
- gl.useProgram(PIXI.currentProgram);
-}
-
-/**
- * Renders a TilingSprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to render
- * @param projectionMatrix {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- var tilePosition = sprite.tilePosition;
- var tileScale = sprite.tileScale;
-
- var offsetX = tilePosition.x/sprite.texture.baseTexture.width;
- var offsetY = tilePosition.y/sprite.texture.baseTexture.height;
-
- var scaleX = (sprite.width / sprite.texture.baseTexture.width) / tileScale.x;
- var scaleY = (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
-
- sprite.uvs[0] = 0 - offsetX;
- sprite.uvs[1] = 0 - offsetY;
-
- sprite.uvs[2] = (1 * scaleX) -offsetX;
- sprite.uvs[3] = 0 - offsetY;
-
- sprite.uvs[4] = (1 *scaleX) - offsetX;
- sprite.uvs[5] = (1 *scaleY) - offsetY;
-
- sprite.uvs[6] = 0 - offsetX;
- sprite.uvs[7] = (1 *scaleY) - offsetY;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
-
- this.renderStrip(sprite, projectionMatrix);
-}
-
-/**
- * Initializes a strip to be rendered
- *
- * @method initStrip
- * @param strip {Strip} The strip to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
-{
- // build the strip!
- var gl = this.gl;
- var shaderProgram = this.shaderProgram;
-
- strip._vertexBuffer = gl.createBuffer();
- strip._indexBuffer = gl.createBuffer();
- strip._uvBuffer = gl.createBuffer();
- strip._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-}
-
-
-/**
- * @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 :)
- *
- * @class CanvasRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
- */
-PIXI.CanvasRenderer = function(width, height, view, transparent)
-{
- this.transparent = transparent;
-
- /**
- * 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 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");
-
- 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;
-}
-
-// constructor
-PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
-
-/**
- * Renders the stage to its canvas view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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;
-
- 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 = [];
- }
-
-
-}
-
-/**
- * resizes the canvas view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the canvas view
- * @param height {Number} the new height of the canvas view
- */
-PIXI.CanvasRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-}
-
-/**
- * Renders a display object
- *
- * @method renderDisplayObject
- * @param displayObject {DisplayObject} The displayObject to render
- * @private
- */
-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)
- {
-
- var frame = displayObject.texture.frame;
-
- if(frame && frame.width && frame.height)
- {
- 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)
- {
- 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(PIXI.FilterBlock.data instanceof PIXI.Graphics)
- {
- if(displayObject.open)
- {
- context.save();
-
- var cacheAlpha = displayObject.mask.alpha;
- var maskTransform = displayObject.mask.worldTransform;
-
- context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
-
- displayObject.mask.worldAlpha = 0.5;
-
- context.worldAlpha = 0;
-
- PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context);
- context.clip();
-
- displayObject.mask.worldAlpha = cacheAlpha;
- }
- else
- {
- context.restore();
- }
- }
- else
- {
- // only masks supported right now!
- }
- }
- // count++
- displayObject = displayObject._iNext;
-
-
- }
- while(displayObject != testObject)
-
-
-}
-
-/**
- * Renders a flat strip
- *
- * @method renderStripFlat
- * @param strip {Strip} The Strip to render
- * @private
- */
-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();
-}
-
-/**
- * Renders a tiling sprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tilingsprite to render
- * @private
- */
-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;
-
- // 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.translate(-tilePosition.x, -tilePosition.y);
-
- context.closePath();
-}
-
-/**
- * Renders a strip
- *
- * @method renderStrip
- * @param strip {Strip} The Strip to render
- * @private
- */
-PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
-{
- 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;
-
-
- 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();
- };
-
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * A set of functions used by the canvas renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.CanvasGraphics = function()
-{
-
-}
-
-
-/*
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- 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.lineWidth = data.lineWidth;
-
- 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]);
- }
-
- // 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.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]);
- }
-
- }
- 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
-
- 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
- *
- * @static
- * @private
- * @method renderGraphicsMask
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- var len = graphics.graphicsData.length;
- if(len > 1)
- {
- len = 1;
- 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;
-
- 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]);
- }
-
- // 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
- }
-
-
- };
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
- * It is important to know that with the webGL renderer only simple polys can be filled at this stage
- * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
- *
- * @class Graphics
- * @extends DisplayObjectContainer
- * @constructor
- */
-PIXI.Graphics = function()
-{
- PIXI.DisplayObjectContainer.call( this );
-
- this.renderable = true;
-
- /**
- * The alpha of the fill of this graphics object
- *
- * @property fillAlpha
- * @type Number
- */
- this.fillAlpha = 1;
-
- /**
- * The width of any lines drawn
- *
- * @property lineWidth
- * @type Number
- */
- this.lineWidth = 0;
-
- /**
- * The color of any lines drawn
- *
- * @property lineColor
- * @type String
- */
- this.lineColor = "black";
-
- /**
- * Graphics data
- *
- * @property graphicsData
- * @type Array
- * @private
- */
- this.graphicsData = [];
-
- /**
- * Current path
- *
- * @property currentPath
- * @type Object
- * @private
- */
- this.currentPath = {points:[]};
-}
-
-// constructor
-PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Graphics.prototype.constructor = PIXI.Graphics;
-
-/**
- * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
- *
- * @method lineStyle
- * @param lineWidth {Number} width of the line to draw, will update the object's stored style
- * @param color {Number} color of the line to draw, will update the object's stored style
- * @param alpha {Number} alpha of the line to draw, will update the object's stored style
- */
-PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
-{
- if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.lineWidth = lineWidth || 0;
- this.lineColor = color || 0;
- this.lineAlpha = (alpha == undefined) ? 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.graphicsData.push(this.currentPath);
-}
-
-/**
- * Moves the current drawing position to (x, y).
- *
- * @method moveTo
- * @param x {Number} the X coord to move to
- * @param y {Number} the Y coord to move to
- */
-PIXI.Graphics.prototype.moveTo = function(x, y)
-{
- if(this.currentPath.points.length == 0)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.points.push(x, y);
-
- this.graphicsData.push(this.currentPath);
-}
-
-/**
- * Draws a line using the current line style from the current drawing position to (x, y);
- * the current drawing position is then set to (x, y).
- *
- * @method lineTo
- * @param x {Number} the X coord to draw to
- * @param y {Number} the Y coord to draw to
- */
-PIXI.Graphics.prototype.lineTo = function(x, y)
-{
- this.currentPath.points.push(x, y);
- this.dirty = true;
-}
-
-/**
- * Specifies a simple one-color fill that subsequent calls to other Graphics methods
- * (such as lineTo() or drawCircle()) use when drawing.
- *
- * @method beginFill
- * @param color {uint} the color of the fill
- * @param alpha {Number} the alpha
- */
-PIXI.Graphics.prototype.beginFill = function(color, alpha)
-{
- this.filling = true;
- this.fillColor = color || 0;
- this.fillAlpha = (alpha == undefined) ? 1 : alpha;
-}
-
-/**
- * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
- *
- * @method endFill
- */
-PIXI.Graphics.prototype.endFill = function()
-{
- this.filling = false;
- this.fillColor = null;
- this.fillAlpha = 1;
-}
-
-/**
- * @method drawRect
- *
- * @param x {Number} The X coord of the top-left of the rectangle
- * @param y {Number} The Y coord of the top-left of the rectangle
- * @param width {Number} The width of the rectangle
- * @param height {Number} The height of the rectangle
- */
-PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws a circle.
- *
- * @method drawCircle
- * @param x {Number} The X coord of the center of the circle
- * @param y {Number} The Y coord of the center of the circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws an elipse.
- *
- * @method drawElipse
- * @param x {Number}
- * @param y {Number}
- * @param width {Number}
- * @param height {Number}
- */
-PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
- *
- * @method clear
- */
-PIXI.Graphics.prototype.clear = function()
-{
- this.lineWidth = 0;
- this.filling = false;
-
- this.dirty = true;
- this.clearDirty = true;
- this.graphicsData = [];
-}
-
-// SOME TYPES:
-PIXI.Graphics.POLY = 0;
-PIXI.Graphics.RECT = 1;
-PIXI.Graphics.CIRC = 2;
-PIXI.Graphics.ELIP = 3;
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-PIXI.Strip = function(texture, width, height)
-{
- 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]);
-
- this.verticies = new Float32Array([0, 0,
- 0,0,
- 0,0, 0,
- 0, 0]);
-
- 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.verticies = [0, 0,
- 0,0,
- 0,0, 0,
- 0, 0];
-
- this.colors = [1, 1, 1, 1];
-
- 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;
-
- // 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;
-}
-
-// constructor
-PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Strip.prototype.constructor = PIXI.Strip;
-
-PIXI.Strip.prototype.setTexture = function(texture)
-{
- //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;
-}
-
-PIXI.Strip.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-// some helper functions..
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-
-PIXI.Rope = function(texture, points)
-{
- PIXI.Strip.call( this, texture );
- this.points = points;
-
- try
- {
- this.verticies = new Float32Array( points.length * 4);
- this.uvs = new Float32Array( points.length * 4);
- this.colors = new Float32Array( points.length * 2);
- this.indices = new Uint16Array( points.length * 2);
- }
- catch(error)
- {
- this.verticies = verticies
-
- this.uvs = uvs
- this.colors = colors
- this.indices = indices
- }
-
- this.refresh();
-}
-
-
-// constructor
-PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
-PIXI.Rope.prototype.constructor = PIXI.Rope;
-
-PIXI.Rope.prototype.refresh = function()
-{
- var points = this.points;
- if(points.length < 1)return;
-
- var uvs = this.uvs
- var indices = this.indices;
- var colors = this.colors;
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
-
- uvs[0] = 0
- uvs[1] = 1
- uvs[2] = 0
- uvs[3] = 1
-
- colors[0] = 1;
- colors[1] = 1;
-
- indices[0] = 0;
- indices[1] = 1;
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
- // time to do some smart drawing!
- var amount = i/(total-1)
-
- if(i%2)
- {
- uvs[index] = amount;
- uvs[index+1] = 0;
-
- uvs[index+2] = amount
- uvs[index+3] = 1
-
- }
- else
- {
- uvs[index] = amount
- uvs[index+1] = 0
-
- uvs[index+2] = amount
- uvs[index+3] = 1
- }
-
- index = i * 2;
- colors[index] = 1;
- colors[index+1] = 1;
-
- index = i * 2;
- indices[index] = index;
- indices[index + 1] = index + 1;
-
- lastPoint = point;
- }
-}
-
-PIXI.Rope.prototype.updateTransform = function()
-{
-
- var points = this.points;
- if(points.length < 1)return;
-
- var verticies = this.verticies
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
- verticies[0] = point.x + perp.x
- verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
- verticies[3] = point.y - perp.y//+200
- // time to do some smart drawing!
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
-
- if(i < points.length-1)
- {
- nextPoint = points[i+1];
- }
- else
- {
- nextPoint = point
- }
-
- perp.y = -(nextPoint.x - lastPoint.x);
- perp.x = nextPoint.y - lastPoint.y;
-
- var ratio = (1 - (i / (total-1))) * 10;
- if(ratio > 1)ratio = 1;
-
- 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;
-
- 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;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
-}
-
-PIXI.Rope.prototype.setTexture = function(texture)
-{
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * A tiling sprite is a fast way of rendering a tiling image
- *
- * @class TilingSprite
- * @extends DisplayObjectContainer
- * @constructor
- * @param texture {Texture} the texture of the tiling sprite
- * @param width {Number} the width of the tiling sprite
- * @param height {Number} the height of the tiling sprite
- */
-PIXI.TilingSprite = function(texture, width, height)
-{
- PIXI.DisplayObjectContainer.call( this );
-
- /**
- * 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 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 offset position of the image that is being tiled
- *
- * @property tilePosition
- * @type Point
- */
- this.tilePosition = new PIXI.Point(0,0);
-
- this.renderable = true;
-
- this.blendMode = PIXI.blendModes.NORMAL
-}
-
-// constructor
-PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
-
-/**
- * Sets the texture of the tiling sprite
- *
- * @method setTexture
- * @param texture {Texture} The PIXI texture that is displayed by the sprite
- */
-PIXI.TilingSprite.prototype.setTexture = function(texture)
-{
- //TODO SET THE TEXTURES
- //TODO VISIBILITY
-
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-/**
- * When the texture is updated, this event will fire to update the frame
- *
- * @method onTextureUpdate
- * @param event
- * @private
- */
-PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
- *
- * Awesome JS run time provided by EsotericSoftware
- * https://github.com/EsotericSoftware/spine-runtimes
- *
- */
-
-/**
- * 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
- * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
- *
- * @class Spine
- * @extends DisplayObjectContainer
- * @constructor
- * @param url {String} The url of the spine anim file to be used
- */
-PIXI.Spine = function (url) {
- PIXI.DisplayObjectContainer.call(this);
-
- this.spineData = PIXI.AnimCache[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.stateData = new spine.AnimationStateData(this.spineData);
- this.state = new spine.AnimationState(this.stateData);
-
- 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);
- }
-};
-
-PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.Spine.prototype.constructor = PIXI.Spine;
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @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();
-
- 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;
-
- 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.rotation = -(slot.bone.worldRotation * Math.PI / 180);
- }
-
- 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;
-
- 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;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * This object is one that will allow you to specify custom rendering functions based on render type
- *
- * @class CustomRenderable
- * @extends DisplayObject
- * @constructor
- */
-PIXI.CustomRenderable = function()
-{
- PIXI.DisplayObject.call( this );
-
-}
-
-// constructor
-PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
-
-/**
- * If this object is being rendered by a CanvasRenderer it will call this callback
- *
- * @method renderCanvas
- * @param renderer {CanvasRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderCanvas = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback to initialize
- *
- * @method initWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.initWebGL = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback
- *
- * @method renderWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderWebGL = function(renderGroup, projectionMatrix)
-{
- // not sure if both needed? but ya have for now!
- // override!
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.BaseTextureCache = {};
-PIXI.texturesToUpdate = [];
-PIXI.texturesToDestroy = [];
-
-/**
- * A texture stores the information that represents an image. All textures have a base texture
- *
- * @class BaseTexture
- * @uses EventTarget
- * @constructor
- * @param source {String} the source object (image or canvas)
- */
-PIXI.BaseTexture = function(source)
-{
- 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 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 source that is loaded to create the texture
- *
- * @property source
- * @type Image
- */
- this.source = source;
-
- if(!source)return;
-
- 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;
-
- PIXI.texturesToUpdate.push(this);
- }
- else
- {
-
- var scope = this;
- this.source.onload = function(){
-
- scope.hasLoaded = true;
- scope.width = scope.source.width;
- scope.height = scope.source.height;
-
- // 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;
-
- PIXI.texturesToUpdate.push(this);
- }
-
- this._powerOf2 = false;
-}
-
-PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
-
-/**
- * Destroys this base texture
- *
- * @method destroy
- */
-PIXI.BaseTexture.prototype.destroy = function()
-{
- if(this.source instanceof Image)
- {
- this.source.src = null;
- }
- this.source = null;
- PIXI.texturesToDestroy.push(this);
-}
-
-/**
- * Helper function that returns a base texture based on an image url
- * If the image is not in the base texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @return BaseTexture
- */
-PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
-{
- 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);
- PIXI.BaseTextureCache[imageUrl] = baseTexture;
- }
-
- return baseTexture;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.TextureCache = {};
-PIXI.FrameCache = {};
-
-/**
- * A texture stores the information that represents an image or part of an image. It cannot be added
- * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
- *
- * @class Texture
- * @uses EventTarget
- * @constructor
- * @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frame {Rectangle} The rectangle frame of the texture to show
- */
-PIXI.Texture = function(baseTexture, frame)
-{
- PIXI.EventTarget.call( this );
-
- if(!frame)
- {
- this.noFrame = true;
- frame = new PIXI.Rectangle(0,0,1,1);
- }
-
- if(baseTexture instanceof PIXI.Texture)
- baseTexture = baseTexture.baseTexture;
-
- /**
- * The base texture of this texture
- *
- * @property baseTexture
- * @type BaseTexture
- */
- this.baseTexture = baseTexture;
-
- /**
- * The frame specifies the region of the base texture that this texture uses
- *
- * @property frame
- * @type Rectangle
- */
- this.frame = frame;
-
- /**
- * The trim point
- *
- * @property trim
- * @type Point
- */
- this.trim = new PIXI.Point();
-
- this.scope = this;
-
- if(baseTexture.hasLoaded)
- {
- if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- //console.log(frame)
-
- this.setFrame(frame);
- }
- else
- {
- var scope = this;
- baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} );
- }
-}
-
-PIXI.Texture.prototype.constructor = PIXI.Texture;
-
-/**
- * Called when the base texture is loaded
- *
- * @method onBaseTextureLoaded
- * @param event
- * @private
- */
-PIXI.Texture.prototype.onBaseTextureLoaded = function(event)
-{
- var baseTexture = this.baseTexture;
- baseTexture.removeEventListener( 'loaded', this.onLoaded );
-
- if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- this.noFrame = false;
- this.width = this.frame.width;
- this.height = this.frame.height;
-
- this.scope.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Destroys this texture
- *
- * @method destroy
- * @param destroyBase {Boolean} Whether to destroy the base texture as well
- */
-PIXI.Texture.prototype.destroy = function(destroyBase)
-{
- if(destroyBase)this.baseTexture.destroy();
-}
-
-/**
- * Specifies the rectangle region of the baseTexture
- *
- * @method setFrame
- * @param frame {Rectangle} The frame of the texture to set it to
- */
-PIXI.Texture.prototype.setFrame = function(frame)
-{
- this.frame = frame;
- this.width = frame.width;
- this.height = frame.height;
-
- 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;
-
- PIXI.Texture.frameUpdates.push(this);
- //this.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Helper function that returns a texture based on an image url
- * If the image is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- * @return Texture
- */
-PIXI.Texture.fromImage = function(imageUrl, crossorigin)
-{
- var texture = PIXI.TextureCache[imageUrl];
-
- if(!texture)
- {
- texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
- PIXI.TextureCache[imageUrl] = texture;
- }
-
- return texture;
-}
-
-/**
- * Helper function that returns a texture based on a frame id
- * If the frame id is not in the texture cache an error will be thrown
- *
- * @static
- * @method fromFrame
- * @param frameId {String} The frame id of the texture
- * @return Texture
- */
-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;
-}
-
-/**
- * Helper function that returns a texture based on a canvas element
- * If the canvas is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromCanvas
- * @param canvas {Canvas} The canvas element source of the texture
- * @return Texture
- */
-PIXI.Texture.fromCanvas = function(canvas)
-{
- var baseTexture = new PIXI.BaseTexture(canvas);
- return new PIXI.Texture(baseTexture);
-}
-
-
-/**
- * Adds a texture to the textureCache.
- *
- * @static
- * @method addTextureToCache
- * @param texture {Texture}
- * @param id {String} the id that the texture will be stored against.
- */
-PIXI.Texture.addTextureToCache = function(texture, id)
-{
- PIXI.TextureCache[id] = texture;
-}
-
-/**
- * Remove a texture from the textureCache.
- *
- * @static
- * @method removeTextureFromCache
- * @param id {String} the id of the texture to be removed
- * @return {Texture} the texture that was removed
- */
-PIXI.Texture.removeTextureFromCache = function(id)
-{
- var texture = PIXI.TextureCache[id]
- PIXI.TextureCache[id] = null;
- return texture;
-}
-
-// this is more for webGL.. it contains updated frames..
-PIXI.Texture.frameUpdates = [];
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- 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.
-
- 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);
-
- 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
-
- @class RenderTexture
- @extends Texture
- @constructor
- @param width {Number} The width of the render texture
- @param height {Number} The height of the render texture
- */
-PIXI.RenderTexture = function(width, height)
-{
- PIXI.EventTarget.call( this );
-
- this.width = width || 100;
- this.height = height || 100;
-
- this.indetityMatrix = PIXI.mat3.create();
-
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
-
- if(PIXI.gl)
- {
- this.initWebGL();
- }
- else
- {
- this.initCanvas();
- }
-}
-
-PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
-PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
-
-/**
- * Initializes the webgl data for this texture
- *
- * @method initWebGL
- * @private
- */
-PIXI.RenderTexture.prototype.initWebGL = function()
-{
- var gl = PIXI.gl;
- this.glFramebuffer = gl.createFramebuffer();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // 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);
- }
-}
-
-/**
- * Initializes the canvas data for this texture
- *
- * @method initCanvas
- * @private
- */
-PIXI.RenderTexture.prototype.initCanvas = function()
-{
- 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.render = this.renderCanvas;
-}
-
-/**
- * This function will draw the display object to the texture.
- *
- * @method renderWebGL
- * @param displayObject {DisplayObject} The display object to render this texture on
- * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
- * @private
- */
-PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
-{
- var gl = PIXI.gl;
-
- // enable the alpha color mask..
- gl.colorMask(true, true, true, true);
-
- gl.viewport(0, 0, this.width, this.height);
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- if(clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
-
- // 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;
-
-
- 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} 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".
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.AssetLoader = function(assetURLs, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The array of asset URLs that are going to be loaded
- *
- * @property assetURLs
- * @type Array
- */
- this.assetURLs = assetURLs;
-
- /**
- * Whether the requests should be treated as cross origin
- *
- * @property crossorigin
- * @type Boolean
- */
- this.crossorigin = crossorigin;
-
- /**
- * Maps file extension to loader types
- *
- * @property loadersByType
- * @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
- };
-
-
-};
-
-/**
- * Fired when an item has loaded
- * @event onProgress
- */
-
-/**
- * Fired when all the assets have loaded
- * @event onComplete
- */
-
-// constructor
-PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
-
-/**
- * Starts loading the assets sequentially
- *
- * @method load
- */
-PIXI.AssetLoader.prototype.load = function()
-{
- var scope = this;
-
- this.loadCount = this.assetURLs.length;
-
- for (var i=0; i < this.assetURLs.length; i++)
- {
- var fileName = this.assetURLs[i];
- var fileType = fileName.split(".").pop().toLowerCase();
-
- var loaderClass = this.loadersByType[fileType];
- if(!loaderClass)
- throw new Error(fileType + " is an unsupported file type");
-
- var loader = new loaderClass(fileName, this.crossorigin);
-
- loader.addEventListener("loaded", function()
- {
- scope.onAssetLoaded();
- });
- loader.load();
- }
-};
-
-/**
- * Invoked after each file is loaded
- *
- * @method onAssetLoaded
- * @private
- */
-PIXI.AssetLoader.prototype.onAssetLoaded = function()
-{
- this.loadCount--;
- 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();
- }
-};
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class JsonLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the JSON file
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.JsonLoader = function (url, crossorigin) {
- PIXI.EventTarget.call(this);
-
- /**
- * 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;
-
- /**
- * [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;
-
-};
-
-// constructor
-PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
-
-/**
- * Loads the JSON data
- *
- * @method load
- */
-PIXI.JsonLoader.prototype.load = function () {
- this.ajaxRequest = new 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);
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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.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();
- });
-
- 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();
-
- }
- 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();
- }
- }
-};
-
-/**
- * Invoke when json file loaded
- *
- * @method onLoaded
- * @private
- */
-PIXI.JsonLoader.prototype.onLoaded = function () {
- this.loaded = true;
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * Invoke when error occured
- *
- * @method onError
- * @private
- */
-PIXI.JsonLoader.prototype.onError = function () {
- this.dispatchEvent({
- type: "error",
- content: this
- });
-};
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- * 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.
- * 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
- *
- * @class SpriteSheetLoader
- * @uses EventTarget
- * @constructor
- * @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);
-
- /**
- * 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;
-
- /**
- * [read-only] The base url of the bitmap font data
- *
- * @property baseUrl
- * @type String
- * @readOnly
- */
- this.baseUrl = url.replace(/[^\/]*$/, "");
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = null;
-
- /**
- * The frames of the sprite sheet
- *
- * @property frames
- * @type Object
- */
- this.frames = {};
-};
-
-// constructor
-PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader;
-
-/**
- * This will begin loading the JSON file
- *
- * @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();
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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;
-
- this.texture = image.texture.baseTexture;
- image.addEventListener("loaded", function (event) {
- 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!
- }
- }
- }
-
- image.load();
-};
-/**
- * Invoke when all files are loaded (json and texture)
- *
- * @method onLoaded
- * @private
- */
-PIXI.SpriteSheetLoader.prototype.onLoaded = function () {
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class ImageLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the image
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.ImageLoader = function(url, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = PIXI.Texture.fromImage(url, crossorigin);
-
- /**
- * if the image is loaded with loadFramedSpriteSheet
- * frames will contain the sprite sheet frames
- *
- */
- this.frames = [];
-};
-
-// constructor
-PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader;
-
-/**
- * Loads image or takes it from cache
- *
- * @method load
- */
-PIXI.ImageLoader.prototype.load = function()
-{
- if(!this.texture.baseTexture.hasLoaded)
- {
- var scope = this;
- this.texture.baseTexture.addEventListener("loaded", function()
- {
- scope.onLoaded();
- });
- }
- else
- {
- this.onLoaded();
- }
-};
-
-/**
- * Invoked when image file is loaded or it is already cached and ready to use
- *
- * @method onLoaded
- * @private
- */
-PIXI.ImageLoader.prototype.onLoaded = function()
-{
- this.dispatchEvent({type: "loaded", content: this});
-};
-
-/**
- * Loads image and split it to uniform sized frames
- *
- *
- * @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
- */
-PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
-{
- this.frames = [];
- var cols = Math.floor(this.texture.width / frameWidth);
- var rows = Math.floor(this.texture.height / frameHeight);
-
- var i=0;
- for (var y=0; y
-
+
+
+
+
+
diff --git a/examples/example 16 - Displacement/pixi.js b/examples/example 16 - Displacement/pixi.js
deleted file mode 100644
index 9cd1b34..0000000
--- a/examples/example 16 - Displacement/pixi.js
+++ /dev/null
@@ -1,10773 +0,0 @@
-/**
- * @license
- * Pixi.JS - v1.3.0
- * Copyright (c) 2012, Mat Groves
- * http://goodboydigital.com/
- *
- * Compiled: 2013-10-20
- *
- * Pixi.JS is licensed under the MIT License.
- * http://www.opensource.org/licenses/mit-license.php
- */
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-(function(){
-
- var root = this;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * @module PIXI
- */
-var PIXI = PIXI || {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
- *
- * @class Point
- * @constructor
- * @param x {Number} position of the point
- * @param y {Number} position of the point
- */
-PIXI.Point = function(x, y)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-}
-
-/**
- * Creates a clone of this point
- *
- * @method clone
- * @return {Point} a copy of the point
- */
-PIXI.Point.prototype.clone = function()
-{
- return new PIXI.Point(this.x, this.y);
-}
-
-// constructor
-PIXI.Point.prototype.constructor = PIXI.Point;
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
- *
- * @class Rectangle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the rectangle
- * @param y {Number} The Y coord of the upper-left corner of the rectangle
- * @param width {Number} The overall width of this rectangle
- * @param height {Number} The overall height of this rectangle
- */
-PIXI.Rectangle = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Rectangle
- *
- * @method clone
- * @return {Rectangle} a copy of the rectangle
- */
-PIXI.Rectangle.prototype.clone = function()
-{
- 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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this Rectangle
- */
-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;
-
- if(y >= y1 && y <= y1 + this.height)
- {
- return true;
- }
- }
-
- return false;
-}
-
-// constructor
-PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
-
-
-/**
- * @author Adrien Brault
- */
-
-/**
- * @class Polygon
- * @constructor
- * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
- * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
- * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
- * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
- * Numbers.
- */
-PIXI.Polygon = function(points)
-{
- //if points isn't an array, use arguments as the array
- if(!(points instanceof Array))
- points = Array.prototype.slice.call(arguments);
-
- //if this is a flat array of numbers, convert it to points
- if(typeof points[0] === 'number') {
- var p = [];
- for(var i = 0, il = points.length; i < il; i+=2) {
- p.push(
- new PIXI.Point(points[i], points[i + 1])
- );
- }
-
- points = p;
- }
-
- this.points = points;
-}
-
-/**
- * Creates a clone of this polygon
- *
- * @method clone
- * @return {Polygon} a copy of the polygon
- */
-PIXI.Polygon.prototype.clone = function()
-{
- var points = [];
- for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
-
- if(intersect) inside = !inside;
- }
-
- return inside;
-}
-
-// constructor
-PIXI.Polygon.prototype.constructor = PIXI.Polygon;
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Circle object can be used to specify a hit area for displayobjects
- *
- * @class Circle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Circle = function(x, y, radius)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property radius
- * @type Number
- * @default 0
- */
- this.radius = radius || 0;
-}
-
-/**
- * Creates a clone of this Circle instance
- *
- * @method clone
- * @return {Circle} a copy of the polygon
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
- */
-PIXI.Circle.prototype.contains = function(x, y)
-{
- if(this.radius <= 0)
- return false;
-
- var dx = (this.x - x),
- dy = (this.y - y),
- r2 = this.radius * this.radius;
-
- dx *= dx;
- dy *= dy;
-
- return (dx + dy <= r2);
-}
-
-// constructor
-PIXI.Circle.prototype.constructor = PIXI.Circle;
-
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Ellipse object can be used to specify a hit area for displayobjects
- *
- * @class Ellipse
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
- * @param width {Number} The overall width of this ellipse
- * @param height {Number} The overall height of this ellipse
- */
-PIXI.Ellipse = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Ellipse instance
- *
- * @method clone
- * @return {Ellipse} a copy of the ellipse
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this ellipse
- */
-PIXI.Ellipse.prototype.contains = function(x, y)
-{
- if(this.width <= 0 || this.height <= 0)
- return false;
-
- //normalize the coords to an ellipse with center 0,0
- //and a radius of 0.5
- var normx = ((x - this.x) / this.width) - 0.5,
- normy = ((y - this.y) / this.height) - 0.5;
-
- normx *= normx;
- normy *= normy;
-
- return (normx + normy < 0.25);
-}
-
-PIXI.Ellipse.getBounds = function()
-{
- return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
-}
-
-// constructor
-PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
-
-
-
-/*
- * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
- * you both rock!
- */
-
-function determineMatrixArrayType() {
- PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return PIXI.Matrix;
-}
-
-determineMatrixArrayType();
-
-PIXI.mat3 = {};
-
-PIXI.mat3.create = function()
-{
- 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;
-
- 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;
-
- return matrix;
-}
-
-
-PIXI.mat4 = {};
-
-PIXI.mat4.create = function()
-{
- 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;
-
- return matrix;
-}
-
-PIXI.mat3.multiply = function (mat, mat2, dest)
-{
- 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],
-
- 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[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;
-
- return dest;
-}
-
-PIXI.mat3.clone = function(mat)
-{
- 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];
-
- 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 (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
-}
-
-PIXI.mat3.toMat4 = function (mat, dest)
-{
- if (!dest) { dest = PIXI.mat4.create(); }
-
- 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[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];
-
- return dest;
-}
-
-
-/////
-
-
-PIXI.mat4.create = function()
-{
- 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;
-
- 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];
-
- 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;
-}
-
-PIXI.mat4.multiply = function (mat, mat2, dest)
-{
- 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 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;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The base class for all objects that are rendered on the screen.
- *
- * @class DisplayObject
- * @constructor
- */
-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();
-
- /**
- * 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 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 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 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;
-
- /**
- * [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 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] Current transform of the object based on world (parent) factors
- *
- * @property worldTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.worldTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [read-only] Current transform of the object locally
- *
- * @property localTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.localTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [NYI] Unkown
- *
- * @property color
- * @type Array<>
- * @private
- */
- this.color = [];
-
- /**
- * [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;
-
- /*
- * MOUSE Callbacks
- */
-
- /**
- * 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 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
- * 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 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 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
- */
-
- /**
- * 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 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}
- */
-}
-
-// constructor
-PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
-
-/**
- * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default
- * Instead of using this function you can now simply set the interactive property to true or false
- *
- * @method setInteractive
- * @param interactive {Boolean}
- * @deprecated Simply set the `interactive` property directly
- */
-PIXI.DisplayObject.prototype.setInteractive = function(interactive)
-{
- this.interactive = interactive;
-}
-
-/**
- * Indicates if the sprite will have touch and mouse interactivity. It is false by default
- *
- * @property interactive
- * @type Boolean
- * @default false
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
- get: function() {
- 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;
- }
-});
-
-/**
- * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
- * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
- * To remove a mask, set this property to null.
- *
- * @property mask
- * @type Graphics
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
- get: function() {
- 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;
- }
- }
- else
- {
- this.removeFilter(this._mask);
- this._mask.renderable = true;
- }
-
- this._mask = value;
- }
-});
-
-/**
- * Sets the filters for the displayObject. Currently there's a few limitations.
- * 1: At the moment only one filter can be applied at a time..
- * 2: They cannot be nested.
- * 3: There's no padding yet.
- * 4: this is a webGL only feature.
- * @property filters
- * @type Array
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
- get: function() {
- return this._filters;
- },
- set: function(value) {
-
- //if(value == )
- if(value)
- {
- if(this._filters)this.removeFilter(this._filters);
- this.addFilter(value)
- }
- else
- {
- if(this._filters)this.removeFilter(this._filters);
- }
-
- this._filters = value;
- }
-});
-
-/*
- * Adds a filter to this displayObject
- *
- * @method addFilter
- * @param mask {Graphics} the graphics object to use as a filter
- * @private
- */
-PIXI.DisplayObject.prototype.addFilter = function(data)
-{
- //if(this.filter)return;
- //this.filter = true;
-
- // 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;
-
- /*
- * 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);
- }
-
-}
-
-/*
- * Removes the filter to this displayObject
- *
- * @method removeFilter
- * @private
- */
-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);
- }
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-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;
-
- // 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],
-
- b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
- b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
-
- 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;
-
- worldTransform[3] = b10 * a00 + b11 * a10;
- 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;
-
-}
-
-PIXI.visibleCount = 0;
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * 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
- * @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 = [];
-}
-
-// constructor
-PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-
-/**
- * Adds a child to the container.
- *
- * @method addChild
- * @param child {DisplayObject} The DisplayObject to add to the container
- */
-PIXI.DisplayObjectContainer.prototype.addChild = function(child)
-{
- if(child.parent != undefined)
- {
-
- //// 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;
- }
-
- 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
- *
- * @method addChildAt
- * @param child {DisplayObject} The child to add
- * @param index {Number} The index to place the child in
- */
-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;
-
- 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
- *
- * @method swapChildren
- * @param child {DisplayObject}
- * @param child2 {DisplayObject}
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
-{
- /*
- * this funtion needs to be recoded..
- * can be done a lot faster..
- */
- return;
-
- // need to fix this function :/
- /*
- // TODO I already know this??
- var index = this.children.indexOf( child );
- var index2 = this.children.indexOf( child2 );
-
- if ( index !== -1 && index2 !== -1 )
- {
- // cool
-
- /*
- if(this.stage)
- {
- // this is to satisfy the webGL batching..
- // TODO sure there is a nicer way to achieve this!
- this.stage.__removeChild(child);
- this.stage.__removeChild(child2);
-
- this.stage.__addChild(child);
- this.stage.__addChild(child2);
- }
-
- // swap the positions..
- this.children[index] = child2;
- this.children[index2] = child;
-
- }
- else
- {
- throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
- }*/
-}
-
-/**
- * Returns the Child at the specified index
- *
- * @method getChildAt
- * @param index {Number} The index to get the child from
- */
-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);
- }
-}
-
-/**
- * Removes a child from the container.
- *
- * @method removeChild
- * @param child {DisplayObject} The DisplayObject to remove
- */
-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 tempLast = childFirst._iPrev;
- // need to make sure the parents last is updated too
- var updateLast = this;
- while(updateLast.last == childLast.last)
- {
- 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
- *
- * @method updateTransform
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.updateTransform = function()
-{
- if(!this.visible)return;
-
- PIXI.DisplayObject.prototype.updateTransform.call( this );
-
- for(var i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation
- */
-PIXI.MovieClip = function(textures)
-{
- PIXI.Sprite.call(this, textures[0]);
-
- /**
- * The array of textures that make up the animation
- *
- * @property textures
- * @type Array
- */
- this.textures = textures;
-
- /**
- * The speed that the MovieClip will play at. Higher is faster, lower is slower
- *
- * @property animationSpeed
- * @type Number
- * @default 1
- */
- this.animationSpeed = 1;
-
- /**
- * Whether or not the movie clip repeats after playing.
- *
- * @property loop
- * @type Boolean
- * @default true
- */
- this.loop = true;
-
- /**
- * Function to call when a MovieClip finishes playing
- *
- * @property onComplete
- * @type Function
- */
- this.onComplete = null;
-
- /**
- * [read-only] The index MovieClips current frame (this may not have to be a whole number)
- *
- * @property currentFrame
- * @type Number
- * @default 0
- * @readOnly
- */
- this.currentFrame = 0;
-
- /**
- * [read-only] Indicates if the MovieClip is currently playing
- *
- * @property playing
- * @type Boolean
- * @readOnly
- */
- this.playing = false;
-}
-
-// constructor
-PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
-PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
-
-/**
-* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
-* assigned to the MovieClip.
-*
-* @property totalFrames
-* @type Number
-* @default 0
-* @readOnly
-*/
-Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
- get: function() {
-
- return this.textures.length;
- }
-});
-
-
-/**
- * Stops the MovieClip
- *
- * @method stop
- */
-PIXI.MovieClip.prototype.stop = function()
-{
- this.playing = false;
-}
-
-/**
- * Plays the MovieClip
- *
- * @method play
- */
-PIXI.MovieClip.prototype.play = function()
-{
- this.playing = true;
-}
-
-/**
- * Stops the MovieClip and goes to a specific frame
- *
- * @method gotoAndStop
- * @param frameNumber {Number} frame index to stop at
- */
-PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
-{
- this.playing = false;
- this.currentFrame = frameNumber;
- var round = (this.currentFrame + 0.5) | 0;
- this.setTexture(this.textures[round % this.textures.length]);
-}
-
-/**
- * Goes to a specific frame and begins playing the MovieClip
- *
- * @method gotoAndPlay
- * @param frameNumber {Number} frame index to start at
- */
-PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
-{
- this.currentFrame = frameNumber;
- this.playing = true;
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.MovieClip.prototype.updateTransform = function()
-{
- PIXI.Sprite.prototype.updateTransform.call(this);
-
- if(!this.playing)return;
-
- this.currentFrame += this.animationSpeed;
-
- var round = (this.currentFrame + 0.5) | 0;
-
- 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();
- }
- }
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.FilterBlock = function()
-{
- this.visible = true;
- this.renderable = true;
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.ColorMatrixFilter = function()
-{
- // 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;",
- "}"
- ];
-
-}
-
-
-Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
- get: function() {
- return this.uniforms.matrix.value;
- },
- set: function(value) {
- this.uniforms.matrix.value = value;
- }
-});
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.GreyFilter = function()
-{
- // set the uniforms
- this.uniforms = {
- grey: {type: 'f', value: 1},
- };
-
- this.fragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "uniform float grey;",
- "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), grey);",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
- ];
-
- this.primitiveFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "uniform float grey;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), grey);",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
- ];
-
-}
-
-Object.defineProperty(PIXI.GreyFilter.prototype, 'grey', {
- get: function() {
- return this.uniforms.grey.value;
- },
- set: function(value) {
- this.uniforms.grey.value = value;
- }
-});
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.DisplacementFilter = function(texture)
-{
- // set the uniforms
-
- this.uniforms = {
- displacementMap: {type: 'sampler2D', value:texture},
- scale: {type: 'f2', value:{x:30, y:30}},
- mapDimensions: {type: 'f2', value:{x:texture.width, y:texture.height}}
- };
-
- this.fragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D displacementMap;",
- "uniform sampler2D uSampler;",
- "uniform vec2 scale;",
- "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);",
- "const vec2 textureDimensions = vec2(245.0, 263.0);",
-
- "void main(void) {",
-
- "vec2 matSample = texture2D(displacementMap, vTextureCoord * (textureDimensions/mapDimensions)).xy;",
- "matSample -= 0.5;",
- "matSample *= scale;",
- "matSample /= textureDimensions;",
- "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);",
- "gl_FragColor = gl_FragColor * vColor;",
-
- "}"
- ];
-
-}
-
-Object.defineProperty(PIXI.DisplacementFilter.prototype, 'map', {
- get: function() {
- return this.uniforms.displacementMap.value;
- },
- set: function(value) {
- this.uniforms.displacementMap.value = value;
- }
-});
-
-Object.defineProperty(PIXI.DisplacementFilter.prototype, 'scale', {
- get: function() {
- return this.uniforms.scale.value;
- },
- set: function(value) {
- this.uniforms.scale.value = value;
- }
-});
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.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");
- PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
-
- this.setText(text);
- this.setStyle(style);
-
- this.updateText();
- this.dirty = false;
-};
-
-// constructor
-PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype);
-PIXI.Text.prototype.constructor = PIXI.Text;
-
-/**
- * Set the style of the 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.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.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.strokeThickness = style.strokeThickness || 0;
- style.wordWrap = style.wordWrap || false;
- style.wordWrapWidth = style.wordWrapWidth || 100;
- this.style = style;
- this.dirty = true;
-};
-
-/**
- * Set the copy for the text object. To split a line you can use "\n"
- *
- * @methos 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.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.Text.prototype.updateText = function()
-{
- this.context.font = this.style.font;
-
- var outputText = 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)/);
-
- //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;
-
- //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.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);
-
- 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.fill)
- {
- this.context.fillText(lines[i], linePosition.x, linePosition.y);
- }
- }
-
- this.updateTexture();
-};
-
-/**
- * Updates texture size based on canvas size
- *
- * @method updateTexture
- * @private
- */
-PIXI.Text.prototype.updateTexture = function()
-{
- this.texture.baseTexture.width = this.canvas.width;
- this.texture.baseTexture.height = this.canvas.height;
- this.texture.frame.width = this.canvas.width;
- this.texture.frame.height = this.canvas.height;
-
- this._width = this.canvas.width;
- this._height = this.canvas.height;
-
- PIXI.texturesToUpdate.push(this.texture.baseTexture);
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.Text.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- this.updateText();
- this.dirty = false;
- }
-
- PIXI.Sprite.prototype.updateTransform.call(this);
-};
-
-/*
- * http://stackoverflow.com/users/34441/ellisbben
- * great solution to the problem!
- *
- * @method determineFontHeight
- * @param fontStyle {Object}
- * @private
- */
-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];
-
- 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;
-
- body.removeChild(dummy);
- }
-
- return result;
-};
-
-/**
- * A Text Object will apply wordwrap
- *
- * @method wordWrap
- * @param text {String}
- * @private
- */
-PIXI.Text.prototype.wordWrap = function(text)
-{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
- var result = "";
- var lines = text.split("\n");
- for (var i = 0; i < lines.length; i++)
- {
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
- }
-
- return result;
-};
-
-/**
- * Destroys this text object
- *
- * @method destroy
- * @param destroyTexture {Boolean}
- */
-PIXI.Text.prototype.destroy = function(destroyTexture)
-{
- if(destroyTexture)
- {
- this.texture.destroy();
- }
-
-};
-
-PIXI.Text.heightCache = {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.
- *
- * @class BitmapText
- * @extends DisplayObjectContainer
- * @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")
- */
-PIXI.BitmapText = function(text, style)
-{
- PIXI.DisplayObjectContainer.call(this);
-
- this.setText(text);
- this.setStyle(style);
- this.updateText();
- this.dirty = false
-
-};
-
-// constructor
-PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
-
-/**
- * Set the copy for the text object
- *
- * @method setText
- * @param text {String} The copy that you would like the text to display
- */
-PIXI.BitmapText.prototype.setText = function(text)
-{
- this.text = text || " ";
- this.dirty = true;
-};
-
-/**
- * Set the style of the 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")
- */
-PIXI.BitmapText.prototype.setStyle = function(style)
-{
- style = style || {};
- style.align = style.align || "left";
- this.style = style;
-
- 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;
-
- this.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.BitmapText.prototype.updateText = function()
-{
- var data = PIXI.BitmapText.fonts[this.fontName];
- var pos = new PIXI.Point();
- var prevCharCode = null;
- var chars = [];
- var maxLineWidth = 0;
- var lineWidths = [];
- var line = 0;
- var scale = this.fontSize / data.size;
- for(var i = 0; i < this.text.length; i++)
- {
- var charCode = this.text.charCodeAt(i);
- if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
- {
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
- line++;
-
- pos.x = 0;
- pos.y += data.lineHeight;
- prevCharCode = null;
- continue;
- }
-
- var charData = data.chars[charCode];
- if(!charData) continue;
-
- if(prevCharCode && charData[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;
-
- prevCharCode = charCode;
- }
-
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
-
- var lineAlignOffsets = [];
- for(i = 0; i <= line; i++)
- {
- var alignOffset = 0;
- if(this.style.align == "right")
- {
- alignOffset = maxLineWidth - lineWidths[i];
- }
- else if(this.style.align == "center")
- {
- alignOffset = (maxLineWidth - lineWidths[i]) / 2;
- }
- lineAlignOffsets.push(alignOffset);
- }
-
- for(i = 0; i < chars.length; i++)
- {
- 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;
- this.addChild(c);
- }
-
- this.width = pos.x * scale;
- this.height = (pos.y + data.lineHeight) * scale;
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.BitmapText.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- while(this.children.length > 0)
- {
- this.removeChild(this.getChildAt(0));
- }
- this.updateText();
-
- this.dirty = false;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
-};
-
-PIXI.BitmapText.fonts = {};
-
-/**
- * @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.
- *
- * @class InteractionManager
- * @constructor
- * @param stage {Stage} The stage to handle interactions
- */
-PIXI.InteractionManager = function(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();
-
- /**
- * 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();
-
- this.mouseoverEnabled = true;
-
- //tiny little interactiveData pool!
- this.pool = [];
-
- 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.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;
-
-/**
- * Collects an interactive sprite recursively to have their interactions managed
- *
- * @method collectInteractiveSprite
- * @param displayObject {DisplayObject} the displayObject to collect
- * @param iParent {DisplayObject}
- * @private
- */
-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);
-
- 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
- *
- * @method setTarget
- * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to
- * @private
- */
-PIXI.InteractionManager.prototype.setTarget = function(target)
-{
- this.target = target;
-
- //check if the dom element has been set. If it has don't do anything
- if( this.interactionDOMElement === null ) {
-
- this.setTargetDomElement( target.view );
- }
-
- document.body.addEventListener('mouseup', this.onMouseUp, true);
-}
-
-
-/**
- * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
- * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
- * to receive those events
- *
- * @method setTargetDomElement
- * @param domElement {DOMElement} the dom element which will receive mouse and touch events
- * @private
- */
-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'] = '';
-
- 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);
- }
-
-
- 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!
- }
-
- this.interactionDOMElement = domElement;
-
- 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
- *
- * @method update
- * @private
- */
-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 = "default";
-
- 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 = "pointer";
-
- 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
- *
- * @method onMouseMove
- * @param event {Event} The DOM event of the mouse moving
- * @private
- */
-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);
- }
- }
-}
-
-/**
- * Is called when the mouse button is pressed down on the renderer element
- *
- * @method onMouseDown
- * @param event {Event} The DOM event of a mouse button being pressed down
- * @private
- */
-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;
- }
- }
- }
-}
-
-
-PIXI.InteractionManager.prototype.onMouseOut = function(event)
-{
- var length = this.interactiveItems.length;
-
- this.interactionDOMElement.style.cursor = "default";
-
- 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
- *
- * @method onMouseUp
- * @param event {Event} The DOM event of a mouse button being released
- * @private
- */
-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;
- }
- }
-}
-
-/**
- * Tests if the current mouse coords hit a sprite
- *
- * @method hitTest
- * @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
- * @private
- */
-PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
-{
- var global = interactionData.global;
-
- if(item.vcount !== PIXI.visibleCount)return false;
-
- 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;
-
- 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;
-
- 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
- *
- * @method onTouchMove
- * @param event {Event} The DOM event of a touch moving accross the renderer view
- * @private
- */
-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);
- }
-}
-
-/**
- * Is called when a touch is started on the renderer element
- *
- * @method onTouchStart
- * @param event {Event} The DOM event of a touch starting on the renderer view
- * @private
- */
-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;
- }
- }
- }
- }
-}
-
-/**
- * Is called when a touch is ended on the renderer element
- *
- * @method onTouchEnd
- * @param event {Event} The DOM event of a touch ending on the renderer view
- * @private
- */
-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;
- }
-}
-
-/**
- * Holds all information related to an Interaction event
- *
- * @class InteractionData
- * @constructor
- */
-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();
-
- /**
- * The target Sprite that was interacted with
- *
- * @property target
- * @type Sprite
- */
- this.target;
-
- /**
- * When passed to an event handler, this will be the original DOM Event that was captured
- *
- * @property originalEvent
- * @type Event
- */
- this.originalEvent;
-}
-
-/**
- * This will return the local coords of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
- */
-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],
- 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)
-}
-
-// constructor
-PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A Stage represents the root of the display tree. Everything connected to the stage is rendered
- *
- * @class Stage
- * @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
- */
-PIXI.Stage = function(backgroundColor)
-{
- 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();
-
- /**
- * 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);
-
- /**
- * Whether the stage is dirty and needs to have interactions updated
- *
- * @property dirty
- * @type Boolean
- * @private
- */
- this.dirty = true;
-
- this.__childrenAdded = [];
- this.__childrenRemoved = [];
-
- //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);
-
- this.setBackgroundColor(backgroundColor);
- this.worldVisible = true;
-}
-
-// constructor
-PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Stage.prototype.constructor = PIXI.Stage;
-
-/**
- * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
- * This is useful for when you have other DOM elements ontop of the Canvas element.
- *
- * @method setInteractionDelegate
- * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
- */
-PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
-{
- this.interactionManager.setTargetDomElement( domElement );
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.Stage.prototype.updateTransform = function()
-{
- this.worldAlpha = 1;
- this.vcount = PIXI.visibleCount;
-
- for(var i=0,j=this.children.length; i> 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 target != 'function') throw new TypeError();
-
- 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);
-
- return bound;
- };
- })();
-}
-
-/**
- * A wrapper for ajax requests to be handled cross browser
- *
- * @class AjaxRequest
- * @constructor
- */
-var AjaxRequest = PIXI.AjaxRequest = function()
-{
- 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);
-
- while(tmp._iNext)
- {
- safe++;
- tmp = tmp._iNext;
- console.log(tmp);
- // console.log(tmp);
-
- if(safe > 100)
- {
- console.log("BREAK")
- break
- }
- }
-}
-
-
-
-
-
-
-/**
- * https://github.com/mrdoob/eventtarget.js/
- * THankS mr DOob!
- */
-
-/**
- * Adds event emitter functionality to a class
- *
- * @class EventTarget
- * @example
- * function MyEmitter() {
- * PIXI.EventTarget.call(this); //mixes in event target stuff
- * }
- *
- * var em = new MyEmitter();
- * em.emit({ type: 'eventName', data: 'some data' });
- */
-PIXI.EventTarget = function () {
-
- var listeners = {};
-
- this.addEventListener = this.on = function ( type, listener ) {
-
-
- if ( listeners[ type ] === undefined ) {
-
- listeners[ type ] = [];
-
- }
-
- if ( listeners[ type ].indexOf( listener ) === - 1 ) {
-
- listeners[ type ].push( listener );
- }
-
- };
-
- this.dispatchEvent = this.emit = function ( event ) {
-
- if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
-
- return;
-
- }
-
- for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
-
- listeners[ event.type ][ i ]( event );
-
- }
-
- };
-
- this.removeEventListener = this.off = function ( type, listener ) {
-
- var index = listeners[ type ].indexOf( listener );
-
- if ( index !== - 1 ) {
-
- listeners[ type ].splice( index, 1 );
-
- }
-
- };
-
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * This helper function will automatically detect which renderer you should be using.
- * WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
- * the browser then this function will return a canvas renderer
- *
- * @method autoDetectRenderer
- * @static
- * @param width {Number} the width of the renderers view
- * @param height {Number} the height of the renderers view
- * @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 webGL chrome at the moment)
- *
- * antialias
- */
-PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
-{
- 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; } } )();
-
- if(webgl)
- {
- var ie = (navigator.userAgent.toLowerCase().indexOf('msie') != -1);
- webgl = !ie;
- }
-
- //console.log(webgl);
- if( webgl )
- {
- return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
- }
-
- return new PIXI.CanvasRenderer(width, height, view, transparent);
-};
-
-
-
-/*
- PolyK library
- url: http://polyk.ivank.net
- Released under MIT licence.
-
- 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:
-
- 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.
-
- This is an amazing lib!
-
- slightly modified by mat groves (matgroves.com);
-*/
-
-PIXI.PolyK = {};
-
-/**
- * Triangulates shapes for webGL graphic fills
- *
- * @method Triangulate
- * @namespace PolyK
- * @constructor
- */
-PIXI.PolyK.Triangulate = function(p)
-{
- var sign = true;
-
- var n = p.length>>1;
- if(n<3) return [];
- var tgs = [];
- var avl = [];
- for(var i=0; i 3)
- {
- var i0 = avl[(i+0)%al];
- var i1 = avl[(i+1)%al];
- var i2 = avl[(i+2)%al];
-
- 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];
-
- 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= 0) && (v >= 0) && (u + v < 1);
-}
-
-/**
- * Checks if a shape is convex
- *
- * @class _convex
- * @namespace PolyK
- * @private
- */
-PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
-{
- return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/*
- * the default suoer fast shader!
- */
-
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
-
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
-
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * the triangle strip shader..
- */
-
-PIXI.stripShaderFragmentSrc = [
- "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;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.shaderStack = [];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
-
- //gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-//gl.enableVertexAttribArray(program.textureCoordAttribute);
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-
-
-}
-
-PIXI.initDefaultShader = function()
-{
- PIXI.defaultShader = new PIXI.PixiShader();
- PIXI.defaultShader.init();
- PIXI.pushShader(PIXI.defaultShader);
- /*
- PIXI.shaderStack.push(PIXI.defaultShader);
- PIXI.current*/
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
-
-PIXI.CompileVertexShader = function(gl, shaderSrc)
-{
- return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
-}
-
-PIXI.CompileFragmentShader = function(gl, shaderSrc)
-{
- 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);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(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();
-
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
-
- return shaderProgram;
-}
-
-PIXI.pushShader = function(shader)
-{
- PIXI.shaderStack.push(shader);
-
- var gl = PIXI.gl;
-
- var shaderProgram = shader.program;
-
-
- // map uniforms..
- gl.useProgram(shaderProgram);
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
-
- shader.syncUniforms();
-
- PIXI.currentShader = shaderProgram;
-}
-
-
-PIXI.popShader = function()
-{
- var gl = PIXI.gl;
- var lastProgram = PIXI.shaderStack.pop();
-
- var shaderProgram = PIXI.shaderStack[ PIXI.shaderStack.length-1 ].program;
-
- gl.useProgram(shaderProgram);
-
- PIXI.currentShader = shaderProgram;
-}
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.primitiveProgram);
- gl.disableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
-}
-
-PIXI.deactivatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.currentShader);
- gl.enableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-PIXI.PixiShader = function()
-{
- // the webGL program..
- this.program;
-
- this.fragmentSrc = [
- "precision lowp float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
- "}"
- ];
-
-}
-
-PIXI.PixiShader.prototype.init = function()
-{
- var program = PIXI.compileProgram(this.vertexSrc || PIXI.shaderVertexSrc, this.fragmentSrc)
-
- var gl = PIXI.gl;
-
- gl.useProgram(program);
-
- // get the default shader bits!
- program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
- program.colorAttribute = gl.getAttribLocation(program, "aColor");
- program.textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
-
- program.projectionVector = gl.getUniformLocation(program, "projectionVector");
- program.samplerUniform = gl.getUniformLocation(program, "uSampler");
-
- // add those custom shaders!
- for (var key in this.uniforms)
- {
- // get the uniform locations..
- program[key] = gl.getUniformLocation(program, key);
- }
-
- this.program = program;
-}
-
-PIXI.PixiShader.prototype.syncUniforms = function()
-{
- var gl = PIXI.gl;
-
- for (var key in this.uniforms)
- {
- //var
- var type = this.uniforms[key].type;
-
- // need to grow this!
- if(type == "f")
- {
- gl.uniform1f(this.program[key], this.uniforms[key].value);
- }
- if(type == "f2")
- {
- gl.uniform2f(this.program[key], this.uniforms[key].value.x, this.uniforms[key].value.y);
- }
- else if(type == "mat4")
- {
- gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- }
- else if(type == "sampler2D")
- {
- // first texture...
- var texture = this.uniforms[key].value;
-
- gl.activeTexture(gl.TEXTURE1);
- gl.bindTexture(gl.TEXTURE_2D, texture.baseTexture._glTexture);
-
- gl.uniform1i(this.program[key], 1);
-
-
- // activate texture..
- // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- }
- }
-
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A set of functions used by the webGL renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.WebGLGraphics = function()
-{
-
-}
-
-/**
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param projection {Object}
- */
-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);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
-
- // WHY DOES THIS LINE NEED TO BE THERE???
- //gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.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
- *
- * @static
- * @private
- * @method updateGraphics
- * @param graphics {Graphics}
- */
-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;
-
- 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
- *
- * @static
- * @private
- * @method buildRectangle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- }
-
-}
-
-/**
- * Builds a circle to draw
- *
- * @static
- * @private
- * @method buildCircle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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;
-
- 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);
- }
-
-}
-
-/**
- * Builds a line to draw
- *
- * @static
- * @private
- * @method buildLine
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
-{
- // TODO OPTIMISE!
-
- var wrap = true;
- var points = graphicsData.points;
- if(points.length == 0)return;
-
- // 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;
-
- 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 (denom == 0) {
- denom+=1;
- }
-
- 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 (var i=0; i < indexCount; i++)
- {
- indices.push(indexStart++);
- };
-
- indices.push(indexStart-1);
-}
-
-/**
- * Builds a polygon to draw
- *
- * @static
- * @private
- * @method buildPoly
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- };
-}
-
-function HEXtoRGB(hex) {
- return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
-
-// an instance of the gl context..
-// only one at the moment :/
-PIXI.gl;
-
-/**
- * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
- * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
- * So no need for Sprite Batch's or Sprite Cloud's
- * Dont forget to add the view to your DOM or you will not see anything :)
- *
- * @class WebGLRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @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..
-
- this.transparent = !!transparent;
-
- this.width = width || 800;
- this.height = height || 600;
-
- this.view = view || document.createElement( 'canvas' );
- this.view.width = this.width;
- this.view.height = this.height;
-
- // 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.batchs = [];
-
- 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);
- }
- }
-
- PIXI.initDefaultShader();
- PIXI.initPrimitiveShader();
- PIXI.initDefaultStripShader();
-
-
-// PIXI.activateDefaultShader();
-
- var gl = this.gl;
- PIXI.WebGLRenderer.gl = gl;
-
- this.batch = new PIXI.WebGLBatch(gl);
- gl.disable(gl.DEPTH_TEST);
- gl.disable(gl.CULL_FACE);
-
- gl.enable(gl.BLEND);
- gl.colorMask(true, true, true, this.transparent);
-
- PIXI.projection = new PIXI.Point(400, 300);
-
- this.resize(this.width, this.height);
- this.contextLost = false;
-
- PIXI.pushShader(PIXI.defaultShader);
-
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
-
-}
-
-// constructor
-PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
-
-/**
- * Gets a new WebGLBatch from the pool
- *
- * @static
- * @method getBatch
- * @return {WebGLBatch}
- * @private
- */
-PIXI.WebGLRenderer.getBatch = function()
-{
- if(PIXI._batchs.length == 0)
- {
- return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
- }
- else
- {
- return PIXI._batchs.pop();
- }
-}
-
-/**
- * Puts a batch back into the pool
- *
- * @static
- * @method returnBatch
- * @param batch {WebGLBatch} The batch to return
- * @private
- */
-PIXI.WebGLRenderer.returnBatch = function(batch)
-{
- batch.clean();
- PIXI._batchs.push(batch);
-}
-
-/**
- * Renders the stage to its webGL view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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);
- }
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
-
- // 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;
- 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
- *
- * @static
- * @method updateTextures
- * @private
- */
-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 = [];
-}
-
-/**
- * Updates a loaded webgl texture
- *
- * @static
- * @method updateTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.updateTexture = function(texture)
-{
- //TODO break this out into a texture manager...
- var gl = PIXI.gl;
-
- if(!texture._glTexture)
- {
- texture._glTexture = gl.createTexture();
- }
-
- if(texture.hasLoaded)
- {
- gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
-
- 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);
-
- // reguler...
-
- 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
- *
- * @method destroyTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.destroyTexture = function(texture)
-{
- //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);
- }
-}
-
-/**
- * resizes the webGL view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the webGL view
- * @param height {Number} the new height of the webGL view
- */
-PIXI.WebGLRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-
- this.gl.viewport(0, 0, this.width, this.height);
-
- //var projectionMatrix = this.projectionMatrix;
-
- 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;
-}
-
-/**
- * Handles a lost webgl context
- *
- * @method handleContextLost
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
-{
- event.preventDefault();
- this.contextLost = true;
-}
-
-/**
- * Handles a restored webgl context
- *
- * @method handleContextRestored
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
-{
- this.gl = this.view.getContext("experimental-webgl", {
- alpha: true
- });
-
- this.initShaders();
-
- 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;
- };
-
- PIXI._restoreBatchs(this.gl);
-
- this.contextLost = false;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._batchs = [];
-
-/**
- * @private
- */
-PIXI._getBatch = function(gl)
-{
- 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);
-}
-
-/**
- * @private
- */
-PIXI._restoreBatchs = function(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.
- * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
- * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
- * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
- * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @constructor
- * @param gl {WebGLContext} an instance of the webGL context
- */
-PIXI.WebGLBatch = function(gl)
-{
- this.gl = gl;
-
- 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;
-
-/**
- * Cleans the batch so that is can be returned to an object pool and reused
- *
- * @method clean
- */
-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;
-}
-
-/**
- * Recreates the buffers in the event of a context loss
- *
- * @method restoreLostContext
- * @param gl {WebGLContext}
- */
-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();
-}
-
-/**
- * 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
- */
-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;
-
- this.growBatch();
-}
-
-/**
- * inserts a sprite before the specified 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++;
-
- 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;
- }
-}
-
-/**
- * inserts a sprite after the specified sprite
- *
- * @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++;
-
- sprite.batch = this;
- this.dirty = true;
-
- var tempNext = previousSprite.__next;
- previousSprite.__next = sprite;
- sprite.__prev = previousSprite;
-
- 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--;
-
- 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.__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;
-}
-
-/**
- * Splits the batch into two with the specified sprite being the start of the new batch.
- *
- * @method split
- * @param sprite {Sprite} the sprite that indicates where the batch should be split
- * @return {WebGLBatch} the new batch
- */
-PIXI.WebGLBatch.prototype.split = function(sprite)
-{
- this.dirty = true;
-
- 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;
-
- 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"?
-
- // 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;
-
- return batch;
-}
-
-/**
- * Merges two batchs together
- *
- * @method merge
- * @param batch {WebGLBatch} the batch that will be merged
- */
-PIXI.WebGLBatch.prototype.merge = function(batch)
-{
- this.dirty = true;
-
- this.tail.__next = batch.head;
- batch.head.__prev = this.tail;
-
- this.size += batch.size;
-
- this.tail = batch.tail;
-
- 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
- * function is used to increase the size of the batch. It also creates a little extra room so
- * that the batch does not need to be resized every time a sprite is added
- *
- * @method growBatch
- */
-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);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
-
- 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.dirtyUVS = 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.dirtyColors = true;
-
- this.indices = new Uint16Array(this.dynamicSize * 6);
- var length = this.indices.length/6;
-
- 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
- *
- * @method refresh
- */
-PIXI.WebGLBatch.prototype.refresh = function()
-{
- var gl = this.gl;
-
- if (this.dynamicSize < this.size)
- {
- this.growBatch();
- }
-
- 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;
-
- while(displayObject)
- {
- index = indexRun * 8;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
-
- colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
-
- displayObject = displayObject.__next;
-
- indexRun ++;
- }
-
- this.dirtyUVS = true;
- this.dirtyColors = true;
-}
-
-/**
- * Updates all the relevant geometry and uploads the data to the GPU
- *
- * @method update
- */
-PIXI.WebGLBatch.prototype.update = function()
-{
- var gl = this.gl;
- var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3
-
- var a, b, c, d, tx, ty;
-
- 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;
-
- // 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;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- index = indexRun * 8;
-
- worldTransform = displayObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- verticies[index + 0 ] = a * w1 + c * h1 + tx;
- verticies[index + 1 ] = d * h1 + b * w1 + ty;
-
- verticies[index + 2 ] = a * w0 + c * h1 + tx;
- verticies[index + 3 ] = d * h1 + b * w0 + ty;
-
- verticies[index + 4 ] = a * w0 + c * h0 + tx;
- verticies[index + 5 ] = d * h0 + b * w0 + ty;
-
- verticies[index + 6] = a * w1 + c * h0 + tx;
- verticies[index + 7] = d * h0 + b * w1 + ty;
-
- if(displayObject.updateFrame || displayObject.texture.updateFrame)
- {
- this.dirtyUVS = true;
-
- var texture = displayObject.texture;
-
- var frame = texture.frame;
- var tw = texture.baseTexture.width;
- var th = texture.baseTexture.height;
-
- uvs[index + 0] = frame.x / tw;
- uvs[index +1] = frame.y / th;
-
- uvs[index +2] = (frame.x + frame.width) / tw;
- uvs[index +3] = frame.y / th;
-
- uvs[index +4] = (frame.x + frame.width) / tw;
- uvs[index +5] = (frame.y + frame.height) / th;
-
- uvs[index +6] = frame.x / tw;
- uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
- }
-
- // TODO this probably could do with some optimisation....
- if(displayObject.cacheAlpha != displayObject.worldAlpha)
- {
- displayObject.cacheAlpha = displayObject.worldAlpha;
-
- var colorIndex = indexRun * 4;
- colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha;
- this.dirtyColors = true;
- }
- }
- else
- {
- index = indexRun * 8;
-
- 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
- *
- * @method render
- */
-PIXI.WebGLBatch.prototype.render = function(start, end)
-{
- start = start || 0;
-
- if(end == undefined)end = this.size;
-
- if(this.dirty)
- {
- this.refresh();
- this.dirty = false;
- }
-
- if (this.size == 0)return;
-
- this.update();
- var gl = this.gl;
-
- //TODO optimize this!
-
- var shaderProgram = PIXI.currentShader;
-
- //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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // update the uvs
- //var isDefault = (shaderProgram == PIXI.shaderProgram)
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
-
- if(this.dirtyUVS)
- {
- this.dirtyUVS = false;
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
- }
-
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
-
- // update color!
- gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
-
- if(this.dirtyColors)
- {
- 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!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
-
- var len = end - start;
-
- // DRAW THAT this!
- gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
- * if a group of sprites all have the same baseTexture and blendMode then they can be
- * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
- * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
- * even if the batch only contains one sprite. Batching is handled automatically by the
- * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @contructor
- * @param gl {WebGLContext} An instance of the webGL context
- */
-PIXI.WebGLRenderGroup = function(gl)
-{
- this.gl = gl;
- this.root;
-
- this.backgroundColor;
- this.batchs = [];
- this.toRemove = [];
-}
-
-// constructor
-PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
-
-/**
- * Add a display object to the webgl renderer
- *
- * @method setRenderable
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
-{
- // has this changed??
- if(this.root)this.removeDisplayObjectAndChildren(this.root);
-
- displayObject.worldVisible = displayObject.visible;
-
- // soooooo //
- // to check if any batchs exist already??
-
- // TODO what if its already has an object? should remove it
- this.root = displayObject;
- this.addDisplayObjectAndChildren(displayObject);
-}
-
-/**
- * Renders the stage to its webgl view
- *
- * @method render
- * @param projection {Object}
- */
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
-
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- // will render all the elements in the group
- var renderable;
- for (var i=0; i < this.batchs.length; i++)
- {
-
- renderable = this.batchs[i];
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- continue;
- }
-
- // non sprite batch..
- var worldVisible = renderable.vcount === PIXI.visibleCount;
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
- }
-
-}
-
-/**
- * Renders a specific displayObject
- *
- * @method renderSpecific
- * @param displayObject {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- // to do!
- // render part of the scene...
-
- var startIndex;
- var startBatchIndex;
-
- var endIndex;
- var endBatchIndex;
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.first;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
- var startBatch = nextRenderable.batch;
-
- if(nextRenderable instanceof PIXI.Sprite)
- {
- startBatch = nextRenderable.batch;
-
- var head = startBatch.head;
- var next = head;
-
- // ok now we have the batch.. need to find the start index!
- if(head == nextRenderable)
- {
- startIndex = 0;
- }
- else
- {
- startIndex = 1;
-
- while(head.__next != nextRenderable)
- {
- startIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- startBatch = nextRenderable;
- }
-
- // Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
- {
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem.last;
- }
-
- if(lastRenderable instanceof PIXI.Sprite)
- {
- endBatch = lastRenderable.batch;
-
- var head = endBatch.head;
-
- if(head == lastRenderable)
- {
- endIndex = 0;
- }
- else
- {
- endIndex = 1;
-
- while(head.__next != lastRenderable)
- {
- endIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- endBatch = lastRenderable;
- }
-
- // TODO - need to fold this up a bit!
-
- if(startBatch == endBatch)
- {
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex, endIndex+1);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
- return;
- }
-
- // now we have first and last!
- startBatchIndex = this.batchs.indexOf(startBatch);
- endBatchIndex = this.batchs.indexOf(endBatch);
-
- // DO the first batch
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
-
- // DO the middle batchs..
- for (var i=startBatchIndex+1; i < endBatchIndex; i++)
- {
- renderable = this.batchs[i];
-
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- }
- else
- {
- this.renderSpecial(renderable, projection);
- }
- }
-
- // DO the last batch..
- if(endBatch instanceof PIXI.WebGLBatch)
- {
- endBatch.render(0, endIndex+1);
- }
- else
- {
- this.renderSpecial(endBatch, projection);
- }
-}
-
-/**
- * Renders a specific renderable
- *
- * @method renderSpecial
- * @param renderable {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
-{
- var sta = PIXI.shaderStack.length;
-
- var worldVisible = renderable.vcount === PIXI.visibleCount
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.CustomRenderable)
- {
- if(worldVisible) renderable.renderWebGL(this, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
-}
-
-PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection)
-{
- /*
- * for now only masks are supported..
- */
- var gl = PIXI.gl;
-
- if(renderable.open)
- {
- if(renderable.data instanceof Array)
- {
- var filter = renderable.data[0];
-
- if(!filter.shader)
- {
- var shader = new PIXI.PixiShader();
-
- shader.fragmentSrc = filter.fragmentSrc;
- shader.uniforms = filter.uniforms;
- shader.init();
-
- filter.shader = shader
- }
-
- PIXI.pushShader(filter.shader);
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
- PIXI.WebGLGraphics.renderGraphics(renderable.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- }
- else
- {
- if(renderable.data instanceof Array)
- {
- PIXI.popShader();
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
-}
-
-/**
- * Updates a webgl texture
- *
- * @method updateTexture
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
-{
-
- // TODO definitely can optimse this function..
-
- this.removeObject(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- this.insertObject(displayObject, previousRenderable, nextRenderable);
-}
-
-/**
- * Adds filter blocks
- *
- * @method addFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
-{
- start.__renderGroup = this;
- end.__renderGroup = this;
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = start;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
- this.insertAfter(start, previousRenderable);
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var previousRenderable2 = end;
- while(previousRenderable2 != this.root.first)
- {
- previousRenderable2 = previousRenderable2._iPrev;
- if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
- }
- this.insertAfter(end, previousRenderable2);
-}
-
-/**
- * Remove filter blocks
- *
- * @method removeFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
-{
- this.removeObject(start);
- this.removeObject(end);
-}
-
-/**
- * Adds a display object and children to the webgl context
- *
- * @method addDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
-
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- // one the display object hits this. we can break the loop
-
- var tempObject = displayObject.first;
- var testObject = displayObject.last._iNext;
- do
- {
- tempObject.__renderGroup = this;
-
- if(tempObject.renderable)
- {
-
- this.insertObject(tempObject, previousRenderable, nextRenderable);
- previousRenderable = tempObject;
- }
-
- tempObject = tempObject._iNext;
- }
- while(tempObject != testObject)
-}
-
-/**
- * Removes a display object and children to the webgl context
- *
- * @method removeDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup != this)return;
-
-// var displayObject = displayObject.first;
- var lastObject = displayObject.last;
- do
- {
- displayObject.__renderGroup = null;
- if(displayObject.renderable)this.removeObject(displayObject);
- displayObject = displayObject._iNext;
- }
- while(displayObject)
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertObject
- * @param displayObject {DisplayObject}
- * @param previousObject {DisplayObject}
- * @param nextObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
-{
- // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
- var previousSprite = previousObject;
- var nextSprite = nextObject;
-
- /*
- * so now we have the next renderable and the previous renderable
- *
- */
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch
- var nextBatch
-
- if(previousSprite instanceof PIXI.Sprite)
- {
- previousBatch = previousSprite.batch;
- if(previousBatch)
- {
- if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
- {
- previousBatch.insertAfter(displayObject, previousSprite);
- return;
- }
- }
- }
- else
- {
- // TODO reword!
- previousBatch = previousSprite;
- }
-
- if(nextSprite)
- {
- if(nextSprite instanceof PIXI.Sprite)
- {
- nextBatch = nextSprite.batch;
-
- //batch may not exist if item was added to the display list but not to the webGL
- if(nextBatch)
- {
- if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
- {
- nextBatch.insertBefore(displayObject, nextSprite);
- return;
- }
- else
- {
- if(nextBatch == previousBatch)
- {
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(nextSprite);
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var batch = PIXI.WebGLRenderer.getBatch();
-
- var index = this.batchs.indexOf( previousBatch );
- batch.init(displayObject);
- this.batchs.splice(index+1, 0, batch, splitBatch);
-
- return;
- }
- }
- }
- }
- else
- {
- // TODO re-word!
-
- nextBatch = nextSprite;
- }
- }
-
- /*
- * looks like it does not belong to any batch!
- * but is also not intersecting one..
- * time to create anew one!
- */
-
- var batch = PIXI.WebGLRenderer.getBatch();
- batch.init(displayObject);
-
- if(previousBatch) // if this is invalid it means
- {
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, batch);
- }
- else
- {
- this.batchs.push(batch);
- }
-
- return;
- }
- else if(displayObject instanceof PIXI.TilingSprite)
- {
-
- // add to a batch!!
- this.initTilingSprite(displayObject);
- // this.batchs.push(displayObject);
-
- }
- else if(displayObject instanceof PIXI.Strip)
- {
- // add to a batch!!
- this.initStrip(displayObject);
- // this.batchs.push(displayObject);
- }
- else if(displayObject)// instanceof PIXI.Graphics)
- {
- //displayObject.initWebGL(this);
-
- // add to a batch!!
- //this.initStrip(displayObject);
- //this.batchs.push(displayObject);
- }
-
- this.insertAfter(displayObject, previousSprite);
-
- // insert and SPLIT!
-
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertAfter
- * @param item {DisplayObject}
- * @param displayObject {DisplayObject} The object to insert
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
-{
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch = displayObject.batch;
-
- if(previousBatch)
- {
- // so this object is in a batch!
-
- // is it not? need to split the batch
- if(previousBatch.tail == displayObject)
- {
- // is it tail? insert in to batchs
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item);
- }
- else
- {
- // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
-
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(displayObject.__next);
-
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item, splitBatch);
- }
- }
- else
- {
- this.batchs.push(item);
- }
- }
- else
- {
- var index = this.batchs.indexOf( displayObject );
- this.batchs.splice(index+1, 0, item);
- }
-}
-
-/**
- * Removes a displayObject from the linked list
- *
- * @method removeObject
- * @param displayObject {DisplayObject} The object to remove
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
-{
- // loop through children..
- // display object //
-
- // add a child from the render group..
- // remove it and all its children!
- //displayObject.cacheVisible = false;//displayObject.visible;
-
- /*
- * removing is a lot quicker..
- *
- */
- var batchToRemove;
-
- if(displayObject instanceof PIXI.Sprite)
- {
- // should always have a batch!
- var batch = displayObject.batch;
- if(!batch)return; // this means the display list has been altered befre rendering
-
- batch.remove(displayObject);
-
- if(batch.size==0)
- {
- batchToRemove = batch;
- }
- }
- else
- {
- batchToRemove = displayObject;
- }
-
- /*
- * Looks like there is somthing that needs removing!
- */
- if(batchToRemove)
- {
- var index = this.batchs.indexOf( batchToRemove );
- if(index == -1)return;// this means it was added then removed before rendered
-
- // ok so.. check to see if you adjacent batchs should be joined.
- // TODO may optimise?
- if(index == 0 || index == this.batchs.length-1)
- {
- // wha - eva! just get of the empty batch!
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
-
- return;
- }
-
- if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
- {
- if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
- {
- //console.log("MERGE")
- this.batchs[index-1].merge(this.batchs[index+1]);
-
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
- this.batchs.splice(index, 2);
- return;
- }
- }
-
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- }
-}
-
-
-/**
- * Initializes a tiling sprite
- *
- * @method initTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
-{
- var gl = this.gl;
-
- // make the texture tilable..
-
- sprite.verticies = new Float32Array([0, 0,
- sprite.width, 0,
- sprite.width, sprite.height,
- 0, sprite.height]);
-
- sprite.uvs = new Float32Array([0, 0,
- 1, 0,
- 1, 1,
- 0, 1]);
-
- sprite.colors = new Float32Array([1,1,1,1]);
-
- sprite.indices = new Uint16Array([0, 1, 3,2])//, 2]);
-
- sprite._vertexBuffer = gl.createBuffer();
- sprite._indexBuffer = gl.createBuffer();
- sprite._uvBuffer = gl.createBuffer();
- sprite._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.uvs, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW);
-
-// return ( (x > 0) && ((x & (x - 1)) == 0) );
-
- if(sprite.texture.baseTexture._glTexture)
- {
- gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- sprite.texture.baseTexture._powerOf2 = true;
- }
- else
- {
- sprite.texture.baseTexture._powerOf2 = true;
- }
-}
-
-/**
- * Renders a Strip
- *
- * @method renderStrip
- * @param strip {Strip} The strip to render
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.stripShaderProgram;
-
-
- gl.useProgram(shaderProgram);
-
- var m = PIXI.mat3.clone(strip.worldTransform);
-
- PIXI.mat3.transpose(m);
-
- // set the matrix transform for the
- gl.uniformMatrix3fv(shaderProgram.translationMatrix, false, m);
- gl.uniform2f(shaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(shaderProgram.alpha, strip.worldAlpha);
-
-/*
- if(strip.blendMode == PIXI.blendModes.NORMAL)
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
- }
- */
-
-
- if(!strip.dirty)
- {
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- }
- else
- {
- strip.dirty = false;
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-
- }
-
- gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
-
- gl.useProgram(PIXI.currentProgram);
-}
-
-/**
- * Renders a TilingSprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to render
- * @param projectionMatrix {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- var tilePosition = sprite.tilePosition;
- var tileScale = sprite.tileScale;
-
- var offsetX = tilePosition.x/sprite.texture.baseTexture.width;
- var offsetY = tilePosition.y/sprite.texture.baseTexture.height;
-
- var scaleX = (sprite.width / sprite.texture.baseTexture.width) / tileScale.x;
- var scaleY = (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
-
- sprite.uvs[0] = 0 - offsetX;
- sprite.uvs[1] = 0 - offsetY;
-
- sprite.uvs[2] = (1 * scaleX) -offsetX;
- sprite.uvs[3] = 0 - offsetY;
-
- sprite.uvs[4] = (1 *scaleX) - offsetX;
- sprite.uvs[5] = (1 *scaleY) - offsetY;
-
- sprite.uvs[6] = 0 - offsetX;
- sprite.uvs[7] = (1 *scaleY) - offsetY;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
-
- this.renderStrip(sprite, projectionMatrix);
-}
-
-/**
- * Initializes a strip to be rendered
- *
- * @method initStrip
- * @param strip {Strip} The strip to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
-{
- // build the strip!
- var gl = this.gl;
- var shaderProgram = this.shaderProgram;
-
- strip._vertexBuffer = gl.createBuffer();
- strip._indexBuffer = gl.createBuffer();
- strip._uvBuffer = gl.createBuffer();
- strip._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-}
-
-
-/**
- * @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 :)
- *
- * @class CanvasRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
- */
-PIXI.CanvasRenderer = function(width, height, view, transparent)
-{
- this.transparent = transparent;
-
- /**
- * 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 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");
-
- 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;
-}
-
-// constructor
-PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
-
-/**
- * Renders the stage to its canvas view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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;
-
- 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 = [];
- }
-
-
-}
-
-/**
- * resizes the canvas view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the canvas view
- * @param height {Number} the new height of the canvas view
- */
-PIXI.CanvasRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-}
-
-/**
- * Renders a display object
- *
- * @method renderDisplayObject
- * @param displayObject {DisplayObject} The displayObject to render
- * @private
- */
-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)
- {
-
- var frame = displayObject.texture.frame;
-
- if(frame && frame.width && frame.height)
- {
- 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;
-
- 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)
-
-
-}
-
-/**
- * Renders a flat strip
- *
- * @method renderStripFlat
- * @param strip {Strip} The Strip to render
- * @private
- */
-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();
-}
-
-/**
- * Renders a tiling sprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tilingsprite to render
- * @private
- */
-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;
-
- // 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.translate(-tilePosition.x, -tilePosition.y);
-
- context.closePath();
-}
-
-/**
- * Renders a strip
- *
- * @method renderStrip
- * @param strip {Strip} The Strip to render
- * @private
- */
-PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
-{
- 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;
-
-
- 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();
- };
-
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * A set of functions used by the canvas renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.CanvasGraphics = function()
-{
-
-}
-
-
-/*
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- 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.lineWidth = data.lineWidth;
-
- 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]);
- }
-
- // 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.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]);
- }
-
- }
- 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
-
- 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
- *
- * @static
- * @private
- * @method renderGraphicsMask
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- var len = graphics.graphicsData.length;
- if(len > 1)
- {
- len = 1;
- 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;
-
- 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]);
- }
-
- // 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
- }
-
-
- };
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
- * It is important to know that with the webGL renderer only simple polys can be filled at this stage
- * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
- *
- * @class Graphics
- * @extends DisplayObjectContainer
- * @constructor
- */
-PIXI.Graphics = function()
-{
- PIXI.DisplayObjectContainer.call( this );
-
- this.renderable = true;
-
- /**
- * The alpha of the fill of this graphics object
- *
- * @property fillAlpha
- * @type Number
- */
- this.fillAlpha = 1;
-
- /**
- * The width of any lines drawn
- *
- * @property lineWidth
- * @type Number
- */
- this.lineWidth = 0;
-
- /**
- * The color of any lines drawn
- *
- * @property lineColor
- * @type String
- */
- this.lineColor = "black";
-
- /**
- * Graphics data
- *
- * @property graphicsData
- * @type Array
- * @private
- */
- this.graphicsData = [];
-
- /**
- * Current path
- *
- * @property currentPath
- * @type Object
- * @private
- */
- this.currentPath = {points:[]};
-}
-
-// constructor
-PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Graphics.prototype.constructor = PIXI.Graphics;
-
-/**
- * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
- *
- * @method lineStyle
- * @param lineWidth {Number} width of the line to draw, will update the object's stored style
- * @param color {Number} color of the line to draw, will update the object's stored style
- * @param alpha {Number} alpha of the line to draw, will update the object's stored style
- */
-PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
-{
- if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.lineWidth = lineWidth || 0;
- this.lineColor = color || 0;
- this.lineAlpha = (alpha == undefined) ? 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.graphicsData.push(this.currentPath);
-}
-
-/**
- * Moves the current drawing position to (x, y).
- *
- * @method moveTo
- * @param x {Number} the X coord to move to
- * @param y {Number} the Y coord to move to
- */
-PIXI.Graphics.prototype.moveTo = function(x, y)
-{
- if(this.currentPath.points.length == 0)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.points.push(x, y);
-
- this.graphicsData.push(this.currentPath);
-}
-
-/**
- * Draws a line using the current line style from the current drawing position to (x, y);
- * the current drawing position is then set to (x, y).
- *
- * @method lineTo
- * @param x {Number} the X coord to draw to
- * @param y {Number} the Y coord to draw to
- */
-PIXI.Graphics.prototype.lineTo = function(x, y)
-{
- this.currentPath.points.push(x, y);
- this.dirty = true;
-}
-
-/**
- * Specifies a simple one-color fill that subsequent calls to other Graphics methods
- * (such as lineTo() or drawCircle()) use when drawing.
- *
- * @method beginFill
- * @param color {uint} the color of the fill
- * @param alpha {Number} the alpha
- */
-PIXI.Graphics.prototype.beginFill = function(color, alpha)
-{
- this.filling = true;
- this.fillColor = color || 0;
- this.fillAlpha = (alpha == undefined) ? 1 : alpha;
-}
-
-/**
- * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
- *
- * @method endFill
- */
-PIXI.Graphics.prototype.endFill = function()
-{
- this.filling = false;
- this.fillColor = null;
- this.fillAlpha = 1;
-}
-
-/**
- * @method drawRect
- *
- * @param x {Number} The X coord of the top-left of the rectangle
- * @param y {Number} The Y coord of the top-left of the rectangle
- * @param width {Number} The width of the rectangle
- * @param height {Number} The height of the rectangle
- */
-PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws a circle.
- *
- * @method drawCircle
- * @param x {Number} The X coord of the center of the circle
- * @param y {Number} The Y coord of the center of the circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws an elipse.
- *
- * @method drawElipse
- * @param x {Number}
- * @param y {Number}
- * @param width {Number}
- * @param height {Number}
- */
-PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
- *
- * @method clear
- */
-PIXI.Graphics.prototype.clear = function()
-{
- this.lineWidth = 0;
- this.filling = false;
-
- this.dirty = true;
- this.clearDirty = true;
- this.graphicsData = [];
-}
-
-// SOME TYPES:
-PIXI.Graphics.POLY = 0;
-PIXI.Graphics.RECT = 1;
-PIXI.Graphics.CIRC = 2;
-PIXI.Graphics.ELIP = 3;
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-PIXI.Strip = function(texture, width, height)
-{
- 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]);
-
- this.verticies = new Float32Array([0, 0,
- 0,0,
- 0,0, 0,
- 0, 0]);
-
- 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.verticies = [0, 0,
- 0,0,
- 0,0, 0,
- 0, 0];
-
- this.colors = [1, 1, 1, 1];
-
- 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;
-
- // 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;
-}
-
-// constructor
-PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Strip.prototype.constructor = PIXI.Strip;
-
-PIXI.Strip.prototype.setTexture = function(texture)
-{
- //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;
-}
-
-PIXI.Strip.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-// some helper functions..
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-
-PIXI.Rope = function(texture, points)
-{
- PIXI.Strip.call( this, texture );
- this.points = points;
-
- try
- {
- this.verticies = new Float32Array( points.length * 4);
- this.uvs = new Float32Array( points.length * 4);
- this.colors = new Float32Array( points.length * 2);
- this.indices = new Uint16Array( points.length * 2);
- }
- catch(error)
- {
- this.verticies = verticies
-
- this.uvs = uvs
- this.colors = colors
- this.indices = indices
- }
-
- this.refresh();
-}
-
-
-// constructor
-PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
-PIXI.Rope.prototype.constructor = PIXI.Rope;
-
-PIXI.Rope.prototype.refresh = function()
-{
- var points = this.points;
- if(points.length < 1)return;
-
- var uvs = this.uvs
- var indices = this.indices;
- var colors = this.colors;
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
-
- uvs[0] = 0
- uvs[1] = 1
- uvs[2] = 0
- uvs[3] = 1
-
- colors[0] = 1;
- colors[1] = 1;
-
- indices[0] = 0;
- indices[1] = 1;
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
- // time to do some smart drawing!
- var amount = i/(total-1)
-
- if(i%2)
- {
- uvs[index] = amount;
- uvs[index+1] = 0;
-
- uvs[index+2] = amount
- uvs[index+3] = 1
-
- }
- else
- {
- uvs[index] = amount
- uvs[index+1] = 0
-
- uvs[index+2] = amount
- uvs[index+3] = 1
- }
-
- index = i * 2;
- colors[index] = 1;
- colors[index+1] = 1;
-
- index = i * 2;
- indices[index] = index;
- indices[index + 1] = index + 1;
-
- lastPoint = point;
- }
-}
-
-PIXI.Rope.prototype.updateTransform = function()
-{
-
- var points = this.points;
- if(points.length < 1)return;
-
- var verticies = this.verticies
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
- verticies[0] = point.x + perp.x
- verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
- verticies[3] = point.y - perp.y//+200
- // time to do some smart drawing!
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
-
- if(i < points.length-1)
- {
- nextPoint = points[i+1];
- }
- else
- {
- nextPoint = point
- }
-
- perp.y = -(nextPoint.x - lastPoint.x);
- perp.x = nextPoint.y - lastPoint.y;
-
- var ratio = (1 - (i / (total-1))) * 10;
- if(ratio > 1)ratio = 1;
-
- 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;
-
- 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;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
-}
-
-PIXI.Rope.prototype.setTexture = function(texture)
-{
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * A tiling sprite is a fast way of rendering a tiling image
- *
- * @class TilingSprite
- * @extends DisplayObjectContainer
- * @constructor
- * @param texture {Texture} the texture of the tiling sprite
- * @param width {Number} the width of the tiling sprite
- * @param height {Number} the height of the tiling sprite
- */
-PIXI.TilingSprite = function(texture, width, height)
-{
- PIXI.DisplayObjectContainer.call( this );
-
- /**
- * 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 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 offset position of the image that is being tiled
- *
- * @property tilePosition
- * @type Point
- */
- this.tilePosition = new PIXI.Point(0,0);
-
- this.renderable = true;
-
- this.blendMode = PIXI.blendModes.NORMAL
-}
-
-// constructor
-PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
-
-/**
- * Sets the texture of the tiling sprite
- *
- * @method setTexture
- * @param texture {Texture} The PIXI texture that is displayed by the sprite
- */
-PIXI.TilingSprite.prototype.setTexture = function(texture)
-{
- //TODO SET THE TEXTURES
- //TODO VISIBILITY
-
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-/**
- * When the texture is updated, this event will fire to update the frame
- *
- * @method onTextureUpdate
- * @param event
- * @private
- */
-PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
- *
- * Awesome JS run time provided by EsotericSoftware
- * https://github.com/EsotericSoftware/spine-runtimes
- *
- */
-
-/**
- * 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
- * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
- *
- * @class Spine
- * @extends DisplayObjectContainer
- * @constructor
- * @param url {String} The url of the spine anim file to be used
- */
-PIXI.Spine = function (url) {
- PIXI.DisplayObjectContainer.call(this);
-
- this.spineData = PIXI.AnimCache[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.stateData = new spine.AnimationStateData(this.spineData);
- this.state = new spine.AnimationState(this.stateData);
-
- 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);
- }
-};
-
-PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.Spine.prototype.constructor = PIXI.Spine;
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @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();
-
- 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;
-
- 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.rotation = -(slot.bone.worldRotation * Math.PI / 180);
- }
-
- 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;
-
- 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;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * This object is one that will allow you to specify custom rendering functions based on render type
- *
- * @class CustomRenderable
- * @extends DisplayObject
- * @constructor
- */
-PIXI.CustomRenderable = function()
-{
- PIXI.DisplayObject.call( this );
-
- this.renderable = true;
-}
-
-// constructor
-PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
-
-/**
- * If this object is being rendered by a CanvasRenderer it will call this callback
- *
- * @method renderCanvas
- * @param renderer {CanvasRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderCanvas = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback to initialize
- *
- * @method initWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.initWebGL = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback
- *
- * @method renderWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderWebGL = function(renderGroup, projectionMatrix)
-{
- // not sure if both needed? but ya have for now!
- // override!
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.BaseTextureCache = {};
-PIXI.texturesToUpdate = [];
-PIXI.texturesToDestroy = [];
-
-/**
- * A texture stores the information that represents an image. All textures have a base texture
- *
- * @class BaseTexture
- * @uses EventTarget
- * @constructor
- * @param source {String} the source object (image or canvas)
- */
-PIXI.BaseTexture = function(source)
-{
- 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 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 source that is loaded to create the texture
- *
- * @property source
- * @type Image
- */
- this.source = source;
-
- if(!source)return;
-
- 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;
-
- PIXI.texturesToUpdate.push(this);
- }
- else
- {
-
- var scope = this;
- this.source.onload = function(){
-
- scope.hasLoaded = true;
- scope.width = scope.source.width;
- scope.height = scope.source.height;
-
- // 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;
-
- PIXI.texturesToUpdate.push(this);
- }
-
- this._powerOf2 = false;
-}
-
-PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
-
-/**
- * Destroys this base texture
- *
- * @method destroy
- */
-PIXI.BaseTexture.prototype.destroy = function()
-{
- if(this.source instanceof Image)
- {
- this.source.src = null;
- }
- this.source = null;
- PIXI.texturesToDestroy.push(this);
-}
-
-/**
- * Helper function that returns a base texture based on an image url
- * If the image is not in the base texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @return BaseTexture
- */
-PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
-{
- 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);
- PIXI.BaseTextureCache[imageUrl] = baseTexture;
- }
-
- return baseTexture;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.TextureCache = {};
-PIXI.FrameCache = {};
-
-/**
- * A texture stores the information that represents an image or part of an image. It cannot be added
- * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
- *
- * @class Texture
- * @uses EventTarget
- * @constructor
- * @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frame {Rectangle} The rectangle frame of the texture to show
- */
-PIXI.Texture = function(baseTexture, frame)
-{
- PIXI.EventTarget.call( this );
-
- if(!frame)
- {
- this.noFrame = true;
- frame = new PIXI.Rectangle(0,0,1,1);
- }
-
- if(baseTexture instanceof PIXI.Texture)
- baseTexture = baseTexture.baseTexture;
-
- /**
- * The base texture of this texture
- *
- * @property baseTexture
- * @type BaseTexture
- */
- this.baseTexture = baseTexture;
-
- /**
- * The frame specifies the region of the base texture that this texture uses
- *
- * @property frame
- * @type Rectangle
- */
- this.frame = frame;
-
- /**
- * The trim point
- *
- * @property trim
- * @type Point
- */
- this.trim = new PIXI.Point();
-
- this.scope = this;
-
- if(baseTexture.hasLoaded)
- {
- if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- //console.log(frame)
-
- this.setFrame(frame);
- }
- else
- {
- var scope = this;
- baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} );
- }
-}
-
-PIXI.Texture.prototype.constructor = PIXI.Texture;
-
-/**
- * Called when the base texture is loaded
- *
- * @method onBaseTextureLoaded
- * @param event
- * @private
- */
-PIXI.Texture.prototype.onBaseTextureLoaded = function(event)
-{
- var baseTexture = this.baseTexture;
- baseTexture.removeEventListener( 'loaded', this.onLoaded );
-
- if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- this.noFrame = false;
- this.width = this.frame.width;
- this.height = this.frame.height;
-
- this.scope.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Destroys this texture
- *
- * @method destroy
- * @param destroyBase {Boolean} Whether to destroy the base texture as well
- */
-PIXI.Texture.prototype.destroy = function(destroyBase)
-{
- if(destroyBase)this.baseTexture.destroy();
-}
-
-/**
- * Specifies the rectangle region of the baseTexture
- *
- * @method setFrame
- * @param frame {Rectangle} The frame of the texture to set it to
- */
-PIXI.Texture.prototype.setFrame = function(frame)
-{
- this.frame = frame;
- this.width = frame.width;
- this.height = frame.height;
-
- 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;
-
- PIXI.Texture.frameUpdates.push(this);
- //this.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Helper function that returns a texture based on an image url
- * If the image is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- * @return Texture
- */
-PIXI.Texture.fromImage = function(imageUrl, crossorigin)
-{
- var texture = PIXI.TextureCache[imageUrl];
-
- if(!texture)
- {
- texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
- PIXI.TextureCache[imageUrl] = texture;
- }
-
- return texture;
-}
-
-/**
- * Helper function that returns a texture based on a frame id
- * If the frame id is not in the texture cache an error will be thrown
- *
- * @static
- * @method fromFrame
- * @param frameId {String} The frame id of the texture
- * @return Texture
- */
-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;
-}
-
-/**
- * Helper function that returns a texture based on a canvas element
- * If the canvas is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromCanvas
- * @param canvas {Canvas} The canvas element source of the texture
- * @return Texture
- */
-PIXI.Texture.fromCanvas = function(canvas)
-{
- var baseTexture = new PIXI.BaseTexture(canvas);
- return new PIXI.Texture(baseTexture);
-}
-
-
-/**
- * Adds a texture to the textureCache.
- *
- * @static
- * @method addTextureToCache
- * @param texture {Texture}
- * @param id {String} the id that the texture will be stored against.
- */
-PIXI.Texture.addTextureToCache = function(texture, id)
-{
- PIXI.TextureCache[id] = texture;
-}
-
-/**
- * Remove a texture from the textureCache.
- *
- * @static
- * @method removeTextureFromCache
- * @param id {String} the id of the texture to be removed
- * @return {Texture} the texture that was removed
- */
-PIXI.Texture.removeTextureFromCache = function(id)
-{
- var texture = PIXI.TextureCache[id]
- PIXI.TextureCache[id] = null;
- return texture;
-}
-
-// this is more for webGL.. it contains updated frames..
-PIXI.Texture.frameUpdates = [];
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- 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.
-
- 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);
-
- 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
-
- @class RenderTexture
- @extends Texture
- @constructor
- @param width {Number} The width of the render texture
- @param height {Number} The height of the render texture
- */
-PIXI.RenderTexture = function(width, height)
-{
- PIXI.EventTarget.call( this );
-
- this.width = width || 100;
- this.height = height || 100;
-
- this.indetityMatrix = PIXI.mat3.create();
-
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
-
- if(PIXI.gl)
- {
- this.initWebGL();
- }
- else
- {
- this.initCanvas();
- }
-}
-
-PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
-PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
-
-/**
- * Initializes the webgl data for this texture
- *
- * @method initWebGL
- * @private
- */
-PIXI.RenderTexture.prototype.initWebGL = function()
-{
- var gl = PIXI.gl;
- this.glFramebuffer = gl.createFramebuffer();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // 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);
- }
-}
-
-/**
- * Initializes the canvas data for this texture
- *
- * @method initCanvas
- * @private
- */
-PIXI.RenderTexture.prototype.initCanvas = function()
-{
- 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.render = this.renderCanvas;
-}
-
-/**
- * This function will draw the display object to the texture.
- *
- * @method renderWebGL
- * @param displayObject {DisplayObject} The display object to render this texture on
- * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
- * @private
- */
-PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
-{
- var gl = PIXI.gl;
-
- // enable the alpha color mask..
- gl.colorMask(true, true, true, true);
-
- gl.viewport(0, 0, this.width, this.height);
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- if(clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
-
- // 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;
-
-
- 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} 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".
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.AssetLoader = function(assetURLs, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The array of asset URLs that are going to be loaded
- *
- * @property assetURLs
- * @type Array
- */
- this.assetURLs = assetURLs;
-
- /**
- * Whether the requests should be treated as cross origin
- *
- * @property crossorigin
- * @type Boolean
- */
- this.crossorigin = crossorigin;
-
- /**
- * Maps file extension to loader types
- *
- * @property loadersByType
- * @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
- };
-
-
-};
-
-/**
- * Fired when an item has loaded
- * @event onProgress
- */
-
-/**
- * Fired when all the assets have loaded
- * @event onComplete
- */
-
-// constructor
-PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
-
-/**
- * Starts loading the assets sequentially
- *
- * @method load
- */
-PIXI.AssetLoader.prototype.load = function()
-{
- var scope = this;
-
- this.loadCount = this.assetURLs.length;
-
- for (var i=0; i < this.assetURLs.length; i++)
- {
- var fileName = this.assetURLs[i];
- var fileType = fileName.split(".").pop().toLowerCase();
-
- var loaderClass = this.loadersByType[fileType];
- if(!loaderClass)
- throw new Error(fileType + " is an unsupported file type");
-
- var loader = new loaderClass(fileName, this.crossorigin);
-
- loader.addEventListener("loaded", function()
- {
- scope.onAssetLoaded();
- });
- loader.load();
- }
-};
-
-/**
- * Invoked after each file is loaded
- *
- * @method onAssetLoaded
- * @private
- */
-PIXI.AssetLoader.prototype.onAssetLoaded = function()
-{
- this.loadCount--;
- 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();
- }
-};
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class JsonLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the JSON file
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.JsonLoader = function (url, crossorigin) {
- PIXI.EventTarget.call(this);
-
- /**
- * 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;
-
- /**
- * [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;
-
-};
-
-// constructor
-PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
-
-/**
- * Loads the JSON data
- *
- * @method load
- */
-PIXI.JsonLoader.prototype.load = function () {
- this.ajaxRequest = new 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);
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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.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();
- });
-
- 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();
-
- }
- 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();
- }
- }
-};
-
-/**
- * Invoke when json file loaded
- *
- * @method onLoaded
- * @private
- */
-PIXI.JsonLoader.prototype.onLoaded = function () {
- this.loaded = true;
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * Invoke when error occured
- *
- * @method onError
- * @private
- */
-PIXI.JsonLoader.prototype.onError = function () {
- this.dispatchEvent({
- type: "error",
- content: this
- });
-};
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- * 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.
- * 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
- *
- * @class SpriteSheetLoader
- * @uses EventTarget
- * @constructor
- * @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);
-
- /**
- * 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;
-
- /**
- * [read-only] The base url of the bitmap font data
- *
- * @property baseUrl
- * @type String
- * @readOnly
- */
- this.baseUrl = url.replace(/[^\/]*$/, "");
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = null;
-
- /**
- * The frames of the sprite sheet
- *
- * @property frames
- * @type Object
- */
- this.frames = {};
-};
-
-// constructor
-PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader;
-
-/**
- * This will begin loading the JSON file
- *
- * @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();
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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;
-
- this.texture = image.texture.baseTexture;
- image.addEventListener("loaded", function (event) {
- 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!
- }
- }
- }
-
- image.load();
-};
-/**
- * Invoke when all files are loaded (json and texture)
- *
- * @method onLoaded
- * @private
- */
-PIXI.SpriteSheetLoader.prototype.onLoaded = function () {
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class ImageLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the image
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.ImageLoader = function(url, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = PIXI.Texture.fromImage(url, crossorigin);
-
- /**
- * if the image is loaded with loadFramedSpriteSheet
- * frames will contain the sprite sheet frames
- *
- */
- this.frames = [];
-};
-
-// constructor
-PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader;
-
-/**
- * Loads image or takes it from cache
- *
- * @method load
- */
-PIXI.ImageLoader.prototype.load = function()
-{
- if(!this.texture.baseTexture.hasLoaded)
- {
- var scope = this;
- this.texture.baseTexture.addEventListener("loaded", function()
- {
- scope.onLoaded();
- });
- }
- else
- {
- this.onLoaded();
- }
-};
-
-/**
- * Invoked when image file is loaded or it is already cached and ready to use
- *
- * @method onLoaded
- * @private
- */
-PIXI.ImageLoader.prototype.onLoaded = function()
-{
- this.dispatchEvent({type: "loaded", content: this});
-};
-
-/**
- * Loads image and split it to uniform sized frames
- *
- *
- * @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
- */
-PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
-{
- this.frames = [];
- var cols = Math.floor(this.texture.width / frameWidth);
- var rows = Math.floor(this.texture.height / frameHeight);
-
- var i=0;
- for (var y=0; y
-
+
+
-
+
diff --git a/examples/example 4 - Balls/pixi.js b/examples/example 4 - Balls/pixi.js
deleted file mode 100644
index 6d567a2..0000000
--- a/examples/example 4 - Balls/pixi.js
+++ /dev/null
@@ -1,10649 +0,0 @@
-/**
- * @license
- * Pixi.JS - v1.3.0
- * Copyright (c) 2012, Mat Groves
- * http://goodboydigital.com/
- *
- * Compiled: 2013-09-30
- *
- * Pixi.JS is licensed under the MIT License.
- * http://www.opensource.org/licenses/mit-license.php
- */
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-(function(){
-
- var root = this;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * @module PIXI
- */
-var PIXI = PIXI || {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
- *
- * @class Point
- * @constructor
- * @param x {Number} position of the point
- * @param y {Number} position of the point
- */
-PIXI.Point = function(x, y)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-}
-
-/**
- * Creates a clone of this point
- *
- * @method clone
- * @return {Point} a copy of the point
- */
-PIXI.Point.prototype.clone = function()
-{
- return new PIXI.Point(this.x, this.y);
-}
-
-// constructor
-PIXI.Point.prototype.constructor = PIXI.Point;
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
- *
- * @class Rectangle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the rectangle
- * @param y {Number} The Y coord of the upper-left corner of the rectangle
- * @param width {Number} The overall width of this rectangle
- * @param height {Number} The overall height of this rectangle
- */
-PIXI.Rectangle = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Rectangle
- *
- * @method clone
- * @return {Rectangle} a copy of the rectangle
- */
-PIXI.Rectangle.prototype.clone = function()
-{
- 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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this Rectangle
- */
-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;
-
- if(y >= y1 && y <= y1 + this.height)
- {
- return true;
- }
- }
-
- return false;
-}
-
-// constructor
-PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
-
-
-/**
- * @author Adrien Brault
- */
-
-/**
- * @class Polygon
- * @constructor
- * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
- * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
- * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
- * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
- * Numbers.
- */
-PIXI.Polygon = function(points)
-{
- //if points isn't an array, use arguments as the array
- if(!(points instanceof Array))
- points = Array.prototype.slice.call(arguments);
-
- //if this is a flat array of numbers, convert it to points
- if(typeof points[0] === 'number') {
- var p = [];
- for(var i = 0, il = points.length; i < il; i+=2) {
- p.push(
- new PIXI.Point(points[i], points[i + 1])
- );
- }
-
- points = p;
- }
-
- this.points = points;
-}
-
-/**
- * Creates a clone of this polygon
- *
- * @method clone
- * @return {Polygon} a copy of the polygon
- */
-PIXI.Polygon.prototype.clone = function()
-{
- var points = [];
- for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
-
- if(intersect) inside = !inside;
- }
-
- return inside;
-}
-
-// constructor
-PIXI.Polygon.prototype.constructor = PIXI.Polygon;
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Circle object can be used to specify a hit area for displayobjects
- *
- * @class Circle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Circle = function(x, y, radius)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property radius
- * @type Number
- * @default 0
- */
- this.radius = radius || 0;
-}
-
-/**
- * Creates a clone of this Circle instance
- *
- * @method clone
- * @return {Circle} a copy of the polygon
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
- */
-PIXI.Circle.prototype.contains = function(x, y)
-{
- if(this.radius <= 0)
- return false;
-
- var dx = (this.x - x),
- dy = (this.y - y),
- r2 = this.radius * this.radius;
-
- dx *= dx;
- dy *= dy;
-
- return (dx + dy <= r2);
-}
-
-// constructor
-PIXI.Circle.prototype.constructor = PIXI.Circle;
-
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Ellipse object can be used to specify a hit area for displayobjects
- *
- * @class Ellipse
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
- * @param width {Number} The overall width of this ellipse
- * @param height {Number} The overall height of this ellipse
- */
-PIXI.Ellipse = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Ellipse instance
- *
- * @method clone
- * @return {Ellipse} a copy of the ellipse
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this ellipse
- */
-PIXI.Ellipse.prototype.contains = function(x, y)
-{
- if(this.width <= 0 || this.height <= 0)
- return false;
-
- //normalize the coords to an ellipse with center 0,0
- //and a radius of 0.5
- var normx = ((x - this.x) / this.width) - 0.5,
- normy = ((y - this.y) / this.height) - 0.5;
-
- normx *= normx;
- normy *= normy;
-
- return (normx + normy < 0.25);
-}
-
-PIXI.Ellipse.getBounds = function()
-{
- return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
-}
-
-// constructor
-PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
-
-
-
-/*
- * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
- * you both rock!
- */
-
-function determineMatrixArrayType() {
- PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return PIXI.Matrix;
-}
-
-determineMatrixArrayType();
-
-PIXI.mat3 = {};
-
-PIXI.mat3.create = function()
-{
- 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;
-
- 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;
-
- return matrix;
-}
-
-
-PIXI.mat4 = {};
-
-PIXI.mat4.create = function()
-{
- 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;
-
- return matrix;
-}
-
-PIXI.mat3.multiply = function (mat, mat2, dest)
-{
- 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],
-
- 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[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;
-
- return dest;
-}
-
-PIXI.mat3.clone = function(mat)
-{
- 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];
-
- 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 (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
-}
-
-PIXI.mat3.toMat4 = function (mat, dest)
-{
- if (!dest) { dest = PIXI.mat4.create(); }
-
- 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[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];
-
- return dest;
-}
-
-
-/////
-
-
-PIXI.mat4.create = function()
-{
- 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;
-
- 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];
-
- 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;
-}
-
-PIXI.mat4.multiply = function (mat, mat2, dest)
-{
- 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 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;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The base class for all objects that are rendered on the screen.
- *
- * @class DisplayObject
- * @constructor
- */
-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();
-
- /**
- * 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 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 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 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;
-
- /**
- * [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 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] Current transform of the object based on world (parent) factors
- *
- * @property worldTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.worldTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [read-only] Current transform of the object locally
- *
- * @property localTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.localTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [NYI] Unkown
- *
- * @property color
- * @type Array<>
- * @private
- */
- this.color = [];
-
- /**
- * [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;
-
- /*
- * MOUSE Callbacks
- */
-
- /**
- * 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 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
- * 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 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 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
- */
-
- /**
- * 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 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}
- */
-}
-
-// constructor
-PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
-
-/**
- * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default
- * Instead of using this function you can now simply set the interactive property to true or false
- *
- * @method setInteractive
- * @param interactive {Boolean}
- * @deprecated Simply set the `interactive` property directly
- */
-PIXI.DisplayObject.prototype.setInteractive = function(interactive)
-{
- this.interactive = interactive;
-}
-
-/**
- * Indicates if the sprite will have touch and mouse interactivity. It is false by default
- *
- * @property interactive
- * @type Boolean
- * @default false
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
- get: function() {
- 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;
- }
-});
-
-/**
- * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
- * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
- * To remove a mask, set this property to null.
- *
- * @property mask
- * @type Graphics
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
- get: function() {
- 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;
- }
- }
- else
- {
- this.removeFilter(this._mask);
- this._mask.renderable = true;
- }
-
- this._mask = value;
- }
-});
-
-/**
- * Sets the filters for the displayObject. Currently there's a few limitations.
- * 1: At the moment only one filter can be applied at a time..
- * 2: They cannot be nested.
- * 3: There's no padding yet.
- * 4: this is a webGL only feature.
- * @property filters
- * @type Array
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
- get: function() {
- return this._filters;
- },
- set: function(value) {
-
- //if(value == )
- if(value)
- {
- if(this._filters)this.removeFilter(this._filters);
- this.addFilter(value)
- }
- else
- {
- if(this._filters)this.removeFilter(this._filters);
- }
-
- this._filters = value;
- }
-});
-
-/*
- * Adds a filter to this displayObject
- *
- * @method addFilter
- * @param mask {Graphics} the graphics object to use as a filter
- * @private
- */
-PIXI.DisplayObject.prototype.addFilter = function(data)
-{
- //if(this.filter)return;
- //this.filter = true;
-
- // 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;
-
- /*
- * 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);
- }
-
-}
-
-/*
- * Removes the filter to this displayObject
- *
- * @method removeFilter
- * @private
- */
-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);
- }
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-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;
-
- // 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],
-
- b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
- b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
-
- 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;
-
- worldTransform[3] = b10 * a00 + b11 * a10;
- 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;
-
-}
-
-PIXI.visibleCount = 0;
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * 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
- * @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 = [];
-}
-
-// constructor
-PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-
-/**
- * Adds a child to the container.
- *
- * @method addChild
- * @param child {DisplayObject} The DisplayObject to add to the container
- */
-PIXI.DisplayObjectContainer.prototype.addChild = function(child)
-{
- if(child.parent != undefined)
- {
-
- //// 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)
- {
- 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
- *
- * @method addChildAt
- * @param child {DisplayObject} The child to add
- * @param index {Number} The index to place the child in
- */
-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;
-
- 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
- *
- * @method swapChildren
- * @param child {DisplayObject}
- * @param child2 {DisplayObject}
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
-{
- /*
- * this funtion needs to be recoded..
- * can be done a lot faster..
- */
- return;
-
- // need to fix this function :/
- /*
- // TODO I already know this??
- var index = this.children.indexOf( child );
- var index2 = this.children.indexOf( child2 );
-
- if ( index !== -1 && index2 !== -1 )
- {
- // cool
-
- /*
- if(this.stage)
- {
- // this is to satisfy the webGL batching..
- // TODO sure there is a nicer way to achieve this!
- this.stage.__removeChild(child);
- this.stage.__removeChild(child2);
-
- this.stage.__addChild(child);
- this.stage.__addChild(child2);
- }
-
- // swap the positions..
- this.children[index] = child2;
- this.children[index2] = child;
-
- }
- else
- {
- throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
- }*/
-}
-
-/**
- * Returns the Child at the specified index
- *
- * @method getChildAt
- * @param index {Number} The index to get the child from
- */
-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);
- }
-}
-
-/**
- * Removes a child from the container.
- *
- * @method removeChild
- * @param child {DisplayObject} The DisplayObject to remove
- */
-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 tempLast = childFirst._iPrev;
- // need to make sure the parents last is updated too
- var updateLast = this;
- while(updateLast.last == childLast.last)
- {
- 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
- *
- * @method updateTransform
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.updateTransform = function()
-{
- if(!this.visible)return;
-
- PIXI.DisplayObject.prototype.updateTransform.call( this );
-
- for(var i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation
- */
-PIXI.MovieClip = function(textures)
-{
- PIXI.Sprite.call(this, textures[0]);
-
- /**
- * The array of textures that make up the animation
- *
- * @property textures
- * @type Array
- */
- this.textures = textures;
-
- /**
- * The speed that the MovieClip will play at. Higher is faster, lower is slower
- *
- * @property animationSpeed
- * @type Number
- * @default 1
- */
- this.animationSpeed = 1;
-
- /**
- * Whether or not the movie clip repeats after playing.
- *
- * @property loop
- * @type Boolean
- * @default true
- */
- this.loop = true;
-
- /**
- * Function to call when a MovieClip finishes playing
- *
- * @property onComplete
- * @type Function
- */
- this.onComplete = null;
-
- /**
- * [read-only] The index MovieClips current frame (this may not have to be a whole number)
- *
- * @property currentFrame
- * @type Number
- * @default 0
- * @readOnly
- */
- this.currentFrame = 0;
-
- /**
- * [read-only] Indicates if the MovieClip is currently playing
- *
- * @property playing
- * @type Boolean
- * @readOnly
- */
- this.playing = false;
-}
-
-// constructor
-PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
-PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
-
-/**
-* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
-* assigned to the MovieClip.
-*
-* @property totalFrames
-* @type Number
-* @default 0
-* @readOnly
-*/
-Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
- get: function() {
-
- return this.textures.length;
- }
-});
-
-
-/**
- * Stops the MovieClip
- *
- * @method stop
- */
-PIXI.MovieClip.prototype.stop = function()
-{
- this.playing = false;
-}
-
-/**
- * Plays the MovieClip
- *
- * @method play
- */
-PIXI.MovieClip.prototype.play = function()
-{
- this.playing = true;
-}
-
-/**
- * Stops the MovieClip and goes to a specific frame
- *
- * @method gotoAndStop
- * @param frameNumber {Number} frame index to stop at
- */
-PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
-{
- this.playing = false;
- this.currentFrame = frameNumber;
- var round = (this.currentFrame + 0.5) | 0;
- this.setTexture(this.textures[round % this.textures.length]);
-}
-
-/**
- * Goes to a specific frame and begins playing the MovieClip
- *
- * @method gotoAndPlay
- * @param frameNumber {Number} frame index to start at
- */
-PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
-{
- this.currentFrame = frameNumber;
- this.playing = true;
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.MovieClip.prototype.updateTransform = function()
-{
- PIXI.Sprite.prototype.updateTransform.call(this);
-
- if(!this.playing)return;
-
- this.currentFrame += this.animationSpeed;
-
- var round = (this.currentFrame + 0.5) | 0;
-
- 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();
- }
- }
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.FilterBlock = function()
-{
- this.visible = true;
- this.renderable = true;
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.ColorMatrixFilter = function()
-{
- // 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;",
- "}"
- ];
-
-}
-
-
-Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
- get: function() {
- return this.uniforms.matrix.value;
- },
- set: function(value) {
- this.uniforms.matrix.value = value;
- }
-});
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.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");
- PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
-
- this.setText(text);
- this.setStyle(style);
-
- this.updateText();
- this.dirty = false;
-};
-
-// constructor
-PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype);
-PIXI.Text.prototype.constructor = PIXI.Text;
-
-/**
- * Set the style of the 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.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.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.strokeThickness = style.strokeThickness || 0;
- style.wordWrap = style.wordWrap || false;
- style.wordWrapWidth = style.wordWrapWidth || 100;
- this.style = style;
- this.dirty = true;
-};
-
-/**
- * Set the copy for the text object. To split a line you can use "\n"
- *
- * @methos 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.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.Text.prototype.updateText = function()
-{
- this.context.font = this.style.font;
-
- var outputText = 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)/);
-
- //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;
-
- //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.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);
-
- 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.fill)
- {
- this.context.fillText(lines[i], linePosition.x, linePosition.y);
- }
- }
-
- this.updateTexture();
-};
-
-/**
- * Updates texture size based on canvas size
- *
- * @method updateTexture
- * @private
- */
-PIXI.Text.prototype.updateTexture = function()
-{
- this.texture.baseTexture.width = this.canvas.width;
- this.texture.baseTexture.height = this.canvas.height;
- this.texture.frame.width = this.canvas.width;
- this.texture.frame.height = this.canvas.height;
-
- this._width = this.canvas.width;
- this._height = this.canvas.height;
-
- PIXI.texturesToUpdate.push(this.texture.baseTexture);
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.Text.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- this.updateText();
- this.dirty = false;
- }
-
- PIXI.Sprite.prototype.updateTransform.call(this);
-};
-
-/*
- * http://stackoverflow.com/users/34441/ellisbben
- * great solution to the problem!
- *
- * @method determineFontHeight
- * @param fontStyle {Object}
- * @private
- */
-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];
-
- 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;
-
- body.removeChild(dummy);
- }
-
- return result;
-};
-
-/**
- * A Text Object will apply wordwrap
- *
- * @method wordWrap
- * @param text {String}
- * @private
- */
-PIXI.Text.prototype.wordWrap = function(text)
-{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
- var result = "";
- var lines = text.split("\n");
- for (var i = 0; i < lines.length; i++)
- {
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
- }
-
- return result;
-};
-
-/**
- * Destroys this text object
- *
- * @method destroy
- * @param destroyTexture {Boolean}
- */
-PIXI.Text.prototype.destroy = function(destroyTexture)
-{
- if(destroyTexture)
- {
- this.texture.destroy();
- }
-
-};
-
-PIXI.Text.heightCache = {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.
- *
- * @class BitmapText
- * @extends DisplayObjectContainer
- * @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")
- */
-PIXI.BitmapText = function(text, style)
-{
- PIXI.DisplayObjectContainer.call(this);
-
- this.setText(text);
- this.setStyle(style);
- this.updateText();
- this.dirty = false
-
-};
-
-// constructor
-PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
-
-/**
- * Set the copy for the text object
- *
- * @method setText
- * @param text {String} The copy that you would like the text to display
- */
-PIXI.BitmapText.prototype.setText = function(text)
-{
- this.text = text || " ";
- this.dirty = true;
-};
-
-/**
- * Set the style of the 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")
- */
-PIXI.BitmapText.prototype.setStyle = function(style)
-{
- style = style || {};
- style.align = style.align || "left";
- this.style = style;
-
- 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;
-
- this.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.BitmapText.prototype.updateText = function()
-{
- var data = PIXI.BitmapText.fonts[this.fontName];
- var pos = new PIXI.Point();
- var prevCharCode = null;
- var chars = [];
- var maxLineWidth = 0;
- var lineWidths = [];
- var line = 0;
- var scale = this.fontSize / data.size;
- for(var i = 0; i < this.text.length; i++)
- {
- var charCode = this.text.charCodeAt(i);
- if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
- {
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
- line++;
-
- pos.x = 0;
- pos.y += data.lineHeight;
- prevCharCode = null;
- continue;
- }
-
- var charData = data.chars[charCode];
- if(!charData) continue;
-
- if(prevCharCode && charData[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;
-
- prevCharCode = charCode;
- }
-
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
-
- var lineAlignOffsets = [];
- for(i = 0; i <= line; i++)
- {
- var alignOffset = 0;
- if(this.style.align == "right")
- {
- alignOffset = maxLineWidth - lineWidths[i];
- }
- else if(this.style.align == "center")
- {
- alignOffset = (maxLineWidth - lineWidths[i]) / 2;
- }
- lineAlignOffsets.push(alignOffset);
- }
-
- for(i = 0; i < chars.length; i++)
- {
- 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;
- this.addChild(c);
- }
-
- this.width = pos.x * scale;
- this.height = (pos.y + data.lineHeight) * scale;
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.BitmapText.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- while(this.children.length > 0)
- {
- this.removeChild(this.getChildAt(0));
- }
- this.updateText();
-
- this.dirty = false;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
-};
-
-PIXI.BitmapText.fonts = {};
-
-/**
- * @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.
- *
- * @class InteractionManager
- * @constructor
- * @param stage {Stage} The stage to handle interactions
- */
-PIXI.InteractionManager = function(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();
-
- /**
- * 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();
-
- this.mouseoverEnabled = true;
-
- //tiny little interactiveData pool!
- this.pool = [];
-
- 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.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;
-
-/**
- * Collects an interactive sprite recursively to have their interactions managed
- *
- * @method collectInteractiveSprite
- * @param displayObject {DisplayObject} the displayObject to collect
- * @param iParent {DisplayObject}
- * @private
- */
-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);
-
- 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
- *
- * @method setTarget
- * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to
- * @private
- */
-PIXI.InteractionManager.prototype.setTarget = function(target)
-{
- this.target = target;
-
- //check if the dom element has been set. If it has don't do anything
- if( this.interactionDOMElement === null ) {
-
- this.setTargetDomElement( target.view );
- }
-
- document.body.addEventListener('mouseup', this.onMouseUp, true);
-}
-
-
-/**
- * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
- * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
- * to receive those events
- *
- * @method setTargetDomElement
- * @param domElement {DOMElement} the dom element which will receive mouse and touch events
- * @private
- */
-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'] = '';
-
- 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);
- }
-
-
- 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!
- }
-
- this.interactionDOMElement = domElement;
-
- 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
- *
- * @method update
- * @private
- */
-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 = "default";
-
- 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 = "pointer";
-
- 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
- *
- * @method onMouseMove
- * @param event {Event} The DOM event of the mouse moving
- * @private
- */
-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);
- }
- }
-}
-
-/**
- * Is called when the mouse button is pressed down on the renderer element
- *
- * @method onMouseDown
- * @param event {Event} The DOM event of a mouse button being pressed down
- * @private
- */
-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;
- }
- }
- }
-}
-
-
-PIXI.InteractionManager.prototype.onMouseOut = function(event)
-{
- var length = this.interactiveItems.length;
-
- this.interactionDOMElement.style.cursor = "default";
-
- 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
- *
- * @method onMouseUp
- * @param event {Event} The DOM event of a mouse button being released
- * @private
- */
-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;
- }
- }
-}
-
-/**
- * Tests if the current mouse coords hit a sprite
- *
- * @method hitTest
- * @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
- * @private
- */
-PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
-{
- var global = interactionData.global;
-
- if(item.vcount !== PIXI.visibleCount)return false;
-
- 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;
-
- 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;
-
- 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
- *
- * @method onTouchMove
- * @param event {Event} The DOM event of a touch moving accross the renderer view
- * @private
- */
-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);
- }
-}
-
-/**
- * Is called when a touch is started on the renderer element
- *
- * @method onTouchStart
- * @param event {Event} The DOM event of a touch starting on the renderer view
- * @private
- */
-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;
- }
- }
- }
- }
-}
-
-/**
- * Is called when a touch is ended on the renderer element
- *
- * @method onTouchEnd
- * @param event {Event} The DOM event of a touch ending on the renderer view
- * @private
- */
-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;
- }
-}
-
-/**
- * Holds all information related to an Interaction event
- *
- * @class InteractionData
- * @constructor
- */
-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();
-
- /**
- * The target Sprite that was interacted with
- *
- * @property target
- * @type Sprite
- */
- this.target;
-
- /**
- * When passed to an event handler, this will be the original DOM Event that was captured
- *
- * @property originalEvent
- * @type Event
- */
- this.originalEvent;
-}
-
-/**
- * This will return the local coords of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
- */
-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],
- 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)
-}
-
-// constructor
-PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A Stage represents the root of the display tree. Everything connected to the stage is rendered
- *
- * @class Stage
- * @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
- */
-PIXI.Stage = function(backgroundColor)
-{
- 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();
-
- /**
- * 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);
-
- /**
- * Whether the stage is dirty and needs to have interactions updated
- *
- * @property dirty
- * @type Boolean
- * @private
- */
- this.dirty = true;
-
- this.__childrenAdded = [];
- this.__childrenRemoved = [];
-
- //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);
-
- this.setBackgroundColor(backgroundColor);
- this.worldVisible = true;
-}
-
-// constructor
-PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Stage.prototype.constructor = PIXI.Stage;
-
-/**
- * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
- * This is useful for when you have other DOM elements ontop of the Canvas element.
- *
- * @method setInteractionDelegate
- * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
- */
-PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
-{
- this.interactionManager.setTargetDomElement( domElement );
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.Stage.prototype.updateTransform = function()
-{
- this.worldAlpha = 1;
- this.vcount = PIXI.visibleCount;
-
- for(var i=0,j=this.children.length; i> 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 target != 'function') throw new TypeError();
-
- 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);
-
- return bound;
- };
- })();
-}
-
-/**
- * A wrapper for ajax requests to be handled cross browser
- *
- * @class AjaxRequest
- * @constructor
- */
-var AjaxRequest = PIXI.AjaxRequest = function()
-{
- 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);
-
- while(tmp._iNext)
- {
- safe++;
- tmp = tmp._iNext;
- console.log(tmp);
- // console.log(tmp);
-
- if(safe > 100)
- {
- console.log("BREAK")
- break
- }
- }
-}
-
-
-
-
-
-
-/**
- * https://github.com/mrdoob/eventtarget.js/
- * THankS mr DOob!
- */
-
-/**
- * Adds event emitter functionality to a class
- *
- * @class EventTarget
- * @example
- * function MyEmitter() {
- * PIXI.EventTarget.call(this); //mixes in event target stuff
- * }
- *
- * var em = new MyEmitter();
- * em.emit({ type: 'eventName', data: 'some data' });
- */
-PIXI.EventTarget = function () {
-
- var listeners = {};
-
- this.addEventListener = this.on = function ( type, listener ) {
-
-
- if ( listeners[ type ] === undefined ) {
-
- listeners[ type ] = [];
-
- }
-
- if ( listeners[ type ].indexOf( listener ) === - 1 ) {
-
- listeners[ type ].push( listener );
- }
-
- };
-
- this.dispatchEvent = this.emit = function ( event ) {
-
- if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
-
- return;
-
- }
-
- for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
-
- listeners[ event.type ][ i ]( event );
-
- }
-
- };
-
- this.removeEventListener = this.off = function ( type, listener ) {
-
- var index = listeners[ type ].indexOf( listener );
-
- if ( index !== - 1 ) {
-
- listeners[ type ].splice( index, 1 );
-
- }
-
- };
-
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * This helper function will automatically detect which renderer you should be using.
- * WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
- * the browser then this function will return a canvas renderer
- *
- * @method autoDetectRenderer
- * @static
- * @param width {Number} the width of the renderers view
- * @param height {Number} the height of the renderers view
- * @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 webGL chrome at the moment)
- *
- * antialias
- */
-PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
-{
- if(!width)width = 800;
- if(!height)height = 600;
-
- // BORROWED from Mr Doob (mrdoob.com)
- var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )();
-
- //console.log(webgl);
- if( webgl )
- {
- return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
- }
-
- return new PIXI.CanvasRenderer(width, height, view, transparent);
-};
-
-
-
-/*
- PolyK library
- url: http://polyk.ivank.net
- Released under MIT licence.
-
- 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:
-
- 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.
-
- This is an amazing lib!
-
- slightly modified by mat groves (matgroves.com);
-*/
-
-PIXI.PolyK = {};
-
-/**
- * Triangulates shapes for webGL graphic fills
- *
- * @method Triangulate
- * @namespace PolyK
- * @constructor
- */
-PIXI.PolyK.Triangulate = function(p)
-{
- var sign = true;
-
- var n = p.length>>1;
- if(n<3) return [];
- var tgs = [];
- var avl = [];
- for(var i=0; i 3)
- {
- var i0 = avl[(i+0)%al];
- var i1 = avl[(i+1)%al];
- var i2 = avl[(i+2)%al];
-
- 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];
-
- 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= 0) && (v >= 0) && (u + v < 1);
-}
-
-/**
- * Checks if a shape is convex
- *
- * @class _convex
- * @namespace PolyK
- * @private
- */
-PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
-{
- return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/*
- * the default suoer fast shader!
- */
-
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
-
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
-
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * the triangle strip shader..
- */
-
-PIXI.stripShaderFragmentSrc = [
- "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;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.shaderStack = [];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
-
- //gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-//gl.enableVertexAttribArray(program.textureCoordAttribute);
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-
-
-}
-
-PIXI.initDefaultShader = function()
-{
- PIXI.defaultShader = new PIXI.PixiShader();
- PIXI.defaultShader.init();
- PIXI.activateShader(PIXI.defaultShader);
- /*
- PIXI.shaderStack.push(PIXI.defaultShader);
- PIXI.current*/
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
-
-PIXI.CompileVertexShader = function(gl, shaderSrc)
-{
- return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
-}
-
-PIXI.CompileFragmentShader = function(gl, shaderSrc)
-{
- 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);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(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();
-
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
-
- return shaderProgram;
-}
-
-PIXI.activateShader = function(shader)
-{
- PIXI.shaderStack.push(shader);
-
- //console.log(">>>")
- var gl = PIXI.gl;
-
- var shaderProgram = shader.program;
-
- // map uniforms..
- gl.useProgram(shaderProgram);
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
-
- shader.syncUniforms();
-
- PIXI.currentShader = shaderProgram;
-}
-
-
-PIXI.popShader = function()
-{
- var gl = PIXI.gl;
- // activate last program..
- var lastProgram = PIXI.shaderStack.pop();
-
- var shaderProgram = PIXI.shaderStack[ PIXI.shaderStack.length-1 ].program;
-
- gl.useProgram(shaderProgram);
-
- PIXI.currentShader = shaderProgram;
-}
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.primitiveProgram);
-
- //gl.disableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.disableVertexAttribArray(PIXI.currentShader.colorAttribute);
- gl.disableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
-
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute);
-}
-
-PIXI.deactivatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.currentShader);
-
- gl.enableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.colorAttribute);
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-PIXI.PixiShader = function()
-{
- // the webGL program..
- this.program;
-
- this.fragmentSrc = [
- "precision lowp float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
- "}"
- ];
-
-}
-
-PIXI.PixiShader.prototype.init = function()
-{
- var program = PIXI.compileProgram(this.vertexSrc || PIXI.shaderVertexSrc, this.fragmentSrc)
-
- var gl = PIXI.gl;
-
- gl.useProgram(program);
-
- // get the default shader bits!
- program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
- program.colorAttribute = gl.getAttribLocation(program, "aColor");
- program.textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
-
- program.projectionVector = gl.getUniformLocation(program, "projectionVector");
- program.samplerUniform = gl.getUniformLocation(program, "uSampler");
-
- // add those custom shaders!
- for (var key in this.uniforms)
- {
- // get the uniform locations..
- program[key] = gl.getUniformLocation(program, key);
- }
-
- this.program = program;
-}
-
-PIXI.PixiShader.prototype.syncUniforms = function()
-{
- var gl = PIXI.gl;
-
- for (var key in this.uniforms)
- {
- //var
- var type = this.uniforms[key].type;
-
- // need to grow this!
- if(type == "f")
- {
- gl.uniform1f(this.program[key], this.uniforms[key].value);
- }
- else if(type == "mat4")
- {
- gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- }
- }
-
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A set of functions used by the webGL renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.WebGLGraphics = function()
-{
-
-}
-
-/**
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param projection {Object}
- */
-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);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
-
- // WHY DOES THIS LINE NEED TO BE THERE???
- //gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.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
- *
- * @static
- * @private
- * @method updateGraphics
- * @param graphics {Graphics}
- */
-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;
-
- 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
- *
- * @static
- * @private
- * @method buildRectangle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- }
-
-}
-
-/**
- * Builds a circle to draw
- *
- * @static
- * @private
- * @method buildCircle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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;
-
- 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);
- }
-
-}
-
-/**
- * Builds a line to draw
- *
- * @static
- * @private
- * @method buildLine
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
-{
- // TODO OPTIMISE!
-
- var wrap = true;
- var points = graphicsData.points;
- if(points.length == 0)return;
-
- // 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;
-
- 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 (denom == 0) {
- denom+=1;
- }
-
- 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 (var i=0; i < indexCount; i++)
- {
- indices.push(indexStart++);
- };
-
- indices.push(indexStart-1);
-}
-
-/**
- * Builds a polygon to draw
- *
- * @static
- * @private
- * @method buildPoly
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- };
-}
-
-function HEXtoRGB(hex) {
- return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
-
-// an instance of the gl context..
-// only one at the moment :/
-PIXI.gl;
-
-/**
- * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
- * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
- * So no need for Sprite Batch's or Sprite Cloud's
- * Dont forget to add the view to your DOM or you will not see anything :)
- *
- * @class WebGLRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @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..
-
- this.transparent = !!transparent;
-
- this.width = width || 800;
- this.height = height || 600;
-
- this.view = view || document.createElement( 'canvas' );
- this.view.width = this.width;
- this.view.height = this.height;
-
- // 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.batchs = [];
-
- try
- {
- PIXI.gl = this.gl = this.view.getContext("experimental-webgl", {
- alpha: this.transparent,
- antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
- stencil:true
- });
- }
- catch (e)
- {
- throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
- }
-
- PIXI.initDefaultShader();
- PIXI.initPrimitiveShader();
- PIXI.initDefaultStripShader();
-
-
-// PIXI.activateDefaultShader();
-
- var gl = this.gl;
- PIXI.WebGLRenderer.gl = gl;
-
- this.batch = new PIXI.WebGLBatch(gl);
- gl.disable(gl.DEPTH_TEST);
- gl.disable(gl.CULL_FACE);
-
- gl.enable(gl.BLEND);
- gl.colorMask(true, true, true, this.transparent);
-
- PIXI.projection = new PIXI.Point(400, 300);
-
- this.resize(this.width, this.height);
- this.contextLost = false;
-
- PIXI.activateShader(PIXI.defaultShader);
-
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
-
-}
-
-// constructor
-PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
-
-/**
- * Gets a new WebGLBatch from the pool
- *
- * @static
- * @method getBatch
- * @return {WebGLBatch}
- * @private
- */
-PIXI.WebGLRenderer.getBatch = function()
-{
- if(PIXI._batchs.length == 0)
- {
- return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
- }
- else
- {
- return PIXI._batchs.pop();
- }
-}
-
-/**
- * Puts a batch back into the pool
- *
- * @static
- * @method returnBatch
- * @param batch {WebGLBatch} The batch to return
- * @private
- */
-PIXI.WebGLRenderer.returnBatch = function(batch)
-{
- batch.clean();
- PIXI._batchs.push(batch);
-}
-
-/**
- * Renders the stage to its webGL view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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);
- }
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
-
- // 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;
- 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
- *
- * @static
- * @method updateTextures
- * @private
- */
-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 = [];
-}
-
-/**
- * Updates a loaded webgl texture
- *
- * @static
- * @method updateTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.updateTexture = function(texture)
-{
- //TODO break this out into a texture manager...
- var gl = PIXI.gl;
-
- if(!texture._glTexture)
- {
- texture._glTexture = gl.createTexture();
- }
-
- if(texture.hasLoaded)
- {
- gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
-
- 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);
-
- // reguler...
-
- 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
- *
- * @method destroyTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.destroyTexture = function(texture)
-{
- //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);
- }
-}
-
-/**
- * resizes the webGL view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the webGL view
- * @param height {Number} the new height of the webGL view
- */
-PIXI.WebGLRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-
- this.gl.viewport(0, 0, this.width, this.height);
-
- //var projectionMatrix = this.projectionMatrix;
-
- 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;
-}
-
-/**
- * Handles a lost webgl context
- *
- * @method handleContextLost
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
-{
- event.preventDefault();
- this.contextLost = true;
-}
-
-/**
- * Handles a restored webgl context
- *
- * @method handleContextRestored
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
-{
- this.gl = this.view.getContext("experimental-webgl", {
- alpha: true
- });
-
- this.initShaders();
-
- 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;
- };
-
- PIXI._restoreBatchs(this.gl);
-
- this.contextLost = false;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._batchs = [];
-
-/**
- * @private
- */
-PIXI._getBatch = function(gl)
-{
- 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);
-}
-
-/**
- * @private
- */
-PIXI._restoreBatchs = function(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.
- * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
- * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
- * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
- * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @constructor
- * @param gl {WebGLContext} an instance of the webGL context
- */
-PIXI.WebGLBatch = function(gl)
-{
- this.gl = gl;
-
- 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;
-
-/**
- * Cleans the batch so that is can be returned to an object pool and reused
- *
- * @method clean
- */
-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;
-}
-
-/**
- * Recreates the buffers in the event of a context loss
- *
- * @method restoreLostContext
- * @param gl {WebGLContext}
- */
-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();
-}
-
-/**
- * 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
- */
-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;
-
- this.growBatch();
-}
-
-/**
- * inserts a sprite before the specified 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++;
-
- 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;
- }
-}
-
-/**
- * inserts a sprite after the specified sprite
- *
- * @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++;
-
- sprite.batch = this;
- this.dirty = true;
-
- var tempNext = previousSprite.__next;
- previousSprite.__next = sprite;
- sprite.__prev = previousSprite;
-
- 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--;
-
- 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.__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;
-}
-
-/**
- * Splits the batch into two with the specified sprite being the start of the new batch.
- *
- * @method split
- * @param sprite {Sprite} the sprite that indicates where the batch should be split
- * @return {WebGLBatch} the new batch
- */
-PIXI.WebGLBatch.prototype.split = function(sprite)
-{
- this.dirty = true;
-
- 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;
-
- 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"?
-
- // 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;
-
- return batch;
-}
-
-/**
- * Merges two batchs together
- *
- * @method merge
- * @param batch {WebGLBatch} the batch that will be merged
- */
-PIXI.WebGLBatch.prototype.merge = function(batch)
-{
- this.dirty = true;
-
- this.tail.__next = batch.head;
- batch.head.__prev = this.tail;
-
- this.size += batch.size;
-
- this.tail = batch.tail;
-
- 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
- * function is used to increase the size of the batch. It also creates a little extra room so
- * that the batch does not need to be resized every time a sprite is added
- *
- * @method growBatch
- */
-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);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
-
- 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.dirtyUVS = 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.dirtyColors = true;
-
- this.indices = new Uint16Array(this.dynamicSize * 6);
- var length = this.indices.length/6;
-
- 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
- *
- * @method refresh
- */
-PIXI.WebGLBatch.prototype.refresh = function()
-{
- var gl = this.gl;
-
- if (this.dynamicSize < this.size)
- {
- this.growBatch();
- }
-
- 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;
-
- while(displayObject)
- {
- index = indexRun * 8;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
-
- colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
-
- displayObject = displayObject.__next;
-
- indexRun ++;
- }
-
- this.dirtyUVS = true;
- this.dirtyColors = true;
-}
-
-/**
- * Updates all the relevant geometry and uploads the data to the GPU
- *
- * @method update
- */
-PIXI.WebGLBatch.prototype.update = function()
-{
- var gl = this.gl;
- var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3
-
- var a, b, c, d, tx, ty;
-
- var indexRun = 0;
-
- var displayObject = this.head;
-
- while(displayObject)
- {
- if(displayObject.vcount === PIXI.visibleCount)
- {
- width = displayObject.texture.frame.width;
- height = displayObject.texture.frame.height;
-
- // 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;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- index = indexRun * 8;
-
- worldTransform = displayObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- this.verticies[index + 0 ] = a * w1 + c * h1 + tx;
- this.verticies[index + 1 ] = d * h1 + b * w1 + ty;
-
- this.verticies[index + 2 ] = a * w0 + c * h1 + tx;
- this.verticies[index + 3 ] = d * h1 + b * w0 + ty;
-
- this.verticies[index + 4 ] = a * w0 + c * h0 + tx;
- this.verticies[index + 5 ] = d * h0 + b * w0 + ty;
-
- this.verticies[index + 6] = a * w1 + c * h0 + tx;
- this.verticies[index + 7] = d * h0 + b * w1 + ty;
-
- if(displayObject.updateFrame || displayObject.texture.updateFrame)
- {
- this.dirtyUVS = true;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
- }
-
- // TODO this probably could do with some optimisation....
- if(displayObject.cacheAlpha != displayObject.worldAlpha)
- {
- displayObject.cacheAlpha = displayObject.worldAlpha;
-
- var colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
- this.dirtyColors = true;
- }
- }
- else
- {
- index = indexRun * 8;
-
- this.verticies[index + 0 ] = 0;
- this.verticies[index + 1 ] = 0;
-
- this.verticies[index + 2 ] = 0;
- this.verticies[index + 3 ] = 0;
-
- this.verticies[index + 4 ] = 0;
- this.verticies[index + 5 ] = 0;
-
- this.verticies[index + 6] = 0;
- this.verticies[index + 7] = 0;
- }
-
- indexRun++;
- displayObject = displayObject.__next;
- }
-}
-
-/**
- * Draws the batch to the frame buffer
- *
- * @method render
- */
-PIXI.WebGLBatch.prototype.render = function(start, end)
-{
- start = start || 0;
-
- if(end == undefined)end = this.size;
-
- if(this.dirty)
- {
- this.refresh();
- this.dirty = false;
- }
-
- if (this.size == 0)return;
-
- this.update();
- var gl = this.gl;
-
- //TODO optimize this!
-
- var shaderProgram = PIXI.currentShader;
-
- //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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // update the uvs
- var isDefault = (shaderProgram == PIXI.shaderProgram)
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
-
- if(this.dirtyUVS)
- {
- this.dirtyUVS = false;
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
- }
-
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
-
- // update color!
- gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
-
- if(this.dirtyColors)
- {
- 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!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
-
- var len = end - start;
-
- // DRAW THAT this!
- gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
- * if a group of sprites all have the same baseTexture and blendMode then they can be
- * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
- * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
- * even if the batch only contains one sprite. Batching is handled automatically by the
- * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @contructor
- * @param gl {WebGLContext} An instance of the webGL context
- */
-PIXI.WebGLRenderGroup = function(gl)
-{
- this.gl = gl;
- this.root;
-
- this.backgroundColor;
- this.batchs = [];
- this.toRemove = [];
-}
-
-// constructor
-PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
-
-/**
- * Add a display object to the webgl renderer
- *
- * @method setRenderable
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
-{
- // has this changed??
- if(this.root)this.removeDisplayObjectAndChildren(this.root);
-
- displayObject.worldVisible = displayObject.visible;
-
- // soooooo //
- // to check if any batchs exist already??
-
- // TODO what if its already has an object? should remove it
- this.root = displayObject;
- this.addDisplayObjectAndChildren(displayObject);
-}
-
-/**
- * Renders the stage to its webgl view
- *
- * @method render
- * @param projection {Object}
- */
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
-
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- // will render all the elements in the group
- var renderable;
- for (var i=0; i < this.batchs.length; i++)
- {
-
- renderable = this.batchs[i];
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- continue;
- }
-
- // non sprite batch..
- var worldVisible = renderable.vcount === PIXI.visibleCount;
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
- }
-
-}
-
-/**
- * Renders a specific displayObject
- *
- * @method renderSpecific
- * @param displayObject {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- // to do!
- // render part of the scene...
-
- var startIndex;
- var startBatchIndex;
-
- var endIndex;
- var endBatchIndex;
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.first;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
- var startBatch = nextRenderable.batch;
-
- if(nextRenderable instanceof PIXI.Sprite)
- {
- startBatch = nextRenderable.batch;
-
- var head = startBatch.head;
- var next = head;
-
- // ok now we have the batch.. need to find the start index!
- if(head == nextRenderable)
- {
- startIndex = 0;
- }
- else
- {
- startIndex = 1;
-
- while(head.__next != nextRenderable)
- {
- startIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- startBatch = nextRenderable;
- }
-
- // Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
- {
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem.last;
- }
-
- if(lastRenderable instanceof PIXI.Sprite)
- {
- endBatch = lastRenderable.batch;
-
- var head = endBatch.head;
-
- if(head == lastRenderable)
- {
- endIndex = 0;
- }
- else
- {
- endIndex = 1;
-
- while(head.__next != lastRenderable)
- {
- endIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- endBatch = lastRenderable;
- }
-
- // TODO - need to fold this up a bit!
-
- if(startBatch == endBatch)
- {
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex, endIndex+1);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
- return;
- }
-
- // now we have first and last!
- startBatchIndex = this.batchs.indexOf(startBatch);
- endBatchIndex = this.batchs.indexOf(endBatch);
-
- // DO the first batch
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
-
- // DO the middle batchs..
- for (var i=startBatchIndex+1; i < endBatchIndex; i++)
- {
- renderable = this.batchs[i];
-
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- }
- else
- {
- this.renderSpecial(renderable, projection);
- }
- }
-
- // DO the last batch..
- if(endBatch instanceof PIXI.WebGLBatch)
- {
- endBatch.render(0, endIndex+1);
- }
- else
- {
- this.renderSpecial(endBatch, projection);
- }
-}
-
-/**
- * Renders a specific renderable
- *
- * @method renderSpecial
- * @param renderable {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
-{
- var sta = PIXI.shaderStack.length;
-
- var worldVisible = renderable.vcount === PIXI.visibleCount
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.CustomRenderable)
- {
- if(worldVisible) renderable.renderWebGL(this, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
-}
-
-PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection)
-{
- /*
- * for now only masks are supported..
- */
- var gl = PIXI.gl;
-
- if(renderable.open)
- {
- if(renderable.data instanceof Array)
- {
- var filter = renderable.data[0];
-
- if(!filter.shader)
- {
- var shader = new PIXI.PixiShader();
-
- shader.fragmentSrc = filter.fragmentSrc;
- shader.uniforms = filter.uniforms;
- shader.init();
-
- filter.shader = shader
- }
-
- PIXI.activateShader(filter.shader);
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
- PIXI.WebGLGraphics.renderGraphics(renderable.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- }
- else
- {
- if(renderable.data instanceof Array)
- {
- PIXI.popShader();
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
-}
-
-/**
- * Updates a webgl texture
- *
- * @method updateTexture
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
-{
-
- // TODO definitely can optimse this function..
-
- this.removeObject(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- this.insertObject(displayObject, previousRenderable, nextRenderable);
-}
-
-/**
- * Adds filter blocks
- *
- * @method addFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
-{
- start.__renderGroup = this;
- end.__renderGroup = this;
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = start;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
- this.insertAfter(start, previousRenderable);
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var previousRenderable2 = end;
- while(previousRenderable2 != this.root.first)
- {
- previousRenderable2 = previousRenderable2._iPrev;
- if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
- }
- this.insertAfter(end, previousRenderable2);
-}
-
-/**
- * Remove filter blocks
- *
- * @method removeFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
-{
- this.removeObject(start);
- this.removeObject(end);
-}
-
-/**
- * Adds a display object and children to the webgl context
- *
- * @method addDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
-
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- // one the display object hits this. we can break the loop
-
- var tempObject = displayObject.first;
- var testObject = displayObject.last._iNext;
- do
- {
- tempObject.__renderGroup = this;
-
- if(tempObject.renderable)
- {
-
- this.insertObject(tempObject, previousRenderable, nextRenderable);
- previousRenderable = tempObject;
- }
-
- tempObject = tempObject._iNext;
- }
- while(tempObject != testObject)
-}
-
-/**
- * Removes a display object and children to the webgl context
- *
- * @method removeDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup != this)return;
-
-// var displayObject = displayObject.first;
- var lastObject = displayObject.last;
- do
- {
- displayObject.__renderGroup = null;
- if(displayObject.renderable)this.removeObject(displayObject);
- displayObject = displayObject._iNext;
- }
- while(displayObject)
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertObject
- * @param displayObject {DisplayObject}
- * @param previousObject {DisplayObject}
- * @param nextObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
-{
- // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
- var previousSprite = previousObject;
- var nextSprite = nextObject;
-
- /*
- * so now we have the next renderable and the previous renderable
- *
- */
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch
- var nextBatch
-
- if(previousSprite instanceof PIXI.Sprite)
- {
- previousBatch = previousSprite.batch;
- if(previousBatch)
- {
- if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
- {
- previousBatch.insertAfter(displayObject, previousSprite);
- return;
- }
- }
- }
- else
- {
- // TODO reword!
- previousBatch = previousSprite;
- }
-
- if(nextSprite)
- {
- if(nextSprite instanceof PIXI.Sprite)
- {
- nextBatch = nextSprite.batch;
-
- //batch may not exist if item was added to the display list but not to the webGL
- if(nextBatch)
- {
- if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
- {
- nextBatch.insertBefore(displayObject, nextSprite);
- return;
- }
- else
- {
- if(nextBatch == previousBatch)
- {
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(nextSprite);
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var batch = PIXI.WebGLRenderer.getBatch();
-
- var index = this.batchs.indexOf( previousBatch );
- batch.init(displayObject);
- this.batchs.splice(index+1, 0, batch, splitBatch);
-
- return;
- }
- }
- }
- }
- else
- {
- // TODO re-word!
-
- nextBatch = nextSprite;
- }
- }
-
- /*
- * looks like it does not belong to any batch!
- * but is also not intersecting one..
- * time to create anew one!
- */
-
- var batch = PIXI.WebGLRenderer.getBatch();
- batch.init(displayObject);
-
- if(previousBatch) // if this is invalid it means
- {
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, batch);
- }
- else
- {
- this.batchs.push(batch);
- }
-
- return;
- }
- else if(displayObject instanceof PIXI.TilingSprite)
- {
-
- // add to a batch!!
- this.initTilingSprite(displayObject);
- // this.batchs.push(displayObject);
-
- }
- else if(displayObject instanceof PIXI.Strip)
- {
- // add to a batch!!
- this.initStrip(displayObject);
- // this.batchs.push(displayObject);
- }
- else if(displayObject)// instanceof PIXI.Graphics)
- {
- //displayObject.initWebGL(this);
-
- // add to a batch!!
- //this.initStrip(displayObject);
- //this.batchs.push(displayObject);
- }
-
- this.insertAfter(displayObject, previousSprite);
-
- // insert and SPLIT!
-
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertAfter
- * @param item {DisplayObject}
- * @param displayObject {DisplayObject} The object to insert
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
-{
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch = displayObject.batch;
-
- if(previousBatch)
- {
- // so this object is in a batch!
-
- // is it not? need to split the batch
- if(previousBatch.tail == displayObject)
- {
- // is it tail? insert in to batchs
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item);
- }
- else
- {
- // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
-
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(displayObject.__next);
-
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item, splitBatch);
- }
- }
- else
- {
- this.batchs.push(item);
- }
- }
- else
- {
- var index = this.batchs.indexOf( displayObject );
- this.batchs.splice(index+1, 0, item);
- }
-}
-
-/**
- * Removes a displayObject from the linked list
- *
- * @method removeObject
- * @param displayObject {DisplayObject} The object to remove
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
-{
- // loop through children..
- // display object //
-
- // add a child from the render group..
- // remove it and all its children!
- //displayObject.cacheVisible = false;//displayObject.visible;
-
- /*
- * removing is a lot quicker..
- *
- */
- var batchToRemove;
-
- if(displayObject instanceof PIXI.Sprite)
- {
- // should always have a batch!
- var batch = displayObject.batch;
- if(!batch)return; // this means the display list has been altered befre rendering
-
- batch.remove(displayObject);
-
- if(batch.size==0)
- {
- batchToRemove = batch;
- }
- }
- else
- {
- batchToRemove = displayObject;
- }
-
- /*
- * Looks like there is somthing that needs removing!
- */
- if(batchToRemove)
- {
- var index = this.batchs.indexOf( batchToRemove );
- if(index == -1)return;// this means it was added then removed before rendered
-
- // ok so.. check to see if you adjacent batchs should be joined.
- // TODO may optimise?
- if(index == 0 || index == this.batchs.length-1)
- {
- // wha - eva! just get of the empty batch!
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
-
- return;
- }
-
- if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
- {
- if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
- {
- //console.log("MERGE")
- this.batchs[index-1].merge(this.batchs[index+1]);
-
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
- this.batchs.splice(index, 2);
- return;
- }
- }
-
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- }
-}
-
-
-/**
- * Initializes a tiling sprite
- *
- * @method initTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
-{
- var gl = this.gl;
-
- // make the texture tilable..
-
- sprite.verticies = new Float32Array([0, 0,
- sprite.width, 0,
- sprite.width, sprite.height,
- 0, sprite.height]);
-
- sprite.uvs = new Float32Array([0, 0,
- 1, 0,
- 1, 1,
- 0, 1]);
-
- sprite.colors = new Float32Array([1,1,1,1]);
-
- sprite.indices = new Uint16Array([0, 1, 3,2])//, 2]);
-
- sprite._vertexBuffer = gl.createBuffer();
- sprite._indexBuffer = gl.createBuffer();
- sprite._uvBuffer = gl.createBuffer();
- sprite._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.uvs, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW);
-
-// return ( (x > 0) && ((x & (x - 1)) == 0) );
-
- if(sprite.texture.baseTexture._glTexture)
- {
- gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- sprite.texture.baseTexture._powerOf2 = true;
- }
- else
- {
- sprite.texture.baseTexture._powerOf2 = true;
- }
-}
-
-/**
- * Renders a Strip
- *
- * @method renderStrip
- * @param strip {Strip} The strip to render
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.stripShaderProgram;
-
-
- gl.useProgram(shaderProgram);
-
- var m = PIXI.mat3.clone(strip.worldTransform);
-
- PIXI.mat3.transpose(m);
-
- // set the matrix transform for the
- gl.uniformMatrix3fv(shaderProgram.translationMatrix, false, m);
- gl.uniform2f(shaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(shaderProgram.alpha, strip.worldAlpha);
-
-/*
- if(strip.blendMode == PIXI.blendModes.NORMAL)
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
- }
- */
-
-
- if(!strip.dirty)
- {
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- }
- else
- {
- strip.dirty = false;
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-
- }
-
- gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
-
- gl.useProgram(PIXI.currentProgram);
-}
-
-/**
- * Renders a TilingSprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to render
- * @param projectionMatrix {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- var tilePosition = sprite.tilePosition;
- var tileScale = sprite.tileScale;
-
- var offsetX = tilePosition.x/sprite.texture.baseTexture.width;
- var offsetY = tilePosition.y/sprite.texture.baseTexture.height;
-
- var scaleX = (sprite.width / sprite.texture.baseTexture.width) / tileScale.x;
- var scaleY = (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
-
- sprite.uvs[0] = 0 - offsetX;
- sprite.uvs[1] = 0 - offsetY;
-
- sprite.uvs[2] = (1 * scaleX) -offsetX;
- sprite.uvs[3] = 0 - offsetY;
-
- sprite.uvs[4] = (1 *scaleX) - offsetX;
- sprite.uvs[5] = (1 *scaleY) - offsetY;
-
- sprite.uvs[6] = 0 - offsetX;
- sprite.uvs[7] = (1 *scaleY) - offsetY;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
-
- this.renderStrip(sprite, projectionMatrix);
-}
-
-/**
- * Initializes a strip to be rendered
- *
- * @method initStrip
- * @param strip {Strip} The strip to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
-{
- // build the strip!
- var gl = this.gl;
- var shaderProgram = this.shaderProgram;
-
- strip._vertexBuffer = gl.createBuffer();
- strip._indexBuffer = gl.createBuffer();
- strip._uvBuffer = gl.createBuffer();
- strip._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-}
-
-
-/**
- * @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 :)
- *
- * @class CanvasRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
- */
-PIXI.CanvasRenderer = function(width, height, view, transparent)
-{
- this.transparent = transparent;
-
- /**
- * 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 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");
-
- 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;
-}
-
-// constructor
-PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
-
-/**
- * Renders the stage to its canvas view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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;
-
- 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 = [];
- }
-
-
-}
-
-/**
- * resizes the canvas view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the canvas view
- * @param height {Number} the new height of the canvas view
- */
-PIXI.CanvasRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-}
-
-/**
- * Renders a display object
- *
- * @method renderDisplayObject
- * @param displayObject {DisplayObject} The displayObject to render
- * @private
- */
-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)
- {
-
- var frame = displayObject.texture.frame;
-
- if(frame && frame.width && frame.height)
- {
- 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)
- {
- 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(PIXI.FilterBlock.data instanceof PIXI.Graphics)
- {
- if(displayObject.open)
- {
- context.save();
-
- var cacheAlpha = displayObject.mask.alpha;
- var maskTransform = displayObject.mask.worldTransform;
-
- context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
-
- displayObject.mask.worldAlpha = 0.5;
-
- context.worldAlpha = 0;
-
- PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context);
- context.clip();
-
- displayObject.mask.worldAlpha = cacheAlpha;
- }
- else
- {
- context.restore();
- }
- }
- else
- {
- // only masks supported right now!
- }
- }
- // count++
- displayObject = displayObject._iNext;
-
-
- }
- while(displayObject != testObject)
-
-
-}
-
-/**
- * Renders a flat strip
- *
- * @method renderStripFlat
- * @param strip {Strip} The Strip to render
- * @private
- */
-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();
-}
-
-/**
- * Renders a tiling sprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tilingsprite to render
- * @private
- */
-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;
-
- // 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.translate(-tilePosition.x, -tilePosition.y);
-
- context.closePath();
-}
-
-/**
- * Renders a strip
- *
- * @method renderStrip
- * @param strip {Strip} The Strip to render
- * @private
- */
-PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
-{
- 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;
-
-
- 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();
- };
-
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * A set of functions used by the canvas renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.CanvasGraphics = function()
-{
-
-}
-
-
-/*
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- 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.lineWidth = data.lineWidth;
-
- 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]);
- }
-
- // 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.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]);
- }
-
- }
- 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
-
- 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
- *
- * @static
- * @private
- * @method renderGraphicsMask
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- var len = graphics.graphicsData.length;
- if(len > 1)
- {
- len = 1;
- 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;
-
- 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]);
- }
-
- // 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
- }
-
-
- };
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
- * It is important to know that with the webGL renderer only simple polys can be filled at this stage
- * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
- *
- * @class Graphics
- * @extends DisplayObjectContainer
- * @constructor
- */
-PIXI.Graphics = function()
-{
- PIXI.DisplayObjectContainer.call( this );
-
- this.renderable = true;
-
- /**
- * The alpha of the fill of this graphics object
- *
- * @property fillAlpha
- * @type Number
- */
- this.fillAlpha = 1;
-
- /**
- * The width of any lines drawn
- *
- * @property lineWidth
- * @type Number
- */
- this.lineWidth = 0;
-
- /**
- * The color of any lines drawn
- *
- * @property lineColor
- * @type String
- */
- this.lineColor = "black";
-
- /**
- * Graphics data
- *
- * @property graphicsData
- * @type Array
- * @private
- */
- this.graphicsData = [];
-
- /**
- * Current path
- *
- * @property currentPath
- * @type Object
- * @private
- */
- this.currentPath = {points:[]};
-}
-
-// constructor
-PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Graphics.prototype.constructor = PIXI.Graphics;
-
-/**
- * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
- *
- * @method lineStyle
- * @param lineWidth {Number} width of the line to draw, will update the object's stored style
- * @param color {Number} color of the line to draw, will update the object's stored style
- * @param alpha {Number} alpha of the line to draw, will update the object's stored style
- */
-PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
-{
- if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.lineWidth = lineWidth || 0;
- this.lineColor = color || 0;
- this.lineAlpha = (alpha == undefined) ? 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.graphicsData.push(this.currentPath);
-}
-
-/**
- * Moves the current drawing position to (x, y).
- *
- * @method moveTo
- * @param x {Number} the X coord to move to
- * @param y {Number} the Y coord to move to
- */
-PIXI.Graphics.prototype.moveTo = function(x, y)
-{
- if(this.currentPath.points.length == 0)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.points.push(x, y);
-
- this.graphicsData.push(this.currentPath);
-}
-
-/**
- * Draws a line using the current line style from the current drawing position to (x, y);
- * the current drawing position is then set to (x, y).
- *
- * @method lineTo
- * @param x {Number} the X coord to draw to
- * @param y {Number} the Y coord to draw to
- */
-PIXI.Graphics.prototype.lineTo = function(x, y)
-{
- this.currentPath.points.push(x, y);
- this.dirty = true;
-}
-
-/**
- * Specifies a simple one-color fill that subsequent calls to other Graphics methods
- * (such as lineTo() or drawCircle()) use when drawing.
- *
- * @method beginFill
- * @param color {uint} the color of the fill
- * @param alpha {Number} the alpha
- */
-PIXI.Graphics.prototype.beginFill = function(color, alpha)
-{
- this.filling = true;
- this.fillColor = color || 0;
- this.fillAlpha = (alpha == undefined) ? 1 : alpha;
-}
-
-/**
- * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
- *
- * @method endFill
- */
-PIXI.Graphics.prototype.endFill = function()
-{
- this.filling = false;
- this.fillColor = null;
- this.fillAlpha = 1;
-}
-
-/**
- * @method drawRect
- *
- * @param x {Number} The X coord of the top-left of the rectangle
- * @param y {Number} The Y coord of the top-left of the rectangle
- * @param width {Number} The width of the rectangle
- * @param height {Number} The height of the rectangle
- */
-PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws a circle.
- *
- * @method drawCircle
- * @param x {Number} The X coord of the center of the circle
- * @param y {Number} The Y coord of the center of the circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws an elipse.
- *
- * @method drawElipse
- * @param x {Number}
- * @param y {Number}
- * @param width {Number}
- * @param height {Number}
- */
-PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
- *
- * @method clear
- */
-PIXI.Graphics.prototype.clear = function()
-{
- this.lineWidth = 0;
- this.filling = false;
-
- this.dirty = true;
- this.clearDirty = true;
- this.graphicsData = [];
-}
-
-// SOME TYPES:
-PIXI.Graphics.POLY = 0;
-PIXI.Graphics.RECT = 1;
-PIXI.Graphics.CIRC = 2;
-PIXI.Graphics.ELIP = 3;
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-PIXI.Strip = function(texture, width, height)
-{
- 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]);
-
- this.verticies = new Float32Array([0, 0,
- 0,0,
- 0,0, 0,
- 0, 0]);
-
- 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.verticies = [0, 0,
- 0,0,
- 0,0, 0,
- 0, 0];
-
- this.colors = [1, 1, 1, 1];
-
- 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;
-
- // 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;
-}
-
-// constructor
-PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Strip.prototype.constructor = PIXI.Strip;
-
-PIXI.Strip.prototype.setTexture = function(texture)
-{
- //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;
-}
-
-PIXI.Strip.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-// some helper functions..
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-
-PIXI.Rope = function(texture, points)
-{
- PIXI.Strip.call( this, texture );
- this.points = points;
-
- try
- {
- this.verticies = new Float32Array( points.length * 4);
- this.uvs = new Float32Array( points.length * 4);
- this.colors = new Float32Array( points.length * 2);
- this.indices = new Uint16Array( points.length * 2);
- }
- catch(error)
- {
- this.verticies = verticies
-
- this.uvs = uvs
- this.colors = colors
- this.indices = indices
- }
-
- this.refresh();
-}
-
-
-// constructor
-PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
-PIXI.Rope.prototype.constructor = PIXI.Rope;
-
-PIXI.Rope.prototype.refresh = function()
-{
- var points = this.points;
- if(points.length < 1)return;
-
- var uvs = this.uvs
- var indices = this.indices;
- var colors = this.colors;
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
-
- uvs[0] = 0
- uvs[1] = 1
- uvs[2] = 0
- uvs[3] = 1
-
- colors[0] = 1;
- colors[1] = 1;
-
- indices[0] = 0;
- indices[1] = 1;
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
- // time to do some smart drawing!
- var amount = i/(total-1)
-
- if(i%2)
- {
- uvs[index] = amount;
- uvs[index+1] = 0;
-
- uvs[index+2] = amount
- uvs[index+3] = 1
-
- }
- else
- {
- uvs[index] = amount
- uvs[index+1] = 0
-
- uvs[index+2] = amount
- uvs[index+3] = 1
- }
-
- index = i * 2;
- colors[index] = 1;
- colors[index+1] = 1;
-
- index = i * 2;
- indices[index] = index;
- indices[index + 1] = index + 1;
-
- lastPoint = point;
- }
-}
-
-PIXI.Rope.prototype.updateTransform = function()
-{
-
- var points = this.points;
- if(points.length < 1)return;
-
- var verticies = this.verticies
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
- verticies[0] = point.x + perp.x
- verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
- verticies[3] = point.y - perp.y//+200
- // time to do some smart drawing!
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
-
- if(i < points.length-1)
- {
- nextPoint = points[i+1];
- }
- else
- {
- nextPoint = point
- }
-
- perp.y = -(nextPoint.x - lastPoint.x);
- perp.x = nextPoint.y - lastPoint.y;
-
- var ratio = (1 - (i / (total-1))) * 10;
- if(ratio > 1)ratio = 1;
-
- 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;
-
- 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;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
-}
-
-PIXI.Rope.prototype.setTexture = function(texture)
-{
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * A tiling sprite is a fast way of rendering a tiling image
- *
- * @class TilingSprite
- * @extends DisplayObjectContainer
- * @constructor
- * @param texture {Texture} the texture of the tiling sprite
- * @param width {Number} the width of the tiling sprite
- * @param height {Number} the height of the tiling sprite
- */
-PIXI.TilingSprite = function(texture, width, height)
-{
- PIXI.DisplayObjectContainer.call( this );
-
- /**
- * 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 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 offset position of the image that is being tiled
- *
- * @property tilePosition
- * @type Point
- */
- this.tilePosition = new PIXI.Point(0,0);
-
- this.renderable = true;
-
- this.blendMode = PIXI.blendModes.NORMAL
-}
-
-// constructor
-PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
-
-/**
- * Sets the texture of the tiling sprite
- *
- * @method setTexture
- * @param texture {Texture} The PIXI texture that is displayed by the sprite
- */
-PIXI.TilingSprite.prototype.setTexture = function(texture)
-{
- //TODO SET THE TEXTURES
- //TODO VISIBILITY
-
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-/**
- * When the texture is updated, this event will fire to update the frame
- *
- * @method onTextureUpdate
- * @param event
- * @private
- */
-PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
- *
- * Awesome JS run time provided by EsotericSoftware
- * https://github.com/EsotericSoftware/spine-runtimes
- *
- */
-
-/**
- * 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
- * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
- *
- * @class Spine
- * @extends DisplayObjectContainer
- * @constructor
- * @param url {String} The url of the spine anim file to be used
- */
-PIXI.Spine = function (url) {
- PIXI.DisplayObjectContainer.call(this);
-
- this.spineData = PIXI.AnimCache[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.stateData = new spine.AnimationStateData(this.spineData);
- this.state = new spine.AnimationState(this.stateData);
-
- 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);
- }
-};
-
-PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.Spine.prototype.constructor = PIXI.Spine;
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @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();
-
- 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;
-
- 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.rotation = -(slot.bone.worldRotation * Math.PI / 180);
- }
-
- 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;
-
- 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;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * This object is one that will allow you to specify custom rendering functions based on render type
- *
- * @class CustomRenderable
- * @extends DisplayObject
- * @constructor
- */
-PIXI.CustomRenderable = function()
-{
- PIXI.DisplayObject.call( this );
-
-}
-
-// constructor
-PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
-
-/**
- * If this object is being rendered by a CanvasRenderer it will call this callback
- *
- * @method renderCanvas
- * @param renderer {CanvasRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderCanvas = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback to initialize
- *
- * @method initWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.initWebGL = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback
- *
- * @method renderWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderWebGL = function(renderGroup, projectionMatrix)
-{
- // not sure if both needed? but ya have for now!
- // override!
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.BaseTextureCache = {};
-PIXI.texturesToUpdate = [];
-PIXI.texturesToDestroy = [];
-
-/**
- * A texture stores the information that represents an image. All textures have a base texture
- *
- * @class BaseTexture
- * @uses EventTarget
- * @constructor
- * @param source {String} the source object (image or canvas)
- */
-PIXI.BaseTexture = function(source)
-{
- 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 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 source that is loaded to create the texture
- *
- * @property source
- * @type Image
- */
- this.source = source;
-
- if(!source)return;
-
- 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;
-
- PIXI.texturesToUpdate.push(this);
- }
- else
- {
-
- var scope = this;
- this.source.onload = function(){
-
- scope.hasLoaded = true;
- scope.width = scope.source.width;
- scope.height = scope.source.height;
-
- // 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;
-
- PIXI.texturesToUpdate.push(this);
- }
-
- this._powerOf2 = false;
-}
-
-PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
-
-/**
- * Destroys this base texture
- *
- * @method destroy
- */
-PIXI.BaseTexture.prototype.destroy = function()
-{
- if(this.source instanceof Image)
- {
- this.source.src = null;
- }
- this.source = null;
- PIXI.texturesToDestroy.push(this);
-}
-
-/**
- * Helper function that returns a base texture based on an image url
- * If the image is not in the base texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @return BaseTexture
- */
-PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
-{
- 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);
- PIXI.BaseTextureCache[imageUrl] = baseTexture;
- }
-
- return baseTexture;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.TextureCache = {};
-PIXI.FrameCache = {};
-
-/**
- * A texture stores the information that represents an image or part of an image. It cannot be added
- * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
- *
- * @class Texture
- * @uses EventTarget
- * @constructor
- * @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frame {Rectangle} The rectangle frame of the texture to show
- */
-PIXI.Texture = function(baseTexture, frame)
-{
- PIXI.EventTarget.call( this );
-
- if(!frame)
- {
- this.noFrame = true;
- frame = new PIXI.Rectangle(0,0,1,1);
- }
-
- if(baseTexture instanceof PIXI.Texture)
- baseTexture = baseTexture.baseTexture;
-
- /**
- * The base texture of this texture
- *
- * @property baseTexture
- * @type BaseTexture
- */
- this.baseTexture = baseTexture;
-
- /**
- * The frame specifies the region of the base texture that this texture uses
- *
- * @property frame
- * @type Rectangle
- */
- this.frame = frame;
-
- /**
- * The trim point
- *
- * @property trim
- * @type Point
- */
- this.trim = new PIXI.Point();
-
- this.scope = this;
-
- if(baseTexture.hasLoaded)
- {
- if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- //console.log(frame)
-
- this.setFrame(frame);
- }
- else
- {
- var scope = this;
- baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} );
- }
-}
-
-PIXI.Texture.prototype.constructor = PIXI.Texture;
-
-/**
- * Called when the base texture is loaded
- *
- * @method onBaseTextureLoaded
- * @param event
- * @private
- */
-PIXI.Texture.prototype.onBaseTextureLoaded = function(event)
-{
- var baseTexture = this.baseTexture;
- baseTexture.removeEventListener( 'loaded', this.onLoaded );
-
- if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- this.noFrame = false;
- this.width = this.frame.width;
- this.height = this.frame.height;
-
- this.scope.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Destroys this texture
- *
- * @method destroy
- * @param destroyBase {Boolean} Whether to destroy the base texture as well
- */
-PIXI.Texture.prototype.destroy = function(destroyBase)
-{
- if(destroyBase)this.baseTexture.destroy();
-}
-
-/**
- * Specifies the rectangle region of the baseTexture
- *
- * @method setFrame
- * @param frame {Rectangle} The frame of the texture to set it to
- */
-PIXI.Texture.prototype.setFrame = function(frame)
-{
- this.frame = frame;
- this.width = frame.width;
- this.height = frame.height;
-
- 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;
-
- PIXI.Texture.frameUpdates.push(this);
- //this.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Helper function that returns a texture based on an image url
- * If the image is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- * @return Texture
- */
-PIXI.Texture.fromImage = function(imageUrl, crossorigin)
-{
- var texture = PIXI.TextureCache[imageUrl];
-
- if(!texture)
- {
- texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
- PIXI.TextureCache[imageUrl] = texture;
- }
-
- return texture;
-}
-
-/**
- * Helper function that returns a texture based on a frame id
- * If the frame id is not in the texture cache an error will be thrown
- *
- * @static
- * @method fromFrame
- * @param frameId {String} The frame id of the texture
- * @return Texture
- */
-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;
-}
-
-/**
- * Helper function that returns a texture based on a canvas element
- * If the canvas is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromCanvas
- * @param canvas {Canvas} The canvas element source of the texture
- * @return Texture
- */
-PIXI.Texture.fromCanvas = function(canvas)
-{
- var baseTexture = new PIXI.BaseTexture(canvas);
- return new PIXI.Texture(baseTexture);
-}
-
-
-/**
- * Adds a texture to the textureCache.
- *
- * @static
- * @method addTextureToCache
- * @param texture {Texture}
- * @param id {String} the id that the texture will be stored against.
- */
-PIXI.Texture.addTextureToCache = function(texture, id)
-{
- PIXI.TextureCache[id] = texture;
-}
-
-/**
- * Remove a texture from the textureCache.
- *
- * @static
- * @method removeTextureFromCache
- * @param id {String} the id of the texture to be removed
- * @return {Texture} the texture that was removed
- */
-PIXI.Texture.removeTextureFromCache = function(id)
-{
- var texture = PIXI.TextureCache[id]
- PIXI.TextureCache[id] = null;
- return texture;
-}
-
-// this is more for webGL.. it contains updated frames..
-PIXI.Texture.frameUpdates = [];
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- 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.
-
- 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);
-
- 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
-
- @class RenderTexture
- @extends Texture
- @constructor
- @param width {Number} The width of the render texture
- @param height {Number} The height of the render texture
- */
-PIXI.RenderTexture = function(width, height)
-{
- PIXI.EventTarget.call( this );
-
- this.width = width || 100;
- this.height = height || 100;
-
- this.indetityMatrix = PIXI.mat3.create();
-
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
-
- if(PIXI.gl)
- {
- this.initWebGL();
- }
- else
- {
- this.initCanvas();
- }
-}
-
-PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
-PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
-
-/**
- * Initializes the webgl data for this texture
- *
- * @method initWebGL
- * @private
- */
-PIXI.RenderTexture.prototype.initWebGL = function()
-{
- var gl = PIXI.gl;
- this.glFramebuffer = gl.createFramebuffer();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // 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);
- }
-}
-
-/**
- * Initializes the canvas data for this texture
- *
- * @method initCanvas
- * @private
- */
-PIXI.RenderTexture.prototype.initCanvas = function()
-{
- 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.render = this.renderCanvas;
-}
-
-/**
- * This function will draw the display object to the texture.
- *
- * @method renderWebGL
- * @param displayObject {DisplayObject} The display object to render this texture on
- * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
- * @private
- */
-PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
-{
- var gl = PIXI.gl;
-
- // enable the alpha color mask..
- gl.colorMask(true, true, true, true);
-
- gl.viewport(0, 0, this.width, this.height);
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- if(clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
-
- // 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;
-
-
- 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} 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".
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.AssetLoader = function(assetURLs, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The array of asset URLs that are going to be loaded
- *
- * @property assetURLs
- * @type Array
- */
- this.assetURLs = assetURLs;
-
- /**
- * Whether the requests should be treated as cross origin
- *
- * @property crossorigin
- * @type Boolean
- */
- this.crossorigin = crossorigin;
-
- /**
- * Maps file extension to loader types
- *
- * @property loadersByType
- * @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
- };
-
-
-};
-
-/**
- * Fired when an item has loaded
- * @event onProgress
- */
-
-/**
- * Fired when all the assets have loaded
- * @event onComplete
- */
-
-// constructor
-PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
-
-/**
- * Starts loading the assets sequentially
- *
- * @method load
- */
-PIXI.AssetLoader.prototype.load = function()
-{
- var scope = this;
-
- this.loadCount = this.assetURLs.length;
-
- for (var i=0; i < this.assetURLs.length; i++)
- {
- var fileName = this.assetURLs[i];
- var fileType = fileName.split(".").pop().toLowerCase();
-
- var loaderClass = this.loadersByType[fileType];
- if(!loaderClass)
- throw new Error(fileType + " is an unsupported file type");
-
- var loader = new loaderClass(fileName, this.crossorigin);
-
- loader.addEventListener("loaded", function()
- {
- scope.onAssetLoaded();
- });
- loader.load();
- }
-};
-
-/**
- * Invoked after each file is loaded
- *
- * @method onAssetLoaded
- * @private
- */
-PIXI.AssetLoader.prototype.onAssetLoaded = function()
-{
- this.loadCount--;
- 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();
- }
-};
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class JsonLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the JSON file
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.JsonLoader = function (url, crossorigin) {
- PIXI.EventTarget.call(this);
-
- /**
- * 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;
-
- /**
- * [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;
-
-};
-
-// constructor
-PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
-
-/**
- * Loads the JSON data
- *
- * @method load
- */
-PIXI.JsonLoader.prototype.load = function () {
- this.ajaxRequest = new 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);
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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.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();
- });
-
- 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();
-
- }
- 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();
- }
- }
-};
-
-/**
- * Invoke when json file loaded
- *
- * @method onLoaded
- * @private
- */
-PIXI.JsonLoader.prototype.onLoaded = function () {
- this.loaded = true;
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * Invoke when error occured
- *
- * @method onError
- * @private
- */
-PIXI.JsonLoader.prototype.onError = function () {
- this.dispatchEvent({
- type: "error",
- content: this
- });
-};
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- * 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.
- * 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
- *
- * @class SpriteSheetLoader
- * @uses EventTarget
- * @constructor
- * @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);
-
- /**
- * 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;
-
- /**
- * [read-only] The base url of the bitmap font data
- *
- * @property baseUrl
- * @type String
- * @readOnly
- */
- this.baseUrl = url.replace(/[^\/]*$/, "");
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = null;
-
- /**
- * The frames of the sprite sheet
- *
- * @property frames
- * @type Object
- */
- this.frames = {};
-};
-
-// constructor
-PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader;
-
-/**
- * This will begin loading the JSON file
- *
- * @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();
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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;
-
- this.texture = image.texture.baseTexture;
- image.addEventListener("loaded", function (event) {
- 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!
- }
- }
- }
-
- image.load();
-};
-/**
- * Invoke when all files are loaded (json and texture)
- *
- * @method onLoaded
- * @private
- */
-PIXI.SpriteSheetLoader.prototype.onLoaded = function () {
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class ImageLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the image
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.ImageLoader = function(url, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = PIXI.Texture.fromImage(url, crossorigin);
-
- /**
- * if the image is loaded with loadFramedSpriteSheet
- * frames will contain the sprite sheet frames
- *
- */
- this.frames = [];
-};
-
-// constructor
-PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader;
-
-/**
- * Loads image or takes it from cache
- *
- * @method load
- */
-PIXI.ImageLoader.prototype.load = function()
-{
- if(!this.texture.baseTexture.hasLoaded)
- {
- var scope = this;
- this.texture.baseTexture.addEventListener("loaded", function()
- {
- scope.onLoaded();
- });
- }
- else
- {
- this.onLoaded();
- }
-};
-
-/**
- * Invoked when image file is loaded or it is already cached and ready to use
- *
- * @method onLoaded
- * @private
- */
-PIXI.ImageLoader.prototype.onLoaded = function()
-{
- this.dispatchEvent({type: "loaded", content: this});
-};
-
-/**
- * Loads image and split it to uniform sized frames
- *
- *
- * @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
- */
-PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
-{
- this.frames = [];
- var cols = Math.floor(this.texture.width / frameWidth);
- var rows = Math.floor(this.texture.height / frameHeight);
-
- var i=0;
- for (var y=0; y
-
+
diff --git a/examples/example 5 - Morph/pixi.js b/examples/example 5 - Morph/pixi.js
deleted file mode 100644
index 6d567a2..0000000
--- a/examples/example 5 - Morph/pixi.js
+++ /dev/null
@@ -1,10649 +0,0 @@
-/**
- * @license
- * Pixi.JS - v1.3.0
- * Copyright (c) 2012, Mat Groves
- * http://goodboydigital.com/
- *
- * Compiled: 2013-09-30
- *
- * Pixi.JS is licensed under the MIT License.
- * http://www.opensource.org/licenses/mit-license.php
- */
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-(function(){
-
- var root = this;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * @module PIXI
- */
-var PIXI = PIXI || {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
- *
- * @class Point
- * @constructor
- * @param x {Number} position of the point
- * @param y {Number} position of the point
- */
-PIXI.Point = function(x, y)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-}
-
-/**
- * Creates a clone of this point
- *
- * @method clone
- * @return {Point} a copy of the point
- */
-PIXI.Point.prototype.clone = function()
-{
- return new PIXI.Point(this.x, this.y);
-}
-
-// constructor
-PIXI.Point.prototype.constructor = PIXI.Point;
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
- *
- * @class Rectangle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the rectangle
- * @param y {Number} The Y coord of the upper-left corner of the rectangle
- * @param width {Number} The overall width of this rectangle
- * @param height {Number} The overall height of this rectangle
- */
-PIXI.Rectangle = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Rectangle
- *
- * @method clone
- * @return {Rectangle} a copy of the rectangle
- */
-PIXI.Rectangle.prototype.clone = function()
-{
- 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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this Rectangle
- */
-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;
-
- if(y >= y1 && y <= y1 + this.height)
- {
- return true;
- }
- }
-
- return false;
-}
-
-// constructor
-PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
-
-
-/**
- * @author Adrien Brault
- */
-
-/**
- * @class Polygon
- * @constructor
- * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
- * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
- * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
- * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
- * Numbers.
- */
-PIXI.Polygon = function(points)
-{
- //if points isn't an array, use arguments as the array
- if(!(points instanceof Array))
- points = Array.prototype.slice.call(arguments);
-
- //if this is a flat array of numbers, convert it to points
- if(typeof points[0] === 'number') {
- var p = [];
- for(var i = 0, il = points.length; i < il; i+=2) {
- p.push(
- new PIXI.Point(points[i], points[i + 1])
- );
- }
-
- points = p;
- }
-
- this.points = points;
-}
-
-/**
- * Creates a clone of this polygon
- *
- * @method clone
- * @return {Polygon} a copy of the polygon
- */
-PIXI.Polygon.prototype.clone = function()
-{
- var points = [];
- for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
-
- if(intersect) inside = !inside;
- }
-
- return inside;
-}
-
-// constructor
-PIXI.Polygon.prototype.constructor = PIXI.Polygon;
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Circle object can be used to specify a hit area for displayobjects
- *
- * @class Circle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Circle = function(x, y, radius)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property radius
- * @type Number
- * @default 0
- */
- this.radius = radius || 0;
-}
-
-/**
- * Creates a clone of this Circle instance
- *
- * @method clone
- * @return {Circle} a copy of the polygon
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
- */
-PIXI.Circle.prototype.contains = function(x, y)
-{
- if(this.radius <= 0)
- return false;
-
- var dx = (this.x - x),
- dy = (this.y - y),
- r2 = this.radius * this.radius;
-
- dx *= dx;
- dy *= dy;
-
- return (dx + dy <= r2);
-}
-
-// constructor
-PIXI.Circle.prototype.constructor = PIXI.Circle;
-
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Ellipse object can be used to specify a hit area for displayobjects
- *
- * @class Ellipse
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
- * @param width {Number} The overall width of this ellipse
- * @param height {Number} The overall height of this ellipse
- */
-PIXI.Ellipse = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Ellipse instance
- *
- * @method clone
- * @return {Ellipse} a copy of the ellipse
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this ellipse
- */
-PIXI.Ellipse.prototype.contains = function(x, y)
-{
- if(this.width <= 0 || this.height <= 0)
- return false;
-
- //normalize the coords to an ellipse with center 0,0
- //and a radius of 0.5
- var normx = ((x - this.x) / this.width) - 0.5,
- normy = ((y - this.y) / this.height) - 0.5;
-
- normx *= normx;
- normy *= normy;
-
- return (normx + normy < 0.25);
-}
-
-PIXI.Ellipse.getBounds = function()
-{
- return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
-}
-
-// constructor
-PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
-
-
-
-/*
- * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
- * you both rock!
- */
-
-function determineMatrixArrayType() {
- PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return PIXI.Matrix;
-}
-
-determineMatrixArrayType();
-
-PIXI.mat3 = {};
-
-PIXI.mat3.create = function()
-{
- 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;
-
- 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;
-
- return matrix;
-}
-
-
-PIXI.mat4 = {};
-
-PIXI.mat4.create = function()
-{
- 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;
-
- return matrix;
-}
-
-PIXI.mat3.multiply = function (mat, mat2, dest)
-{
- 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],
-
- 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[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;
-
- return dest;
-}
-
-PIXI.mat3.clone = function(mat)
-{
- 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];
-
- 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 (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
-}
-
-PIXI.mat3.toMat4 = function (mat, dest)
-{
- if (!dest) { dest = PIXI.mat4.create(); }
-
- 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[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];
-
- return dest;
-}
-
-
-/////
-
-
-PIXI.mat4.create = function()
-{
- 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;
-
- 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];
-
- 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;
-}
-
-PIXI.mat4.multiply = function (mat, mat2, dest)
-{
- 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 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;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The base class for all objects that are rendered on the screen.
- *
- * @class DisplayObject
- * @constructor
- */
-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();
-
- /**
- * 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 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 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 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;
-
- /**
- * [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 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] Current transform of the object based on world (parent) factors
- *
- * @property worldTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.worldTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [read-only] Current transform of the object locally
- *
- * @property localTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.localTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [NYI] Unkown
- *
- * @property color
- * @type Array<>
- * @private
- */
- this.color = [];
-
- /**
- * [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;
-
- /*
- * MOUSE Callbacks
- */
-
- /**
- * 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 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
- * 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 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 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
- */
-
- /**
- * 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 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}
- */
-}
-
-// constructor
-PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
-
-/**
- * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default
- * Instead of using this function you can now simply set the interactive property to true or false
- *
- * @method setInteractive
- * @param interactive {Boolean}
- * @deprecated Simply set the `interactive` property directly
- */
-PIXI.DisplayObject.prototype.setInteractive = function(interactive)
-{
- this.interactive = interactive;
-}
-
-/**
- * Indicates if the sprite will have touch and mouse interactivity. It is false by default
- *
- * @property interactive
- * @type Boolean
- * @default false
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
- get: function() {
- 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;
- }
-});
-
-/**
- * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
- * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
- * To remove a mask, set this property to null.
- *
- * @property mask
- * @type Graphics
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
- get: function() {
- 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;
- }
- }
- else
- {
- this.removeFilter(this._mask);
- this._mask.renderable = true;
- }
-
- this._mask = value;
- }
-});
-
-/**
- * Sets the filters for the displayObject. Currently there's a few limitations.
- * 1: At the moment only one filter can be applied at a time..
- * 2: They cannot be nested.
- * 3: There's no padding yet.
- * 4: this is a webGL only feature.
- * @property filters
- * @type Array
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
- get: function() {
- return this._filters;
- },
- set: function(value) {
-
- //if(value == )
- if(value)
- {
- if(this._filters)this.removeFilter(this._filters);
- this.addFilter(value)
- }
- else
- {
- if(this._filters)this.removeFilter(this._filters);
- }
-
- this._filters = value;
- }
-});
-
-/*
- * Adds a filter to this displayObject
- *
- * @method addFilter
- * @param mask {Graphics} the graphics object to use as a filter
- * @private
- */
-PIXI.DisplayObject.prototype.addFilter = function(data)
-{
- //if(this.filter)return;
- //this.filter = true;
-
- // 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;
-
- /*
- * 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);
- }
-
-}
-
-/*
- * Removes the filter to this displayObject
- *
- * @method removeFilter
- * @private
- */
-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);
- }
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-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;
-
- // 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],
-
- b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
- b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
-
- 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;
-
- worldTransform[3] = b10 * a00 + b11 * a10;
- 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;
-
-}
-
-PIXI.visibleCount = 0;
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * 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
- * @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 = [];
-}
-
-// constructor
-PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-
-/**
- * Adds a child to the container.
- *
- * @method addChild
- * @param child {DisplayObject} The DisplayObject to add to the container
- */
-PIXI.DisplayObjectContainer.prototype.addChild = function(child)
-{
- if(child.parent != undefined)
- {
-
- //// 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)
- {
- 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
- *
- * @method addChildAt
- * @param child {DisplayObject} The child to add
- * @param index {Number} The index to place the child in
- */
-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;
-
- 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
- *
- * @method swapChildren
- * @param child {DisplayObject}
- * @param child2 {DisplayObject}
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
-{
- /*
- * this funtion needs to be recoded..
- * can be done a lot faster..
- */
- return;
-
- // need to fix this function :/
- /*
- // TODO I already know this??
- var index = this.children.indexOf( child );
- var index2 = this.children.indexOf( child2 );
-
- if ( index !== -1 && index2 !== -1 )
- {
- // cool
-
- /*
- if(this.stage)
- {
- // this is to satisfy the webGL batching..
- // TODO sure there is a nicer way to achieve this!
- this.stage.__removeChild(child);
- this.stage.__removeChild(child2);
-
- this.stage.__addChild(child);
- this.stage.__addChild(child2);
- }
-
- // swap the positions..
- this.children[index] = child2;
- this.children[index2] = child;
-
- }
- else
- {
- throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
- }*/
-}
-
-/**
- * Returns the Child at the specified index
- *
- * @method getChildAt
- * @param index {Number} The index to get the child from
- */
-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);
- }
-}
-
-/**
- * Removes a child from the container.
- *
- * @method removeChild
- * @param child {DisplayObject} The DisplayObject to remove
- */
-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 tempLast = childFirst._iPrev;
- // need to make sure the parents last is updated too
- var updateLast = this;
- while(updateLast.last == childLast.last)
- {
- 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
- *
- * @method updateTransform
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.updateTransform = function()
-{
- if(!this.visible)return;
-
- PIXI.DisplayObject.prototype.updateTransform.call( this );
-
- for(var i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation
- */
-PIXI.MovieClip = function(textures)
-{
- PIXI.Sprite.call(this, textures[0]);
-
- /**
- * The array of textures that make up the animation
- *
- * @property textures
- * @type Array
- */
- this.textures = textures;
-
- /**
- * The speed that the MovieClip will play at. Higher is faster, lower is slower
- *
- * @property animationSpeed
- * @type Number
- * @default 1
- */
- this.animationSpeed = 1;
-
- /**
- * Whether or not the movie clip repeats after playing.
- *
- * @property loop
- * @type Boolean
- * @default true
- */
- this.loop = true;
-
- /**
- * Function to call when a MovieClip finishes playing
- *
- * @property onComplete
- * @type Function
- */
- this.onComplete = null;
-
- /**
- * [read-only] The index MovieClips current frame (this may not have to be a whole number)
- *
- * @property currentFrame
- * @type Number
- * @default 0
- * @readOnly
- */
- this.currentFrame = 0;
-
- /**
- * [read-only] Indicates if the MovieClip is currently playing
- *
- * @property playing
- * @type Boolean
- * @readOnly
- */
- this.playing = false;
-}
-
-// constructor
-PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
-PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
-
-/**
-* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
-* assigned to the MovieClip.
-*
-* @property totalFrames
-* @type Number
-* @default 0
-* @readOnly
-*/
-Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
- get: function() {
-
- return this.textures.length;
- }
-});
-
-
-/**
- * Stops the MovieClip
- *
- * @method stop
- */
-PIXI.MovieClip.prototype.stop = function()
-{
- this.playing = false;
-}
-
-/**
- * Plays the MovieClip
- *
- * @method play
- */
-PIXI.MovieClip.prototype.play = function()
-{
- this.playing = true;
-}
-
-/**
- * Stops the MovieClip and goes to a specific frame
- *
- * @method gotoAndStop
- * @param frameNumber {Number} frame index to stop at
- */
-PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
-{
- this.playing = false;
- this.currentFrame = frameNumber;
- var round = (this.currentFrame + 0.5) | 0;
- this.setTexture(this.textures[round % this.textures.length]);
-}
-
-/**
- * Goes to a specific frame and begins playing the MovieClip
- *
- * @method gotoAndPlay
- * @param frameNumber {Number} frame index to start at
- */
-PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
-{
- this.currentFrame = frameNumber;
- this.playing = true;
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.MovieClip.prototype.updateTransform = function()
-{
- PIXI.Sprite.prototype.updateTransform.call(this);
-
- if(!this.playing)return;
-
- this.currentFrame += this.animationSpeed;
-
- var round = (this.currentFrame + 0.5) | 0;
-
- 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();
- }
- }
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.FilterBlock = function()
-{
- this.visible = true;
- this.renderable = true;
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.ColorMatrixFilter = function()
-{
- // 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;",
- "}"
- ];
-
-}
-
-
-Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
- get: function() {
- return this.uniforms.matrix.value;
- },
- set: function(value) {
- this.uniforms.matrix.value = value;
- }
-});
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.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");
- PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
-
- this.setText(text);
- this.setStyle(style);
-
- this.updateText();
- this.dirty = false;
-};
-
-// constructor
-PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype);
-PIXI.Text.prototype.constructor = PIXI.Text;
-
-/**
- * Set the style of the 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.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.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.strokeThickness = style.strokeThickness || 0;
- style.wordWrap = style.wordWrap || false;
- style.wordWrapWidth = style.wordWrapWidth || 100;
- this.style = style;
- this.dirty = true;
-};
-
-/**
- * Set the copy for the text object. To split a line you can use "\n"
- *
- * @methos 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.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.Text.prototype.updateText = function()
-{
- this.context.font = this.style.font;
-
- var outputText = 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)/);
-
- //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;
-
- //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.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);
-
- 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.fill)
- {
- this.context.fillText(lines[i], linePosition.x, linePosition.y);
- }
- }
-
- this.updateTexture();
-};
-
-/**
- * Updates texture size based on canvas size
- *
- * @method updateTexture
- * @private
- */
-PIXI.Text.prototype.updateTexture = function()
-{
- this.texture.baseTexture.width = this.canvas.width;
- this.texture.baseTexture.height = this.canvas.height;
- this.texture.frame.width = this.canvas.width;
- this.texture.frame.height = this.canvas.height;
-
- this._width = this.canvas.width;
- this._height = this.canvas.height;
-
- PIXI.texturesToUpdate.push(this.texture.baseTexture);
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.Text.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- this.updateText();
- this.dirty = false;
- }
-
- PIXI.Sprite.prototype.updateTransform.call(this);
-};
-
-/*
- * http://stackoverflow.com/users/34441/ellisbben
- * great solution to the problem!
- *
- * @method determineFontHeight
- * @param fontStyle {Object}
- * @private
- */
-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];
-
- 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;
-
- body.removeChild(dummy);
- }
-
- return result;
-};
-
-/**
- * A Text Object will apply wordwrap
- *
- * @method wordWrap
- * @param text {String}
- * @private
- */
-PIXI.Text.prototype.wordWrap = function(text)
-{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
- var result = "";
- var lines = text.split("\n");
- for (var i = 0; i < lines.length; i++)
- {
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
- }
-
- return result;
-};
-
-/**
- * Destroys this text object
- *
- * @method destroy
- * @param destroyTexture {Boolean}
- */
-PIXI.Text.prototype.destroy = function(destroyTexture)
-{
- if(destroyTexture)
- {
- this.texture.destroy();
- }
-
-};
-
-PIXI.Text.heightCache = {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.
- *
- * @class BitmapText
- * @extends DisplayObjectContainer
- * @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")
- */
-PIXI.BitmapText = function(text, style)
-{
- PIXI.DisplayObjectContainer.call(this);
-
- this.setText(text);
- this.setStyle(style);
- this.updateText();
- this.dirty = false
-
-};
-
-// constructor
-PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
-
-/**
- * Set the copy for the text object
- *
- * @method setText
- * @param text {String} The copy that you would like the text to display
- */
-PIXI.BitmapText.prototype.setText = function(text)
-{
- this.text = text || " ";
- this.dirty = true;
-};
-
-/**
- * Set the style of the 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")
- */
-PIXI.BitmapText.prototype.setStyle = function(style)
-{
- style = style || {};
- style.align = style.align || "left";
- this.style = style;
-
- 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;
-
- this.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.BitmapText.prototype.updateText = function()
-{
- var data = PIXI.BitmapText.fonts[this.fontName];
- var pos = new PIXI.Point();
- var prevCharCode = null;
- var chars = [];
- var maxLineWidth = 0;
- var lineWidths = [];
- var line = 0;
- var scale = this.fontSize / data.size;
- for(var i = 0; i < this.text.length; i++)
- {
- var charCode = this.text.charCodeAt(i);
- if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
- {
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
- line++;
-
- pos.x = 0;
- pos.y += data.lineHeight;
- prevCharCode = null;
- continue;
- }
-
- var charData = data.chars[charCode];
- if(!charData) continue;
-
- if(prevCharCode && charData[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;
-
- prevCharCode = charCode;
- }
-
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
-
- var lineAlignOffsets = [];
- for(i = 0; i <= line; i++)
- {
- var alignOffset = 0;
- if(this.style.align == "right")
- {
- alignOffset = maxLineWidth - lineWidths[i];
- }
- else if(this.style.align == "center")
- {
- alignOffset = (maxLineWidth - lineWidths[i]) / 2;
- }
- lineAlignOffsets.push(alignOffset);
- }
-
- for(i = 0; i < chars.length; i++)
- {
- 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;
- this.addChild(c);
- }
-
- this.width = pos.x * scale;
- this.height = (pos.y + data.lineHeight) * scale;
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.BitmapText.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- while(this.children.length > 0)
- {
- this.removeChild(this.getChildAt(0));
- }
- this.updateText();
-
- this.dirty = false;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
-};
-
-PIXI.BitmapText.fonts = {};
-
-/**
- * @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.
- *
- * @class InteractionManager
- * @constructor
- * @param stage {Stage} The stage to handle interactions
- */
-PIXI.InteractionManager = function(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();
-
- /**
- * 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();
-
- this.mouseoverEnabled = true;
-
- //tiny little interactiveData pool!
- this.pool = [];
-
- 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.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;
-
-/**
- * Collects an interactive sprite recursively to have their interactions managed
- *
- * @method collectInteractiveSprite
- * @param displayObject {DisplayObject} the displayObject to collect
- * @param iParent {DisplayObject}
- * @private
- */
-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);
-
- 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
- *
- * @method setTarget
- * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to
- * @private
- */
-PIXI.InteractionManager.prototype.setTarget = function(target)
-{
- this.target = target;
-
- //check if the dom element has been set. If it has don't do anything
- if( this.interactionDOMElement === null ) {
-
- this.setTargetDomElement( target.view );
- }
-
- document.body.addEventListener('mouseup', this.onMouseUp, true);
-}
-
-
-/**
- * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
- * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
- * to receive those events
- *
- * @method setTargetDomElement
- * @param domElement {DOMElement} the dom element which will receive mouse and touch events
- * @private
- */
-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'] = '';
-
- 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);
- }
-
-
- 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!
- }
-
- this.interactionDOMElement = domElement;
-
- 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
- *
- * @method update
- * @private
- */
-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 = "default";
-
- 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 = "pointer";
-
- 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
- *
- * @method onMouseMove
- * @param event {Event} The DOM event of the mouse moving
- * @private
- */
-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);
- }
- }
-}
-
-/**
- * Is called when the mouse button is pressed down on the renderer element
- *
- * @method onMouseDown
- * @param event {Event} The DOM event of a mouse button being pressed down
- * @private
- */
-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;
- }
- }
- }
-}
-
-
-PIXI.InteractionManager.prototype.onMouseOut = function(event)
-{
- var length = this.interactiveItems.length;
-
- this.interactionDOMElement.style.cursor = "default";
-
- 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
- *
- * @method onMouseUp
- * @param event {Event} The DOM event of a mouse button being released
- * @private
- */
-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;
- }
- }
-}
-
-/**
- * Tests if the current mouse coords hit a sprite
- *
- * @method hitTest
- * @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
- * @private
- */
-PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
-{
- var global = interactionData.global;
-
- if(item.vcount !== PIXI.visibleCount)return false;
-
- 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;
-
- 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;
-
- 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
- *
- * @method onTouchMove
- * @param event {Event} The DOM event of a touch moving accross the renderer view
- * @private
- */
-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);
- }
-}
-
-/**
- * Is called when a touch is started on the renderer element
- *
- * @method onTouchStart
- * @param event {Event} The DOM event of a touch starting on the renderer view
- * @private
- */
-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;
- }
- }
- }
- }
-}
-
-/**
- * Is called when a touch is ended on the renderer element
- *
- * @method onTouchEnd
- * @param event {Event} The DOM event of a touch ending on the renderer view
- * @private
- */
-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;
- }
-}
-
-/**
- * Holds all information related to an Interaction event
- *
- * @class InteractionData
- * @constructor
- */
-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();
-
- /**
- * The target Sprite that was interacted with
- *
- * @property target
- * @type Sprite
- */
- this.target;
-
- /**
- * When passed to an event handler, this will be the original DOM Event that was captured
- *
- * @property originalEvent
- * @type Event
- */
- this.originalEvent;
-}
-
-/**
- * This will return the local coords of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
- */
-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],
- 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)
-}
-
-// constructor
-PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A Stage represents the root of the display tree. Everything connected to the stage is rendered
- *
- * @class Stage
- * @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
- */
-PIXI.Stage = function(backgroundColor)
-{
- 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();
-
- /**
- * 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);
-
- /**
- * Whether the stage is dirty and needs to have interactions updated
- *
- * @property dirty
- * @type Boolean
- * @private
- */
- this.dirty = true;
-
- this.__childrenAdded = [];
- this.__childrenRemoved = [];
-
- //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);
-
- this.setBackgroundColor(backgroundColor);
- this.worldVisible = true;
-}
-
-// constructor
-PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Stage.prototype.constructor = PIXI.Stage;
-
-/**
- * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
- * This is useful for when you have other DOM elements ontop of the Canvas element.
- *
- * @method setInteractionDelegate
- * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
- */
-PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
-{
- this.interactionManager.setTargetDomElement( domElement );
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.Stage.prototype.updateTransform = function()
-{
- this.worldAlpha = 1;
- this.vcount = PIXI.visibleCount;
-
- for(var i=0,j=this.children.length; i> 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 target != 'function') throw new TypeError();
-
- 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);
-
- return bound;
- };
- })();
-}
-
-/**
- * A wrapper for ajax requests to be handled cross browser
- *
- * @class AjaxRequest
- * @constructor
- */
-var AjaxRequest = PIXI.AjaxRequest = function()
-{
- 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);
-
- while(tmp._iNext)
- {
- safe++;
- tmp = tmp._iNext;
- console.log(tmp);
- // console.log(tmp);
-
- if(safe > 100)
- {
- console.log("BREAK")
- break
- }
- }
-}
-
-
-
-
-
-
-/**
- * https://github.com/mrdoob/eventtarget.js/
- * THankS mr DOob!
- */
-
-/**
- * Adds event emitter functionality to a class
- *
- * @class EventTarget
- * @example
- * function MyEmitter() {
- * PIXI.EventTarget.call(this); //mixes in event target stuff
- * }
- *
- * var em = new MyEmitter();
- * em.emit({ type: 'eventName', data: 'some data' });
- */
-PIXI.EventTarget = function () {
-
- var listeners = {};
-
- this.addEventListener = this.on = function ( type, listener ) {
-
-
- if ( listeners[ type ] === undefined ) {
-
- listeners[ type ] = [];
-
- }
-
- if ( listeners[ type ].indexOf( listener ) === - 1 ) {
-
- listeners[ type ].push( listener );
- }
-
- };
-
- this.dispatchEvent = this.emit = function ( event ) {
-
- if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
-
- return;
-
- }
-
- for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
-
- listeners[ event.type ][ i ]( event );
-
- }
-
- };
-
- this.removeEventListener = this.off = function ( type, listener ) {
-
- var index = listeners[ type ].indexOf( listener );
-
- if ( index !== - 1 ) {
-
- listeners[ type ].splice( index, 1 );
-
- }
-
- };
-
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * This helper function will automatically detect which renderer you should be using.
- * WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
- * the browser then this function will return a canvas renderer
- *
- * @method autoDetectRenderer
- * @static
- * @param width {Number} the width of the renderers view
- * @param height {Number} the height of the renderers view
- * @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 webGL chrome at the moment)
- *
- * antialias
- */
-PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
-{
- if(!width)width = 800;
- if(!height)height = 600;
-
- // BORROWED from Mr Doob (mrdoob.com)
- var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )();
-
- //console.log(webgl);
- if( webgl )
- {
- return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
- }
-
- return new PIXI.CanvasRenderer(width, height, view, transparent);
-};
-
-
-
-/*
- PolyK library
- url: http://polyk.ivank.net
- Released under MIT licence.
-
- 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:
-
- 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.
-
- This is an amazing lib!
-
- slightly modified by mat groves (matgroves.com);
-*/
-
-PIXI.PolyK = {};
-
-/**
- * Triangulates shapes for webGL graphic fills
- *
- * @method Triangulate
- * @namespace PolyK
- * @constructor
- */
-PIXI.PolyK.Triangulate = function(p)
-{
- var sign = true;
-
- var n = p.length>>1;
- if(n<3) return [];
- var tgs = [];
- var avl = [];
- for(var i=0; i 3)
- {
- var i0 = avl[(i+0)%al];
- var i1 = avl[(i+1)%al];
- var i2 = avl[(i+2)%al];
-
- 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];
-
- 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= 0) && (v >= 0) && (u + v < 1);
-}
-
-/**
- * Checks if a shape is convex
- *
- * @class _convex
- * @namespace PolyK
- * @private
- */
-PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
-{
- return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/*
- * the default suoer fast shader!
- */
-
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
-
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
-
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * the triangle strip shader..
- */
-
-PIXI.stripShaderFragmentSrc = [
- "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;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.shaderStack = [];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
-
- //gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-//gl.enableVertexAttribArray(program.textureCoordAttribute);
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-
-
-}
-
-PIXI.initDefaultShader = function()
-{
- PIXI.defaultShader = new PIXI.PixiShader();
- PIXI.defaultShader.init();
- PIXI.activateShader(PIXI.defaultShader);
- /*
- PIXI.shaderStack.push(PIXI.defaultShader);
- PIXI.current*/
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
-
-PIXI.CompileVertexShader = function(gl, shaderSrc)
-{
- return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
-}
-
-PIXI.CompileFragmentShader = function(gl, shaderSrc)
-{
- 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);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(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();
-
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
-
- return shaderProgram;
-}
-
-PIXI.activateShader = function(shader)
-{
- PIXI.shaderStack.push(shader);
-
- //console.log(">>>")
- var gl = PIXI.gl;
-
- var shaderProgram = shader.program;
-
- // map uniforms..
- gl.useProgram(shaderProgram);
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
-
- shader.syncUniforms();
-
- PIXI.currentShader = shaderProgram;
-}
-
-
-PIXI.popShader = function()
-{
- var gl = PIXI.gl;
- // activate last program..
- var lastProgram = PIXI.shaderStack.pop();
-
- var shaderProgram = PIXI.shaderStack[ PIXI.shaderStack.length-1 ].program;
-
- gl.useProgram(shaderProgram);
-
- PIXI.currentShader = shaderProgram;
-}
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.primitiveProgram);
-
- //gl.disableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.disableVertexAttribArray(PIXI.currentShader.colorAttribute);
- gl.disableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
-
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute);
-}
-
-PIXI.deactivatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.currentShader);
-
- gl.enableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.colorAttribute);
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-PIXI.PixiShader = function()
-{
- // the webGL program..
- this.program;
-
- this.fragmentSrc = [
- "precision lowp float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
- "}"
- ];
-
-}
-
-PIXI.PixiShader.prototype.init = function()
-{
- var program = PIXI.compileProgram(this.vertexSrc || PIXI.shaderVertexSrc, this.fragmentSrc)
-
- var gl = PIXI.gl;
-
- gl.useProgram(program);
-
- // get the default shader bits!
- program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
- program.colorAttribute = gl.getAttribLocation(program, "aColor");
- program.textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
-
- program.projectionVector = gl.getUniformLocation(program, "projectionVector");
- program.samplerUniform = gl.getUniformLocation(program, "uSampler");
-
- // add those custom shaders!
- for (var key in this.uniforms)
- {
- // get the uniform locations..
- program[key] = gl.getUniformLocation(program, key);
- }
-
- this.program = program;
-}
-
-PIXI.PixiShader.prototype.syncUniforms = function()
-{
- var gl = PIXI.gl;
-
- for (var key in this.uniforms)
- {
- //var
- var type = this.uniforms[key].type;
-
- // need to grow this!
- if(type == "f")
- {
- gl.uniform1f(this.program[key], this.uniforms[key].value);
- }
- else if(type == "mat4")
- {
- gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- }
- }
-
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A set of functions used by the webGL renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.WebGLGraphics = function()
-{
-
-}
-
-/**
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param projection {Object}
- */
-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);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
-
- // WHY DOES THIS LINE NEED TO BE THERE???
- //gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.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
- *
- * @static
- * @private
- * @method updateGraphics
- * @param graphics {Graphics}
- */
-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;
-
- 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
- *
- * @static
- * @private
- * @method buildRectangle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- }
-
-}
-
-/**
- * Builds a circle to draw
- *
- * @static
- * @private
- * @method buildCircle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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;
-
- 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);
- }
-
-}
-
-/**
- * Builds a line to draw
- *
- * @static
- * @private
- * @method buildLine
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
-{
- // TODO OPTIMISE!
-
- var wrap = true;
- var points = graphicsData.points;
- if(points.length == 0)return;
-
- // 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;
-
- 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 (denom == 0) {
- denom+=1;
- }
-
- 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 (var i=0; i < indexCount; i++)
- {
- indices.push(indexStart++);
- };
-
- indices.push(indexStart-1);
-}
-
-/**
- * Builds a polygon to draw
- *
- * @static
- * @private
- * @method buildPoly
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- };
-}
-
-function HEXtoRGB(hex) {
- return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
-
-// an instance of the gl context..
-// only one at the moment :/
-PIXI.gl;
-
-/**
- * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
- * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
- * So no need for Sprite Batch's or Sprite Cloud's
- * Dont forget to add the view to your DOM or you will not see anything :)
- *
- * @class WebGLRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @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..
-
- this.transparent = !!transparent;
-
- this.width = width || 800;
- this.height = height || 600;
-
- this.view = view || document.createElement( 'canvas' );
- this.view.width = this.width;
- this.view.height = this.height;
-
- // 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.batchs = [];
-
- try
- {
- PIXI.gl = this.gl = this.view.getContext("experimental-webgl", {
- alpha: this.transparent,
- antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
- stencil:true
- });
- }
- catch (e)
- {
- throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
- }
-
- PIXI.initDefaultShader();
- PIXI.initPrimitiveShader();
- PIXI.initDefaultStripShader();
-
-
-// PIXI.activateDefaultShader();
-
- var gl = this.gl;
- PIXI.WebGLRenderer.gl = gl;
-
- this.batch = new PIXI.WebGLBatch(gl);
- gl.disable(gl.DEPTH_TEST);
- gl.disable(gl.CULL_FACE);
-
- gl.enable(gl.BLEND);
- gl.colorMask(true, true, true, this.transparent);
-
- PIXI.projection = new PIXI.Point(400, 300);
-
- this.resize(this.width, this.height);
- this.contextLost = false;
-
- PIXI.activateShader(PIXI.defaultShader);
-
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
-
-}
-
-// constructor
-PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
-
-/**
- * Gets a new WebGLBatch from the pool
- *
- * @static
- * @method getBatch
- * @return {WebGLBatch}
- * @private
- */
-PIXI.WebGLRenderer.getBatch = function()
-{
- if(PIXI._batchs.length == 0)
- {
- return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
- }
- else
- {
- return PIXI._batchs.pop();
- }
-}
-
-/**
- * Puts a batch back into the pool
- *
- * @static
- * @method returnBatch
- * @param batch {WebGLBatch} The batch to return
- * @private
- */
-PIXI.WebGLRenderer.returnBatch = function(batch)
-{
- batch.clean();
- PIXI._batchs.push(batch);
-}
-
-/**
- * Renders the stage to its webGL view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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);
- }
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
-
- // 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;
- 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
- *
- * @static
- * @method updateTextures
- * @private
- */
-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 = [];
-}
-
-/**
- * Updates a loaded webgl texture
- *
- * @static
- * @method updateTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.updateTexture = function(texture)
-{
- //TODO break this out into a texture manager...
- var gl = PIXI.gl;
-
- if(!texture._glTexture)
- {
- texture._glTexture = gl.createTexture();
- }
-
- if(texture.hasLoaded)
- {
- gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
-
- 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);
-
- // reguler...
-
- 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
- *
- * @method destroyTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.destroyTexture = function(texture)
-{
- //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);
- }
-}
-
-/**
- * resizes the webGL view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the webGL view
- * @param height {Number} the new height of the webGL view
- */
-PIXI.WebGLRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-
- this.gl.viewport(0, 0, this.width, this.height);
-
- //var projectionMatrix = this.projectionMatrix;
-
- 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;
-}
-
-/**
- * Handles a lost webgl context
- *
- * @method handleContextLost
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
-{
- event.preventDefault();
- this.contextLost = true;
-}
-
-/**
- * Handles a restored webgl context
- *
- * @method handleContextRestored
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
-{
- this.gl = this.view.getContext("experimental-webgl", {
- alpha: true
- });
-
- this.initShaders();
-
- 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;
- };
-
- PIXI._restoreBatchs(this.gl);
-
- this.contextLost = false;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._batchs = [];
-
-/**
- * @private
- */
-PIXI._getBatch = function(gl)
-{
- 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);
-}
-
-/**
- * @private
- */
-PIXI._restoreBatchs = function(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.
- * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
- * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
- * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
- * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @constructor
- * @param gl {WebGLContext} an instance of the webGL context
- */
-PIXI.WebGLBatch = function(gl)
-{
- this.gl = gl;
-
- 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;
-
-/**
- * Cleans the batch so that is can be returned to an object pool and reused
- *
- * @method clean
- */
-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;
-}
-
-/**
- * Recreates the buffers in the event of a context loss
- *
- * @method restoreLostContext
- * @param gl {WebGLContext}
- */
-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();
-}
-
-/**
- * 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
- */
-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;
-
- this.growBatch();
-}
-
-/**
- * inserts a sprite before the specified 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++;
-
- 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;
- }
-}
-
-/**
- * inserts a sprite after the specified sprite
- *
- * @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++;
-
- sprite.batch = this;
- this.dirty = true;
-
- var tempNext = previousSprite.__next;
- previousSprite.__next = sprite;
- sprite.__prev = previousSprite;
-
- 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--;
-
- 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.__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;
-}
-
-/**
- * Splits the batch into two with the specified sprite being the start of the new batch.
- *
- * @method split
- * @param sprite {Sprite} the sprite that indicates where the batch should be split
- * @return {WebGLBatch} the new batch
- */
-PIXI.WebGLBatch.prototype.split = function(sprite)
-{
- this.dirty = true;
-
- 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;
-
- 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"?
-
- // 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;
-
- return batch;
-}
-
-/**
- * Merges two batchs together
- *
- * @method merge
- * @param batch {WebGLBatch} the batch that will be merged
- */
-PIXI.WebGLBatch.prototype.merge = function(batch)
-{
- this.dirty = true;
-
- this.tail.__next = batch.head;
- batch.head.__prev = this.tail;
-
- this.size += batch.size;
-
- this.tail = batch.tail;
-
- 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
- * function is used to increase the size of the batch. It also creates a little extra room so
- * that the batch does not need to be resized every time a sprite is added
- *
- * @method growBatch
- */
-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);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
-
- 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.dirtyUVS = 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.dirtyColors = true;
-
- this.indices = new Uint16Array(this.dynamicSize * 6);
- var length = this.indices.length/6;
-
- 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
- *
- * @method refresh
- */
-PIXI.WebGLBatch.prototype.refresh = function()
-{
- var gl = this.gl;
-
- if (this.dynamicSize < this.size)
- {
- this.growBatch();
- }
-
- 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;
-
- while(displayObject)
- {
- index = indexRun * 8;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
-
- colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
-
- displayObject = displayObject.__next;
-
- indexRun ++;
- }
-
- this.dirtyUVS = true;
- this.dirtyColors = true;
-}
-
-/**
- * Updates all the relevant geometry and uploads the data to the GPU
- *
- * @method update
- */
-PIXI.WebGLBatch.prototype.update = function()
-{
- var gl = this.gl;
- var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3
-
- var a, b, c, d, tx, ty;
-
- var indexRun = 0;
-
- var displayObject = this.head;
-
- while(displayObject)
- {
- if(displayObject.vcount === PIXI.visibleCount)
- {
- width = displayObject.texture.frame.width;
- height = displayObject.texture.frame.height;
-
- // 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;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- index = indexRun * 8;
-
- worldTransform = displayObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- this.verticies[index + 0 ] = a * w1 + c * h1 + tx;
- this.verticies[index + 1 ] = d * h1 + b * w1 + ty;
-
- this.verticies[index + 2 ] = a * w0 + c * h1 + tx;
- this.verticies[index + 3 ] = d * h1 + b * w0 + ty;
-
- this.verticies[index + 4 ] = a * w0 + c * h0 + tx;
- this.verticies[index + 5 ] = d * h0 + b * w0 + ty;
-
- this.verticies[index + 6] = a * w1 + c * h0 + tx;
- this.verticies[index + 7] = d * h0 + b * w1 + ty;
-
- if(displayObject.updateFrame || displayObject.texture.updateFrame)
- {
- this.dirtyUVS = true;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
- }
-
- // TODO this probably could do with some optimisation....
- if(displayObject.cacheAlpha != displayObject.worldAlpha)
- {
- displayObject.cacheAlpha = displayObject.worldAlpha;
-
- var colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
- this.dirtyColors = true;
- }
- }
- else
- {
- index = indexRun * 8;
-
- this.verticies[index + 0 ] = 0;
- this.verticies[index + 1 ] = 0;
-
- this.verticies[index + 2 ] = 0;
- this.verticies[index + 3 ] = 0;
-
- this.verticies[index + 4 ] = 0;
- this.verticies[index + 5 ] = 0;
-
- this.verticies[index + 6] = 0;
- this.verticies[index + 7] = 0;
- }
-
- indexRun++;
- displayObject = displayObject.__next;
- }
-}
-
-/**
- * Draws the batch to the frame buffer
- *
- * @method render
- */
-PIXI.WebGLBatch.prototype.render = function(start, end)
-{
- start = start || 0;
-
- if(end == undefined)end = this.size;
-
- if(this.dirty)
- {
- this.refresh();
- this.dirty = false;
- }
-
- if (this.size == 0)return;
-
- this.update();
- var gl = this.gl;
-
- //TODO optimize this!
-
- var shaderProgram = PIXI.currentShader;
-
- //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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // update the uvs
- var isDefault = (shaderProgram == PIXI.shaderProgram)
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
-
- if(this.dirtyUVS)
- {
- this.dirtyUVS = false;
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
- }
-
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
-
- // update color!
- gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
-
- if(this.dirtyColors)
- {
- 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!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
-
- var len = end - start;
-
- // DRAW THAT this!
- gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
- * if a group of sprites all have the same baseTexture and blendMode then they can be
- * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
- * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
- * even if the batch only contains one sprite. Batching is handled automatically by the
- * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @contructor
- * @param gl {WebGLContext} An instance of the webGL context
- */
-PIXI.WebGLRenderGroup = function(gl)
-{
- this.gl = gl;
- this.root;
-
- this.backgroundColor;
- this.batchs = [];
- this.toRemove = [];
-}
-
-// constructor
-PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
-
-/**
- * Add a display object to the webgl renderer
- *
- * @method setRenderable
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
-{
- // has this changed??
- if(this.root)this.removeDisplayObjectAndChildren(this.root);
-
- displayObject.worldVisible = displayObject.visible;
-
- // soooooo //
- // to check if any batchs exist already??
-
- // TODO what if its already has an object? should remove it
- this.root = displayObject;
- this.addDisplayObjectAndChildren(displayObject);
-}
-
-/**
- * Renders the stage to its webgl view
- *
- * @method render
- * @param projection {Object}
- */
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
-
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- // will render all the elements in the group
- var renderable;
- for (var i=0; i < this.batchs.length; i++)
- {
-
- renderable = this.batchs[i];
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- continue;
- }
-
- // non sprite batch..
- var worldVisible = renderable.vcount === PIXI.visibleCount;
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
- }
-
-}
-
-/**
- * Renders a specific displayObject
- *
- * @method renderSpecific
- * @param displayObject {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- // to do!
- // render part of the scene...
-
- var startIndex;
- var startBatchIndex;
-
- var endIndex;
- var endBatchIndex;
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.first;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
- var startBatch = nextRenderable.batch;
-
- if(nextRenderable instanceof PIXI.Sprite)
- {
- startBatch = nextRenderable.batch;
-
- var head = startBatch.head;
- var next = head;
-
- // ok now we have the batch.. need to find the start index!
- if(head == nextRenderable)
- {
- startIndex = 0;
- }
- else
- {
- startIndex = 1;
-
- while(head.__next != nextRenderable)
- {
- startIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- startBatch = nextRenderable;
- }
-
- // Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
- {
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem.last;
- }
-
- if(lastRenderable instanceof PIXI.Sprite)
- {
- endBatch = lastRenderable.batch;
-
- var head = endBatch.head;
-
- if(head == lastRenderable)
- {
- endIndex = 0;
- }
- else
- {
- endIndex = 1;
-
- while(head.__next != lastRenderable)
- {
- endIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- endBatch = lastRenderable;
- }
-
- // TODO - need to fold this up a bit!
-
- if(startBatch == endBatch)
- {
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex, endIndex+1);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
- return;
- }
-
- // now we have first and last!
- startBatchIndex = this.batchs.indexOf(startBatch);
- endBatchIndex = this.batchs.indexOf(endBatch);
-
- // DO the first batch
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
-
- // DO the middle batchs..
- for (var i=startBatchIndex+1; i < endBatchIndex; i++)
- {
- renderable = this.batchs[i];
-
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- }
- else
- {
- this.renderSpecial(renderable, projection);
- }
- }
-
- // DO the last batch..
- if(endBatch instanceof PIXI.WebGLBatch)
- {
- endBatch.render(0, endIndex+1);
- }
- else
- {
- this.renderSpecial(endBatch, projection);
- }
-}
-
-/**
- * Renders a specific renderable
- *
- * @method renderSpecial
- * @param renderable {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
-{
- var sta = PIXI.shaderStack.length;
-
- var worldVisible = renderable.vcount === PIXI.visibleCount
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.CustomRenderable)
- {
- if(worldVisible) renderable.renderWebGL(this, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
-}
-
-PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection)
-{
- /*
- * for now only masks are supported..
- */
- var gl = PIXI.gl;
-
- if(renderable.open)
- {
- if(renderable.data instanceof Array)
- {
- var filter = renderable.data[0];
-
- if(!filter.shader)
- {
- var shader = new PIXI.PixiShader();
-
- shader.fragmentSrc = filter.fragmentSrc;
- shader.uniforms = filter.uniforms;
- shader.init();
-
- filter.shader = shader
- }
-
- PIXI.activateShader(filter.shader);
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
- PIXI.WebGLGraphics.renderGraphics(renderable.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- }
- else
- {
- if(renderable.data instanceof Array)
- {
- PIXI.popShader();
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
-}
-
-/**
- * Updates a webgl texture
- *
- * @method updateTexture
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
-{
-
- // TODO definitely can optimse this function..
-
- this.removeObject(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- this.insertObject(displayObject, previousRenderable, nextRenderable);
-}
-
-/**
- * Adds filter blocks
- *
- * @method addFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
-{
- start.__renderGroup = this;
- end.__renderGroup = this;
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = start;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
- this.insertAfter(start, previousRenderable);
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var previousRenderable2 = end;
- while(previousRenderable2 != this.root.first)
- {
- previousRenderable2 = previousRenderable2._iPrev;
- if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
- }
- this.insertAfter(end, previousRenderable2);
-}
-
-/**
- * Remove filter blocks
- *
- * @method removeFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
-{
- this.removeObject(start);
- this.removeObject(end);
-}
-
-/**
- * Adds a display object and children to the webgl context
- *
- * @method addDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
-
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- // one the display object hits this. we can break the loop
-
- var tempObject = displayObject.first;
- var testObject = displayObject.last._iNext;
- do
- {
- tempObject.__renderGroup = this;
-
- if(tempObject.renderable)
- {
-
- this.insertObject(tempObject, previousRenderable, nextRenderable);
- previousRenderable = tempObject;
- }
-
- tempObject = tempObject._iNext;
- }
- while(tempObject != testObject)
-}
-
-/**
- * Removes a display object and children to the webgl context
- *
- * @method removeDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup != this)return;
-
-// var displayObject = displayObject.first;
- var lastObject = displayObject.last;
- do
- {
- displayObject.__renderGroup = null;
- if(displayObject.renderable)this.removeObject(displayObject);
- displayObject = displayObject._iNext;
- }
- while(displayObject)
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertObject
- * @param displayObject {DisplayObject}
- * @param previousObject {DisplayObject}
- * @param nextObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
-{
- // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
- var previousSprite = previousObject;
- var nextSprite = nextObject;
-
- /*
- * so now we have the next renderable and the previous renderable
- *
- */
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch
- var nextBatch
-
- if(previousSprite instanceof PIXI.Sprite)
- {
- previousBatch = previousSprite.batch;
- if(previousBatch)
- {
- if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
- {
- previousBatch.insertAfter(displayObject, previousSprite);
- return;
- }
- }
- }
- else
- {
- // TODO reword!
- previousBatch = previousSprite;
- }
-
- if(nextSprite)
- {
- if(nextSprite instanceof PIXI.Sprite)
- {
- nextBatch = nextSprite.batch;
-
- //batch may not exist if item was added to the display list but not to the webGL
- if(nextBatch)
- {
- if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
- {
- nextBatch.insertBefore(displayObject, nextSprite);
- return;
- }
- else
- {
- if(nextBatch == previousBatch)
- {
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(nextSprite);
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var batch = PIXI.WebGLRenderer.getBatch();
-
- var index = this.batchs.indexOf( previousBatch );
- batch.init(displayObject);
- this.batchs.splice(index+1, 0, batch, splitBatch);
-
- return;
- }
- }
- }
- }
- else
- {
- // TODO re-word!
-
- nextBatch = nextSprite;
- }
- }
-
- /*
- * looks like it does not belong to any batch!
- * but is also not intersecting one..
- * time to create anew one!
- */
-
- var batch = PIXI.WebGLRenderer.getBatch();
- batch.init(displayObject);
-
- if(previousBatch) // if this is invalid it means
- {
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, batch);
- }
- else
- {
- this.batchs.push(batch);
- }
-
- return;
- }
- else if(displayObject instanceof PIXI.TilingSprite)
- {
-
- // add to a batch!!
- this.initTilingSprite(displayObject);
- // this.batchs.push(displayObject);
-
- }
- else if(displayObject instanceof PIXI.Strip)
- {
- // add to a batch!!
- this.initStrip(displayObject);
- // this.batchs.push(displayObject);
- }
- else if(displayObject)// instanceof PIXI.Graphics)
- {
- //displayObject.initWebGL(this);
-
- // add to a batch!!
- //this.initStrip(displayObject);
- //this.batchs.push(displayObject);
- }
-
- this.insertAfter(displayObject, previousSprite);
-
- // insert and SPLIT!
-
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertAfter
- * @param item {DisplayObject}
- * @param displayObject {DisplayObject} The object to insert
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
-{
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch = displayObject.batch;
-
- if(previousBatch)
- {
- // so this object is in a batch!
-
- // is it not? need to split the batch
- if(previousBatch.tail == displayObject)
- {
- // is it tail? insert in to batchs
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item);
- }
- else
- {
- // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
-
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(displayObject.__next);
-
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item, splitBatch);
- }
- }
- else
- {
- this.batchs.push(item);
- }
- }
- else
- {
- var index = this.batchs.indexOf( displayObject );
- this.batchs.splice(index+1, 0, item);
- }
-}
-
-/**
- * Removes a displayObject from the linked list
- *
- * @method removeObject
- * @param displayObject {DisplayObject} The object to remove
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
-{
- // loop through children..
- // display object //
-
- // add a child from the render group..
- // remove it and all its children!
- //displayObject.cacheVisible = false;//displayObject.visible;
-
- /*
- * removing is a lot quicker..
- *
- */
- var batchToRemove;
-
- if(displayObject instanceof PIXI.Sprite)
- {
- // should always have a batch!
- var batch = displayObject.batch;
- if(!batch)return; // this means the display list has been altered befre rendering
-
- batch.remove(displayObject);
-
- if(batch.size==0)
- {
- batchToRemove = batch;
- }
- }
- else
- {
- batchToRemove = displayObject;
- }
-
- /*
- * Looks like there is somthing that needs removing!
- */
- if(batchToRemove)
- {
- var index = this.batchs.indexOf( batchToRemove );
- if(index == -1)return;// this means it was added then removed before rendered
-
- // ok so.. check to see if you adjacent batchs should be joined.
- // TODO may optimise?
- if(index == 0 || index == this.batchs.length-1)
- {
- // wha - eva! just get of the empty batch!
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
-
- return;
- }
-
- if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
- {
- if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
- {
- //console.log("MERGE")
- this.batchs[index-1].merge(this.batchs[index+1]);
-
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
- this.batchs.splice(index, 2);
- return;
- }
- }
-
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- }
-}
-
-
-/**
- * Initializes a tiling sprite
- *
- * @method initTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
-{
- var gl = this.gl;
-
- // make the texture tilable..
-
- sprite.verticies = new Float32Array([0, 0,
- sprite.width, 0,
- sprite.width, sprite.height,
- 0, sprite.height]);
-
- sprite.uvs = new Float32Array([0, 0,
- 1, 0,
- 1, 1,
- 0, 1]);
-
- sprite.colors = new Float32Array([1,1,1,1]);
-
- sprite.indices = new Uint16Array([0, 1, 3,2])//, 2]);
-
- sprite._vertexBuffer = gl.createBuffer();
- sprite._indexBuffer = gl.createBuffer();
- sprite._uvBuffer = gl.createBuffer();
- sprite._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.uvs, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW);
-
-// return ( (x > 0) && ((x & (x - 1)) == 0) );
-
- if(sprite.texture.baseTexture._glTexture)
- {
- gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- sprite.texture.baseTexture._powerOf2 = true;
- }
- else
- {
- sprite.texture.baseTexture._powerOf2 = true;
- }
-}
-
-/**
- * Renders a Strip
- *
- * @method renderStrip
- * @param strip {Strip} The strip to render
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.stripShaderProgram;
-
-
- gl.useProgram(shaderProgram);
-
- var m = PIXI.mat3.clone(strip.worldTransform);
-
- PIXI.mat3.transpose(m);
-
- // set the matrix transform for the
- gl.uniformMatrix3fv(shaderProgram.translationMatrix, false, m);
- gl.uniform2f(shaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(shaderProgram.alpha, strip.worldAlpha);
-
-/*
- if(strip.blendMode == PIXI.blendModes.NORMAL)
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
- }
- */
-
-
- if(!strip.dirty)
- {
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- }
- else
- {
- strip.dirty = false;
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-
- }
-
- gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
-
- gl.useProgram(PIXI.currentProgram);
-}
-
-/**
- * Renders a TilingSprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to render
- * @param projectionMatrix {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- var tilePosition = sprite.tilePosition;
- var tileScale = sprite.tileScale;
-
- var offsetX = tilePosition.x/sprite.texture.baseTexture.width;
- var offsetY = tilePosition.y/sprite.texture.baseTexture.height;
-
- var scaleX = (sprite.width / sprite.texture.baseTexture.width) / tileScale.x;
- var scaleY = (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
-
- sprite.uvs[0] = 0 - offsetX;
- sprite.uvs[1] = 0 - offsetY;
-
- sprite.uvs[2] = (1 * scaleX) -offsetX;
- sprite.uvs[3] = 0 - offsetY;
-
- sprite.uvs[4] = (1 *scaleX) - offsetX;
- sprite.uvs[5] = (1 *scaleY) - offsetY;
-
- sprite.uvs[6] = 0 - offsetX;
- sprite.uvs[7] = (1 *scaleY) - offsetY;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
-
- this.renderStrip(sprite, projectionMatrix);
-}
-
-/**
- * Initializes a strip to be rendered
- *
- * @method initStrip
- * @param strip {Strip} The strip to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
-{
- // build the strip!
- var gl = this.gl;
- var shaderProgram = this.shaderProgram;
-
- strip._vertexBuffer = gl.createBuffer();
- strip._indexBuffer = gl.createBuffer();
- strip._uvBuffer = gl.createBuffer();
- strip._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-}
-
-
-/**
- * @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 :)
- *
- * @class CanvasRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
- */
-PIXI.CanvasRenderer = function(width, height, view, transparent)
-{
- this.transparent = transparent;
-
- /**
- * 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 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");
-
- 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;
-}
-
-// constructor
-PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
-
-/**
- * Renders the stage to its canvas view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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;
-
- 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 = [];
- }
-
-
-}
-
-/**
- * resizes the canvas view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the canvas view
- * @param height {Number} the new height of the canvas view
- */
-PIXI.CanvasRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-}
-
-/**
- * Renders a display object
- *
- * @method renderDisplayObject
- * @param displayObject {DisplayObject} The displayObject to render
- * @private
- */
-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)
- {
-
- var frame = displayObject.texture.frame;
-
- if(frame && frame.width && frame.height)
- {
- 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)
- {
- 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(PIXI.FilterBlock.data instanceof PIXI.Graphics)
- {
- if(displayObject.open)
- {
- context.save();
-
- var cacheAlpha = displayObject.mask.alpha;
- var maskTransform = displayObject.mask.worldTransform;
-
- context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
-
- displayObject.mask.worldAlpha = 0.5;
-
- context.worldAlpha = 0;
-
- PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context);
- context.clip();
-
- displayObject.mask.worldAlpha = cacheAlpha;
- }
- else
- {
- context.restore();
- }
- }
- else
- {
- // only masks supported right now!
- }
- }
- // count++
- displayObject = displayObject._iNext;
-
-
- }
- while(displayObject != testObject)
-
-
-}
-
-/**
- * Renders a flat strip
- *
- * @method renderStripFlat
- * @param strip {Strip} The Strip to render
- * @private
- */
-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();
-}
-
-/**
- * Renders a tiling sprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tilingsprite to render
- * @private
- */
-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;
-
- // 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.translate(-tilePosition.x, -tilePosition.y);
-
- context.closePath();
-}
-
-/**
- * Renders a strip
- *
- * @method renderStrip
- * @param strip {Strip} The Strip to render
- * @private
- */
-PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
-{
- 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;
-
-
- 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();
- };
-
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * A set of functions used by the canvas renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.CanvasGraphics = function()
-{
-
-}
-
-
-/*
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- 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.lineWidth = data.lineWidth;
-
- 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]);
- }
-
- // 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.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]);
- }
-
- }
- 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
-
- 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
- *
- * @static
- * @private
- * @method renderGraphicsMask
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- var len = graphics.graphicsData.length;
- if(len > 1)
- {
- len = 1;
- 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;
-
- 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]);
- }
-
- // 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
- }
-
-
- };
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
- * It is important to know that with the webGL renderer only simple polys can be filled at this stage
- * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
- *
- * @class Graphics
- * @extends DisplayObjectContainer
- * @constructor
- */
-PIXI.Graphics = function()
-{
- PIXI.DisplayObjectContainer.call( this );
-
- this.renderable = true;
-
- /**
- * The alpha of the fill of this graphics object
- *
- * @property fillAlpha
- * @type Number
- */
- this.fillAlpha = 1;
-
- /**
- * The width of any lines drawn
- *
- * @property lineWidth
- * @type Number
- */
- this.lineWidth = 0;
-
- /**
- * The color of any lines drawn
- *
- * @property lineColor
- * @type String
- */
- this.lineColor = "black";
-
- /**
- * Graphics data
- *
- * @property graphicsData
- * @type Array
- * @private
- */
- this.graphicsData = [];
-
- /**
- * Current path
- *
- * @property currentPath
- * @type Object
- * @private
- */
- this.currentPath = {points:[]};
-}
-
-// constructor
-PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Graphics.prototype.constructor = PIXI.Graphics;
-
-/**
- * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
- *
- * @method lineStyle
- * @param lineWidth {Number} width of the line to draw, will update the object's stored style
- * @param color {Number} color of the line to draw, will update the object's stored style
- * @param alpha {Number} alpha of the line to draw, will update the object's stored style
- */
-PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
-{
- if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.lineWidth = lineWidth || 0;
- this.lineColor = color || 0;
- this.lineAlpha = (alpha == undefined) ? 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.graphicsData.push(this.currentPath);
-}
-
-/**
- * Moves the current drawing position to (x, y).
- *
- * @method moveTo
- * @param x {Number} the X coord to move to
- * @param y {Number} the Y coord to move to
- */
-PIXI.Graphics.prototype.moveTo = function(x, y)
-{
- if(this.currentPath.points.length == 0)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.points.push(x, y);
-
- this.graphicsData.push(this.currentPath);
-}
-
-/**
- * Draws a line using the current line style from the current drawing position to (x, y);
- * the current drawing position is then set to (x, y).
- *
- * @method lineTo
- * @param x {Number} the X coord to draw to
- * @param y {Number} the Y coord to draw to
- */
-PIXI.Graphics.prototype.lineTo = function(x, y)
-{
- this.currentPath.points.push(x, y);
- this.dirty = true;
-}
-
-/**
- * Specifies a simple one-color fill that subsequent calls to other Graphics methods
- * (such as lineTo() or drawCircle()) use when drawing.
- *
- * @method beginFill
- * @param color {uint} the color of the fill
- * @param alpha {Number} the alpha
- */
-PIXI.Graphics.prototype.beginFill = function(color, alpha)
-{
- this.filling = true;
- this.fillColor = color || 0;
- this.fillAlpha = (alpha == undefined) ? 1 : alpha;
-}
-
-/**
- * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
- *
- * @method endFill
- */
-PIXI.Graphics.prototype.endFill = function()
-{
- this.filling = false;
- this.fillColor = null;
- this.fillAlpha = 1;
-}
-
-/**
- * @method drawRect
- *
- * @param x {Number} The X coord of the top-left of the rectangle
- * @param y {Number} The Y coord of the top-left of the rectangle
- * @param width {Number} The width of the rectangle
- * @param height {Number} The height of the rectangle
- */
-PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws a circle.
- *
- * @method drawCircle
- * @param x {Number} The X coord of the center of the circle
- * @param y {Number} The Y coord of the center of the circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws an elipse.
- *
- * @method drawElipse
- * @param x {Number}
- * @param y {Number}
- * @param width {Number}
- * @param height {Number}
- */
-PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
- *
- * @method clear
- */
-PIXI.Graphics.prototype.clear = function()
-{
- this.lineWidth = 0;
- this.filling = false;
-
- this.dirty = true;
- this.clearDirty = true;
- this.graphicsData = [];
-}
-
-// SOME TYPES:
-PIXI.Graphics.POLY = 0;
-PIXI.Graphics.RECT = 1;
-PIXI.Graphics.CIRC = 2;
-PIXI.Graphics.ELIP = 3;
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-PIXI.Strip = function(texture, width, height)
-{
- 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]);
-
- this.verticies = new Float32Array([0, 0,
- 0,0,
- 0,0, 0,
- 0, 0]);
-
- 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.verticies = [0, 0,
- 0,0,
- 0,0, 0,
- 0, 0];
-
- this.colors = [1, 1, 1, 1];
-
- 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;
-
- // 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;
-}
-
-// constructor
-PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Strip.prototype.constructor = PIXI.Strip;
-
-PIXI.Strip.prototype.setTexture = function(texture)
-{
- //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;
-}
-
-PIXI.Strip.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-// some helper functions..
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-
-PIXI.Rope = function(texture, points)
-{
- PIXI.Strip.call( this, texture );
- this.points = points;
-
- try
- {
- this.verticies = new Float32Array( points.length * 4);
- this.uvs = new Float32Array( points.length * 4);
- this.colors = new Float32Array( points.length * 2);
- this.indices = new Uint16Array( points.length * 2);
- }
- catch(error)
- {
- this.verticies = verticies
-
- this.uvs = uvs
- this.colors = colors
- this.indices = indices
- }
-
- this.refresh();
-}
-
-
-// constructor
-PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
-PIXI.Rope.prototype.constructor = PIXI.Rope;
-
-PIXI.Rope.prototype.refresh = function()
-{
- var points = this.points;
- if(points.length < 1)return;
-
- var uvs = this.uvs
- var indices = this.indices;
- var colors = this.colors;
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
-
- uvs[0] = 0
- uvs[1] = 1
- uvs[2] = 0
- uvs[3] = 1
-
- colors[0] = 1;
- colors[1] = 1;
-
- indices[0] = 0;
- indices[1] = 1;
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
- // time to do some smart drawing!
- var amount = i/(total-1)
-
- if(i%2)
- {
- uvs[index] = amount;
- uvs[index+1] = 0;
-
- uvs[index+2] = amount
- uvs[index+3] = 1
-
- }
- else
- {
- uvs[index] = amount
- uvs[index+1] = 0
-
- uvs[index+2] = amount
- uvs[index+3] = 1
- }
-
- index = i * 2;
- colors[index] = 1;
- colors[index+1] = 1;
-
- index = i * 2;
- indices[index] = index;
- indices[index + 1] = index + 1;
-
- lastPoint = point;
- }
-}
-
-PIXI.Rope.prototype.updateTransform = function()
-{
-
- var points = this.points;
- if(points.length < 1)return;
-
- var verticies = this.verticies
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
- verticies[0] = point.x + perp.x
- verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
- verticies[3] = point.y - perp.y//+200
- // time to do some smart drawing!
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
-
- if(i < points.length-1)
- {
- nextPoint = points[i+1];
- }
- else
- {
- nextPoint = point
- }
-
- perp.y = -(nextPoint.x - lastPoint.x);
- perp.x = nextPoint.y - lastPoint.y;
-
- var ratio = (1 - (i / (total-1))) * 10;
- if(ratio > 1)ratio = 1;
-
- 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;
-
- 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;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
-}
-
-PIXI.Rope.prototype.setTexture = function(texture)
-{
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * A tiling sprite is a fast way of rendering a tiling image
- *
- * @class TilingSprite
- * @extends DisplayObjectContainer
- * @constructor
- * @param texture {Texture} the texture of the tiling sprite
- * @param width {Number} the width of the tiling sprite
- * @param height {Number} the height of the tiling sprite
- */
-PIXI.TilingSprite = function(texture, width, height)
-{
- PIXI.DisplayObjectContainer.call( this );
-
- /**
- * 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 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 offset position of the image that is being tiled
- *
- * @property tilePosition
- * @type Point
- */
- this.tilePosition = new PIXI.Point(0,0);
-
- this.renderable = true;
-
- this.blendMode = PIXI.blendModes.NORMAL
-}
-
-// constructor
-PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
-
-/**
- * Sets the texture of the tiling sprite
- *
- * @method setTexture
- * @param texture {Texture} The PIXI texture that is displayed by the sprite
- */
-PIXI.TilingSprite.prototype.setTexture = function(texture)
-{
- //TODO SET THE TEXTURES
- //TODO VISIBILITY
-
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-/**
- * When the texture is updated, this event will fire to update the frame
- *
- * @method onTextureUpdate
- * @param event
- * @private
- */
-PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
- *
- * Awesome JS run time provided by EsotericSoftware
- * https://github.com/EsotericSoftware/spine-runtimes
- *
- */
-
-/**
- * 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
- * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
- *
- * @class Spine
- * @extends DisplayObjectContainer
- * @constructor
- * @param url {String} The url of the spine anim file to be used
- */
-PIXI.Spine = function (url) {
- PIXI.DisplayObjectContainer.call(this);
-
- this.spineData = PIXI.AnimCache[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.stateData = new spine.AnimationStateData(this.spineData);
- this.state = new spine.AnimationState(this.stateData);
-
- 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);
- }
-};
-
-PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.Spine.prototype.constructor = PIXI.Spine;
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @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();
-
- 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;
-
- 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.rotation = -(slot.bone.worldRotation * Math.PI / 180);
- }
-
- 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;
-
- 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;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * This object is one that will allow you to specify custom rendering functions based on render type
- *
- * @class CustomRenderable
- * @extends DisplayObject
- * @constructor
- */
-PIXI.CustomRenderable = function()
-{
- PIXI.DisplayObject.call( this );
-
-}
-
-// constructor
-PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
-
-/**
- * If this object is being rendered by a CanvasRenderer it will call this callback
- *
- * @method renderCanvas
- * @param renderer {CanvasRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderCanvas = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback to initialize
- *
- * @method initWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.initWebGL = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback
- *
- * @method renderWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderWebGL = function(renderGroup, projectionMatrix)
-{
- // not sure if both needed? but ya have for now!
- // override!
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.BaseTextureCache = {};
-PIXI.texturesToUpdate = [];
-PIXI.texturesToDestroy = [];
-
-/**
- * A texture stores the information that represents an image. All textures have a base texture
- *
- * @class BaseTexture
- * @uses EventTarget
- * @constructor
- * @param source {String} the source object (image or canvas)
- */
-PIXI.BaseTexture = function(source)
-{
- 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 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 source that is loaded to create the texture
- *
- * @property source
- * @type Image
- */
- this.source = source;
-
- if(!source)return;
-
- 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;
-
- PIXI.texturesToUpdate.push(this);
- }
- else
- {
-
- var scope = this;
- this.source.onload = function(){
-
- scope.hasLoaded = true;
- scope.width = scope.source.width;
- scope.height = scope.source.height;
-
- // 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;
-
- PIXI.texturesToUpdate.push(this);
- }
-
- this._powerOf2 = false;
-}
-
-PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
-
-/**
- * Destroys this base texture
- *
- * @method destroy
- */
-PIXI.BaseTexture.prototype.destroy = function()
-{
- if(this.source instanceof Image)
- {
- this.source.src = null;
- }
- this.source = null;
- PIXI.texturesToDestroy.push(this);
-}
-
-/**
- * Helper function that returns a base texture based on an image url
- * If the image is not in the base texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @return BaseTexture
- */
-PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
-{
- 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);
- PIXI.BaseTextureCache[imageUrl] = baseTexture;
- }
-
- return baseTexture;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.TextureCache = {};
-PIXI.FrameCache = {};
-
-/**
- * A texture stores the information that represents an image or part of an image. It cannot be added
- * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
- *
- * @class Texture
- * @uses EventTarget
- * @constructor
- * @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frame {Rectangle} The rectangle frame of the texture to show
- */
-PIXI.Texture = function(baseTexture, frame)
-{
- PIXI.EventTarget.call( this );
-
- if(!frame)
- {
- this.noFrame = true;
- frame = new PIXI.Rectangle(0,0,1,1);
- }
-
- if(baseTexture instanceof PIXI.Texture)
- baseTexture = baseTexture.baseTexture;
-
- /**
- * The base texture of this texture
- *
- * @property baseTexture
- * @type BaseTexture
- */
- this.baseTexture = baseTexture;
-
- /**
- * The frame specifies the region of the base texture that this texture uses
- *
- * @property frame
- * @type Rectangle
- */
- this.frame = frame;
-
- /**
- * The trim point
- *
- * @property trim
- * @type Point
- */
- this.trim = new PIXI.Point();
-
- this.scope = this;
-
- if(baseTexture.hasLoaded)
- {
- if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- //console.log(frame)
-
- this.setFrame(frame);
- }
- else
- {
- var scope = this;
- baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} );
- }
-}
-
-PIXI.Texture.prototype.constructor = PIXI.Texture;
-
-/**
- * Called when the base texture is loaded
- *
- * @method onBaseTextureLoaded
- * @param event
- * @private
- */
-PIXI.Texture.prototype.onBaseTextureLoaded = function(event)
-{
- var baseTexture = this.baseTexture;
- baseTexture.removeEventListener( 'loaded', this.onLoaded );
-
- if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- this.noFrame = false;
- this.width = this.frame.width;
- this.height = this.frame.height;
-
- this.scope.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Destroys this texture
- *
- * @method destroy
- * @param destroyBase {Boolean} Whether to destroy the base texture as well
- */
-PIXI.Texture.prototype.destroy = function(destroyBase)
-{
- if(destroyBase)this.baseTexture.destroy();
-}
-
-/**
- * Specifies the rectangle region of the baseTexture
- *
- * @method setFrame
- * @param frame {Rectangle} The frame of the texture to set it to
- */
-PIXI.Texture.prototype.setFrame = function(frame)
-{
- this.frame = frame;
- this.width = frame.width;
- this.height = frame.height;
-
- 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;
-
- PIXI.Texture.frameUpdates.push(this);
- //this.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Helper function that returns a texture based on an image url
- * If the image is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- * @return Texture
- */
-PIXI.Texture.fromImage = function(imageUrl, crossorigin)
-{
- var texture = PIXI.TextureCache[imageUrl];
-
- if(!texture)
- {
- texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
- PIXI.TextureCache[imageUrl] = texture;
- }
-
- return texture;
-}
-
-/**
- * Helper function that returns a texture based on a frame id
- * If the frame id is not in the texture cache an error will be thrown
- *
- * @static
- * @method fromFrame
- * @param frameId {String} The frame id of the texture
- * @return Texture
- */
-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;
-}
-
-/**
- * Helper function that returns a texture based on a canvas element
- * If the canvas is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromCanvas
- * @param canvas {Canvas} The canvas element source of the texture
- * @return Texture
- */
-PIXI.Texture.fromCanvas = function(canvas)
-{
- var baseTexture = new PIXI.BaseTexture(canvas);
- return new PIXI.Texture(baseTexture);
-}
-
-
-/**
- * Adds a texture to the textureCache.
- *
- * @static
- * @method addTextureToCache
- * @param texture {Texture}
- * @param id {String} the id that the texture will be stored against.
- */
-PIXI.Texture.addTextureToCache = function(texture, id)
-{
- PIXI.TextureCache[id] = texture;
-}
-
-/**
- * Remove a texture from the textureCache.
- *
- * @static
- * @method removeTextureFromCache
- * @param id {String} the id of the texture to be removed
- * @return {Texture} the texture that was removed
- */
-PIXI.Texture.removeTextureFromCache = function(id)
-{
- var texture = PIXI.TextureCache[id]
- PIXI.TextureCache[id] = null;
- return texture;
-}
-
-// this is more for webGL.. it contains updated frames..
-PIXI.Texture.frameUpdates = [];
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- 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.
-
- 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);
-
- 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
-
- @class RenderTexture
- @extends Texture
- @constructor
- @param width {Number} The width of the render texture
- @param height {Number} The height of the render texture
- */
-PIXI.RenderTexture = function(width, height)
-{
- PIXI.EventTarget.call( this );
-
- this.width = width || 100;
- this.height = height || 100;
-
- this.indetityMatrix = PIXI.mat3.create();
-
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
-
- if(PIXI.gl)
- {
- this.initWebGL();
- }
- else
- {
- this.initCanvas();
- }
-}
-
-PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
-PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
-
-/**
- * Initializes the webgl data for this texture
- *
- * @method initWebGL
- * @private
- */
-PIXI.RenderTexture.prototype.initWebGL = function()
-{
- var gl = PIXI.gl;
- this.glFramebuffer = gl.createFramebuffer();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // 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);
- }
-}
-
-/**
- * Initializes the canvas data for this texture
- *
- * @method initCanvas
- * @private
- */
-PIXI.RenderTexture.prototype.initCanvas = function()
-{
- 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.render = this.renderCanvas;
-}
-
-/**
- * This function will draw the display object to the texture.
- *
- * @method renderWebGL
- * @param displayObject {DisplayObject} The display object to render this texture on
- * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
- * @private
- */
-PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
-{
- var gl = PIXI.gl;
-
- // enable the alpha color mask..
- gl.colorMask(true, true, true, true);
-
- gl.viewport(0, 0, this.width, this.height);
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- if(clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
-
- // 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;
-
-
- 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} 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".
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.AssetLoader = function(assetURLs, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The array of asset URLs that are going to be loaded
- *
- * @property assetURLs
- * @type Array
- */
- this.assetURLs = assetURLs;
-
- /**
- * Whether the requests should be treated as cross origin
- *
- * @property crossorigin
- * @type Boolean
- */
- this.crossorigin = crossorigin;
-
- /**
- * Maps file extension to loader types
- *
- * @property loadersByType
- * @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
- };
-
-
-};
-
-/**
- * Fired when an item has loaded
- * @event onProgress
- */
-
-/**
- * Fired when all the assets have loaded
- * @event onComplete
- */
-
-// constructor
-PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
-
-/**
- * Starts loading the assets sequentially
- *
- * @method load
- */
-PIXI.AssetLoader.prototype.load = function()
-{
- var scope = this;
-
- this.loadCount = this.assetURLs.length;
-
- for (var i=0; i < this.assetURLs.length; i++)
- {
- var fileName = this.assetURLs[i];
- var fileType = fileName.split(".").pop().toLowerCase();
-
- var loaderClass = this.loadersByType[fileType];
- if(!loaderClass)
- throw new Error(fileType + " is an unsupported file type");
-
- var loader = new loaderClass(fileName, this.crossorigin);
-
- loader.addEventListener("loaded", function()
- {
- scope.onAssetLoaded();
- });
- loader.load();
- }
-};
-
-/**
- * Invoked after each file is loaded
- *
- * @method onAssetLoaded
- * @private
- */
-PIXI.AssetLoader.prototype.onAssetLoaded = function()
-{
- this.loadCount--;
- 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();
- }
-};
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class JsonLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the JSON file
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.JsonLoader = function (url, crossorigin) {
- PIXI.EventTarget.call(this);
-
- /**
- * 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;
-
- /**
- * [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;
-
-};
-
-// constructor
-PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
-
-/**
- * Loads the JSON data
- *
- * @method load
- */
-PIXI.JsonLoader.prototype.load = function () {
- this.ajaxRequest = new 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);
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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.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();
- });
-
- 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();
-
- }
- 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();
- }
- }
-};
-
-/**
- * Invoke when json file loaded
- *
- * @method onLoaded
- * @private
- */
-PIXI.JsonLoader.prototype.onLoaded = function () {
- this.loaded = true;
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * Invoke when error occured
- *
- * @method onError
- * @private
- */
-PIXI.JsonLoader.prototype.onError = function () {
- this.dispatchEvent({
- type: "error",
- content: this
- });
-};
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- * 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.
- * 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
- *
- * @class SpriteSheetLoader
- * @uses EventTarget
- * @constructor
- * @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);
-
- /**
- * 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;
-
- /**
- * [read-only] The base url of the bitmap font data
- *
- * @property baseUrl
- * @type String
- * @readOnly
- */
- this.baseUrl = url.replace(/[^\/]*$/, "");
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = null;
-
- /**
- * The frames of the sprite sheet
- *
- * @property frames
- * @type Object
- */
- this.frames = {};
-};
-
-// constructor
-PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader;
-
-/**
- * This will begin loading the JSON file
- *
- * @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();
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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;
-
- this.texture = image.texture.baseTexture;
- image.addEventListener("loaded", function (event) {
- 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!
- }
- }
- }
-
- image.load();
-};
-/**
- * Invoke when all files are loaded (json and texture)
- *
- * @method onLoaded
- * @private
- */
-PIXI.SpriteSheetLoader.prototype.onLoaded = function () {
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class ImageLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the image
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.ImageLoader = function(url, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = PIXI.Texture.fromImage(url, crossorigin);
-
- /**
- * if the image is loaded with loadFramedSpriteSheet
- * frames will contain the sprite sheet frames
- *
- */
- this.frames = [];
-};
-
-// constructor
-PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader;
-
-/**
- * Loads image or takes it from cache
- *
- * @method load
- */
-PIXI.ImageLoader.prototype.load = function()
-{
- if(!this.texture.baseTexture.hasLoaded)
- {
- var scope = this;
- this.texture.baseTexture.addEventListener("loaded", function()
- {
- scope.onLoaded();
- });
- }
- else
- {
- this.onLoaded();
- }
-};
-
-/**
- * Invoked when image file is loaded or it is already cached and ready to use
- *
- * @method onLoaded
- * @private
- */
-PIXI.ImageLoader.prototype.onLoaded = function()
-{
- this.dispatchEvent({type: "loaded", content: this});
-};
-
-/**
- * Loads image and split it to uniform sized frames
- *
- *
- * @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
- */
-PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
-{
- this.frames = [];
- var cols = Math.floor(this.texture.width / frameWidth);
- var rows = Math.floor(this.texture.height / frameHeight);
-
- var i=0;
- for (var y=0; y
+
+
diff --git a/examples/example 7 - Transparent Background/pixi.js b/examples/example 7 - Transparent Background/pixi.js
deleted file mode 100644
index 6d567a2..0000000
--- a/examples/example 7 - Transparent Background/pixi.js
+++ /dev/null
@@ -1,10649 +0,0 @@
-/**
- * @license
- * Pixi.JS - v1.3.0
- * Copyright (c) 2012, Mat Groves
- * http://goodboydigital.com/
- *
- * Compiled: 2013-09-30
- *
- * Pixi.JS is licensed under the MIT License.
- * http://www.opensource.org/licenses/mit-license.php
- */
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-(function(){
-
- var root = this;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * @module PIXI
- */
-var PIXI = PIXI || {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
- *
- * @class Point
- * @constructor
- * @param x {Number} position of the point
- * @param y {Number} position of the point
- */
-PIXI.Point = function(x, y)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-}
-
-/**
- * Creates a clone of this point
- *
- * @method clone
- * @return {Point} a copy of the point
- */
-PIXI.Point.prototype.clone = function()
-{
- return new PIXI.Point(this.x, this.y);
-}
-
-// constructor
-PIXI.Point.prototype.constructor = PIXI.Point;
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
- *
- * @class Rectangle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the rectangle
- * @param y {Number} The Y coord of the upper-left corner of the rectangle
- * @param width {Number} The overall width of this rectangle
- * @param height {Number} The overall height of this rectangle
- */
-PIXI.Rectangle = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Rectangle
- *
- * @method clone
- * @return {Rectangle} a copy of the rectangle
- */
-PIXI.Rectangle.prototype.clone = function()
-{
- 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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this Rectangle
- */
-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;
-
- if(y >= y1 && y <= y1 + this.height)
- {
- return true;
- }
- }
-
- return false;
-}
-
-// constructor
-PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
-
-
-/**
- * @author Adrien Brault
- */
-
-/**
- * @class Polygon
- * @constructor
- * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
- * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
- * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
- * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
- * Numbers.
- */
-PIXI.Polygon = function(points)
-{
- //if points isn't an array, use arguments as the array
- if(!(points instanceof Array))
- points = Array.prototype.slice.call(arguments);
-
- //if this is a flat array of numbers, convert it to points
- if(typeof points[0] === 'number') {
- var p = [];
- for(var i = 0, il = points.length; i < il; i+=2) {
- p.push(
- new PIXI.Point(points[i], points[i + 1])
- );
- }
-
- points = p;
- }
-
- this.points = points;
-}
-
-/**
- * Creates a clone of this polygon
- *
- * @method clone
- * @return {Polygon} a copy of the polygon
- */
-PIXI.Polygon.prototype.clone = function()
-{
- var points = [];
- for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
-
- if(intersect) inside = !inside;
- }
-
- return inside;
-}
-
-// constructor
-PIXI.Polygon.prototype.constructor = PIXI.Polygon;
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Circle object can be used to specify a hit area for displayobjects
- *
- * @class Circle
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Circle = function(x, y, radius)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property radius
- * @type Number
- * @default 0
- */
- this.radius = radius || 0;
-}
-
-/**
- * Creates a clone of this Circle instance
- *
- * @method clone
- * @return {Circle} a copy of the polygon
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
- */
-PIXI.Circle.prototype.contains = function(x, y)
-{
- if(this.radius <= 0)
- return false;
-
- var dx = (this.x - x),
- dy = (this.y - y),
- r2 = this.radius * this.radius;
-
- dx *= dx;
- dy *= dy;
-
- return (dx + dy <= r2);
-}
-
-// constructor
-PIXI.Circle.prototype.constructor = PIXI.Circle;
-
-
-/**
- * @author Chad Engler
- */
-
-/**
- * The Ellipse object can be used to specify a hit area for displayobjects
- *
- * @class Ellipse
- * @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
- * @param width {Number} The overall width of this ellipse
- * @param height {Number} The overall height of this ellipse
- */
-PIXI.Ellipse = function(x, y, width, height)
-{
- /**
- * @property x
- * @type Number
- * @default 0
- */
- this.x = x || 0;
-
- /**
- * @property y
- * @type Number
- * @default 0
- */
- this.y = y || 0;
-
- /**
- * @property width
- * @type Number
- * @default 0
- */
- this.width = width || 0;
-
- /**
- * @property height
- * @type Number
- * @default 0
- */
- this.height = height || 0;
-}
-
-/**
- * Creates a clone of this Ellipse instance
- *
- * @method clone
- * @return {Ellipse} a copy of the ellipse
- */
-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
- *
- * @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this ellipse
- */
-PIXI.Ellipse.prototype.contains = function(x, y)
-{
- if(this.width <= 0 || this.height <= 0)
- return false;
-
- //normalize the coords to an ellipse with center 0,0
- //and a radius of 0.5
- var normx = ((x - this.x) / this.width) - 0.5,
- normy = ((y - this.y) / this.height) - 0.5;
-
- normx *= normx;
- normy *= normy;
-
- return (normx + normy < 0.25);
-}
-
-PIXI.Ellipse.getBounds = function()
-{
- return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
-}
-
-// constructor
-PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
-
-
-
-/*
- * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
- * you both rock!
- */
-
-function determineMatrixArrayType() {
- PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return PIXI.Matrix;
-}
-
-determineMatrixArrayType();
-
-PIXI.mat3 = {};
-
-PIXI.mat3.create = function()
-{
- 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;
-
- 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;
-
- return matrix;
-}
-
-
-PIXI.mat4 = {};
-
-PIXI.mat4.create = function()
-{
- 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;
-
- return matrix;
-}
-
-PIXI.mat3.multiply = function (mat, mat2, dest)
-{
- 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],
-
- 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[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;
-
- return dest;
-}
-
-PIXI.mat3.clone = function(mat)
-{
- 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];
-
- 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 (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
-}
-
-PIXI.mat3.toMat4 = function (mat, dest)
-{
- if (!dest) { dest = PIXI.mat4.create(); }
-
- 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[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];
-
- return dest;
-}
-
-
-/////
-
-
-PIXI.mat4.create = function()
-{
- 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;
-
- 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];
-
- 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;
-}
-
-PIXI.mat4.multiply = function (mat, mat2, dest)
-{
- 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 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;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * The base class for all objects that are rendered on the screen.
- *
- * @class DisplayObject
- * @constructor
- */
-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();
-
- /**
- * 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 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 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 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;
-
- /**
- * [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 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] Current transform of the object based on world (parent) factors
- *
- * @property worldTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.worldTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [read-only] Current transform of the object locally
- *
- * @property localTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.localTransform = PIXI.mat3.create()//mat3.identity();
-
- /**
- * [NYI] Unkown
- *
- * @property color
- * @type Array<>
- * @private
- */
- this.color = [];
-
- /**
- * [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;
-
- /*
- * MOUSE Callbacks
- */
-
- /**
- * 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 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
- * 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 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 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
- */
-
- /**
- * 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 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}
- */
-}
-
-// constructor
-PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject;
-
-/**
- * [Deprecated] Indicates if the sprite will have touch and mouse interactivity. It is false by default
- * Instead of using this function you can now simply set the interactive property to true or false
- *
- * @method setInteractive
- * @param interactive {Boolean}
- * @deprecated Simply set the `interactive` property directly
- */
-PIXI.DisplayObject.prototype.setInteractive = function(interactive)
-{
- this.interactive = interactive;
-}
-
-/**
- * Indicates if the sprite will have touch and mouse interactivity. It is false by default
- *
- * @property interactive
- * @type Boolean
- * @default false
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
- get: function() {
- 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;
- }
-});
-
-/**
- * Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
- * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
- * To remove a mask, set this property to null.
- *
- * @property mask
- * @type Graphics
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
- get: function() {
- 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;
- }
- }
- else
- {
- this.removeFilter(this._mask);
- this._mask.renderable = true;
- }
-
- this._mask = value;
- }
-});
-
-/**
- * Sets the filters for the displayObject. Currently there's a few limitations.
- * 1: At the moment only one filter can be applied at a time..
- * 2: They cannot be nested.
- * 3: There's no padding yet.
- * 4: this is a webGL only feature.
- * @property filters
- * @type Array
- */
-Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
- get: function() {
- return this._filters;
- },
- set: function(value) {
-
- //if(value == )
- if(value)
- {
- if(this._filters)this.removeFilter(this._filters);
- this.addFilter(value)
- }
- else
- {
- if(this._filters)this.removeFilter(this._filters);
- }
-
- this._filters = value;
- }
-});
-
-/*
- * Adds a filter to this displayObject
- *
- * @method addFilter
- * @param mask {Graphics} the graphics object to use as a filter
- * @private
- */
-PIXI.DisplayObject.prototype.addFilter = function(data)
-{
- //if(this.filter)return;
- //this.filter = true;
-
- // 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;
-
- /*
- * 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);
- }
-
-}
-
-/*
- * Removes the filter to this displayObject
- *
- * @method removeFilter
- * @private
- */
-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);
- }
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-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;
-
- // 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],
-
- b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
- b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
-
- 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;
-
- worldTransform[3] = b10 * a00 + b11 * a10;
- 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;
-
-}
-
-PIXI.visibleCount = 0;
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * 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
- * @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 = [];
-}
-
-// constructor
-PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-
-/**
- * Adds a child to the container.
- *
- * @method addChild
- * @param child {DisplayObject} The DisplayObject to add to the container
- */
-PIXI.DisplayObjectContainer.prototype.addChild = function(child)
-{
- if(child.parent != undefined)
- {
-
- //// 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)
- {
- 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
- *
- * @method addChildAt
- * @param child {DisplayObject} The child to add
- * @param index {Number} The index to place the child in
- */
-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;
-
- 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
- *
- * @method swapChildren
- * @param child {DisplayObject}
- * @param child2 {DisplayObject}
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
-{
- /*
- * this funtion needs to be recoded..
- * can be done a lot faster..
- */
- return;
-
- // need to fix this function :/
- /*
- // TODO I already know this??
- var index = this.children.indexOf( child );
- var index2 = this.children.indexOf( child2 );
-
- if ( index !== -1 && index2 !== -1 )
- {
- // cool
-
- /*
- if(this.stage)
- {
- // this is to satisfy the webGL batching..
- // TODO sure there is a nicer way to achieve this!
- this.stage.__removeChild(child);
- this.stage.__removeChild(child2);
-
- this.stage.__addChild(child);
- this.stage.__addChild(child2);
- }
-
- // swap the positions..
- this.children[index] = child2;
- this.children[index2] = child;
-
- }
- else
- {
- throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this);
- }*/
-}
-
-/**
- * Returns the Child at the specified index
- *
- * @method getChildAt
- * @param index {Number} The index to get the child from
- */
-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);
- }
-}
-
-/**
- * Removes a child from the container.
- *
- * @method removeChild
- * @param child {DisplayObject} The DisplayObject to remove
- */
-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 tempLast = childFirst._iPrev;
- // need to make sure the parents last is updated too
- var updateLast = this;
- while(updateLast.last == childLast.last)
- {
- 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
- *
- * @method updateTransform
- * @private
- */
-PIXI.DisplayObjectContainer.prototype.updateTransform = function()
-{
- if(!this.visible)return;
-
- PIXI.DisplayObject.prototype.updateTransform.call( this );
-
- for(var i=0,j=this.children.length; i} an array of {Texture} objects that make up the animation
- */
-PIXI.MovieClip = function(textures)
-{
- PIXI.Sprite.call(this, textures[0]);
-
- /**
- * The array of textures that make up the animation
- *
- * @property textures
- * @type Array
- */
- this.textures = textures;
-
- /**
- * The speed that the MovieClip will play at. Higher is faster, lower is slower
- *
- * @property animationSpeed
- * @type Number
- * @default 1
- */
- this.animationSpeed = 1;
-
- /**
- * Whether or not the movie clip repeats after playing.
- *
- * @property loop
- * @type Boolean
- * @default true
- */
- this.loop = true;
-
- /**
- * Function to call when a MovieClip finishes playing
- *
- * @property onComplete
- * @type Function
- */
- this.onComplete = null;
-
- /**
- * [read-only] The index MovieClips current frame (this may not have to be a whole number)
- *
- * @property currentFrame
- * @type Number
- * @default 0
- * @readOnly
- */
- this.currentFrame = 0;
-
- /**
- * [read-only] Indicates if the MovieClip is currently playing
- *
- * @property playing
- * @type Boolean
- * @readOnly
- */
- this.playing = false;
-}
-
-// constructor
-PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
-PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
-
-/**
-* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
-* assigned to the MovieClip.
-*
-* @property totalFrames
-* @type Number
-* @default 0
-* @readOnly
-*/
-Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
- get: function() {
-
- return this.textures.length;
- }
-});
-
-
-/**
- * Stops the MovieClip
- *
- * @method stop
- */
-PIXI.MovieClip.prototype.stop = function()
-{
- this.playing = false;
-}
-
-/**
- * Plays the MovieClip
- *
- * @method play
- */
-PIXI.MovieClip.prototype.play = function()
-{
- this.playing = true;
-}
-
-/**
- * Stops the MovieClip and goes to a specific frame
- *
- * @method gotoAndStop
- * @param frameNumber {Number} frame index to stop at
- */
-PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
-{
- this.playing = false;
- this.currentFrame = frameNumber;
- var round = (this.currentFrame + 0.5) | 0;
- this.setTexture(this.textures[round % this.textures.length]);
-}
-
-/**
- * Goes to a specific frame and begins playing the MovieClip
- *
- * @method gotoAndPlay
- * @param frameNumber {Number} frame index to start at
- */
-PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
-{
- this.currentFrame = frameNumber;
- this.playing = true;
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.MovieClip.prototype.updateTransform = function()
-{
- PIXI.Sprite.prototype.updateTransform.call(this);
-
- if(!this.playing)return;
-
- this.currentFrame += this.animationSpeed;
-
- var round = (this.currentFrame + 0.5) | 0;
-
- 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();
- }
- }
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-
-PIXI.FilterBlock = function()
-{
- this.visible = true;
- this.renderable = true;
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.ColorMatrixFilter = function()
-{
- // 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;",
- "}"
- ];
-
-}
-
-
-Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
- get: function() {
- return this.uniforms.matrix.value;
- },
- set: function(value) {
- this.uniforms.matrix.value = value;
- }
-});
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.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");
- PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
-
- this.setText(text);
- this.setStyle(style);
-
- this.updateText();
- this.dirty = false;
-};
-
-// constructor
-PIXI.Text.prototype = Object.create(PIXI.Sprite.prototype);
-PIXI.Text.prototype.constructor = PIXI.Text;
-
-/**
- * Set the style of the 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.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.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.strokeThickness = style.strokeThickness || 0;
- style.wordWrap = style.wordWrap || false;
- style.wordWrapWidth = style.wordWrapWidth || 100;
- this.style = style;
- this.dirty = true;
-};
-
-/**
- * Set the copy for the text object. To split a line you can use "\n"
- *
- * @methos 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.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.Text.prototype.updateText = function()
-{
- this.context.font = this.style.font;
-
- var outputText = 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)/);
-
- //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;
-
- //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.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);
-
- 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.fill)
- {
- this.context.fillText(lines[i], linePosition.x, linePosition.y);
- }
- }
-
- this.updateTexture();
-};
-
-/**
- * Updates texture size based on canvas size
- *
- * @method updateTexture
- * @private
- */
-PIXI.Text.prototype.updateTexture = function()
-{
- this.texture.baseTexture.width = this.canvas.width;
- this.texture.baseTexture.height = this.canvas.height;
- this.texture.frame.width = this.canvas.width;
- this.texture.frame.height = this.canvas.height;
-
- this._width = this.canvas.width;
- this._height = this.canvas.height;
-
- PIXI.texturesToUpdate.push(this.texture.baseTexture);
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.Text.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- this.updateText();
- this.dirty = false;
- }
-
- PIXI.Sprite.prototype.updateTransform.call(this);
-};
-
-/*
- * http://stackoverflow.com/users/34441/ellisbben
- * great solution to the problem!
- *
- * @method determineFontHeight
- * @param fontStyle {Object}
- * @private
- */
-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];
-
- 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;
-
- body.removeChild(dummy);
- }
-
- return result;
-};
-
-/**
- * A Text Object will apply wordwrap
- *
- * @method wordWrap
- * @param text {String}
- * @private
- */
-PIXI.Text.prototype.wordWrap = function(text)
-{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
- var result = "";
- var lines = text.split("\n");
- for (var i = 0; i < lines.length; i++)
- {
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
- }
-
- return result;
-};
-
-/**
- * Destroys this text object
- *
- * @method destroy
- * @param destroyTexture {Boolean}
- */
-PIXI.Text.prototype.destroy = function(destroyTexture)
-{
- if(destroyTexture)
- {
- this.texture.destroy();
- }
-
-};
-
-PIXI.Text.heightCache = {};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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.
- *
- * @class BitmapText
- * @extends DisplayObjectContainer
- * @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")
- */
-PIXI.BitmapText = function(text, style)
-{
- PIXI.DisplayObjectContainer.call(this);
-
- this.setText(text);
- this.setStyle(style);
- this.updateText();
- this.dirty = false
-
-};
-
-// constructor
-PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
-
-/**
- * Set the copy for the text object
- *
- * @method setText
- * @param text {String} The copy that you would like the text to display
- */
-PIXI.BitmapText.prototype.setText = function(text)
-{
- this.text = text || " ";
- this.dirty = true;
-};
-
-/**
- * Set the style of the 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")
- */
-PIXI.BitmapText.prototype.setStyle = function(style)
-{
- style = style || {};
- style.align = style.align || "left";
- this.style = style;
-
- 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;
-
- this.dirty = true;
-};
-
-/**
- * Renders text
- *
- * @method updateText
- * @private
- */
-PIXI.BitmapText.prototype.updateText = function()
-{
- var data = PIXI.BitmapText.fonts[this.fontName];
- var pos = new PIXI.Point();
- var prevCharCode = null;
- var chars = [];
- var maxLineWidth = 0;
- var lineWidths = [];
- var line = 0;
- var scale = this.fontSize / data.size;
- for(var i = 0; i < this.text.length; i++)
- {
- var charCode = this.text.charCodeAt(i);
- if(/(?:\r\n|\r|\n)/.test(this.text.charAt(i)))
- {
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
- line++;
-
- pos.x = 0;
- pos.y += data.lineHeight;
- prevCharCode = null;
- continue;
- }
-
- var charData = data.chars[charCode];
- if(!charData) continue;
-
- if(prevCharCode && charData[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;
-
- prevCharCode = charCode;
- }
-
- lineWidths.push(pos.x);
- maxLineWidth = Math.max(maxLineWidth, pos.x);
-
- var lineAlignOffsets = [];
- for(i = 0; i <= line; i++)
- {
- var alignOffset = 0;
- if(this.style.align == "right")
- {
- alignOffset = maxLineWidth - lineWidths[i];
- }
- else if(this.style.align == "center")
- {
- alignOffset = (maxLineWidth - lineWidths[i]) / 2;
- }
- lineAlignOffsets.push(alignOffset);
- }
-
- for(i = 0; i < chars.length; i++)
- {
- 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;
- this.addChild(c);
- }
-
- this.width = pos.x * scale;
- this.height = (pos.y + data.lineHeight) * scale;
-};
-
-/**
- * Updates the transfor of this object
- *
- * @method updateTransform
- * @private
- */
-PIXI.BitmapText.prototype.updateTransform = function()
-{
- if(this.dirty)
- {
- while(this.children.length > 0)
- {
- this.removeChild(this.getChildAt(0));
- }
- this.updateText();
-
- this.dirty = false;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
-};
-
-PIXI.BitmapText.fonts = {};
-
-/**
- * @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.
- *
- * @class InteractionManager
- * @constructor
- * @param stage {Stage} The stage to handle interactions
- */
-PIXI.InteractionManager = function(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();
-
- /**
- * 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();
-
- this.mouseoverEnabled = true;
-
- //tiny little interactiveData pool!
- this.pool = [];
-
- 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.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;
-
-/**
- * Collects an interactive sprite recursively to have their interactions managed
- *
- * @method collectInteractiveSprite
- * @param displayObject {DisplayObject} the displayObject to collect
- * @param iParent {DisplayObject}
- * @private
- */
-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);
-
- 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
- *
- * @method setTarget
- * @param target {WebGLRenderer|CanvasRenderer} the renderer to bind events to
- * @private
- */
-PIXI.InteractionManager.prototype.setTarget = function(target)
-{
- this.target = target;
-
- //check if the dom element has been set. If it has don't do anything
- if( this.interactionDOMElement === null ) {
-
- this.setTargetDomElement( target.view );
- }
-
- document.body.addEventListener('mouseup', this.onMouseUp, true);
-}
-
-
-/**
- * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
- * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
- * to receive those events
- *
- * @method setTargetDomElement
- * @param domElement {DOMElement} the dom element which will receive mouse and touch events
- * @private
- */
-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'] = '';
-
- 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);
- }
-
-
- 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!
- }
-
- this.interactionDOMElement = domElement;
-
- 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
- *
- * @method update
- * @private
- */
-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 = "default";
-
- 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 = "pointer";
-
- 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
- *
- * @method onMouseMove
- * @param event {Event} The DOM event of the mouse moving
- * @private
- */
-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);
- }
- }
-}
-
-/**
- * Is called when the mouse button is pressed down on the renderer element
- *
- * @method onMouseDown
- * @param event {Event} The DOM event of a mouse button being pressed down
- * @private
- */
-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;
- }
- }
- }
-}
-
-
-PIXI.InteractionManager.prototype.onMouseOut = function(event)
-{
- var length = this.interactiveItems.length;
-
- this.interactionDOMElement.style.cursor = "default";
-
- 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
- *
- * @method onMouseUp
- * @param event {Event} The DOM event of a mouse button being released
- * @private
- */
-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;
- }
- }
-}
-
-/**
- * Tests if the current mouse coords hit a sprite
- *
- * @method hitTest
- * @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
- * @private
- */
-PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
-{
- var global = interactionData.global;
-
- if(item.vcount !== PIXI.visibleCount)return false;
-
- 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;
-
- 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;
-
- 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
- *
- * @method onTouchMove
- * @param event {Event} The DOM event of a touch moving accross the renderer view
- * @private
- */
-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);
- }
-}
-
-/**
- * Is called when a touch is started on the renderer element
- *
- * @method onTouchStart
- * @param event {Event} The DOM event of a touch starting on the renderer view
- * @private
- */
-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;
- }
- }
- }
- }
-}
-
-/**
- * Is called when a touch is ended on the renderer element
- *
- * @method onTouchEnd
- * @param event {Event} The DOM event of a touch ending on the renderer view
- * @private
- */
-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;
- }
-}
-
-/**
- * Holds all information related to an Interaction event
- *
- * @class InteractionData
- * @constructor
- */
-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();
-
- /**
- * The target Sprite that was interacted with
- *
- * @property target
- * @type Sprite
- */
- this.target;
-
- /**
- * When passed to an event handler, this will be the original DOM Event that was captured
- *
- * @property originalEvent
- * @type Event
- */
- this.originalEvent;
-}
-
-/**
- * This will return the local coords of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
- */
-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],
- 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)
-}
-
-// constructor
-PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A Stage represents the root of the display tree. Everything connected to the stage is rendered
- *
- * @class Stage
- * @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
- */
-PIXI.Stage = function(backgroundColor)
-{
- 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();
-
- /**
- * 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);
-
- /**
- * Whether the stage is dirty and needs to have interactions updated
- *
- * @property dirty
- * @type Boolean
- * @private
- */
- this.dirty = true;
-
- this.__childrenAdded = [];
- this.__childrenRemoved = [];
-
- //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);
-
- this.setBackgroundColor(backgroundColor);
- this.worldVisible = true;
-}
-
-// constructor
-PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Stage.prototype.constructor = PIXI.Stage;
-
-/**
- * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
- * This is useful for when you have other DOM elements ontop of the Canvas element.
- *
- * @method setInteractionDelegate
- * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
- */
-PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
-{
- this.interactionManager.setTargetDomElement( domElement );
-}
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @private
- */
-PIXI.Stage.prototype.updateTransform = function()
-{
- this.worldAlpha = 1;
- this.vcount = PIXI.visibleCount;
-
- for(var i=0,j=this.children.length; i> 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 target != 'function') throw new TypeError();
-
- 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);
-
- return bound;
- };
- })();
-}
-
-/**
- * A wrapper for ajax requests to be handled cross browser
- *
- * @class AjaxRequest
- * @constructor
- */
-var AjaxRequest = PIXI.AjaxRequest = function()
-{
- 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);
-
- while(tmp._iNext)
- {
- safe++;
- tmp = tmp._iNext;
- console.log(tmp);
- // console.log(tmp);
-
- if(safe > 100)
- {
- console.log("BREAK")
- break
- }
- }
-}
-
-
-
-
-
-
-/**
- * https://github.com/mrdoob/eventtarget.js/
- * THankS mr DOob!
- */
-
-/**
- * Adds event emitter functionality to a class
- *
- * @class EventTarget
- * @example
- * function MyEmitter() {
- * PIXI.EventTarget.call(this); //mixes in event target stuff
- * }
- *
- * var em = new MyEmitter();
- * em.emit({ type: 'eventName', data: 'some data' });
- */
-PIXI.EventTarget = function () {
-
- var listeners = {};
-
- this.addEventListener = this.on = function ( type, listener ) {
-
-
- if ( listeners[ type ] === undefined ) {
-
- listeners[ type ] = [];
-
- }
-
- if ( listeners[ type ].indexOf( listener ) === - 1 ) {
-
- listeners[ type ].push( listener );
- }
-
- };
-
- this.dispatchEvent = this.emit = function ( event ) {
-
- if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
-
- return;
-
- }
-
- for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
-
- listeners[ event.type ][ i ]( event );
-
- }
-
- };
-
- this.removeEventListener = this.off = function ( type, listener ) {
-
- var index = listeners[ type ].indexOf( listener );
-
- if ( index !== - 1 ) {
-
- listeners[ type ].splice( index, 1 );
-
- }
-
- };
-
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * This helper function will automatically detect which renderer you should be using.
- * WebGL is the preferred renderer as it is a lot fastest. If webGL is not supported by
- * the browser then this function will return a canvas renderer
- *
- * @method autoDetectRenderer
- * @static
- * @param width {Number} the width of the renderers view
- * @param height {Number} the height of the renderers view
- * @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 webGL chrome at the moment)
- *
- * antialias
- */
-PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
-{
- if(!width)width = 800;
- if(!height)height = 600;
-
- // BORROWED from Mr Doob (mrdoob.com)
- var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )();
-
- //console.log(webgl);
- if( webgl )
- {
- return new PIXI.WebGLRenderer(width, height, view, transparent, antialias);
- }
-
- return new PIXI.CanvasRenderer(width, height, view, transparent);
-};
-
-
-
-/*
- PolyK library
- url: http://polyk.ivank.net
- Released under MIT licence.
-
- 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:
-
- 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.
-
- This is an amazing lib!
-
- slightly modified by mat groves (matgroves.com);
-*/
-
-PIXI.PolyK = {};
-
-/**
- * Triangulates shapes for webGL graphic fills
- *
- * @method Triangulate
- * @namespace PolyK
- * @constructor
- */
-PIXI.PolyK.Triangulate = function(p)
-{
- var sign = true;
-
- var n = p.length>>1;
- if(n<3) return [];
- var tgs = [];
- var avl = [];
- for(var i=0; i 3)
- {
- var i0 = avl[(i+0)%al];
- var i1 = avl[(i+1)%al];
- var i2 = avl[(i+2)%al];
-
- 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];
-
- 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= 0) && (v >= 0) && (u + v < 1);
-}
-
-/**
- * Checks if a shape is convex
- *
- * @class _convex
- * @namespace PolyK
- * @private
- */
-PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign)
-{
- return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/*
- * the default suoer fast shader!
- */
-
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
-
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
-
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * the triangle strip shader..
- */
-
-PIXI.stripShaderFragmentSrc = [
- "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;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.shaderStack = [];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
-
- //gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-//gl.enableVertexAttribArray(program.textureCoordAttribute);
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-
-
-}
-
-PIXI.initDefaultShader = function()
-{
- PIXI.defaultShader = new PIXI.PixiShader();
- PIXI.defaultShader.init();
- PIXI.activateShader(PIXI.defaultShader);
- /*
- PIXI.shaderStack.push(PIXI.defaultShader);
- PIXI.current*/
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
-
-PIXI.CompileVertexShader = function(gl, shaderSrc)
-{
- return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
-}
-
-PIXI.CompileFragmentShader = function(gl, shaderSrc)
-{
- 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);
-
- if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(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();
-
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
- }
-
- return shaderProgram;
-}
-
-PIXI.activateShader = function(shader)
-{
- PIXI.shaderStack.push(shader);
-
- //console.log(">>>")
- var gl = PIXI.gl;
-
- var shaderProgram = shader.program;
-
- // map uniforms..
- gl.useProgram(shaderProgram);
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
-
- shader.syncUniforms();
-
- PIXI.currentShader = shaderProgram;
-}
-
-
-PIXI.popShader = function()
-{
- var gl = PIXI.gl;
- // activate last program..
- var lastProgram = PIXI.shaderStack.pop();
-
- var shaderProgram = PIXI.shaderStack[ PIXI.shaderStack.length-1 ].program;
-
- gl.useProgram(shaderProgram);
-
- PIXI.currentShader = shaderProgram;
-}
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.primitiveProgram);
-
- //gl.disableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.disableVertexAttribArray(PIXI.currentShader.colorAttribute);
- gl.disableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
-
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute);
-}
-
-PIXI.deactivatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.currentShader);
-
- gl.enableVertexAttribArray(PIXI.currentShader.textureCoordAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.vertexPositionAttribute);
- //gl.enableVertexAttribArray(PIXI.currentShader.colorAttribute);
-}
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-PIXI.PixiShader = function()
-{
- // the webGL program..
- this.program;
-
- this.fragmentSrc = [
- "precision lowp float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
- "}"
- ];
-
-}
-
-PIXI.PixiShader.prototype.init = function()
-{
- var program = PIXI.compileProgram(this.vertexSrc || PIXI.shaderVertexSrc, this.fragmentSrc)
-
- var gl = PIXI.gl;
-
- gl.useProgram(program);
-
- // get the default shader bits!
- program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
- program.colorAttribute = gl.getAttribLocation(program, "aColor");
- program.textureCoordAttribute = gl.getAttribLocation(program, "aTextureCoord");
-
- program.projectionVector = gl.getUniformLocation(program, "projectionVector");
- program.samplerUniform = gl.getUniformLocation(program, "uSampler");
-
- // add those custom shaders!
- for (var key in this.uniforms)
- {
- // get the uniform locations..
- program[key] = gl.getUniformLocation(program, key);
- }
-
- this.program = program;
-}
-
-PIXI.PixiShader.prototype.syncUniforms = function()
-{
- var gl = PIXI.gl;
-
- for (var key in this.uniforms)
- {
- //var
- var type = this.uniforms[key].type;
-
- // need to grow this!
- if(type == "f")
- {
- gl.uniform1f(this.program[key], this.uniforms[key].value);
- }
- else if(type == "mat4")
- {
- gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
- }
- }
-
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A set of functions used by the webGL renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.WebGLGraphics = function()
-{
-
-}
-
-/**
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param projection {Object}
- */
-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);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
-
- // WHY DOES THIS LINE NEED TO BE THERE???
- //gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.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
- *
- * @static
- * @private
- * @method updateGraphics
- * @param graphics {Graphics}
- */
-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;
-
- 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
- *
- * @static
- * @private
- * @method buildRectangle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- }
-
-}
-
-/**
- * Builds a circle to draw
- *
- * @static
- * @private
- * @method buildCircle
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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;
-
- 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);
- }
-
-}
-
-/**
- * Builds a line to draw
- *
- * @static
- * @private
- * @method buildLine
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
-{
- // TODO OPTIMISE!
-
- var wrap = true;
- var points = graphicsData.points;
- if(points.length == 0)return;
-
- // 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;
-
- 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 (denom == 0) {
- denom+=1;
- }
-
- 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 (var i=0; i < indexCount; i++)
- {
- indices.push(indexStart++);
- };
-
- indices.push(indexStart-1);
-}
-
-/**
- * Builds a polygon to draw
- *
- * @static
- * @private
- * @method buildPoly
- * @param graphics {Graphics}
- * @param webGLData {Object}
- */
-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);
- };
-}
-
-function HEXtoRGB(hex) {
- return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
-
-// an instance of the gl context..
-// only one at the moment :/
-PIXI.gl;
-
-/**
- * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
- * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
- * So no need for Sprite Batch's or Sprite Cloud's
- * Dont forget to add the view to your DOM or you will not see anything :)
- *
- * @class WebGLRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @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..
-
- this.transparent = !!transparent;
-
- this.width = width || 800;
- this.height = height || 600;
-
- this.view = view || document.createElement( 'canvas' );
- this.view.width = this.width;
- this.view.height = this.height;
-
- // 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.batchs = [];
-
- try
- {
- PIXI.gl = this.gl = this.view.getContext("experimental-webgl", {
- alpha: this.transparent,
- antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
- stencil:true
- });
- }
- catch (e)
- {
- throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
- }
-
- PIXI.initDefaultShader();
- PIXI.initPrimitiveShader();
- PIXI.initDefaultStripShader();
-
-
-// PIXI.activateDefaultShader();
-
- var gl = this.gl;
- PIXI.WebGLRenderer.gl = gl;
-
- this.batch = new PIXI.WebGLBatch(gl);
- gl.disable(gl.DEPTH_TEST);
- gl.disable(gl.CULL_FACE);
-
- gl.enable(gl.BLEND);
- gl.colorMask(true, true, true, this.transparent);
-
- PIXI.projection = new PIXI.Point(400, 300);
-
- this.resize(this.width, this.height);
- this.contextLost = false;
-
- PIXI.activateShader(PIXI.defaultShader);
-
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
-
-}
-
-// constructor
-PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
-
-/**
- * Gets a new WebGLBatch from the pool
- *
- * @static
- * @method getBatch
- * @return {WebGLBatch}
- * @private
- */
-PIXI.WebGLRenderer.getBatch = function()
-{
- if(PIXI._batchs.length == 0)
- {
- return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
- }
- else
- {
- return PIXI._batchs.pop();
- }
-}
-
-/**
- * Puts a batch back into the pool
- *
- * @static
- * @method returnBatch
- * @param batch {WebGLBatch} The batch to return
- * @private
- */
-PIXI.WebGLRenderer.returnBatch = function(batch)
-{
- batch.clean();
- PIXI._batchs.push(batch);
-}
-
-/**
- * Renders the stage to its webGL view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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);
- }
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
-
- // 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;
- 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
- *
- * @static
- * @method updateTextures
- * @private
- */
-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 = [];
-}
-
-/**
- * Updates a loaded webgl texture
- *
- * @static
- * @method updateTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.updateTexture = function(texture)
-{
- //TODO break this out into a texture manager...
- var gl = PIXI.gl;
-
- if(!texture._glTexture)
- {
- texture._glTexture = gl.createTexture();
- }
-
- if(texture.hasLoaded)
- {
- gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
-
- 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);
-
- // reguler...
-
- 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
- *
- * @method destroyTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.destroyTexture = function(texture)
-{
- //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);
- }
-}
-
-/**
- * resizes the webGL view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the webGL view
- * @param height {Number} the new height of the webGL view
- */
-PIXI.WebGLRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-
- this.gl.viewport(0, 0, this.width, this.height);
-
- //var projectionMatrix = this.projectionMatrix;
-
- 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;
-}
-
-/**
- * Handles a lost webgl context
- *
- * @method handleContextLost
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
-{
- event.preventDefault();
- this.contextLost = true;
-}
-
-/**
- * Handles a restored webgl context
- *
- * @method handleContextRestored
- * @param event {Event}
- * @private
- */
-PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
-{
- this.gl = this.view.getContext("experimental-webgl", {
- alpha: true
- });
-
- this.initShaders();
-
- 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;
- };
-
- PIXI._restoreBatchs(this.gl);
-
- this.contextLost = false;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._batchs = [];
-
-/**
- * @private
- */
-PIXI._getBatch = function(gl)
-{
- 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);
-}
-
-/**
- * @private
- */
-PIXI._restoreBatchs = function(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.
- * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
- * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
- * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
- * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @constructor
- * @param gl {WebGLContext} an instance of the webGL context
- */
-PIXI.WebGLBatch = function(gl)
-{
- this.gl = gl;
-
- 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;
-
-/**
- * Cleans the batch so that is can be returned to an object pool and reused
- *
- * @method clean
- */
-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;
-}
-
-/**
- * Recreates the buffers in the event of a context loss
- *
- * @method restoreLostContext
- * @param gl {WebGLContext}
- */
-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();
-}
-
-/**
- * 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
- */
-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;
-
- this.growBatch();
-}
-
-/**
- * inserts a sprite before the specified 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++;
-
- 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;
- }
-}
-
-/**
- * inserts a sprite after the specified sprite
- *
- * @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++;
-
- sprite.batch = this;
- this.dirty = true;
-
- var tempNext = previousSprite.__next;
- previousSprite.__next = sprite;
- sprite.__prev = previousSprite;
-
- 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--;
-
- 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.__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;
-}
-
-/**
- * Splits the batch into two with the specified sprite being the start of the new batch.
- *
- * @method split
- * @param sprite {Sprite} the sprite that indicates where the batch should be split
- * @return {WebGLBatch} the new batch
- */
-PIXI.WebGLBatch.prototype.split = function(sprite)
-{
- this.dirty = true;
-
- 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;
-
- 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"?
-
- // 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;
-
- return batch;
-}
-
-/**
- * Merges two batchs together
- *
- * @method merge
- * @param batch {WebGLBatch} the batch that will be merged
- */
-PIXI.WebGLBatch.prototype.merge = function(batch)
-{
- this.dirty = true;
-
- this.tail.__next = batch.head;
- batch.head.__prev = this.tail;
-
- this.size += batch.size;
-
- this.tail = batch.tail;
-
- 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
- * function is used to increase the size of the batch. It also creates a little extra room so
- * that the batch does not need to be resized every time a sprite is added
- *
- * @method growBatch
- */
-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);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
-
- 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.dirtyUVS = 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.dirtyColors = true;
-
- this.indices = new Uint16Array(this.dynamicSize * 6);
- var length = this.indices.length/6;
-
- 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
- *
- * @method refresh
- */
-PIXI.WebGLBatch.prototype.refresh = function()
-{
- var gl = this.gl;
-
- if (this.dynamicSize < this.size)
- {
- this.growBatch();
- }
-
- 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;
-
- while(displayObject)
- {
- index = indexRun * 8;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
-
- colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
-
- displayObject = displayObject.__next;
-
- indexRun ++;
- }
-
- this.dirtyUVS = true;
- this.dirtyColors = true;
-}
-
-/**
- * Updates all the relevant geometry and uploads the data to the GPU
- *
- * @method update
- */
-PIXI.WebGLBatch.prototype.update = function()
-{
- var gl = this.gl;
- var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3
-
- var a, b, c, d, tx, ty;
-
- var indexRun = 0;
-
- var displayObject = this.head;
-
- while(displayObject)
- {
- if(displayObject.vcount === PIXI.visibleCount)
- {
- width = displayObject.texture.frame.width;
- height = displayObject.texture.frame.height;
-
- // 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;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- index = indexRun * 8;
-
- worldTransform = displayObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- this.verticies[index + 0 ] = a * w1 + c * h1 + tx;
- this.verticies[index + 1 ] = d * h1 + b * w1 + ty;
-
- this.verticies[index + 2 ] = a * w0 + c * h1 + tx;
- this.verticies[index + 3 ] = d * h1 + b * w0 + ty;
-
- this.verticies[index + 4 ] = a * w0 + c * h0 + tx;
- this.verticies[index + 5 ] = d * h0 + b * w0 + ty;
-
- this.verticies[index + 6] = a * w1 + c * h0 + tx;
- this.verticies[index + 7] = d * h0 + b * w1 + ty;
-
- if(displayObject.updateFrame || displayObject.texture.updateFrame)
- {
- this.dirtyUVS = true;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
- }
-
- // TODO this probably could do with some optimisation....
- if(displayObject.cacheAlpha != displayObject.worldAlpha)
- {
- displayObject.cacheAlpha = displayObject.worldAlpha;
-
- var colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
- this.dirtyColors = true;
- }
- }
- else
- {
- index = indexRun * 8;
-
- this.verticies[index + 0 ] = 0;
- this.verticies[index + 1 ] = 0;
-
- this.verticies[index + 2 ] = 0;
- this.verticies[index + 3 ] = 0;
-
- this.verticies[index + 4 ] = 0;
- this.verticies[index + 5 ] = 0;
-
- this.verticies[index + 6] = 0;
- this.verticies[index + 7] = 0;
- }
-
- indexRun++;
- displayObject = displayObject.__next;
- }
-}
-
-/**
- * Draws the batch to the frame buffer
- *
- * @method render
- */
-PIXI.WebGLBatch.prototype.render = function(start, end)
-{
- start = start || 0;
-
- if(end == undefined)end = this.size;
-
- if(this.dirty)
- {
- this.refresh();
- this.dirty = false;
- }
-
- if (this.size == 0)return;
-
- this.update();
- var gl = this.gl;
-
- //TODO optimize this!
-
- var shaderProgram = PIXI.currentShader;
-
- //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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // update the uvs
- var isDefault = (shaderProgram == PIXI.shaderProgram)
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
-
- if(this.dirtyUVS)
- {
- this.dirtyUVS = false;
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
- }
-
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
-
- // update color!
- gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
-
- if(this.dirtyColors)
- {
- 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!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
-
- var len = end - start;
-
- // DRAW THAT this!
- gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
- * if a group of sprites all have the same baseTexture and blendMode then they can be
- * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
- * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
- * even if the batch only contains one sprite. Batching is handled automatically by the
- * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @contructor
- * @param gl {WebGLContext} An instance of the webGL context
- */
-PIXI.WebGLRenderGroup = function(gl)
-{
- this.gl = gl;
- this.root;
-
- this.backgroundColor;
- this.batchs = [];
- this.toRemove = [];
-}
-
-// constructor
-PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
-
-/**
- * Add a display object to the webgl renderer
- *
- * @method setRenderable
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
-{
- // has this changed??
- if(this.root)this.removeDisplayObjectAndChildren(this.root);
-
- displayObject.worldVisible = displayObject.visible;
-
- // soooooo //
- // to check if any batchs exist already??
-
- // TODO what if its already has an object? should remove it
- this.root = displayObject;
- this.addDisplayObjectAndChildren(displayObject);
-}
-
-/**
- * Renders the stage to its webgl view
- *
- * @method render
- * @param projection {Object}
- */
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
-
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- // will render all the elements in the group
- var renderable;
- for (var i=0; i < this.batchs.length; i++)
- {
-
- renderable = this.batchs[i];
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- continue;
- }
-
- // non sprite batch..
- var worldVisible = renderable.vcount === PIXI.visibleCount;
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
- }
-
-}
-
-/**
- * Renders a specific displayObject
- *
- * @method renderSpecific
- * @param displayObject {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
-
- // to do!
- // render part of the scene...
-
- var startIndex;
- var startBatchIndex;
-
- var endIndex;
- var endBatchIndex;
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.first;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
- var startBatch = nextRenderable.batch;
-
- if(nextRenderable instanceof PIXI.Sprite)
- {
- startBatch = nextRenderable.batch;
-
- var head = startBatch.head;
- var next = head;
-
- // ok now we have the batch.. need to find the start index!
- if(head == nextRenderable)
- {
- startIndex = 0;
- }
- else
- {
- startIndex = 1;
-
- while(head.__next != nextRenderable)
- {
- startIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- startBatch = nextRenderable;
- }
-
- // Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
- {
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem.last;
- }
-
- if(lastRenderable instanceof PIXI.Sprite)
- {
- endBatch = lastRenderable.batch;
-
- var head = endBatch.head;
-
- if(head == lastRenderable)
- {
- endIndex = 0;
- }
- else
- {
- endIndex = 1;
-
- while(head.__next != lastRenderable)
- {
- endIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- endBatch = lastRenderable;
- }
-
- // TODO - need to fold this up a bit!
-
- if(startBatch == endBatch)
- {
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex, endIndex+1);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
- return;
- }
-
- // now we have first and last!
- startBatchIndex = this.batchs.indexOf(startBatch);
- endBatchIndex = this.batchs.indexOf(endBatch);
-
- // DO the first batch
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
-
- // DO the middle batchs..
- for (var i=startBatchIndex+1; i < endBatchIndex; i++)
- {
- renderable = this.batchs[i];
-
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- }
- else
- {
- this.renderSpecial(renderable, projection);
- }
- }
-
- // DO the last batch..
- if(endBatch instanceof PIXI.WebGLBatch)
- {
- endBatch.render(0, endIndex+1);
- }
- else
- {
- this.renderSpecial(endBatch, projection);
- }
-}
-
-/**
- * Renders a specific renderable
- *
- * @method renderSpecial
- * @param renderable {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
-{
- var sta = PIXI.shaderStack.length;
-
- var worldVisible = renderable.vcount === PIXI.visibleCount
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.CustomRenderable)
- {
- if(worldVisible) renderable.renderWebGL(this, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
-}
-
-PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(renderable, projection)
-{
- /*
- * for now only masks are supported..
- */
- var gl = PIXI.gl;
-
- if(renderable.open)
- {
- if(renderable.data instanceof Array)
- {
- var filter = renderable.data[0];
-
- if(!filter.shader)
- {
- var shader = new PIXI.PixiShader();
-
- shader.fragmentSrc = filter.fragmentSrc;
- shader.uniforms = filter.uniforms;
- shader.init();
-
- filter.shader = shader
- }
-
- PIXI.activateShader(filter.shader);
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
- PIXI.WebGLGraphics.renderGraphics(renderable.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- }
- else
- {
- if(renderable.data instanceof Array)
- {
- PIXI.popShader();
- gl.uniform2f(PIXI.currentShader.projectionVector, projection.x, projection.y);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
-}
-
-/**
- * Updates a webgl texture
- *
- * @method updateTexture
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
-{
-
- // TODO definitely can optimse this function..
-
- this.removeObject(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- this.insertObject(displayObject, previousRenderable, nextRenderable);
-}
-
-/**
- * Adds filter blocks
- *
- * @method addFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
-{
- start.__renderGroup = this;
- end.__renderGroup = this;
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = start;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
- this.insertAfter(start, previousRenderable);
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var previousRenderable2 = end;
- while(previousRenderable2 != this.root.first)
- {
- previousRenderable2 = previousRenderable2._iPrev;
- if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
- }
- this.insertAfter(end, previousRenderable2);
-}
-
-/**
- * Remove filter blocks
- *
- * @method removeFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
-{
- this.removeObject(start);
- this.removeObject(end);
-}
-
-/**
- * Adds a display object and children to the webgl context
- *
- * @method addDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
-
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- // one the display object hits this. we can break the loop
-
- var tempObject = displayObject.first;
- var testObject = displayObject.last._iNext;
- do
- {
- tempObject.__renderGroup = this;
-
- if(tempObject.renderable)
- {
-
- this.insertObject(tempObject, previousRenderable, nextRenderable);
- previousRenderable = tempObject;
- }
-
- tempObject = tempObject._iNext;
- }
- while(tempObject != testObject)
-}
-
-/**
- * Removes a display object and children to the webgl context
- *
- * @method removeDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup != this)return;
-
-// var displayObject = displayObject.first;
- var lastObject = displayObject.last;
- do
- {
- displayObject.__renderGroup = null;
- if(displayObject.renderable)this.removeObject(displayObject);
- displayObject = displayObject._iNext;
- }
- while(displayObject)
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertObject
- * @param displayObject {DisplayObject}
- * @param previousObject {DisplayObject}
- * @param nextObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
-{
- // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
- var previousSprite = previousObject;
- var nextSprite = nextObject;
-
- /*
- * so now we have the next renderable and the previous renderable
- *
- */
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch
- var nextBatch
-
- if(previousSprite instanceof PIXI.Sprite)
- {
- previousBatch = previousSprite.batch;
- if(previousBatch)
- {
- if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
- {
- previousBatch.insertAfter(displayObject, previousSprite);
- return;
- }
- }
- }
- else
- {
- // TODO reword!
- previousBatch = previousSprite;
- }
-
- if(nextSprite)
- {
- if(nextSprite instanceof PIXI.Sprite)
- {
- nextBatch = nextSprite.batch;
-
- //batch may not exist if item was added to the display list but not to the webGL
- if(nextBatch)
- {
- if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
- {
- nextBatch.insertBefore(displayObject, nextSprite);
- return;
- }
- else
- {
- if(nextBatch == previousBatch)
- {
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(nextSprite);
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var batch = PIXI.WebGLRenderer.getBatch();
-
- var index = this.batchs.indexOf( previousBatch );
- batch.init(displayObject);
- this.batchs.splice(index+1, 0, batch, splitBatch);
-
- return;
- }
- }
- }
- }
- else
- {
- // TODO re-word!
-
- nextBatch = nextSprite;
- }
- }
-
- /*
- * looks like it does not belong to any batch!
- * but is also not intersecting one..
- * time to create anew one!
- */
-
- var batch = PIXI.WebGLRenderer.getBatch();
- batch.init(displayObject);
-
- if(previousBatch) // if this is invalid it means
- {
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, batch);
- }
- else
- {
- this.batchs.push(batch);
- }
-
- return;
- }
- else if(displayObject instanceof PIXI.TilingSprite)
- {
-
- // add to a batch!!
- this.initTilingSprite(displayObject);
- // this.batchs.push(displayObject);
-
- }
- else if(displayObject instanceof PIXI.Strip)
- {
- // add to a batch!!
- this.initStrip(displayObject);
- // this.batchs.push(displayObject);
- }
- else if(displayObject)// instanceof PIXI.Graphics)
- {
- //displayObject.initWebGL(this);
-
- // add to a batch!!
- //this.initStrip(displayObject);
- //this.batchs.push(displayObject);
- }
-
- this.insertAfter(displayObject, previousSprite);
-
- // insert and SPLIT!
-
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertAfter
- * @param item {DisplayObject}
- * @param displayObject {DisplayObject} The object to insert
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
-{
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch = displayObject.batch;
-
- if(previousBatch)
- {
- // so this object is in a batch!
-
- // is it not? need to split the batch
- if(previousBatch.tail == displayObject)
- {
- // is it tail? insert in to batchs
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item);
- }
- else
- {
- // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
-
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(displayObject.__next);
-
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item, splitBatch);
- }
- }
- else
- {
- this.batchs.push(item);
- }
- }
- else
- {
- var index = this.batchs.indexOf( displayObject );
- this.batchs.splice(index+1, 0, item);
- }
-}
-
-/**
- * Removes a displayObject from the linked list
- *
- * @method removeObject
- * @param displayObject {DisplayObject} The object to remove
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
-{
- // loop through children..
- // display object //
-
- // add a child from the render group..
- // remove it and all its children!
- //displayObject.cacheVisible = false;//displayObject.visible;
-
- /*
- * removing is a lot quicker..
- *
- */
- var batchToRemove;
-
- if(displayObject instanceof PIXI.Sprite)
- {
- // should always have a batch!
- var batch = displayObject.batch;
- if(!batch)return; // this means the display list has been altered befre rendering
-
- batch.remove(displayObject);
-
- if(batch.size==0)
- {
- batchToRemove = batch;
- }
- }
- else
- {
- batchToRemove = displayObject;
- }
-
- /*
- * Looks like there is somthing that needs removing!
- */
- if(batchToRemove)
- {
- var index = this.batchs.indexOf( batchToRemove );
- if(index == -1)return;// this means it was added then removed before rendered
-
- // ok so.. check to see if you adjacent batchs should be joined.
- // TODO may optimise?
- if(index == 0 || index == this.batchs.length-1)
- {
- // wha - eva! just get of the empty batch!
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
-
- return;
- }
-
- if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
- {
- if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
- {
- //console.log("MERGE")
- this.batchs[index-1].merge(this.batchs[index+1]);
-
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
- this.batchs.splice(index, 2);
- return;
- }
- }
-
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- }
-}
-
-
-/**
- * Initializes a tiling sprite
- *
- * @method initTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
-{
- var gl = this.gl;
-
- // make the texture tilable..
-
- sprite.verticies = new Float32Array([0, 0,
- sprite.width, 0,
- sprite.width, sprite.height,
- 0, sprite.height]);
-
- sprite.uvs = new Float32Array([0, 0,
- 1, 0,
- 1, 1,
- 0, 1]);
-
- sprite.colors = new Float32Array([1,1,1,1]);
-
- sprite.indices = new Uint16Array([0, 1, 3,2])//, 2]);
-
- sprite._vertexBuffer = gl.createBuffer();
- sprite._indexBuffer = gl.createBuffer();
- sprite._uvBuffer = gl.createBuffer();
- sprite._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.uvs, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW);
-
-// return ( (x > 0) && ((x & (x - 1)) == 0) );
-
- if(sprite.texture.baseTexture._glTexture)
- {
- gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- sprite.texture.baseTexture._powerOf2 = true;
- }
- else
- {
- sprite.texture.baseTexture._powerOf2 = true;
- }
-}
-
-/**
- * Renders a Strip
- *
- * @method renderStrip
- * @param strip {Strip} The strip to render
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.stripShaderProgram;
-
-
- gl.useProgram(shaderProgram);
-
- var m = PIXI.mat3.clone(strip.worldTransform);
-
- PIXI.mat3.transpose(m);
-
- // set the matrix transform for the
- gl.uniformMatrix3fv(shaderProgram.translationMatrix, false, m);
- gl.uniform2f(shaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(shaderProgram.alpha, strip.worldAlpha);
-
-/*
- if(strip.blendMode == PIXI.blendModes.NORMAL)
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
- }
- */
-
-
- if(!strip.dirty)
- {
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- }
- else
- {
- strip.dirty = false;
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-
- }
-
- gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
-
- gl.useProgram(PIXI.currentProgram);
-}
-
-/**
- * Renders a TilingSprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to render
- * @param projectionMatrix {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
-{
- var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- var tilePosition = sprite.tilePosition;
- var tileScale = sprite.tileScale;
-
- var offsetX = tilePosition.x/sprite.texture.baseTexture.width;
- var offsetY = tilePosition.y/sprite.texture.baseTexture.height;
-
- var scaleX = (sprite.width / sprite.texture.baseTexture.width) / tileScale.x;
- var scaleY = (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
-
- sprite.uvs[0] = 0 - offsetX;
- sprite.uvs[1] = 0 - offsetY;
-
- sprite.uvs[2] = (1 * scaleX) -offsetX;
- sprite.uvs[3] = 0 - offsetY;
-
- sprite.uvs[4] = (1 *scaleX) - offsetX;
- sprite.uvs[5] = (1 *scaleY) - offsetY;
-
- sprite.uvs[6] = 0 - offsetX;
- sprite.uvs[7] = (1 *scaleY) - offsetY;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
-
- this.renderStrip(sprite, projectionMatrix);
-}
-
-/**
- * Initializes a strip to be rendered
- *
- * @method initStrip
- * @param strip {Strip} The strip to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
-{
- // build the strip!
- var gl = this.gl;
- var shaderProgram = this.shaderProgram;
-
- strip._vertexBuffer = gl.createBuffer();
- strip._indexBuffer = gl.createBuffer();
- strip._uvBuffer = gl.createBuffer();
- strip._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-}
-
-
-/**
- * @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 :)
- *
- * @class CanvasRenderer
- * @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
- */
-PIXI.CanvasRenderer = function(width, height, view, transparent)
-{
- this.transparent = transparent;
-
- /**
- * 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 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");
-
- 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;
-}
-
-// constructor
-PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
-
-/**
- * Renders the stage to its canvas view
- *
- * @method render
- * @param stage {Stage} the Stage element to be rendered
- */
-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;
-
- 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 = [];
- }
-
-
-}
-
-/**
- * resizes the canvas view to the specified width and height
- *
- * @method resize
- * @param width {Number} the new width of the canvas view
- * @param height {Number} the new height of the canvas view
- */
-PIXI.CanvasRenderer.prototype.resize = function(width, height)
-{
- this.width = width;
- this.height = height;
-
- this.view.width = width;
- this.view.height = height;
-}
-
-/**
- * Renders a display object
- *
- * @method renderDisplayObject
- * @param displayObject {DisplayObject} The displayObject to render
- * @private
- */
-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)
- {
-
- var frame = displayObject.texture.frame;
-
- if(frame && frame.width && frame.height)
- {
- 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)
- {
- 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(PIXI.FilterBlock.data instanceof PIXI.Graphics)
- {
- if(displayObject.open)
- {
- context.save();
-
- var cacheAlpha = displayObject.mask.alpha;
- var maskTransform = displayObject.mask.worldTransform;
-
- context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
-
- displayObject.mask.worldAlpha = 0.5;
-
- context.worldAlpha = 0;
-
- PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context);
- context.clip();
-
- displayObject.mask.worldAlpha = cacheAlpha;
- }
- else
- {
- context.restore();
- }
- }
- else
- {
- // only masks supported right now!
- }
- }
- // count++
- displayObject = displayObject._iNext;
-
-
- }
- while(displayObject != testObject)
-
-
-}
-
-/**
- * Renders a flat strip
- *
- * @method renderStripFlat
- * @param strip {Strip} The Strip to render
- * @private
- */
-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();
-}
-
-/**
- * Renders a tiling sprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tilingsprite to render
- * @private
- */
-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;
-
- // 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.translate(-tilePosition.x, -tilePosition.y);
-
- context.closePath();
-}
-
-/**
- * Renders a strip
- *
- * @method renderStrip
- * @param strip {Strip} The Strip to render
- * @private
- */
-PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
-{
- 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;
-
-
- 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();
- };
-
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * A set of functions used by the canvas renderer to draw the primitive graphics data
- *
- * @class CanvasGraphics
- */
-PIXI.CanvasGraphics = function()
-{
-
-}
-
-
-/*
- * Renders the graphics object
- *
- * @static
- * @private
- * @method renderGraphics
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- 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.lineWidth = data.lineWidth;
-
- 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]);
- }
-
- // 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.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]);
- }
-
- }
- 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
-
- 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
- *
- * @static
- * @private
- * @method renderGraphicsMask
- * @param graphics {Graphics}
- * @param context {Context2D}
- */
-PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
-{
- var worldAlpha = graphics.worldAlpha;
-
- var len = graphics.graphicsData.length;
- if(len > 1)
- {
- len = 1;
- 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;
-
- 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]);
- }
-
- // 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)
- {
-
- // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
- var elipseData = data.points;
-
- var w = elipseData[2] * 2;
- var h = elipseData[3] * 2;
-
- var x = elipseData[0] - w/2;
- var y = elipseData[1] - h/2;
-
- 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
-
- 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();
- }
-
-
- };
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
- * It is important to know that with the webGL renderer only simple polys can be filled at this stage
- * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
- *
- * @class Graphics
- * @extends DisplayObjectContainer
- * @constructor
- */
-PIXI.Graphics = function()
-{
- PIXI.DisplayObjectContainer.call( this );
-
- this.renderable = true;
-
- /**
- * The alpha of the fill of this graphics object
- *
- * @property fillAlpha
- * @type Number
- */
- this.fillAlpha = 1;
-
- /**
- * The width of any lines drawn
- *
- * @property lineWidth
- * @type Number
- */
- this.lineWidth = 0;
-
- /**
- * The color of any lines drawn
- *
- * @property lineColor
- * @type String
- */
- this.lineColor = "black";
-
- /**
- * Graphics data
- *
- * @property graphicsData
- * @type Array
- * @private
- */
- this.graphicsData = [];
-
- /**
- * Current path
- *
- * @property currentPath
- * @type Object
- * @private
- */
- this.currentPath = {points:[]};
-}
-
-// constructor
-PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Graphics.prototype.constructor = PIXI.Graphics;
-
-/**
- * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
- *
- * @method lineStyle
- * @param lineWidth {Number} width of the line to draw, will update the object's stored style
- * @param color {Number} color of the line to draw, will update the object's stored style
- * @param alpha {Number} alpha of the line to draw, will update the object's stored style
- */
-PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
-{
- if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.lineWidth = lineWidth || 0;
- this.lineColor = color || 0;
- this.lineAlpha = (alpha == undefined) ? 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.graphicsData.push(this.currentPath);
-}
-
-/**
- * Moves the current drawing position to (x, y).
- *
- * @method moveTo
- * @param x {Number} the X coord to move to
- * @param y {Number} the Y coord to move to
- */
-PIXI.Graphics.prototype.moveTo = function(x, y)
-{
- if(this.currentPath.points.length == 0)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.points.push(x, y);
-
- this.graphicsData.push(this.currentPath);
-}
-
-/**
- * Draws a line using the current line style from the current drawing position to (x, y);
- * the current drawing position is then set to (x, y).
- *
- * @method lineTo
- * @param x {Number} the X coord to draw to
- * @param y {Number} the Y coord to draw to
- */
-PIXI.Graphics.prototype.lineTo = function(x, y)
-{
- this.currentPath.points.push(x, y);
- this.dirty = true;
-}
-
-/**
- * Specifies a simple one-color fill that subsequent calls to other Graphics methods
- * (such as lineTo() or drawCircle()) use when drawing.
- *
- * @method beginFill
- * @param color {uint} the color of the fill
- * @param alpha {Number} the alpha
- */
-PIXI.Graphics.prototype.beginFill = function(color, alpha)
-{
- this.filling = true;
- this.fillColor = color || 0;
- this.fillAlpha = (alpha == undefined) ? 1 : alpha;
-}
-
-/**
- * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
- *
- * @method endFill
- */
-PIXI.Graphics.prototype.endFill = function()
-{
- this.filling = false;
- this.fillColor = null;
- this.fillAlpha = 1;
-}
-
-/**
- * @method drawRect
- *
- * @param x {Number} The X coord of the top-left of the rectangle
- * @param y {Number} The Y coord of the top-left of the rectangle
- * @param width {Number} The width of the rectangle
- * @param height {Number} The height of the rectangle
- */
-PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws a circle.
- *
- * @method drawCircle
- * @param x {Number} The X coord of the center of the circle
- * @param y {Number} The Y coord of the center of the circle
- * @param radius {Number} The radius of the circle
- */
-PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Draws an elipse.
- *
- * @method drawElipse
- * @param x {Number}
- * @param y {Number}
- * @param width {Number}
- * @param height {Number}
- */
-PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
-{
- if(this.currentPath.points.length == 0)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.graphicsData.push(this.currentPath);
- this.dirty = true;
-}
-
-/**
- * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
- *
- * @method clear
- */
-PIXI.Graphics.prototype.clear = function()
-{
- this.lineWidth = 0;
- this.filling = false;
-
- this.dirty = true;
- this.clearDirty = true;
- this.graphicsData = [];
-}
-
-// SOME TYPES:
-PIXI.Graphics.POLY = 0;
-PIXI.Graphics.RECT = 1;
-PIXI.Graphics.CIRC = 2;
-PIXI.Graphics.ELIP = 3;
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-PIXI.Strip = function(texture, width, height)
-{
- 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]);
-
- this.verticies = new Float32Array([0, 0,
- 0,0,
- 0,0, 0,
- 0, 0]);
-
- 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.verticies = [0, 0,
- 0,0,
- 0,0, 0,
- 0, 0];
-
- this.colors = [1, 1, 1, 1];
-
- 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;
-
- // 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;
-}
-
-// constructor
-PIXI.Strip.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.Strip.prototype.constructor = PIXI.Strip;
-
-PIXI.Strip.prototype.setTexture = function(texture)
-{
- //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;
-}
-
-PIXI.Strip.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-// some helper functions..
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-
-PIXI.Rope = function(texture, points)
-{
- PIXI.Strip.call( this, texture );
- this.points = points;
-
- try
- {
- this.verticies = new Float32Array( points.length * 4);
- this.uvs = new Float32Array( points.length * 4);
- this.colors = new Float32Array( points.length * 2);
- this.indices = new Uint16Array( points.length * 2);
- }
- catch(error)
- {
- this.verticies = verticies
-
- this.uvs = uvs
- this.colors = colors
- this.indices = indices
- }
-
- this.refresh();
-}
-
-
-// constructor
-PIXI.Rope.prototype = Object.create( PIXI.Strip.prototype );
-PIXI.Rope.prototype.constructor = PIXI.Rope;
-
-PIXI.Rope.prototype.refresh = function()
-{
- var points = this.points;
- if(points.length < 1)return;
-
- var uvs = this.uvs
- var indices = this.indices;
- var colors = this.colors;
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
-
- uvs[0] = 0
- uvs[1] = 1
- uvs[2] = 0
- uvs[3] = 1
-
- colors[0] = 1;
- colors[1] = 1;
-
- indices[0] = 0;
- indices[1] = 1;
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
- // time to do some smart drawing!
- var amount = i/(total-1)
-
- if(i%2)
- {
- uvs[index] = amount;
- uvs[index+1] = 0;
-
- uvs[index+2] = amount
- uvs[index+3] = 1
-
- }
- else
- {
- uvs[index] = amount
- uvs[index+1] = 0
-
- uvs[index+2] = amount
- uvs[index+3] = 1
- }
-
- index = i * 2;
- colors[index] = 1;
- colors[index+1] = 1;
-
- index = i * 2;
- indices[index] = index;
- indices[index + 1] = index + 1;
-
- lastPoint = point;
- }
-}
-
-PIXI.Rope.prototype.updateTransform = function()
-{
-
- var points = this.points;
- if(points.length < 1)return;
-
- var verticies = this.verticies
-
- var lastPoint = points[0];
- var nextPoint;
- var perp = {x:0, y:0};
- var point = points[0];
-
- this.count-=0.2;
-
- verticies[0] = point.x + perp.x
- verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
- verticies[3] = point.y - perp.y//+200
- // time to do some smart drawing!
-
- var total = points.length;
-
- for (var i = 1; i < total; i++)
- {
-
- var point = points[i];
- var index = i * 4;
-
- if(i < points.length-1)
- {
- nextPoint = points[i+1];
- }
- else
- {
- nextPoint = point
- }
-
- perp.y = -(nextPoint.x - lastPoint.x);
- perp.x = nextPoint.y - lastPoint.y;
-
- var ratio = (1 - (i / (total-1))) * 10;
- if(ratio > 1)ratio = 1;
-
- 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;
-
- 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;
- }
-
- PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
-}
-
-PIXI.Rope.prototype.setTexture = function(texture)
-{
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-
-
-
-
-/**
- * @author Mat Groves http://matgroves.com/
- */
-
-/**
- * A tiling sprite is a fast way of rendering a tiling image
- *
- * @class TilingSprite
- * @extends DisplayObjectContainer
- * @constructor
- * @param texture {Texture} the texture of the tiling sprite
- * @param width {Number} the width of the tiling sprite
- * @param height {Number} the height of the tiling sprite
- */
-PIXI.TilingSprite = function(texture, width, height)
-{
- PIXI.DisplayObjectContainer.call( this );
-
- /**
- * 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 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 offset position of the image that is being tiled
- *
- * @property tilePosition
- * @type Point
- */
- this.tilePosition = new PIXI.Point(0,0);
-
- this.renderable = true;
-
- this.blendMode = PIXI.blendModes.NORMAL
-}
-
-// constructor
-PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
-PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite;
-
-/**
- * Sets the texture of the tiling sprite
- *
- * @method setTexture
- * @param texture {Texture} The PIXI texture that is displayed by the sprite
- */
-PIXI.TilingSprite.prototype.setTexture = function(texture)
-{
- //TODO SET THE TEXTURES
- //TODO VISIBILITY
-
- // stop current texture
- this.texture = texture;
- this.updateFrame = true;
-}
-
-/**
- * When the texture is updated, this event will fire to update the frame
- *
- * @method onTextureUpdate
- * @param event
- * @private
- */
-PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
-{
- this.updateFrame = true;
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- * based on pixi impact spine implementation made by Eemeli Kelokorpi (@ekelokorpi) https://github.com/ekelokorpi
- *
- * Awesome JS run time provided by EsotericSoftware
- * https://github.com/EsotericSoftware/spine-runtimes
- *
- */
-
-/**
- * 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
- * See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
- *
- * @class Spine
- * @extends DisplayObjectContainer
- * @constructor
- * @param url {String} The url of the spine anim file to be used
- */
-PIXI.Spine = function (url) {
- PIXI.DisplayObjectContainer.call(this);
-
- this.spineData = PIXI.AnimCache[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.stateData = new spine.AnimationStateData(this.spineData);
- this.state = new spine.AnimationState(this.stateData);
-
- 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);
- }
-};
-
-PIXI.Spine.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
-PIXI.Spine.prototype.constructor = PIXI.Spine;
-
-/*
- * Updates the object transform for rendering
- *
- * @method updateTransform
- * @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();
-
- 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;
-
- 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.rotation = -(slot.bone.worldRotation * Math.PI / 180);
- }
-
- 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;
-
- 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;
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-
-/**
- * This object is one that will allow you to specify custom rendering functions based on render type
- *
- * @class CustomRenderable
- * @extends DisplayObject
- * @constructor
- */
-PIXI.CustomRenderable = function()
-{
- PIXI.DisplayObject.call( this );
-
-}
-
-// constructor
-PIXI.CustomRenderable.prototype = Object.create( PIXI.DisplayObject.prototype );
-PIXI.CustomRenderable.prototype.constructor = PIXI.CustomRenderable;
-
-/**
- * If this object is being rendered by a CanvasRenderer it will call this callback
- *
- * @method renderCanvas
- * @param renderer {CanvasRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderCanvas = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback to initialize
- *
- * @method initWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.initWebGL = function(renderer)
-{
- // override!
-}
-
-/**
- * If this object is being rendered by a WebGLRenderer it will call this callback
- *
- * @method renderWebGL
- * @param renderer {WebGLRenderer} The renderer instance
- */
-PIXI.CustomRenderable.prototype.renderWebGL = function(renderGroup, projectionMatrix)
-{
- // not sure if both needed? but ya have for now!
- // override!
-}
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.BaseTextureCache = {};
-PIXI.texturesToUpdate = [];
-PIXI.texturesToDestroy = [];
-
-/**
- * A texture stores the information that represents an image. All textures have a base texture
- *
- * @class BaseTexture
- * @uses EventTarget
- * @constructor
- * @param source {String} the source object (image or canvas)
- */
-PIXI.BaseTexture = function(source)
-{
- 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 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 source that is loaded to create the texture
- *
- * @property source
- * @type Image
- */
- this.source = source;
-
- if(!source)return;
-
- 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;
-
- PIXI.texturesToUpdate.push(this);
- }
- else
- {
-
- var scope = this;
- this.source.onload = function(){
-
- scope.hasLoaded = true;
- scope.width = scope.source.width;
- scope.height = scope.source.height;
-
- // 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;
-
- PIXI.texturesToUpdate.push(this);
- }
-
- this._powerOf2 = false;
-}
-
-PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
-
-/**
- * Destroys this base texture
- *
- * @method destroy
- */
-PIXI.BaseTexture.prototype.destroy = function()
-{
- if(this.source instanceof Image)
- {
- this.source.src = null;
- }
- this.source = null;
- PIXI.texturesToDestroy.push(this);
-}
-
-/**
- * Helper function that returns a base texture based on an image url
- * If the image is not in the base texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @return BaseTexture
- */
-PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
-{
- 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);
- PIXI.BaseTextureCache[imageUrl] = baseTexture;
- }
-
- return baseTexture;
-}
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.TextureCache = {};
-PIXI.FrameCache = {};
-
-/**
- * A texture stores the information that represents an image or part of an image. It cannot be added
- * to the display list directly. To do this use PIXI.Sprite. If no frame is provided then the whole image is used
- *
- * @class Texture
- * @uses EventTarget
- * @constructor
- * @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frame {Rectangle} The rectangle frame of the texture to show
- */
-PIXI.Texture = function(baseTexture, frame)
-{
- PIXI.EventTarget.call( this );
-
- if(!frame)
- {
- this.noFrame = true;
- frame = new PIXI.Rectangle(0,0,1,1);
- }
-
- if(baseTexture instanceof PIXI.Texture)
- baseTexture = baseTexture.baseTexture;
-
- /**
- * The base texture of this texture
- *
- * @property baseTexture
- * @type BaseTexture
- */
- this.baseTexture = baseTexture;
-
- /**
- * The frame specifies the region of the base texture that this texture uses
- *
- * @property frame
- * @type Rectangle
- */
- this.frame = frame;
-
- /**
- * The trim point
- *
- * @property trim
- * @type Point
- */
- this.trim = new PIXI.Point();
-
- this.scope = this;
-
- if(baseTexture.hasLoaded)
- {
- if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- //console.log(frame)
-
- this.setFrame(frame);
- }
- else
- {
- var scope = this;
- baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} );
- }
-}
-
-PIXI.Texture.prototype.constructor = PIXI.Texture;
-
-/**
- * Called when the base texture is loaded
- *
- * @method onBaseTextureLoaded
- * @param event
- * @private
- */
-PIXI.Texture.prototype.onBaseTextureLoaded = function(event)
-{
- var baseTexture = this.baseTexture;
- baseTexture.removeEventListener( 'loaded', this.onLoaded );
-
- if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
- this.noFrame = false;
- this.width = this.frame.width;
- this.height = this.frame.height;
-
- this.scope.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Destroys this texture
- *
- * @method destroy
- * @param destroyBase {Boolean} Whether to destroy the base texture as well
- */
-PIXI.Texture.prototype.destroy = function(destroyBase)
-{
- if(destroyBase)this.baseTexture.destroy();
-}
-
-/**
- * Specifies the rectangle region of the baseTexture
- *
- * @method setFrame
- * @param frame {Rectangle} The frame of the texture to set it to
- */
-PIXI.Texture.prototype.setFrame = function(frame)
-{
- this.frame = frame;
- this.width = frame.width;
- this.height = frame.height;
-
- 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;
-
- PIXI.Texture.frameUpdates.push(this);
- //this.dispatchEvent( { type: 'update', content: this } );
-}
-
-/**
- * Helper function that returns a texture based on an image url
- * If the image is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromImage
- * @param imageUrl {String} The image url of the texture
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- * @return Texture
- */
-PIXI.Texture.fromImage = function(imageUrl, crossorigin)
-{
- var texture = PIXI.TextureCache[imageUrl];
-
- if(!texture)
- {
- texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
- PIXI.TextureCache[imageUrl] = texture;
- }
-
- return texture;
-}
-
-/**
- * Helper function that returns a texture based on a frame id
- * If the frame id is not in the texture cache an error will be thrown
- *
- * @static
- * @method fromFrame
- * @param frameId {String} The frame id of the texture
- * @return Texture
- */
-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;
-}
-
-/**
- * Helper function that returns a texture based on a canvas element
- * If the canvas is not in the texture cache it will be created and loaded
- *
- * @static
- * @method fromCanvas
- * @param canvas {Canvas} The canvas element source of the texture
- * @return Texture
- */
-PIXI.Texture.fromCanvas = function(canvas)
-{
- var baseTexture = new PIXI.BaseTexture(canvas);
- return new PIXI.Texture(baseTexture);
-}
-
-
-/**
- * Adds a texture to the textureCache.
- *
- * @static
- * @method addTextureToCache
- * @param texture {Texture}
- * @param id {String} the id that the texture will be stored against.
- */
-PIXI.Texture.addTextureToCache = function(texture, id)
-{
- PIXI.TextureCache[id] = texture;
-}
-
-/**
- * Remove a texture from the textureCache.
- *
- * @static
- * @method removeTextureFromCache
- * @param id {String} the id of the texture to be removed
- * @return {Texture} the texture that was removed
- */
-PIXI.Texture.removeTextureFromCache = function(id)
-{
- var texture = PIXI.TextureCache[id]
- PIXI.TextureCache[id] = null;
- return texture;
-}
-
-// this is more for webGL.. it contains updated frames..
-PIXI.Texture.frameUpdates = [];
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- 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.
-
- 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);
-
- 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
-
- @class RenderTexture
- @extends Texture
- @constructor
- @param width {Number} The width of the render texture
- @param height {Number} The height of the render texture
- */
-PIXI.RenderTexture = function(width, height)
-{
- PIXI.EventTarget.call( this );
-
- this.width = width || 100;
- this.height = height || 100;
-
- this.indetityMatrix = PIXI.mat3.create();
-
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
-
- if(PIXI.gl)
- {
- this.initWebGL();
- }
- else
- {
- this.initCanvas();
- }
-}
-
-PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
-PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
-
-/**
- * Initializes the webgl data for this texture
- *
- * @method initWebGL
- * @private
- */
-PIXI.RenderTexture.prototype.initWebGL = function()
-{
- var gl = PIXI.gl;
- this.glFramebuffer = gl.createFramebuffer();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // 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);
- }
-}
-
-/**
- * Initializes the canvas data for this texture
- *
- * @method initCanvas
- * @private
- */
-PIXI.RenderTexture.prototype.initCanvas = function()
-{
- 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.render = this.renderCanvas;
-}
-
-/**
- * This function will draw the display object to the texture.
- *
- * @method renderWebGL
- * @param displayObject {DisplayObject} The display object to render this texture on
- * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
- * @private
- */
-PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
-{
- var gl = PIXI.gl;
-
- // enable the alpha color mask..
- gl.colorMask(true, true, true, true);
-
- gl.viewport(0, 0, this.width, this.height);
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- if(clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
-
- // 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;
-
-
- 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} 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".
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.AssetLoader = function(assetURLs, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The array of asset URLs that are going to be loaded
- *
- * @property assetURLs
- * @type Array
- */
- this.assetURLs = assetURLs;
-
- /**
- * Whether the requests should be treated as cross origin
- *
- * @property crossorigin
- * @type Boolean
- */
- this.crossorigin = crossorigin;
-
- /**
- * Maps file extension to loader types
- *
- * @property loadersByType
- * @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
- };
-
-
-};
-
-/**
- * Fired when an item has loaded
- * @event onProgress
- */
-
-/**
- * Fired when all the assets have loaded
- * @event onComplete
- */
-
-// constructor
-PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
-
-/**
- * Starts loading the assets sequentially
- *
- * @method load
- */
-PIXI.AssetLoader.prototype.load = function()
-{
- var scope = this;
-
- this.loadCount = this.assetURLs.length;
-
- for (var i=0; i < this.assetURLs.length; i++)
- {
- var fileName = this.assetURLs[i];
- var fileType = fileName.split(".").pop().toLowerCase();
-
- var loaderClass = this.loadersByType[fileType];
- if(!loaderClass)
- throw new Error(fileType + " is an unsupported file type");
-
- var loader = new loaderClass(fileName, this.crossorigin);
-
- loader.addEventListener("loaded", function()
- {
- scope.onAssetLoaded();
- });
- loader.load();
- }
-};
-
-/**
- * Invoked after each file is loaded
- *
- * @method onAssetLoaded
- * @private
- */
-PIXI.AssetLoader.prototype.onAssetLoaded = function()
-{
- this.loadCount--;
- 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();
- }
-};
-
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class JsonLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the JSON file
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.JsonLoader = function (url, crossorigin) {
- PIXI.EventTarget.call(this);
-
- /**
- * 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;
-
- /**
- * [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;
-
-};
-
-// constructor
-PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
-
-/**
- * Loads the JSON data
- *
- * @method load
- */
-PIXI.JsonLoader.prototype.load = function () {
- this.ajaxRequest = new 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);
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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.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();
- });
-
- 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();
-
- }
- 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();
- }
- }
-};
-
-/**
- * Invoke when json file loaded
- *
- * @method onLoaded
- * @private
- */
-PIXI.JsonLoader.prototype.onLoaded = function () {
- this.loaded = true;
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * Invoke when error occured
- *
- * @method onError
- * @private
- */
-PIXI.JsonLoader.prototype.onError = function () {
- this.dispatchEvent({
- type: "error",
- content: this
- });
-};
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- * 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.
- * 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
- *
- * @class SpriteSheetLoader
- * @uses EventTarget
- * @constructor
- * @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);
-
- /**
- * 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;
-
- /**
- * [read-only] The base url of the bitmap font data
- *
- * @property baseUrl
- * @type String
- * @readOnly
- */
- this.baseUrl = url.replace(/[^\/]*$/, "");
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = null;
-
- /**
- * The frames of the sprite sheet
- *
- * @property frames
- * @type Object
- */
- this.frames = {};
-};
-
-// constructor
-PIXI.SpriteSheetLoader.prototype.constructor = PIXI.SpriteSheetLoader;
-
-/**
- * This will begin loading the JSON file
- *
- * @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();
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @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;
-
- this.texture = image.texture.baseTexture;
- image.addEventListener("loaded", function (event) {
- 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!
- }
- }
- }
-
- image.load();
-};
-/**
- * Invoke when all files are loaded (json and texture)
- *
- * @method onLoaded
- * @private
- */
-PIXI.SpriteSheetLoader.prototype.onLoaded = function () {
- this.dispatchEvent({
- type: "loaded",
- content: this
- });
-};
-
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * 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
- *
- * @class ImageLoader
- * @uses EventTarget
- * @constructor
- * @param url {String} The url of the image
- * @param crossorigin {Boolean} Whether requests should be treated as crossorigin
- */
-PIXI.ImageLoader = function(url, crossorigin)
-{
- PIXI.EventTarget.call(this);
-
- /**
- * The texture being loaded
- *
- * @property texture
- * @type Texture
- */
- this.texture = PIXI.Texture.fromImage(url, crossorigin);
-
- /**
- * if the image is loaded with loadFramedSpriteSheet
- * frames will contain the sprite sheet frames
- *
- */
- this.frames = [];
-};
-
-// constructor
-PIXI.ImageLoader.prototype.constructor = PIXI.ImageLoader;
-
-/**
- * Loads image or takes it from cache
- *
- * @method load
- */
-PIXI.ImageLoader.prototype.load = function()
-{
- if(!this.texture.baseTexture.hasLoaded)
- {
- var scope = this;
- this.texture.baseTexture.addEventListener("loaded", function()
- {
- scope.onLoaded();
- });
- }
- else
- {
- this.onLoaded();
- }
-};
-
-/**
- * Invoked when image file is loaded or it is already cached and ready to use
- *
- * @method onLoaded
- * @private
- */
-PIXI.ImageLoader.prototype.onLoaded = function()
-{
- this.dispatchEvent({type: "loaded", content: this});
-};
-
-/**
- * Loads image and split it to uniform sized frames
- *
- *
- * @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
- */
-PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
-{
- this.frames = [];
- var cols = Math.floor(this.texture.width / frameWidth);
- var rows = Math.floor(this.texture.height / frameHeight);
-
- var i=0;
- for (var y=0; y
-
+
+