├── .gitignore
├── demo
├── primary
│ ├── cube
│ │ ├── main.js
│ │ └── index.html
│ ├── pyramid
│ │ ├── main.js
│ │ └── index.html
│ ├── brick
│ │ ├── main.js
│ │ └── index.html
│ └── side
│ │ ├── main.js
│ │ └── index.html
├── advanced
│ ├── flexible-cube
│ │ ├── index.html
│ │ └── main.js
│ ├── gif-rendering
│ │ ├── main.js
│ │ └── index.html
│ ├── input-text-rendering
│ │ ├── index.html
│ │ └── main.js
│ └── flappy-bird
│ │ ├── index.html
│ │ └── main.js
└── vendor
│ ├── modernizr-2.6.2.min.js
│ ├── dat.gui.min.js
│ └── easeljs-0.6.1.min.js
├── src
├── namespace.js
├── geom
│ ├── Point.js
│ ├── Point3D.js
│ └── Matrix.js
├── utils
│ ├── CanvasTool.js
│ ├── CanvasManager.js
│ ├── ColorPattern.js
│ └── ColorGeom.js
├── dimensions
│ ├── PyramidDimension.js
│ ├── SideXDimension.js
│ ├── SideYDimension.js
│ ├── BrickDimension.js
│ ├── AbstractDimension.js
│ └── CubeDimension.js
├── colors
│ ├── SideColor.js
│ ├── PyramidColor.js
│ ├── AbstractColor.js
│ └── CubeColor.js
├── display
│ ├── PixelObject.js
│ ├── PixelView.js
│ └── BitmapData.js
└── primitives
│ ├── AbstractPrimitive.js
│ ├── SideX.js
│ ├── SideY.js
│ ├── Brick.js
│ ├── Cube.js
│ └── Pyramid.js
├── bower.json
├── package.json
├── LICENSE
├── Gruntfile.js
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /node_modules
3 | /.idea
4 | /local
--------------------------------------------------------------------------------
/demo/primary/cube/main.js:
--------------------------------------------------------------------------------
1 | // get DOM or jQuery element
2 | // like: $('#canvas-demo')
3 | var canvas = document.getElementById('canvas-demo');
4 |
5 | // create pixel view container in point
6 | var point = new obelisk.Point(500, 240);
7 | var pixelView = new obelisk.PixelView(canvas, point);
8 |
9 | // create cube
10 | var dimension = new obelisk.CubeDimension(120, 200, 60);
11 | var color = new obelisk.CubeColor().getByHorizontalColor(obelisk.ColorPattern.GRAY);
12 | var cube = new obelisk.Cube(dimension, color);
13 | //var cube = new obelisk.Cube(dimension, color, false);
14 | pixelView.renderObject(cube);
15 |
--------------------------------------------------------------------------------
/demo/primary/pyramid/main.js:
--------------------------------------------------------------------------------
1 | // get DOM or jQuery element
2 | // like: $('#canvas-demo')
3 | var canvas = document.getElementById('canvas-demo');
4 |
5 | // create pixel view container in point
6 | var point = new obelisk.Point(500, 240);
7 | var pixelView = new obelisk.PixelView(canvas, point);
8 |
9 | // create pyramid
10 | //var dimension = new obelisk.PyramidDimension(120, true);
11 | var dimension = new obelisk.PyramidDimension(120);
12 | var color = new obelisk.PyramidColor().getByRightColor(obelisk.ColorPattern.YELLOW);
13 | var pyramid = new obelisk.Pyramid(dimension, color);
14 | pixelView.renderObject(pyramid);
15 |
--------------------------------------------------------------------------------
/src/namespace.js:
--------------------------------------------------------------------------------
1 | /*global window:true*/
2 |
3 | /*
4 | * obelisk
5 | */
6 |
7 | (function (window) {
8 | "use strict";
9 |
10 | /**
11 | * Static class holding library specific information
12 | * the library.
13 | * @class obelisk
14 | **/
15 | var obelisk = {};
16 |
17 | /**
18 | * @property version
19 | * @type String
20 | * @static
21 | **/
22 | obelisk.version = '1.0.2';
23 |
24 | /**
25 | * @property author
26 | * @type String
27 | * @static
28 | **/
29 | obelisk.author = 'max huang';
30 |
31 | window.obelisk = obelisk;
32 | }(window));
33 |
--------------------------------------------------------------------------------
/demo/primary/brick/main.js:
--------------------------------------------------------------------------------
1 | // get DOM or jQuery element
2 | // like: $('#canvas-demo')
3 | var canvas = document.getElementById('canvas-demo');
4 |
5 | // create pixel view container in point
6 | var point = new obelisk.Point(500, 20);
7 | var pixelView = new obelisk.PixelView(canvas, point);
8 |
9 | // create brick
10 | var color = new obelisk.SideColor().getByInnerColor(obelisk.ColorPattern.PINK);
11 | var dimension = new obelisk.BrickDimension(300, 400);
12 | var brick = new obelisk.Brick(dimension, color);
13 |
14 | // render in view
15 | pixelView.renderObject(brick);
16 | //var p3D = new obelisk.Point3D(20, 20, 0);
17 | //pixelView.renderObject(brick, p3D);
18 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name":"obelisk.js",
3 | "version":"1.0.2",
4 | "homepage":"https://github.com/nosir/obelisk.js",
5 | "authors":[
6 | "max huang risonhuang@gmail.com"
7 | ],
8 | "description":"JavaScript Engine for Building Pixel Isometric Element with HTML5 Canvas",
9 | "main":"build/obelisk.min.js",
10 | "keywords":[
11 | "javascript",
12 | "canvas",
13 | "pixel",
14 | "isometric",
15 | "game",
16 | "graphic",
17 | "art",
18 | "2.5D"
19 | ],
20 | "license":"MIT",
21 | "ignore":[
22 | "**/.*",
23 | "node_modules",
24 | "bower_components",
25 | "test",
26 | "tests"
27 | ]
28 | }
29 |
--------------------------------------------------------------------------------
/src/geom/Point.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * Point
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var Point, p;
11 | Point = function (x, y) {
12 | this.initialize(x, y);
13 | };
14 | p = Point.prototype;
15 |
16 | // public properties
17 | p.x = 0;
18 | p.y = 0;
19 |
20 | // constructor
21 | p.initialize = function (x, y) {
22 | this.x = (x === undefined ? 0 : x);
23 | this.y = (y === undefined ? 0 : y);
24 | return this;
25 | };
26 |
27 | // public methods
28 | p.toString = function () {
29 | return "[Point x : " + this.x + ", y : " + this.y + "]";
30 | };
31 |
32 | // private methods
33 |
34 | obelisk.Point = Point;
35 | }(obelisk));
36 |
--------------------------------------------------------------------------------
/src/utils/CanvasTool.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * CanvasTool
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var CanvasTool, p;
11 |
12 | CanvasTool = function () {
13 | throw new Error('CanvasTool is a static Class, cannot be instanced.');
14 | };
15 | p = CanvasTool;
16 |
17 | // public methods
18 | p.getPixel = function (imageData, x, y) {
19 | var data, index, r, g, b;
20 | data = imageData.data;
21 | index = (y * imageData.width + x) * 4;
22 | r = data[index];
23 | g = data[index + 1];
24 | b = data[index + 2];
25 |
26 | return ((r << 16) | (g << 8) | b);
27 | };
28 |
29 | p.toString = function () {
30 | return "[CanvasTool]";
31 | };
32 |
33 | obelisk.CanvasTool = CanvasTool;
34 | }(obelisk));
35 |
--------------------------------------------------------------------------------
/demo/primary/side/main.js:
--------------------------------------------------------------------------------
1 | // get DOM or jQuery element
2 | // like: $('#canvas-demo')
3 | var canvas = document.getElementById('canvas-demo');
4 |
5 | // create pixel view container in point
6 | var point = new obelisk.Point(500, 200);
7 | var pixelView = new obelisk.PixelView(canvas, point);
8 |
9 | // create brick
10 | var colorX = new obelisk.SideColor().getByInnerColor(obelisk.ColorPattern.PINK);
11 | var colorY = new obelisk.SideColor().getByInnerColor(obelisk.ColorPattern.GRASS_GREEN);
12 | var dimensionX = new obelisk.SideXDimension(300, 100);
13 | var dimensionY = new obelisk.SideYDimension(300, 100);
14 | var sideX = new obelisk.SideX(dimensionX, colorX);
15 | var sideY = new obelisk.SideY(dimensionY, colorY);
16 |
17 | // render in view
18 | pixelView.renderObject(sideX);
19 |
20 | var p3DY = new obelisk.Point3D(0, 30, 0);
21 | pixelView.renderObject(sideY, p3DY);
--------------------------------------------------------------------------------
/demo/primary/brick/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | obelisk.js Demo
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/demo/primary/cube/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | obelisk.js Demo
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/demo/primary/side/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | obelisk.js Demo
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/geom/Point3D.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * Point3D
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var Point3D, p;
11 | Point3D = function (x, y, z) {
12 | this.initialize(x, y, z);
13 | };
14 | p = Point3D.prototype;
15 |
16 | // public properties
17 | p.x = 0;
18 | p.y = 0;
19 | p.z = 0;
20 |
21 | // constructor
22 | p.initialize = function (x, y, z) {
23 | this.x = (x === undefined ? 0 : x);
24 | this.y = (y === undefined ? 0 : y);
25 | this.z = (z === undefined ? 0 : z);
26 | return this;
27 | };
28 |
29 | // public methods
30 | p.toString = function () {
31 | return "[Point3D x : " + this.x + ", y : " + this.y + ", z: " + this.z + "]";
32 | };
33 |
34 | // private methods
35 |
36 | obelisk.Point3D = Point3D;
37 | }(obelisk));
38 |
--------------------------------------------------------------------------------
/demo/primary/pyramid/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | obelisk.js Demo
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/utils/CanvasManager.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true, document:true*/
2 |
3 | /*
4 | * CanvasManager
5 | */
6 |
7 | (function (obelisk, document) {
8 | "use strict";
9 |
10 | var CanvasManager, p;
11 | CanvasManager = function () {
12 | throw new Error('ColorGeom is a static Class, cannot be instanced.');
13 | };
14 | p = CanvasManager;
15 |
16 | // public properties
17 | p.defaultCanvas = null;
18 |
19 | // public methods
20 | p.getDefaultCanvas = function () {
21 | p.defaultCanvas = p.defaultCanvas || document.createElement('canvas');
22 | return p.defaultCanvas;
23 | };
24 |
25 | p.getNewCanvas = function () {
26 | return document.createElement('canvas');
27 | };
28 |
29 | p.toString = function () {
30 | return "[CanvasManager]";
31 | };
32 |
33 | obelisk.CanvasManager = CanvasManager;
34 | }(obelisk, document));
35 |
--------------------------------------------------------------------------------
/demo/advanced/flexible-cube/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | obelisk.js Demo
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/src/dimensions/PyramidDimension.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * PyramidDimension
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var PyramidDimension, p;
11 | PyramidDimension = function (axis, tall) {
12 | this.initialize(axis, tall);
13 | };
14 | p = PyramidDimension.prototype = new obelisk.AbstractDimension();
15 |
16 | // constructor
17 | p.initialize = function (axis, tall) {
18 | this.xAxis = axis || 30;
19 | this.yAxis = axis || 30;
20 | this.tall = tall || false;
21 |
22 | if (this.xAxis % 2 === 1) {
23 | throw new Error("axis must be even number");
24 | }
25 |
26 | if (this.xAxis <= 4) {
27 | throw new Error("dimension is too small");
28 | }
29 |
30 | return this;
31 | };
32 |
33 | p.toString = function () {
34 | return "[PyramidDimension]";
35 | };
36 |
37 | obelisk.PyramidDimension = PyramidDimension;
38 | }(obelisk));
39 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name":"obelisk.js",
3 | "version":"1.0.2",
4 | "description":"JavaScript Engine for Building Pixel Isometric Element with HTML5 Canvas",
5 | "main":"Gruntfile.js",
6 | "dependencies":{
7 | "grunt":"~0.4.1"
8 | },
9 | "devDependencies":{
10 | "grunt-contrib-watch":"*",
11 | "grunt-contrib-concat":"*",
12 | "grunt-contrib-uglify":"*"
13 | },
14 | "scripts":{
15 | "test":"grunt test",
16 | "start":""
17 | },
18 | "repository":{
19 | "type":"git",
20 | "url":"https://github.com/rison/obelisk.js.git"
21 | },
22 | "keywords":[
23 | "javascript",
24 | "canvas",
25 | "pixel",
26 | "isometric",
27 | "game",
28 | "graphic",
29 | "art",
30 | "2.5D"
31 | ],
32 | "author":"max huang risonhuang@gmail.com",
33 | "license":"MIT",
34 | "readmeFilename":"README.md",
35 | "gitHead":"23cba75da3465a1d207a9ffdfb20050bf9de2fdc"
36 | }
37 |
--------------------------------------------------------------------------------
/src/dimensions/SideXDimension.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * SideXDimension
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var SideXDimension, p;
11 | SideXDimension = function (xAxis, zAxis) {
12 | this.initialize(xAxis, zAxis);
13 | };
14 | p = SideXDimension.prototype = new obelisk.AbstractDimension();
15 |
16 | // constructor
17 | p.initialize = function (xAxis, zAxis) {
18 | this.xAxis = xAxis || 30;
19 | this.zAxis = zAxis || 30;
20 |
21 | if (this.xAxis % 2 === 1) {
22 | throw new Error("xAxis must be even number");
23 | }
24 |
25 | // xAxis || zAxis = 4 floodFill could not be applied
26 | if (this.xAxis <= 4 || this.zAxis <= 2) {
27 | throw new Error("dimension is too small");
28 | }
29 |
30 | return this;
31 | };
32 |
33 | p.toString = function () {
34 | return "[SideXDimension]";
35 | };
36 |
37 | obelisk.SideXDimension = SideXDimension;
38 | }(obelisk));
39 |
--------------------------------------------------------------------------------
/src/dimensions/SideYDimension.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * SideYDimension
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var SideYDimension, p;
11 |
12 | SideYDimension = function (yAxis, zAxis) {
13 | this.initialize(yAxis, zAxis);
14 | };
15 | p = SideYDimension.prototype = new obelisk.AbstractDimension();
16 |
17 | // constructor
18 | p.initialize = function (yAxis, zAxis) {
19 | this.yAxis = yAxis || 30;
20 | this.zAxis = zAxis || 30;
21 |
22 | if (this.yAxis % 2 === 1) {
23 | throw new Error("yAxis must be even number");
24 | }
25 |
26 | // yAxis || zAxis = 4 floodFill could not be applied
27 | if (this.yAxis <= 4 || this.zAxis <= 2) {
28 | throw new Error("dimension is too small");
29 | }
30 |
31 | return this;
32 | };
33 |
34 | p.toString = function () {
35 | return "[SideYDimension]";
36 | };
37 |
38 | obelisk.SideYDimension = SideYDimension;
39 | }(obelisk));
40 |
--------------------------------------------------------------------------------
/src/dimensions/BrickDimension.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * BrickDimension
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var BrickDimension, p;
11 | BrickDimension = function (xAxis, yAxis) {
12 | this.initialize(xAxis, yAxis);
13 | };
14 | p = BrickDimension.prototype = new obelisk.AbstractDimension();
15 |
16 | // constructor
17 | p.initialize = function (xAxis, yAxis) {
18 | this.xAxis = xAxis || 30;
19 | this.yAxis = yAxis || 30;
20 |
21 | if (this.xAxis % 2 === 1 || this.yAxis % 2 === 1) {
22 | throw new Error("x,yAxis must be even number");
23 | }
24 |
25 | // xAxis || yAxis = 4 floodFill could not be applied
26 | if (this.xAxis <= 4 || this.yAxis <= 4) {
27 | throw new Error("dimension is too small");
28 | }
29 |
30 | return this;
31 | };
32 |
33 | p.toString = function () {
34 | return "[BrickDimension]";
35 | };
36 |
37 | obelisk.BrickDimension = BrickDimension;
38 | }(obelisk));
39 |
--------------------------------------------------------------------------------
/src/dimensions/AbstractDimension.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * AbstractDimension
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var AbstractDimension, p;
11 | AbstractDimension = function () {
12 | this.initialize();
13 | };
14 | p = AbstractDimension.prototype;
15 |
16 | // public properties
17 | /**
18 | * The x Axis dimensions in 22.6 degrees coordinate
19 | */
20 | p.xAxis = null;
21 |
22 | /**
23 | * The y Axis dimensions in 22.6 degrees coordinate
24 | */
25 | p.yAxis = null;
26 |
27 | /**
28 | * The z Axis dimensions in 22.6 degrees coordinate
29 | */
30 | p.zAxis = null;
31 |
32 | /**
33 | * Pyramid tall mode
34 | */
35 | p.tall = false;
36 |
37 | // constructor
38 | p.initialize = function () {
39 | return this;
40 | };
41 |
42 | // public methods
43 | p.toString = function () {
44 | return "[AbstractDimension]";
45 | };
46 |
47 | // private methods
48 |
49 | obelisk.AbstractDimension = AbstractDimension;
50 | }(obelisk));
51 |
--------------------------------------------------------------------------------
/src/colors/SideColor.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * SideColor
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var SideColor, p;
11 | SideColor = function (border, inner) {
12 | this.initialize(border, inner);
13 | };
14 | p = SideColor.prototype = new obelisk.AbstractColor();
15 |
16 | // public properties
17 | p.BRIGHTNESS_GAIN = -20;
18 |
19 | // constructor
20 | p.initialize = function (border, inner) {
21 | this.border = obelisk.ColorGeom.get32(border === undefined ? 0x878787 : border);
22 | this.inner = obelisk.ColorGeom.get32(inner === undefined ? 0xEEEEEE : inner);
23 | return this;
24 | };
25 |
26 | // public methods
27 | p.getByInnerColor = function (inner) {
28 | return new obelisk.SideColor(
29 | obelisk.ColorGeom.applyBrightness(inner, this.BRIGHTNESS_GAIN * 4),
30 | inner
31 | );
32 | };
33 |
34 | p.toString = function () {
35 | return "[SideColor]";
36 | };
37 |
38 | // private methods
39 |
40 | obelisk.SideColor = SideColor;
41 | }(obelisk));
42 |
--------------------------------------------------------------------------------
/src/dimensions/CubeDimension.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * CubeDimension
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var CubeDimension, p;
11 | CubeDimension = function (xAxis, yAxis, zAxis) {
12 | this.initialize(xAxis, yAxis, zAxis);
13 | };
14 | p = CubeDimension.prototype = new obelisk.AbstractDimension();
15 |
16 | // constructor
17 | p.initialize = function (xAxis, yAxis, zAxis) {
18 | this.xAxis = xAxis || 30;
19 | this.yAxis = yAxis || 30;
20 | this.zAxis = zAxis || 30;
21 |
22 | if (this.xAxis % 2 === 1 || this.yAxis % 2 === 1) {
23 | throw new Error("x,yAxis must be even number");
24 | }
25 |
26 | // xAxis || yAxis = 4 floodFill could not be applied
27 | if (this.xAxis <= 4 || this.yAxis <= 4 || this.zAxis <= 2) {
28 | throw new Error("dimension is too small");
29 | }
30 |
31 | return this;
32 | };
33 |
34 | p.toString = function () {
35 | return "[CubeDimension]";
36 | };
37 |
38 | obelisk.CubeDimension = CubeDimension;
39 | }(obelisk));
40 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Max Huang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/src/display/PixelObject.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * PixelObject
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var PixelObject, p;
11 | PixelObject = function (primitive, point3D) {
12 | this.initialize(primitive, point3D);
13 | };
14 | p = PixelObject.prototype;
15 |
16 | // public properties
17 | p.x = null;
18 | p.y = null;
19 | p.canvas = null;
20 |
21 | // constructor
22 | p.initialize = function (primitive, point3D) {
23 | if (!primitive) {
24 | throw new Error("Primitive is not defined");
25 | }
26 |
27 | var p3D = point3D || new obelisk.Point3D();
28 |
29 | this.canvas = primitive.canvas;
30 | this.x = primitive.matrix.tx + p3D.x - p3D.y;
31 | this.y = primitive.matrix.ty + Math.floor(p3D.x / 2 + p3D.y / 2) - p3D.z;
32 |
33 | return this;
34 | };
35 |
36 | // public methods
37 |
38 | // todo: add canvas remove method
39 |
40 | p.toString = function () {
41 | return "[PixelObject]";
42 | };
43 |
44 | // private methods
45 |
46 | obelisk.PixelObject = PixelObject;
47 | }(obelisk));
48 |
--------------------------------------------------------------------------------
/src/utils/ColorPattern.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * ColorPattern
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var ColorPattren, p;
11 |
12 | ColorPattren = function () {
13 | throw new Error('ColorGeom is a static Class, cannot be instanced.');
14 | };
15 | p = ColorPattren;
16 |
17 | // public properties
18 | p.GRASS_GREEN = 0xCCFF00;
19 | p.YELLOW = 0xFFFF00;
20 | p.WINE_RED = 0xFF0099;
21 | p.PINK = 0xFF7CBF;
22 | p.PURPLE = 0xCC00FF;
23 | p.BLUE = 0x00CCFF;
24 | p.GRAY = 0xEEEEEE;
25 | p.BLACK = 0x666666;
26 | p.FINE_COLORS =
27 | [
28 | p.GRASS_GREEN,
29 | p.YELLOW,
30 | p.WINE_RED,
31 | p.PINK,
32 | p.PURPLE,
33 | p.BLUE,
34 | p.GRAY,
35 | p.BLACK
36 | ];
37 |
38 | // public methods
39 | p.getRandomComfortableColor = function () {
40 | return p.FINE_COLORS[Math.floor(Math.random() * p.FINE_COLORS.length)];
41 | };
42 |
43 | p.toString = function () {
44 | return "[ColorPattern]";
45 | };
46 |
47 | obelisk.ColorPattern = ColorPattren;
48 | }(obelisk));
49 |
--------------------------------------------------------------------------------
/src/display/PixelView.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true, jQuery:true*/
2 |
3 | /*
4 | * PixelView
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var PixelView, p;
11 | PixelView = function (canvas, point) {
12 | this.initialize(canvas, point);
13 | };
14 | p = PixelView.prototype;
15 |
16 | // public properties
17 | p.canvas = null;
18 | p.context = null;
19 | p.point = null;
20 |
21 | // constructor
22 | p.initialize = function (canvas, point) {
23 | if (!canvas) {
24 | throw new Error("Canvas is not defined");
25 | }
26 |
27 | try {
28 | if (canvas instanceof jQuery) {
29 | canvas = canvas.get(0);
30 | }
31 | } catch (e) {
32 | }
33 |
34 | this.canvas = canvas;
35 | this.context = this.canvas.getContext('2d');
36 | this.point = point || new obelisk.Point(0, 0);
37 |
38 | return this;
39 | };
40 |
41 | // public methods
42 | p.renderObject = function (primitive, point3D) {
43 | var po = new obelisk.PixelObject(primitive, point3D);
44 | this.context.drawImage(po.canvas, this.point.x + po.x, this.point.y + po.y);
45 | };
46 |
47 | p.clear = function () {
48 | this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
49 | };
50 |
51 | p.toString = function () {
52 | return "[PixelView]";
53 | };
54 |
55 | obelisk.PixelView = PixelView;
56 | }(obelisk));
57 |
--------------------------------------------------------------------------------
/src/colors/PyramidColor.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * PyramidColor
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var PyramidColor, p;
11 | PyramidColor = function (border, borderHighlight, left, right) {
12 | this.initialize(border, borderHighlight, left, right);
13 | };
14 | p = PyramidColor.prototype = new obelisk.AbstractColor();
15 |
16 | // public properties
17 | p.BRIGHTNESS_GAIN = -20;
18 |
19 | // constructor
20 | p.initialize = function (border, borderHighlight, left, right) {
21 | this.border = obelisk.ColorGeom.get32(border === undefined ? 0x949698 : border);
22 | this.borderHighlight = obelisk.ColorGeom.get32(borderHighlight === undefined ? 0xFFFFFF : borderHighlight);
23 | this.left = obelisk.ColorGeom.get32(left === undefined ? 0xE6E8E9 : left);
24 | this.right = obelisk.ColorGeom.get32(right === undefined ? 0xEEEFF0 : right);
25 | return this;
26 | };
27 |
28 | // public methods
29 | p.getByRightColor = function (right) {
30 | return new PyramidColor(
31 | obelisk.ColorGeom.applyBrightness(right, this.BRIGHTNESS_GAIN * 4),
32 | //apply hightlight
33 | obelisk.ColorGeom.applyBrightness(right, 0, true),
34 | obelisk.ColorGeom.applyBrightness(right, this.BRIGHTNESS_GAIN),
35 | right
36 | );
37 | };
38 |
39 | p.toString = function () {
40 | return "[PyramidColor]";
41 | };
42 |
43 | // private methods
44 |
45 | obelisk.PyramidColor = PyramidColor;
46 | }(obelisk));
47 |
--------------------------------------------------------------------------------
/demo/advanced/flexible-cube/main.js:
--------------------------------------------------------------------------------
1 | var canvas = document.getElementById('canvas-demo');
2 |
3 | var point = new obelisk.Point(500, 200);
4 | var pixelView = new obelisk.PixelView(canvas, point);
5 |
6 | function buildCube(xDimension, yDimension, zDimension, border) {
7 | var color = new obelisk.CubeColor().getByHorizontalColor(obelisk.ColorPattern.GRASS_GREEN);
8 | var dimension = new obelisk.CubeDimension(xDimension, yDimension, zDimension);
9 | var cube = new obelisk.Cube(dimension, color, border);
10 | pixelView.clear();
11 | pixelView.renderObject(cube);
12 | }
13 |
14 | // control bar
15 | var ControlBar = function () {
16 | this.xDimension = 80;
17 | this.yDimension = 120;
18 | this.zDimension = 50;
19 | this.border = true;
20 | };
21 |
22 | var con = new ControlBar();
23 | var gui = new dat.GUI();
24 |
25 | var conX = gui.add(con, 'xDimension', 6, 400).step(2);
26 | conX.onChange(function (value) {
27 | buildCube(value, con.yDimension, con.zDimension, con.border);
28 | });
29 |
30 | var conY = gui.add(con, 'yDimension', 6, 400).step(2);
31 | conY.onChange(function (value) {
32 | buildCube(con.xDimension, value, con.zDimension, con.border);
33 | });
34 |
35 | var conZ = gui.add(con, 'zDimension', 6, 400).step(2);
36 | conZ.onChange(function (value) {
37 | buildCube(con.xDimension, con.yDimension, value, con.border);
38 | });
39 |
40 | var conBorder = gui.add(con, 'border');
41 | conBorder.onChange(function (value) {
42 | buildCube(con.xDimension, con.yDimension, con.zDimension, value);
43 | });
44 |
45 | // build first one
46 | buildCube(con.xDimension, con.yDimension, con.zDimension, con.border);
47 |
--------------------------------------------------------------------------------
/src/colors/AbstractColor.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * AbstractColor
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var AbstractColor, p;
11 |
12 | AbstractColor = function () {
13 | this.initialize();
14 | };
15 | p = AbstractColor.prototype;
16 |
17 | // public properties
18 | /**
19 | * The inner colors for elements of certain primitive
20 | */
21 | p.inner = null;
22 |
23 | /**
24 | * The border colors for elements of certain primitive
25 | */
26 | p.border = null;
27 |
28 | /**
29 | * The borderHighlight colors for elements of certain primitive
30 | */
31 | p.borderHighlight = null;
32 |
33 | /**
34 | * The left side colors for elements of certain primitive
35 | */
36 | p.left = null;
37 |
38 | /**
39 | * The right side colors for elements of certain primitive
40 | */
41 | p.right = null;
42 |
43 | /**
44 | * The horizontal colors for elements of certain primitive
45 | */
46 | p.horizontal = null;
47 |
48 | /**
49 | * The left slot side colors for elements of certain primitive
50 | */
51 | p.leftSlope = null;
52 |
53 | /**
54 | * The right slot side colors for elements of certain primitive
55 | */
56 | p.rightSlope = null;
57 |
58 | // constructor
59 | p.initialize = function () {
60 | return this;
61 | };
62 |
63 | // public methods
64 | p.toString = function () {
65 | return "[AbstractColor]";
66 | };
67 |
68 | // private methods
69 |
70 | obelisk.AbstractColor = AbstractColor;
71 | }(obelisk));
72 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /* global module:false */
2 | module.exports = function (grunt) {
3 |
4 | // Project configuration
5 | grunt.initConfig({
6 | pkg:grunt.file.readJSON('package.json'),
7 | meta:{
8 | banner:'/*!\n' +
9 | ' * obelisk.js <%= pkg.version %>\n' +
10 | ' * https://github.com/nosir/obelisk.js\n' +
11 | ' * MIT licensed\n' +
12 | ' *\n' +
13 | ' * Copyright (C) 2012 Max Huang https://github.com/nosir/\n' +
14 | ' */',
15 | version:'<%= pkg.version %>'
16 | },
17 |
18 | concat:{
19 | core:{
20 | src:[
21 | 'src/namespace.js',
22 | 'src/*/**/*.js'
23 | ],
24 | dest:'build/obelisk.js'
25 | }
26 | },
27 |
28 | uglify:{
29 | options:{
30 | banner:'<%= meta.banner %>\n'
31 | },
32 | build:{
33 | src:'<%= concat.core.dest %>',
34 | dest:'build/obelisk.min.js'
35 | }
36 | },
37 |
38 | watch:{
39 | scripts:{
40 | files:[
41 | 'src/**/*.js'
42 | ],
43 | tasks:['concat']
44 | }
45 | }
46 | });
47 |
48 | // Dependencies
49 | grunt.loadNpmTasks('grunt-contrib-watch');
50 | grunt.loadNpmTasks('grunt-contrib-concat');
51 | grunt.loadNpmTasks('grunt-contrib-uglify');
52 |
53 | // Default task
54 | grunt.registerTask('default', [ 'concat', 'uglify']);
55 |
56 | };
57 |
--------------------------------------------------------------------------------
/src/geom/Matrix.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * Matrix
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var Matrix, p;
11 | Matrix = function (a, b, c, d, tx, ty) {
12 | this.initialize(a, b, c, d, tx, ty);
13 | };
14 | p = Matrix.prototype;
15 |
16 | // public properties:
17 | /**
18 | * Position (0, 0) in a 3x3 matrix.
19 | * @property a
20 | * @type Number
21 | **/
22 | p.a = 1;
23 |
24 | /**
25 | * Position (0, 1) in a 3x3 matrix.
26 | * @property b
27 | * @type Number
28 | **/
29 | p.b = 0;
30 |
31 | /**
32 | * Position (1, 0) in a 3x3 matrix.
33 | * @property c
34 | * @type Number
35 | **/
36 | p.c = 0;
37 |
38 | /**
39 | * Position (1, 1) in a 3x3 matrix.
40 | * @property d
41 | * @type Number
42 | **/
43 | p.d = 1;
44 |
45 | /**
46 | * Position (2, 0) in a 3x3 matrix.
47 | * @property tx
48 | * @type Number
49 | **/
50 | p.tx = 0;
51 |
52 | /**
53 | * Position (2, 1) in a 3x3 matrix.
54 | * @property ty
55 | * @type Number
56 | **/
57 | p.ty = 0;
58 |
59 | // constructor
60 | p.initialize = function (a, b, c, d, tx, ty) {
61 | this.a = (a === undefined) ? 1 : a;
62 | this.b = b || 0;
63 | this.c = c || 0;
64 | this.d = (d === undefined) ? 1 : d;
65 | this.tx = tx || 0;
66 | this.ty = ty || 0;
67 | return this;
68 | };
69 |
70 | // public methods
71 | p.toString = function () {
72 | return "[Matrix]";
73 | };
74 |
75 | obelisk.Matrix = Matrix;
76 | }(obelisk));
77 |
--------------------------------------------------------------------------------
/src/utils/ColorGeom.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * ColorGeom
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var ColorGeom, p;
11 |
12 | ColorGeom = function () {
13 | throw new Error('ColorGeom is a static Class, cannot be instanced.');
14 | };
15 | p = ColorGeom;
16 |
17 | // public methods
18 | p.get32 = function (color) {
19 | return color < 0xFF000000 ? (color + 0xFF000000) : color;
20 | };
21 |
22 | p.applyBrightness = function (color, brightness, highlight) {
23 | var a, r, g, b, y, v, u;
24 | a = ((color >>> 24) & 0x000000FF);
25 | r = ((color >>> 16) & 0x000000FF);
26 | g = ((color >>> 8) & 0x000000FF);
27 | b = (color & 0x000000FF);
28 |
29 | y = ((r * 313524) >> 20) + ((g * 615514) >> 20) + ((b * 119538) >> 20);
30 | u = -((155189 * r) >> 20) - ((303038 * g) >> 20) + ((458227 * b) >> 20);
31 | v = ((644874 * r) >> 20) - ((540016 * g) >> 20) - ((104857 * b) >> 20);
32 |
33 | if (!highlight) {
34 | y += brightness;
35 | } else {
36 | y = 60 + Math.pow(y, 1.2);
37 | }
38 |
39 | r = y + ((1195376 * v) >> 20);
40 | g = y - ((408944 * u) >> 20) - ((608174 * v) >> 20);
41 | b = y + ((2128609 * u) >> 20);
42 |
43 | r = Math.max(0, Math.min(r, 255));
44 | g = Math.max(0, Math.min(g, 255));
45 | b = Math.max(0, Math.min(b, 255));
46 |
47 | return (a << 24) | (r << 16) | (g << 8) | b;
48 | };
49 |
50 | p.toString = function () {
51 | return "[ColorGeom]";
52 | };
53 |
54 | obelisk.ColorGeom = ColorGeom;
55 | }(obelisk));
56 |
--------------------------------------------------------------------------------
/src/primitives/AbstractPrimitive.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * AbstractPrimitive
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var AbstractPrimitive, p;
11 | AbstractPrimitive = function () {
12 | this.initialize();
13 | };
14 | p = AbstractPrimitive.prototype;
15 |
16 | // public properties
17 | /**
18 | * the canvas for drawImage to any canvas
19 | */
20 | p.canvas = null;
21 |
22 | // protect properties
23 | /**
24 | * the width of the bitmap in 2d flash coordinate
25 | */
26 | p.w = null;
27 |
28 | /**
29 | * the height of the bitmap in 2d flash coordinate
30 | */
31 | p.h = null;
32 |
33 | /**
34 | * the dimension of primitive in 3d pixel coordinate
35 | */
36 | p.dimension = null;
37 |
38 | /**
39 | * the color obj of the primitive
40 | */
41 | p.color = null;
42 |
43 | /**
44 | * the border option of the primitive
45 | */
46 | p.border = null;
47 |
48 | /**
49 | * the source bitmapdata contains pixel graphic
50 | */
51 | p.bitmapData = null;
52 |
53 | /**
54 | * the preserve canvas option
55 | */
56 | p.useDefaultCanvas = null;
57 |
58 | /**
59 | * the matrix offset between the bitmap and the 3d pixel coordinate ZERO point
60 | */
61 | p.matrix = null;
62 |
63 | // constructor
64 | p.initialize = function () {
65 | return this;
66 | };
67 |
68 | // public methods
69 | p.toString = function () {
70 | return "[AbstractPrimitive]";
71 | };
72 |
73 | // private methods
74 |
75 | obelisk.AbstractPrimitive = AbstractPrimitive;
76 | }(obelisk));
77 |
--------------------------------------------------------------------------------
/src/colors/CubeColor.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * CubeColor
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var CubeColor, p;
11 | CubeColor = function (border, borderHighlight, left, right, horizontal) {
12 | this.initialize(border, borderHighlight, left, right, horizontal);
13 | };
14 | p = CubeColor.prototype = new obelisk.AbstractColor();
15 |
16 | // public properties
17 | p.BRIGHTNESS_GAIN = -20;
18 |
19 | // constructor
20 | p.initialize = function (border, borderHighlight, left, right, horizontal) {
21 | this.border = obelisk.ColorGeom.get32(border === undefined ? 0x878787 : border);
22 | this.borderHighlight = obelisk.ColorGeom.get32(borderHighlight === undefined ? 0xFFFFFF : borderHighlight);
23 | this.left = obelisk.ColorGeom.get32(left === undefined ? 0xC9CFD0 : left);
24 | this.right = obelisk.ColorGeom.get32(right === undefined ? 0xE3E3E3 : right);
25 | this.horizontal = obelisk.ColorGeom.get32(horizontal === undefined ? 0xEEEFF0 : horizontal);
26 | return this;
27 | };
28 |
29 | // public methods
30 | p.getByHorizontalColor = function (horizontal) {
31 | return new CubeColor(
32 | obelisk.ColorGeom.applyBrightness(horizontal, this.BRIGHTNESS_GAIN * 4),
33 | //apply hightlight
34 | obelisk.ColorGeom.applyBrightness(horizontal, 0, true),
35 | obelisk.ColorGeom.applyBrightness(horizontal, this.BRIGHTNESS_GAIN * 2),
36 | obelisk.ColorGeom.applyBrightness(horizontal, this.BRIGHTNESS_GAIN),
37 | horizontal
38 | );
39 | };
40 |
41 | p.toString = function () {
42 | return "[CubeColor]";
43 | };
44 |
45 | // private methods
46 |
47 | obelisk.CubeColor = CubeColor;
48 | }(obelisk));
49 |
--------------------------------------------------------------------------------
/demo/advanced/gif-rendering/main.js:
--------------------------------------------------------------------------------
1 | var WIDTH = 64;
2 | var HEIGHT = 28;
3 |
4 | var img = document.getElementById('animation');
5 | var ctx = document.createElement('canvas').getContext("2d");
6 | var canvas = document.getElementById('canvas-uncle');
7 |
8 | var stack = [];
9 | var size = 8;
10 | var point = new obelisk.Point(50, 120);
11 | var pixelView = new obelisk.PixelView(canvas, point);
12 |
13 | function draw() {
14 | ctx.drawImage(img, 0, 0, WIDTH, HEIGHT);
15 | var imgData = ctx.getImageData(0, 0, WIDTH, HEIGHT);
16 | pixelView.clear();
17 | for (var y = HEIGHT - 1; y >= 0; y--) {
18 | for (var x = 0; x < WIDTH - 1; x++) {
19 | var pixelColor = obelisk.CanvasTool.getPixel(imgData, x, y);
20 | if (pixelColor !== 0xFFFFFF) {
21 | var cube;
22 | var flag = false;
23 | for (var i in stack) {
24 | if (stack[i][1] === pixelColor) {
25 | cube = stack[i][0];
26 | flag = true;
27 | break;
28 | }
29 | }
30 | if (!flag) {
31 | var fixedColor = obelisk.ColorGeom.applyBrightness(pixelColor, 50)
32 | var color = new obelisk.CubeColor().getByHorizontalColor(fixedColor);
33 | var dimension = new obelisk.CubeDimension(size, size + 2, size);
34 | cube = new obelisk.Cube(dimension, color, false);
35 | stack.push([cube, pixelColor]);
36 | }
37 | var p3d = new obelisk.Point3D(x * (size - 2), 0, (HEIGHT - 1 - y) * (size));
38 | pixelView.renderObject(cube, p3d);
39 | }
40 | }
41 | }
42 | }
43 | // render interval
44 | window.setInterval(draw, 50);
45 |
46 | // build floor
47 | var canvasFloor = document.getElementById('canvas-floor');
48 | var pixelViewFloor = new obelisk.PixelView(canvasFloor, point);
49 | var floorDimension = new obelisk.CubeDimension((size - 2) * (WIDTH + 2), (size - 2) * 9, size);
50 | var floor = new obelisk.Cube(floorDimension, new obelisk.CubeColor(), false);
51 | pixelViewFloor.renderObject(floor, new obelisk.Point3D(-20, -30, 0));
52 |
--------------------------------------------------------------------------------
/demo/advanced/input-text-rendering/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/demo/advanced/flappy-bird/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | obelisk.js Demo
10 |
11 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/demo/advanced/flappy-bird/main.js:
--------------------------------------------------------------------------------
1 | // control bar
2 | var ControlBar = function () {
3 | this.size = 20;
4 | this.snap = false;
5 | };
6 |
7 | var con = new ControlBar();
8 | var gui = new dat.GUI();
9 |
10 | var conSize = gui.add(con, 'size', 6, 40).step(2);
11 | conSize.onChange(function () {
12 | draw();
13 | });
14 |
15 | var conSnap = gui.add(con, 'snap');
16 | conSnap.onChange(function () {
17 | draw();
18 | });
19 |
20 | var WIDTH = 17;
21 | var HEIGHT = 12;
22 |
23 | var img = document.getElementById('animation');
24 | var ctx = document.createElement('canvas').getContext("2d");
25 | var canvas = document.getElementById('canvas-demo');
26 |
27 | var stack = [];
28 | var point = new obelisk.Point(400, 50);
29 | var pixelView = new obelisk.PixelView(canvas, point);
30 |
31 | function getPixel(data, x, y) {
32 | var index = (y * WIDTH + x) * 4;
33 | var r = data[index];
34 | var g = data[index + 1];
35 | var b = data[index + 2];
36 | return ((r << 16) | (g << 8) | b);
37 | }
38 |
39 | function draw() {
40 | var size = con.size;
41 | var snap = con.snap ? 2 : 0;
42 | stack = [];
43 | ctx.drawImage(img, 0, 0, WIDTH, HEIGHT);
44 | var imgData = ctx.getImageData(0, 0, WIDTH, HEIGHT);
45 | pixelView.clear();
46 |
47 | var color = new obelisk.SideColor().getByInnerColor(obelisk.ColorPattern.GRAY);
48 | var dimension = new obelisk.BrickDimension(size, size);
49 | var brick = new obelisk.Brick(dimension, color);
50 | for (var y = 0; y <= HEIGHT; y++) {
51 | for (var x = 0; x <= WIDTH; x++) {
52 | var p3d = new obelisk.Point3D(x * (size - snap), y * (size - snap), 0);
53 | pixelView.renderObject(brick, p3d)
54 | }
55 | }
56 |
57 | for (var y = 0; y < HEIGHT; y++) {
58 | for (var x = 0; x < WIDTH; x++) {
59 | var pixelColor = getPixel(imgData.data, x, y);
60 | if (pixelColor !== 0xFFFFFF) {
61 | var cube;
62 | var flag = false;
63 | for (var i in stack) {
64 | if (stack[i][1] === pixelColor) {
65 | cube = stack[i][0];
66 | flag = true;
67 | break;
68 | }
69 | }
70 |
71 | if (!flag) {
72 | var color = new obelisk.CubeColor().getByHorizontalColor(pixelColor);
73 | var dimension = new obelisk.CubeDimension(size, size, size - 2);
74 | cube = new obelisk.Cube(dimension, color, false);
75 | stack.push([cube, pixelColor]);
76 | }
77 | var p3d = new obelisk.Point3D(x * (size - snap), y * (size - snap), 0);
78 | pixelView.renderObject(cube, p3d);
79 | }
80 | }
81 | }
82 | }
83 |
84 | draw();
85 |
--------------------------------------------------------------------------------
/src/primitives/SideX.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * SideX
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 | var SideX, p;
10 | SideX = function (dimension, color, border, useDefaultCanvas) {
11 | this.initialize(dimension, color, border, useDefaultCanvas);
12 | };
13 | p = SideX.prototype = new obelisk.AbstractPrimitive();
14 |
15 | // public properties
16 |
17 | // constructor
18 | p.initialize = function (dimension, color, border, useDefaultCanvas) {
19 | this.initRender(dimension, color, border, useDefaultCanvas);
20 | this.initRectangle();
21 | this.initBitmapData();
22 | this.build();
23 | this.renderBitmapDataForCanvas();
24 | return this;
25 | };
26 |
27 | // private method
28 | p.initRender = function (dimension, color, border, useDefaultCanvas) {
29 | this.useDefaultCanvas = useDefaultCanvas || false;
30 | this.border = border || border === undefined;
31 | this.dimension = dimension === undefined ? new obelisk.SideXDimension() : dimension;
32 | this.color = color === undefined ? new obelisk.SideColor() : color;
33 | };
34 |
35 | p.initRectangle = function () {
36 | this.w = this.dimension.xAxis;
37 | this.h = this.dimension.zAxis + this.dimension.xAxis / 2;
38 |
39 | // the matrix offset between the bitmap and the 3d pixel coordinate ZERO point
40 | this.matrix = new obelisk.Matrix();
41 | this.matrix.tx = 0;
42 | this.matrix.ty = -this.dimension.zAxis;
43 | };
44 |
45 | p.initBitmapData = function () {
46 | this.bitmapData = new obelisk.BitmapData(this.w, this.h, this.useDefaultCanvas);
47 | };
48 | p.renderBitmapDataForCanvas = function () {
49 | this.bitmapData.context.putImageData(this.bitmapData.imageData, 0, 0);
50 | this.canvas = this.bitmapData.canvas;
51 | };
52 |
53 | p.build = function () {
54 | var xOffsetInner, yOffsetInner, xOffsetOut, yOffsetOut, i, j, borderColor;
55 |
56 | xOffsetInner = 0;
57 | yOffsetInner = this.dimension.zAxis;
58 | xOffsetOut = this.dimension.xAxis - 1;
59 | yOffsetOut = this.h - this.dimension.zAxis - 1;
60 | borderColor = this.border ? this.color.border : this.color.inner;
61 |
62 | //x axis
63 | for (i = 0; i < this.dimension.xAxis; i += 1) {
64 | this.bitmapData.setPixel(xOffsetInner + i, yOffsetInner + Math.floor(i / 2), borderColor);
65 | this.bitmapData.setPixel(xOffsetOut - i, yOffsetOut - Math.floor(i / 2), borderColor);
66 | }
67 |
68 | //z axis
69 | for (j = 0; j < this.dimension.zAxis; j += 1) {
70 | this.bitmapData.setPixel(xOffsetInner, yOffsetInner - j, borderColor);
71 | this.bitmapData.setPixel(xOffsetOut, yOffsetOut + j, borderColor);
72 | }
73 |
74 | //fill an pixel graphic enclosed
75 | this.bitmapData.floodFill(Math.floor(this.w / 2), Math.floor(this.h / 2), this.color.inner);
76 | };
77 |
78 | // public methods
79 | p.toString = function () {
80 | return "[SideX]";
81 | };
82 |
83 | obelisk.SideX = SideX;
84 | }(obelisk));
85 |
--------------------------------------------------------------------------------
/src/primitives/SideY.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * SideY
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var SideY, p;
11 | SideY = function (dimension, color, border, useDefaultCanvas) {
12 | this.initialize(dimension, color, border, useDefaultCanvas);
13 | };
14 | p = SideY.prototype = new obelisk.AbstractPrimitive();
15 |
16 | // public properties
17 |
18 | // constructor
19 | p.initialize = function (dimension, color, border, useDefaultCanvas) {
20 | this.initRender(dimension, color, border, useDefaultCanvas);
21 | this.initRectangle();
22 | this.initBitmapData();
23 | this.build();
24 | this.renderBitmapDataForCanvas();
25 | return this;
26 | };
27 |
28 | // private method
29 | p.initRender = function (dimension, color, border, useDefaultCanvas) {
30 | this.useDefaultCanvas = useDefaultCanvas || false;
31 | this.border = border || border === undefined;
32 | this.dimension = dimension === undefined ? new obelisk.SideYDimension() : dimension;
33 | this.color = color === undefined ? new obelisk.SideColor() : color;
34 | };
35 |
36 | p.initRectangle = function () {
37 | this.w = this.dimension.yAxis;
38 | this.h = this.dimension.zAxis + this.dimension.yAxis / 2;
39 |
40 | // the matrix offset between the bitmap and the 3d pixel coordinate ZERO point
41 | this.matrix = new obelisk.Matrix();
42 | this.matrix.tx = -this.dimension.yAxis + 2;
43 | this.matrix.ty = -this.dimension.zAxis;
44 | };
45 |
46 | p.initBitmapData = function () {
47 | this.bitmapData = new obelisk.BitmapData(this.w, this.h, this.useDefaultCanvas);
48 | };
49 | p.renderBitmapDataForCanvas = function () {
50 | this.bitmapData.context.putImageData(this.bitmapData.imageData, 0, 0);
51 | this.canvas = this.bitmapData.canvas;
52 | };
53 |
54 | p.build = function () {
55 | var xOffsetInner, yOffsetInner, xOffsetOut, yOffsetOut, i, j, borderColor;
56 | xOffsetInner = 0;
57 | yOffsetInner = this.h - this.dimension.zAxis - 1;
58 | xOffsetOut = this.dimension.yAxis - 1;
59 | yOffsetOut = this.dimension.zAxis;
60 | borderColor = this.border ? this.color.border : this.color.inner;
61 |
62 | //y axis
63 | for (i = 0; i < this.dimension.yAxis; i += 1) {
64 | this.bitmapData.setPixel(xOffsetInner + i, yOffsetInner - Math.floor(i / 2), borderColor);
65 | this.bitmapData.setPixel(xOffsetOut - i, yOffsetOut + Math.floor(i / 2), borderColor);
66 | }
67 |
68 | //z axis
69 | for (j = 0; j < this.dimension.zAxis; j += 1) {
70 | this.bitmapData.setPixel(xOffsetInner, yOffsetInner + j, borderColor);
71 | this.bitmapData.setPixel(xOffsetOut, yOffsetOut - j, borderColor);
72 | }
73 |
74 | //fill an pixel graphic enclosed
75 | this.bitmapData.floodFill(Math.floor(this.w / 2), Math.floor(this.h / 2), this.color.inner);
76 | };
77 |
78 | // public methods
79 | p.toString = function () {
80 | return "[SideY]";
81 | };
82 |
83 | obelisk.SideY = SideY;
84 | }(obelisk));
85 |
--------------------------------------------------------------------------------
/src/primitives/Brick.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * Brick
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var Brick, p;
11 | Brick = function (dimension, color, border, useDefaultCanvas) {
12 | this.initialize(dimension, color, border, useDefaultCanvas);
13 | };
14 | p = Brick.prototype = new obelisk.AbstractPrimitive();
15 |
16 | // public properties
17 |
18 | // constructor
19 | p.initialize = function (dimension, color, border, useDefaultCanvas) {
20 | this.initRender(dimension, color, border, useDefaultCanvas);
21 | this.initRectangle();
22 | this.initBitmapData();
23 | this.build();
24 | this.renderBitmapDataForCanvas();
25 | return this;
26 | };
27 |
28 | // private method
29 | p.initRender = function (dimension, color, border, useDefaultCanvas) {
30 | this.useDefaultCanvas = useDefaultCanvas || false;
31 | this.border = border || border === undefined;
32 | this.dimension = dimension === undefined ? new obelisk.BrickDimension() : dimension;
33 | this.color = color === undefined ? new obelisk.SideColor() : color;
34 | };
35 |
36 | p.initRectangle = function () {
37 | this.w = this.dimension.xAxis + this.dimension.yAxis;
38 | this.h = (this.dimension.xAxis + this.dimension.yAxis) / 2;
39 |
40 | // 22.6 degrees implementation
41 | this.w -= 2;
42 | this.h -= 1;
43 |
44 | // the matrix offset between the bitmap and the 3d pixel coordinate ZERO point
45 | this.matrix = new obelisk.Matrix();
46 | this.matrix.tx = -this.dimension.yAxis + 2;
47 | this.matrix.ty = 0;
48 | };
49 |
50 | p.initBitmapData = function () {
51 | this.bitmapData = new obelisk.BitmapData(this.w, this.h, this.useDefaultCanvas);
52 | };
53 | p.renderBitmapDataForCanvas = function () {
54 | this.bitmapData.context.putImageData(this.bitmapData.imageData, 0, 0);
55 | this.canvas = this.bitmapData.canvas;
56 | };
57 |
58 | p.build = function () {
59 | var xOffsetInner, yOffsetInner, xOffsetOut, yOffsetOut, i, j, borderColor;
60 | xOffsetInner = this.dimension.yAxis - 2;
61 | yOffsetInner = 0;
62 | xOffsetOut = this.dimension.xAxis - 1;
63 | yOffsetOut = this.h - 1;
64 | borderColor = this.border ? this.color.border : this.color.inner;
65 |
66 | //x axis
67 | for (i = 0; i < this.dimension.xAxis; i += 1) {
68 | this.bitmapData.setPixel(xOffsetInner + i, yOffsetInner + Math.floor(i / 2), borderColor);
69 | this.bitmapData.setPixel(xOffsetOut - i, yOffsetOut - Math.floor(i / 2), borderColor);
70 | }
71 |
72 | //y axis
73 | for (j = 0; j < this.dimension.yAxis; j += 1) {
74 | this.bitmapData.setPixel(xOffsetInner + 1 - j, yOffsetInner + Math.floor(j / 2), borderColor);
75 | this.bitmapData.setPixel(xOffsetOut - 1 + j, yOffsetOut - Math.floor(j / 2), borderColor);
76 | }
77 |
78 | //fill an pixel graphic enclosed
79 | this.bitmapData.floodFill(Math.floor(this.w / 2), Math.floor(this.h / 2), this.color.inner);
80 | };
81 |
82 | // public methods
83 | p.toString = function () {
84 | return "[Brick]";
85 | };
86 |
87 | obelisk.Brick = Brick;
88 | }(obelisk));
89 |
--------------------------------------------------------------------------------
/demo/advanced/input-text-rendering/main.js:
--------------------------------------------------------------------------------
1 | // control bar
2 | var ControlBar = function () {
3 | this.size = 10;
4 | this.height = 24;
5 | this.threshold = 130;
6 | };
7 | var con = new ControlBar();
8 | var gui = new dat.GUI();
9 | var conSize = gui.add(con, 'size', 6, 20).step(2);
10 | var conHeight = gui.add(con, 'height', 4, 100).step(1);
11 | var conThreshold = gui.add(con, 'threshold', 80, 200).step(1);
12 | conSize.onChange(function () {
13 | buildPrimitive();
14 | draw();
15 | });
16 | conHeight.onChange(function () {
17 | buildPrimitive();
18 | draw();
19 | });
20 | conThreshold.onChange(function () {
21 | buildPrimitive();
22 | draw();
23 | });
24 |
25 | // color patterns
26 | var colorData = ['#CCFF00', '#FF0099', '#FF7CBF', '#EEEEEE', '#666666'];
27 | var iMax = colorData.length;
28 | var colorHtml = '';
29 | for (var i = 0; i < iMax; i++) {
30 | colorHtml += '';
31 | }
32 | $('#color-box').html(colorHtml);
33 | $('#color-box').find('li').on('click', function () {
34 | var index = $(this).index();
35 | color = parseInt(colorData[index].replace('#', '0x'), 16);
36 | buildPrimitive();
37 | draw();
38 | });
39 |
40 | // input field
41 | var ipt = $('#ipt');
42 | ipt.on('keyup', draw);
43 | ipt.on('click', function () {
44 | $(this).select();
45 | });
46 |
47 | // input off canvas
48 | var offCanvas = $('#canvas-txt').get(0);
49 | var ctx = offCanvas.getContext("2d");
50 | ctx.font = "20px Helvetica,sans-serif";
51 |
52 | // pixel view
53 | var canvas = $('#canvas-demo');
54 | var point = new obelisk.Point(150, 30);
55 | var pixelView = new obelisk.PixelView(canvas, point);
56 | var brick;
57 | var cube;
58 | var color = 0xCCFF00;
59 |
60 | // build method
61 | function buildPrimitive() {
62 | // floor
63 | var colorBrick = new obelisk.SideColor(0xAAAAAA, 0xEEEEEE);
64 | var dimensionBrick = new obelisk.BrickDimension(con.size, con.size);
65 | brick = new obelisk.Brick(dimensionBrick, colorBrick);
66 |
67 | // cube
68 | var colorCube = new obelisk.CubeColor().getByHorizontalColor(color);
69 | var dimensionCube = new obelisk.CubeDimension(con.size, con.size, con.height);
70 | cube = new obelisk.Cube(dimensionCube, colorCube, false);
71 | }
72 | function draw() {
73 | var size = con.size;
74 | var txtWidth = offCanvas.width;
75 | var txtHeight = offCanvas.height;
76 |
77 | // clear everything
78 | pixelView.clear();
79 | ctx.clearRect(0, 0, txtWidth, txtHeight);
80 |
81 | ctx.fillText(ipt.val(), 2, 18);
82 | var textData = ctx.getImageData(0, 0, txtWidth, txtHeight);
83 |
84 | for (var y = 0; y <= txtHeight; y++) {
85 | for (var x = 0; x <= txtWidth; x++) {
86 | var p3d = new obelisk.Point3D(x * (size - 2), y * (size - 2), 0);
87 | pixelView.renderObject(brick, p3d);
88 | }
89 | }
90 |
91 | for (var y = 0; y < txtHeight; y++) {
92 | for (var x = 0; x < txtWidth; x++) {
93 | // check pixel
94 | var index = (y * textData.width + x) * 4;
95 |
96 | if (textData.data[index + 3] > con.threshold) {
97 | var p3d = new obelisk.Point3D(x * (size - 2), y * (size - 2), 0);
98 | pixelView.renderObject(cube, p3d);
99 | }
100 | }
101 | }
102 | }
103 |
104 | // main
105 | buildPrimitive();
106 | draw();
107 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Obelisk.js
2 |
3 | Obelisk.js is a JavaScript Engine for building isometric pixel objects.
4 |
5 | With the simple and flexible API provided by this engine, you can easily add isometric pixel element like brick, cube, pyramid onto HTML5 canvas. Obelisk.js strictly follows the pixel neat pattern: lines with 1:2 pixel dot arrangement, leading to an angle of 22.6 degrees. Also you should know this is not only for game, just try it out and pixelate something. Have fun.
6 |
7 |
8 |
9 | ## Showcase
10 |
11 | Experiments:
12 | - GIF Animation Rendering: http://codepen.io/nosir/details/mdiHe (WebKit browser only - Chrome, Safari)
13 | - Input Text Rendering: http://codepen.io/nosir/details/IxBJn
14 | - Pixel Isometirc Flappy Bird: http://codepen.io/nosir/details/rzaLA
15 | - Cube Generator: http://codepen.io/nosir/details/ganrh
16 |
17 | User Contributed:
18 | - Github Contribution Chart Isometric View Chrome Extension: [Github URL](https://github.com/jasonlong/isometric-contributions) by [@jasonlong](https://twitter.com/jasonlong)
19 | - Snake Game: http://codepen.io/sfaedo/full/AwGjg (Use ← → Key) by [@Sebastian Faedo](http://codepen.io/sfaedo)
20 | - Mario 3D Model: http://jsdo.it/cx20/bQtQ by [@cx20](https://twitter.com/cx20)
21 | - Conway's Game of Life: http://codepen.io/safx/full/Ewcym by [@safxdev](https://twitter.com/safxdev)
22 |
23 | ## Getting started
24 |
25 | Simply include obelisk.js in your project
26 | ```html
27 |
28 | ```
29 |
30 | Create pixel world
31 | ```javascript
32 | // create a canvas 2D point for pixel view world
33 | var point = new obelisk.Point(200, 200);
34 |
35 | // create view instance to nest everything
36 | // canvas could be either DOM or jQuery element
37 | var pixelView = new obelisk.PixelView(canvas, point);
38 |
39 | // create cube dimension and color instance
40 | var dimension = new obelisk.CubeDimension(80, 100, 120);
41 | var gray = obelisk.ColorPattern.GRAY;
42 | var color = new obelisk.CubeColor().getByHorizontalColor(gray);
43 |
44 | // build cube with dimension and color instance
45 | var cube = new obelisk.Cube(dimension, color, true);
46 |
47 | // render cube primitive into view
48 | pixelView.renderObject(cube);
49 | ```
50 | You can find out more details in tutorial part 1: [To build the first cube](https://github.com/nosir/obelisk.js/wiki/Tutorial-Part-1%3A-To-build-the-first-cube) or [try the code yourself](http://jsfiddle.net/nosir/ygWEW/)
51 |
52 | ## Tutorials
53 | Step by step:
54 | - Part 1: [To build the first cube](https://github.com/nosir/obelisk.js/wiki/Tutorial-Part-1%3A-To-build-the-first-cube)
55 | - Part 2: [Coordinate system](https://github.com/nosir/obelisk.js/wiki/Tutorial-Part-2%3A-Coordinate-system)
56 | - Part 3: [Primitives](https://github.com/nosir/obelisk.js/wiki/Tutorial-Part-3%3A-Primitives)
57 | - Part 4: [Color](https://github.com/nosir/obelisk.js/wiki/Tutorial-Part-4%3A-Color)
58 | - Part 5: [Dimension](https://github.com/nosir/obelisk.js/wiki/Tutorial-Part-5%3A-Dimension)
59 |
60 | Sample code for building all primitives:
61 | - Cube: http://jsfiddle.net/nosir/ygWEW/
62 | - Pyramid : http://jsfiddle.net/nosir/ZVURu/
63 | - Brick: http://jsfiddle.net/nosir/6MuVr/
64 | - SideX & SideY: http://jsfiddle.net/nosir/bLsew/
65 |
66 | ## Roadmap
67 |
68 | To add more pixel primitives - 4 directions [slopes](http://nosir.github.io/obelisk.js/images/slope.gif) will be the first
69 |
70 | ## Get in Touch
71 |
72 | - Build any cool stuff with obelisk.js? Please feel free to add it here: [User Contributed Showcase](https://github.com/nosir/obelisk.js/wiki/User-Contributed-Showcase)
73 | - Bugs & Suggestions: [open an issue](https://github.com/nosir/obelisk.js/issues)
74 | - Twitter: [@rison](https://twitter.com/rison)
75 |
76 | ## Changelog
77 |
78 | See details in the [release notes](https://github.com/nosir/obelisk.js/releases).
79 |
80 | ## References
81 | Pixel art is a form of digital art, where images are edited and displayed on the pixel level. The isometric projection is commonly seen in games to provide a 3D view without using any real 3D processing.
82 |
83 | - Isometric projection http://en.wikipedia.org/wiki/Isometric_projection
84 | - Flood fill implementation http://en.wikipedia.org/wiki/Flood_fill
85 | - Pixel grapic - Eboy http://eboy.com
86 |
87 | ## License
88 |
89 | Obelisk.js is released under the [MIT License](http://opensource.org/licenses/MIT)
90 |
--------------------------------------------------------------------------------
/src/primitives/Cube.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * Cube
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var Cube, p;
11 | Cube = function (dimension, color, border, useDefaultCanvas) {
12 | this.initialize(dimension, color, border, useDefaultCanvas);
13 | };
14 | p = Cube.prototype = new obelisk.AbstractPrimitive();
15 |
16 | // public properties
17 |
18 | // constructor
19 | p.initialize = function (dimension, color, border, useDefaultCanvas) {
20 | this.initRender(dimension, color, border, useDefaultCanvas);
21 | this.initRectangle();
22 | this.initBitmapData();
23 | this.build();
24 | this.renderBitmapDataForCanvas();
25 | return this;
26 | };
27 |
28 | // private method
29 | p.initRender = function (dimension, color, border, useDefaultCanvas) {
30 | this.useDefaultCanvas = useDefaultCanvas || false;
31 | this.border = border || border === undefined;
32 | this.dimension = dimension === undefined ? new obelisk.CubeDimension() : dimension;
33 | this.color = color === undefined ? new obelisk.CubeColor() : color;
34 | };
35 |
36 | p.initRectangle = function () {
37 | this.w = this.dimension.xAxis + this.dimension.yAxis;
38 | this.h = this.dimension.zAxis + (this.dimension.xAxis + this.dimension.yAxis) / 2;
39 |
40 | // 22.6 degrees implementation
41 | this.w -= 2;
42 | this.h -= 1;
43 |
44 | // the matrix offset between the bitmap and the 3d pixel coordinate ZERO point
45 | this.matrix = new obelisk.Matrix();
46 | this.matrix.tx = -this.dimension.yAxis + 2;
47 | this.matrix.ty = -this.dimension.zAxis;
48 | };
49 |
50 | p.initBitmapData = function () {
51 | this.bitmapData = new obelisk.BitmapData(this.w, this.h, this.useDefaultCanvas);
52 | };
53 | p.renderBitmapDataForCanvas = function () {
54 | this.canvas = this.bitmapData.canvas;
55 | };
56 |
57 | p.build = function () {
58 | var brick, sideX, sideY, po_brick, po_x, po_y, ctx, bmd, offsetX, offsetY,
59 | i, j, k;
60 | // horizontal layer
61 | brick = new obelisk.Brick(
62 | new obelisk.BrickDimension(this.dimension.xAxis, this.dimension.yAxis),
63 | new obelisk.SideColor(this.color.border, this.color.horizontal),
64 | this.border
65 | );
66 |
67 | // left side
68 | sideX = new obelisk.SideX(
69 | new obelisk.SideXDimension(this.dimension.xAxis, this.dimension.zAxis),
70 | new obelisk.SideColor(this.color.border, this.color.left),
71 | this.border
72 | );
73 |
74 | // right side
75 | sideY = new obelisk.SideY(
76 | new obelisk.SideYDimension(this.dimension.yAxis, this.dimension.zAxis),
77 | new obelisk.SideColor(this.color.border, this.color.right),
78 | this.border
79 | );
80 |
81 | po_brick = new obelisk.PixelObject(brick);
82 | po_x = new obelisk.PixelObject(sideX);
83 | po_y = new obelisk.PixelObject(sideY);
84 |
85 | ctx = this.bitmapData.context;
86 | ctx.drawImage(po_brick.canvas, po_brick.x + this.dimension.yAxis - 2, po_brick.y);
87 | ctx.drawImage(po_x.canvas, po_x.x, po_x.y + this.dimension.zAxis + this.dimension.yAxis / 2 - 1);
88 | ctx.drawImage(po_y.canvas, po_y.x + this.w - 2, po_x.y + this.dimension.zAxis + this.dimension.xAxis / 2 - 1);
89 |
90 | // highlight & highlight fix
91 | bmd = new obelisk.BitmapData(this.w, this.h);
92 |
93 | if (this.border) {
94 | offsetX = this.dimension.xAxis - 2;
95 | offsetY = (this.dimension.xAxis + this.dimension.yAxis) / 2 - 2;
96 |
97 | //the 2px in bounding without hightlight
98 | for (i = 0; i < this.dimension.xAxis - 2; i += 1) {
99 | bmd.setPixel(offsetX + 1 - i, offsetY - Math.floor(i / 2), this.color.borderHighlight);
100 | }
101 |
102 | //the 2px in bounding without hightlight
103 | for (j = 0; j < this.dimension.yAxis - 2; j += 1) {
104 | bmd.setPixel(offsetX + j, offsetY - Math.floor(j / 2), this.color.borderHighlight);
105 | }
106 |
107 | for (k = 0; k < this.dimension.zAxis; k += 1) {
108 | bmd.setPixel(offsetX, offsetY + k, this.color.borderHighlight);
109 | }
110 | } else {
111 | for (i = 0; i < this.dimension.zAxis; i += 1) {
112 | bmd.setPixel(this.dimension.xAxis - 2, (this.dimension.xAxis + this.dimension.yAxis) / 2 - 1 + i, this.color.left);
113 | }
114 | }
115 | bmd.context.putImageData(bmd.imageData, 0, 0);
116 | ctx.drawImage(bmd.canvas, 0, 0);
117 | };
118 |
119 | // public methods
120 | p.toString = function () {
121 | return "[Cube]";
122 | };
123 |
124 | obelisk.Cube = Cube;
125 | }(obelisk));
126 |
--------------------------------------------------------------------------------
/src/primitives/Pyramid.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * Pyramid
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var Pyramid, p;
11 | Pyramid = function (dimension, color, border, useDefaultCanvas) {
12 | this.initialize(dimension, color, border, useDefaultCanvas);
13 | };
14 | p = Pyramid.prototype = new obelisk.AbstractPrimitive();
15 |
16 | // private properties
17 | p.hSize = null;
18 | p.hOffset = null;
19 |
20 | // constructor
21 | p.initialize = function (dimension, color, border, useDefaultCanvas) {
22 | this.initRender(dimension, color, border, useDefaultCanvas);
23 | this.initRectangle();
24 | this.initBitmapData();
25 | this.build();
26 | this.renderBitmapDataForCanvas();
27 | return this;
28 | };
29 |
30 | // private method
31 | p.initRender = function (dimension, color, border, useDefaultCanvas) {
32 | this.useDefaultCanvas = useDefaultCanvas || false;
33 | this.border = border || border === undefined;
34 | this.dimension = dimension === undefined ? new obelisk.PyramidDimension() : dimension;
35 | this.color = color === undefined ? new obelisk.PyramidColor() : color;
36 |
37 | this.hSize = this.dimension.tall ? this.dimension.xAxis * 2 : this.dimension.xAxis;
38 | this.hOffset = this.dimension.tall ? -3 : -2;
39 | };
40 |
41 | p.initRectangle = function () {
42 | this.w = this.dimension.xAxis + this.dimension.yAxis;
43 | this.h = this.hSize + this.dimension.xAxis / 2;
44 |
45 | // 22.6 degrees implementation
46 | this.w -= 2;
47 | this.h += this.hOffset;
48 |
49 | // the matrix offset between the bitmap and the 3d pixel coordinate ZERO point
50 | this.matrix = new obelisk.Matrix();
51 | this.matrix.tx = -this.dimension.xAxis + 2;
52 | this.matrix.ty = -this.hSize / 2 + 2 - (this.dimension.tall ? this.dimension.xAxis / 2 : 1);
53 | };
54 |
55 | p.initBitmapData = function () {
56 | this.bitmapData = new obelisk.BitmapData(this.w, this.h, this.useDefaultCanvas);
57 | };
58 | p.renderBitmapDataForCanvas = function () {
59 | this.bitmapData.context.putImageData(this.bitmapData.imageData, 0, 0);
60 | this.canvas = this.bitmapData.canvas;
61 | };
62 |
63 | p.build = function () {
64 | var colorborder_left, colorborder_right, colorborder_highlight,
65 | i, j, k, l1, m1, l2, m2;
66 | colorborder_left = this.border ? this.color.border : this.color.left;
67 | colorborder_right = this.border ? this.color.border : this.color.right;
68 |
69 | colorborder_highlight = this.border ? this.color.borderHighlight : colorborder_left;
70 |
71 | //z axis || hightlight
72 | for (k = 0; k < this.hSize + this.dimension.xAxis / 2 - 4; k += 1) {
73 | this.bitmapData.setPixel(this.dimension.xAxis - 2, k + 3 + this.hOffset, colorborder_highlight);
74 | }
75 |
76 | //x axis
77 | for (i = 0; i < this.dimension.xAxis; i += 1) {
78 | this.bitmapData.setPixel(i, this.hSize + Math.floor(i / 2) + this.hOffset, colorborder_left);
79 | }
80 |
81 | //y axis
82 | for (j = 0; j < this.dimension.xAxis; j += 1) {
83 | this.bitmapData.setPixel(j + this.dimension.xAxis - 2, this.hSize + this.dimension.xAxis / 2 - Math.floor(j / 2) - 1 + this.hOffset, colorborder_right);
84 | }
85 |
86 | if (!this.dimension.tall) {
87 | //left edge
88 | for (l1 = 0; l1 < this.hSize; l1 += 1) {
89 | this.bitmapData.setPixel(l1, this.hSize - l1 + this.hOffset, colorborder_left);
90 | }
91 |
92 | //right edge
93 | for (m1 = 0; m1 < this.hSize; m1 += 1) {
94 | this.bitmapData.setPixel(m1 + this.hSize - 2, m1 + 1 + this.hOffset, colorborder_right);
95 | }
96 | } else {
97 | //left edge
98 | for (l2 = 0; l2 < this.hSize - 2; l2 += 1) {
99 | this.bitmapData.setPixel(Math.floor(l2 / 2), this.hSize - l2 + this.hOffset, colorborder_left);
100 | }
101 |
102 | //right edge
103 | for (m2 = 2; m2 < this.hSize; m2 += 1) {
104 | this.bitmapData.setPixel(Math.floor(m2 / 2) + this.dimension.xAxis - 2, m2 + 1 + this.hOffset, colorborder_right);
105 | }
106 | }
107 |
108 | if (!this.border) {
109 | this.bitmapData.setPixel(this.dimension.xAxis - 2, this.hSize + this.dimension.xAxis / 2 - 1 + this.hOffset, colorborder_left);
110 | }
111 |
112 | //floodfill
113 | this.bitmapData.floodFill(this.dimension.xAxis - 1, this.hSize + Math.floor((this.dimension.xAxis - 1) / 2) + this.hOffset - 1, this.color.right);
114 | this.bitmapData.floodFill(this.dimension.xAxis - 3, this.hSize + Math.floor((this.dimension.xAxis - 1) / 2) + this.hOffset - 2, this.color.left);
115 | };
116 |
117 | // public methods
118 | p.toString = function () {
119 | return "[Pyramid]";
120 | };
121 |
122 | obelisk.Pyramid = Pyramid;
123 | }(obelisk));
124 |
--------------------------------------------------------------------------------
/src/display/BitmapData.js:
--------------------------------------------------------------------------------
1 | /*global obelisk:true*/
2 |
3 | /*
4 | * BitmapData
5 | */
6 |
7 | (function (obelisk) {
8 | "use strict";
9 |
10 | var BitmapData, p;
11 | BitmapData = function (w, h, useDefaultCanvas) {
12 | this.initialize(w, h, useDefaultCanvas);
13 | };
14 | p = BitmapData.prototype;
15 |
16 | // public property
17 | p.imageData = null;
18 | p.canvas = null;
19 | p.context = null;
20 |
21 | // constructor
22 | p.initialize = function (w, h, useDefaultCanvas) {
23 | if (w === undefined || h === undefined) {
24 | throw new Error("BitmapData width or height is missing");
25 | }
26 |
27 | if (useDefaultCanvas) {
28 | this.canvas = obelisk.CanvasManager.getDefaultCanvas();
29 | } else {
30 | this.canvas = obelisk.CanvasManager.getNewCanvas();
31 | }
32 |
33 | this.canvas.setAttribute('width', w);
34 | this.canvas.setAttribute('height', h);
35 |
36 | this.context = this.canvas.getContext('2d');
37 | this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
38 |
39 | this.imageData = this.context.createImageData(w, h);
40 |
41 | return this;
42 | };
43 |
44 | p.setPixel = function (posX, posY, color) {
45 | var index = (posY * this.imageData.width + posX) * 4;
46 | this.setPixelByIndex(index, color);
47 | };
48 |
49 | p.setPixelByIndex = function (index, color) {
50 | var pixels = this.imageData.data;
51 | pixels[index] = (color >>> 16) & 0xFF;
52 | pixels[index + 1] = (color >>> 8) & 0xFF;
53 | pixels[index + 2] = (color >>> 0) & 0xFF;
54 | pixels[index + 3] = (color >>> 24) & 0xFF;
55 | };
56 |
57 | p.checkPixelAvailable = function (x, y) {
58 | var index = (y * this.imageData.width + x) * 4;
59 | return this.imageData.data[index + 3] === 0;
60 | };
61 |
62 | p.floodFill = function (posX, posY, color) {
63 | if (((color >>> 24) & 0xFF) === 0x00) {
64 | // transparent flood fill
65 | return;
66 | }
67 |
68 | var x = posX, y = posY,
69 | stack = [],
70 | nowCol = [],
71 | prevCol = [],
72 | col, row, matchFlag,
73 | w = this.imageData.width,
74 | h = this.imageData.height,
75 | i, j;
76 |
77 | // bound reach
78 | if (x < 0 || y < 0 || x >= w || y >= h) {
79 | return;
80 | }
81 |
82 | // first point check fail
83 | if (!this.checkPixelAvailable(x, y)) {
84 | throw new Error("Start point for flood fill is already filled");
85 | }
86 |
87 | // left side flood fill
88 | for (col = x; col >= 0; col -= 1) {
89 | // top side
90 | for (row = y; row >= 0; row -= 1) {
91 | if (this.checkPixelAvailable(col, row)) {
92 | // available pixel
93 | stack.push((row * w + col) * 4);
94 | nowCol.push(row);
95 | } else {
96 | // unavailable pixel
97 | if (!(row === y && this.checkPixelAvailable(col + 1, row - 1))) {
98 | break;
99 | }
100 | // let's continue to check more data in this column
101 | }
102 | }
103 |
104 | // top side
105 | for (row = y; row < h; row += 1) {
106 | if (this.checkPixelAvailable(col, row)) {
107 | // available pixel
108 | stack.push((row * w + col) * 4);
109 | nowCol.push(row);
110 | } else {
111 | // unavailable pixel
112 | if (!(row === y && this.checkPixelAvailable(col + 1, row + 1))) {
113 | break;
114 | }
115 | // let's continue to check more data in this column
116 | }
117 | }
118 |
119 | // compare with previous column
120 | // for first column
121 | // the given point should be inside the container
122 | if (col === x) {
123 | prevCol = nowCol.concat();
124 | }
125 |
126 | matchFlag = false;
127 |
128 | for (i = 0; i < prevCol.length; i += 1) {
129 | for (j = 0; j < prevCol.length; j += 1) {
130 | if (nowCol[j] === prevCol[i]) {
131 | matchFlag = true;
132 | y = prevCol[i];
133 | break;
134 | }
135 | }
136 |
137 | if (matchFlag) {
138 | break;
139 | }
140 | }
141 |
142 | if (matchFlag) {
143 | prevCol = nowCol.concat();
144 | nowCol = [];
145 | } else {
146 | // bound reach
147 | break;
148 | }
149 | }
150 |
151 | // reset start point
152 | x = posX;
153 | y = posY;
154 | prevCol = [];
155 | nowCol = [];
156 |
157 | // right side flood fill
158 | for (col = x; col < w; col += 1) {
159 | // top side
160 | for (row = y; row >= 0; row -= 1) {
161 | if (this.checkPixelAvailable(col, row)) {
162 | // available pixel
163 | stack.push((row * w + col) * 4);
164 | nowCol.push(row);
165 | } else {
166 | // unavailable pixel
167 | if (!(row === y && this.checkPixelAvailable(col - 1, row - 1))) {
168 | break;
169 | }
170 | // let's continue to check more data in this column
171 | }
172 | }
173 |
174 | // top side
175 | for (row = y; row < h; row += 1) {
176 | if (this.checkPixelAvailable(col, row)) {
177 | // available pixel
178 | stack.push((row * w + col) * 4);
179 | nowCol.push(row);
180 | } else {
181 | // unavailable pixel
182 | if (!(row === y && this.checkPixelAvailable(col - 1, row + 1))) {
183 | break;
184 | }
185 | // let's continue to check more data in this column
186 | }
187 | }
188 |
189 | // compare with previous column
190 | // for first column
191 | // the given point should be inside the container
192 | if (col === x) {
193 | prevCol = nowCol.concat();
194 | }
195 |
196 | matchFlag = false;
197 |
198 | for (i = 0; i < prevCol.length; i += 1) {
199 | for (j = 0; j < prevCol.length; j += 1) {
200 | if (nowCol[j] === prevCol[i]) {
201 | matchFlag = true;
202 | y = prevCol[i];
203 | break;
204 | }
205 | }
206 |
207 | if (matchFlag) {
208 | break;
209 | }
210 | }
211 |
212 | if (matchFlag) {
213 | prevCol = nowCol.concat();
214 | nowCol = [];
215 | } else {
216 | // bound reach
217 | break;
218 | }
219 | }
220 |
221 | // fill image data
222 | for (i = 0; i < stack.length; i += 1) {
223 | this.setPixelByIndex(stack[i], color);
224 | }
225 | };
226 |
227 | p.toString = function () {
228 | return "[BitmapData]";
229 | };
230 |
231 | obelisk.BitmapData = BitmapData;
232 | }(obelisk));
233 |
--------------------------------------------------------------------------------
/demo/vendor/modernizr-2.6.2.min.js:
--------------------------------------------------------------------------------
1 | /* Modernizr 2.6.2 (Custom Build) | MIT & BSD
2 | * Build: http://modernizr.com/download/#-fontface-backgroundsize-borderimage-borderradius-boxshadow-flexbox-hsla-multiplebgs-opacity-rgba-textshadow-cssanimations-csscolumns-generatedcontent-cssgradients-cssreflections-csstransforms-csstransforms3d-csstransitions-applicationcache-canvas-canvastext-draganddrop-hashchange-history-audio-video-indexeddb-input-inputtypes-localstorage-postmessage-sessionstorage-websockets-websqldatabase-webworkers-geolocation-inlinesvg-smil-svg-svgclippaths-touch-webgl-shiv-mq-cssclasses-addtest-prefixed-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes-load
3 | */
4 | ;window.Modernizr=function(a,b,c){function D(a){j.cssText=a}function E(a,b){return D(n.join(a+";")+(b||""))}function F(a,b){return typeof a===b}function G(a,b){return!!~(""+a).indexOf(b)}function H(a,b){for(var d in a){var e=a[d];if(!G(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function I(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:F(f,"function")?f.bind(d||b):f}return!1}function J(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+p.join(d+" ")+d).split(" ");return F(b,"string")||F(b,"undefined")?H(e,b):(e=(a+" "+q.join(d+" ")+d).split(" "),I(e,b,c))}function K(){e.input=function(c){for(var d=0,e=c.length;d',a,""].join(""),l.id=h,(m?l:n).innerHTML+=f,n.appendChild(l),m||(n.style.background="",n.style.overflow="hidden",k=g.style.overflow,g.style.overflow="hidden",g.appendChild(n)),i=c(l,a),m?l.parentNode.removeChild(l):(n.parentNode.removeChild(n),g.style.overflow=k),!!i},z=function(b){var c=a.matchMedia||a.msMatchMedia;if(c)return c(b).matches;var d;return y("@media "+b+" { #"+h+" { position: absolute; } }",function(b){d=(a.getComputedStyle?getComputedStyle(b,null):b.currentStyle)["position"]=="absolute"}),d},A=function(){function d(d,e){e=e||b.createElement(a[d]||"div"),d="on"+d;var f=d in e;return f||(e.setAttribute||(e=b.createElement("div")),e.setAttribute&&e.removeAttribute&&(e.setAttribute(d,""),f=F(e[d],"function"),F(e[d],"undefined")||(e[d]=c),e.removeAttribute(d))),e=null,f}var a={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return d}(),B={}.hasOwnProperty,C;!F(B,"undefined")&&!F(B.call,"undefined")?C=function(a,b){return B.call(a,b)}:C=function(a,b){return b in a&&F(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=w.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(w.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(w.call(arguments)))};return e}),s.flexbox=function(){return J("flexWrap")},s.canvas=function(){var a=b.createElement("canvas");return!!a.getContext&&!!a.getContext("2d")},s.canvastext=function(){return!!e.canvas&&!!F(b.createElement("canvas").getContext("2d").fillText,"function")},s.webgl=function(){return!!a.WebGLRenderingContext},s.touch=function(){var c;return"ontouchstart"in a||a.DocumentTouch&&b instanceof DocumentTouch?c=!0:y(["@media (",n.join("touch-enabled),("),h,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(a){c=a.offsetTop===9}),c},s.geolocation=function(){return"geolocation"in navigator},s.postmessage=function(){return!!a.postMessage},s.websqldatabase=function(){return!!a.openDatabase},s.indexedDB=function(){return!!J("indexedDB",a)},s.hashchange=function(){return A("hashchange",a)&&(b.documentMode===c||b.documentMode>7)},s.history=function(){return!!a.history&&!!history.pushState},s.draganddrop=function(){var a=b.createElement("div");return"draggable"in a||"ondragstart"in a&&"ondrop"in a},s.websockets=function(){return"WebSocket"in a||"MozWebSocket"in a},s.rgba=function(){return D("background-color:rgba(150,255,150,.5)"),G(j.backgroundColor,"rgba")},s.hsla=function(){return D("background-color:hsla(120,40%,100%,.5)"),G(j.backgroundColor,"rgba")||G(j.backgroundColor,"hsla")},s.multiplebgs=function(){return D("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(j.background)},s.backgroundsize=function(){return J("backgroundSize")},s.borderimage=function(){return J("borderImage")},s.borderradius=function(){return J("borderRadius")},s.boxshadow=function(){return J("boxShadow")},s.textshadow=function(){return b.createElement("div").style.textShadow===""},s.opacity=function(){return E("opacity:.55"),/^0.55$/.test(j.opacity)},s.cssanimations=function(){return J("animationName")},s.csscolumns=function(){return J("columnCount")},s.cssgradients=function(){var a="background-image:",b="gradient(linear,left top,right bottom,from(#9f9),to(white));",c="linear-gradient(left top,#9f9, white);";return D((a+"-webkit- ".split(" ").join(b+a)+n.join(c+a)).slice(0,-a.length)),G(j.backgroundImage,"gradient")},s.cssreflections=function(){return J("boxReflect")},s.csstransforms=function(){return!!J("transform")},s.csstransforms3d=function(){var a=!!J("perspective");return a&&"webkitPerspective"in g.style&&y("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(b,c){a=b.offsetLeft===9&&b.offsetHeight===3}),a},s.csstransitions=function(){return J("transition")},s.fontface=function(){var a;return y('@font-face {font-family:"font";src:url("https://")}',function(c,d){var e=b.getElementById("smodernizr"),f=e.sheet||e.styleSheet,g=f?f.cssRules&&f.cssRules[0]?f.cssRules[0].cssText:f.cssText||"":"";a=/src/i.test(g)&&g.indexOf(d.split(" ")[0])===0}),a},s.generatedcontent=function(){var a;return y(["#",h,"{font:0/0 a}#",h,':after{content:"',l,'";visibility:hidden;font:3px/1 a}'].join(""),function(b){a=b.offsetHeight>=3}),a},s.video=function(){var a=b.createElement("video"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),c.h264=a.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),c.webm=a.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,"")}catch(d){}return c},s.audio=function(){var a=b.createElement("audio"),c=!1;try{if(c=!!a.canPlayType)c=new Boolean(c),c.ogg=a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),c.mp3=a.canPlayType("audio/mpeg;").replace(/^no$/,""),c.wav=a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),c.m4a=(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;")).replace(/^no$/,"")}catch(d){}return c},s.localstorage=function(){try{return localStorage.setItem(h,h),localStorage.removeItem(h),!0}catch(a){return!1}},s.sessionstorage=function(){try{return sessionStorage.setItem(h,h),sessionStorage.removeItem(h),!0}catch(a){return!1}},s.webworkers=function(){return!!a.Worker},s.applicationcache=function(){return!!a.applicationCache},s.svg=function(){return!!b.createElementNS&&!!b.createElementNS(r.svg,"svg").createSVGRect},s.inlinesvg=function(){var a=b.createElement("div");return a.innerHTML="",(a.firstChild&&a.firstChild.namespaceURI)==r.svg},s.smil=function(){return!!b.createElementNS&&/SVGAnimate/.test(m.call(b.createElementNS(r.svg,"animate")))},s.svgclippaths=function(){return!!b.createElementNS&&/SVGClipPath/.test(m.call(b.createElementNS(r.svg,"clipPath")))};for(var L in s)C(s,L)&&(x=L.toLowerCase(),e[x]=s[L](),v.push((e[x]?"":"no-")+x));return e.input||K(),e.addTest=function(a,b){if(typeof a=="object")for(var d in a)C(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},D(""),i=k=null,function(a,b){function k(a,b){var c=a.createElement("p"),d=a.getElementsByTagName("head")[0]||a.documentElement;return c.innerHTML="x",d.insertBefore(c.lastChild,d.firstChild)}function l(){var a=r.elements;return typeof a=="string"?a.split(" "):a}function m(a){var b=i[a[g]];return b||(b={},h++,a[g]=h,i[h]=b),b}function n(a,c,f){c||(c=b);if(j)return c.createElement(a);f||(f=m(c));var g;return f.cache[a]?g=f.cache[a].cloneNode():e.test(a)?g=(f.cache[a]=f.createElem(a)).cloneNode():g=f.createElem(a),g.canHaveChildren&&!d.test(a)?f.frag.appendChild(g):g}function o(a,c){a||(a=b);if(j)return a.createDocumentFragment();c=c||m(a);var d=c.frag.cloneNode(),e=0,f=l(),g=f.length;for(;e",f="hidden"in a,j=a.childNodes.length==1||function(){b.createElement("a");var a=b.createDocumentFragment();return typeof a.cloneNode=="undefined"||typeof a.createDocumentFragment=="undefined"||typeof a.createElement=="undefined"}()}catch(c){f=!0,j=!0}})();var r={elements:c.elements||"abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup mark meter nav output progress section summary time video",shivCSS:c.shivCSS!==!1,supportsUnknownElements:j,shivMethods:c.shivMethods!==!1,type:"default",shivDocument:q,createElement:n,createDocumentFragment:o};a.html5=r,q(b)}(this,b),e._version=d,e._prefixes=n,e._domPrefixes=q,e._cssomPrefixes=p,e.mq=z,e.hasEvent=A,e.testProp=function(a){return H([a])},e.testAllProps=J,e.testStyles=y,e.prefixed=function(a,b,c){return b?J(a,b,c):J(a,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+v.join(" "):""),e}(this,this.document),function(a,b,c){function d(a){return"[object Function]"==o.call(a)}function e(a){return"string"==typeof a}function f(){}function g(a){return!a||"loaded"==a||"complete"==a||"uninitialized"==a}function h(){var a=p.shift();q=1,a?a.t?m(function(){("c"==a.t?B.injectCss:B.injectJs)(a.s,0,a.a,a.x,a.e,1)},0):(a(),h()):q=0}function i(a,c,d,e,f,i,j){function k(b){if(!o&&g(l.readyState)&&(u.r=o=1,!q&&h(),l.onload=l.onreadystatechange=null,b)){"img"!=a&&m(function(){t.removeChild(l)},50);for(var d in y[c])y[c].hasOwnProperty(d)&&y[c][d].onload()}}var j=j||B.errorTimeout,l=b.createElement(a),o=0,r=0,u={t:d,s:c,e:f,a:i,x:j};1===y[c]&&(r=1,y[c]=[]),"object"==a?l.data=c:(l.src=c,l.type=a),l.width=l.height="0",l.onerror=l.onload=l.onreadystatechange=function(){k.call(this,r)},p.splice(e,0,u),"img"!=a&&(r||2===y[c]?(t.insertBefore(l,s?null:n),m(k,j)):y[c].push(l))}function j(a,b,c,d,f){return q=0,b=b||"j",e(a)?i("c"==b?v:u,a,b,this.i++,c,d,f):(p.splice(this.i++,0,a),1==p.length&&h()),this}function k(){var a=B;return a.loader={load:j,i:0},a}var l=b.documentElement,m=a.setTimeout,n=b.getElementsByTagName("script")[0],o={}.toString,p=[],q=0,r="MozAppearance"in l.style,s=r&&!!b.createRange().compareNode,t=s?l:n.parentNode,l=a.opera&&"[object Opera]"==o.call(a.opera),l=!!b.attachEvent&&!l,u=r?"object":l?"script":"img",v=l?"script":u,w=Array.isArray||function(a){return"[object Array]"==o.call(a)},x=[],y={},z={timeout:function(a,b){return b.length&&(a.timeout=b[0]),a}},A,B;B=function(a){function b(a){var a=a.split("!"),b=x.length,c=a.pop(),d=a.length,c={url:c,origUrl:c,prefixes:a},e,f,g;for(f=0;f
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | obelisk.js Demo
10 |
11 |
34 |
35 |
36 |
37 |

38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
--------------------------------------------------------------------------------
/demo/vendor/dat.gui.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * dat-gui JavaScript Controller Library
3 | * http://code.google.com/p/dat-gui
4 | *
5 | * Copyright 2011 Data Arts Team, Google Creative Lab
6 | *
7 | * Licensed under the Apache License, Version 2.0 (the "License");
8 | * you may not use this file except in compliance with the License.
9 | * You may obtain a copy of the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | */
13 | var dat=dat||{};dat.gui=dat.gui||{};dat.utils=dat.utils||{};dat.controllers=dat.controllers||{};dat.dom=dat.dom||{};dat.color=dat.color||{};dat.utils.css=function(){return{load:function(e,a){var a=a||document,c=a.createElement("link");c.type="text/css";c.rel="stylesheet";c.href=e;a.getElementsByTagName("head")[0].appendChild(c)},inject:function(e,a){var a=a||document,c=document.createElement("style");c.type="text/css";c.innerHTML=e;a.getElementsByTagName("head")[0].appendChild(c)}}}();
14 | dat.utils.common=function(){var e=Array.prototype.forEach,a=Array.prototype.slice;return{BREAK:{},extend:function(c){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(a[f])||(c[f]=a[f])},this);return c},defaults:function(c){this.each(a.call(arguments,1),function(a){for(var f in a)this.isUndefined(c[f])&&(c[f]=a[f])},this);return c},compose:function(){var c=a.call(arguments);return function(){for(var d=a.call(arguments),f=c.length-1;f>=0;f--)d=[c[f].apply(this,d)];return d[0]}},
15 | each:function(a,d,f){if(e&&a.forEach===e)a.forEach(d,f);else if(a.length===a.length+0)for(var b=0,n=a.length;b-1?d.length-d.indexOf(".")-1:0};c.superclass=e;a.extend(c.prototype,e.prototype,{setValue:function(a){if(this.__min!==void 0&&athis.__max)a=this.__max;this.__step!==void 0&&a%this.__step!=0&&(a=Math.round(a/this.__step)*this.__step);return c.superclass.prototype.setValue.call(this,a)},min:function(a){this.__min=a;return this},max:function(a){this.__max=a;return this},step:function(a){this.__step=a;return this}});return c}(dat.controllers.Controller,dat.utils.common);
29 | dat.controllers.NumberControllerBox=function(e,a,c){var d=function(f,b,e){function h(){var a=parseFloat(l.__input.value);c.isNaN(a)||l.setValue(a)}function j(a){var b=o-a.clientY;l.setValue(l.getValue()+b*l.__impliedStep);o=a.clientY}function m(){a.unbind(window,"mousemove",j);a.unbind(window,"mouseup",m)}this.__truncationSuspended=false;d.superclass.call(this,f,b,e);var l=this,o;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"change",h);
30 | a.bind(this.__input,"blur",function(){h();l.__onFinishChange&&l.__onFinishChange.call(l,l.getValue())});a.bind(this.__input,"mousedown",function(b){a.bind(window,"mousemove",j);a.bind(window,"mouseup",m);o=b.clientY});a.bind(this.__input,"keydown",function(a){if(a.keyCode===13)l.__truncationSuspended=true,this.blur(),l.__truncationSuspended=false});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;c.extend(d.prototype,e.prototype,{updateDisplay:function(){var a=this.__input,
31 | b;if(this.__truncationSuspended)b=this.getValue();else{b=this.getValue();var c=Math.pow(10,this.__precision);b=Math.round(b*c)/c}a.value=b;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.NumberController,dat.dom.dom,dat.utils.common);
32 | dat.controllers.NumberControllerSlider=function(e,a,c,d,f){var b=function(d,c,f,e,l){function o(b){b.preventDefault();var d=a.getOffset(g.__background),c=a.getWidth(g.__background);g.setValue(g.__min+(g.__max-g.__min)*((b.clientX-d.left)/(d.left+c-d.left)));return false}function y(){a.unbind(window,"mousemove",o);a.unbind(window,"mouseup",y);g.__onFinishChange&&g.__onFinishChange.call(g,g.getValue())}b.superclass.call(this,d,c,{min:f,max:e,step:l});var g=this;this.__background=document.createElement("div");
33 | this.__foreground=document.createElement("div");a.bind(this.__background,"mousedown",function(b){a.bind(window,"mousemove",o);a.bind(window,"mouseup",y);o(b)});a.addClass(this.__background,"slider");a.addClass(this.__foreground,"slider-fg");this.updateDisplay();this.__background.appendChild(this.__foreground);this.domElement.appendChild(this.__background)};b.superclass=e;b.useDefaultStyles=function(){c.inject(f)};d.extend(b.prototype,e.prototype,{updateDisplay:function(){this.__foreground.style.width=
34 | (this.getValue()-this.__min)/(this.__max-this.__min)*100+"%";return b.superclass.prototype.updateDisplay.call(this)}});return b}(dat.controllers.NumberController,dat.dom.dom,dat.utils.css,dat.utils.common,".slider {\n box-shadow: inset 0 2px 4px rgba(0,0,0,0.15);\n height: 1em;\n border-radius: 1em;\n background-color: #eee;\n padding: 0 0.5em;\n overflow: hidden;\n}\n\n.slider-fg {\n padding: 1px 0 2px 0;\n background-color: #aaa;\n height: 1em;\n margin-left: -0.5em;\n padding-right: 0.5em;\n border-radius: 1em 0 0 1em;\n}\n\n.slider-fg:after {\n display: inline-block;\n border-radius: 1em;\n background-color: #fff;\n border: 1px solid #aaa;\n content: '';\n float: right;\n margin-right: -1em;\n margin-top: -1px;\n height: 0.9em;\n width: 0.9em;\n}");
35 | dat.controllers.FunctionController=function(e,a,c){var d=function(c,b,e){d.superclass.call(this,c,b);var h=this;this.__button=document.createElement("div");this.__button.innerHTML=e===void 0?"Fire":e;a.bind(this.__button,"click",function(a){a.preventDefault();h.fire();return false});a.addClass(this.__button,"button");this.domElement.appendChild(this.__button)};d.superclass=e;c.extend(d.prototype,e.prototype,{fire:function(){this.__onChange&&this.__onChange.call(this);this.__onFinishChange&&this.__onFinishChange.call(this,
36 | this.getValue());this.getValue().call(this.object)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);
37 | dat.controllers.BooleanController=function(e,a,c){var d=function(c,b){d.superclass.call(this,c,b);var e=this;this.__prev=this.getValue();this.__checkbox=document.createElement("input");this.__checkbox.setAttribute("type","checkbox");a.bind(this.__checkbox,"change",function(){e.setValue(!e.__prev)},false);this.domElement.appendChild(this.__checkbox);this.updateDisplay()};d.superclass=e;c.extend(d.prototype,e.prototype,{setValue:function(a){a=d.superclass.prototype.setValue.call(this,a);this.__onFinishChange&&
38 | this.__onFinishChange.call(this,this.getValue());this.__prev=this.getValue();return a},updateDisplay:function(){this.getValue()===true?(this.__checkbox.setAttribute("checked","checked"),this.__checkbox.checked=true):this.__checkbox.checked=false;return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common);
39 | dat.color.toString=function(e){return function(a){if(a.a==1||e.isUndefined(a.a)){for(a=a.hex.toString(16);a.length<6;)a="0"+a;return"#"+a}else return"rgba("+Math.round(a.r)+","+Math.round(a.g)+","+Math.round(a.b)+","+a.a+")"}}(dat.utils.common);
40 | dat.color.interpret=function(e,a){var c,d,f=[{litmus:a.isString,conversions:{THREE_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9])([A-F0-9])([A-F0-9])$/i);return a===null?false:{space:"HEX",hex:parseInt("0x"+a[1].toString()+a[1].toString()+a[2].toString()+a[2].toString()+a[3].toString()+a[3].toString())}},write:e},SIX_CHAR_HEX:{read:function(a){a=a.match(/^#([A-F0-9]{6})$/i);return a===null?false:{space:"HEX",hex:parseInt("0x"+a[1].toString())}},write:e},CSS_RGB:{read:function(a){a=a.match(/^rgb\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\)/);
41 | return a===null?false:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3])}},write:e},CSS_RGBA:{read:function(a){a=a.match(/^rgba\(\s*(.+)\s*,\s*(.+)\s*,\s*(.+)\s*\,\s*(.+)\s*\)/);return a===null?false:{space:"RGB",r:parseFloat(a[1]),g:parseFloat(a[2]),b:parseFloat(a[3]),a:parseFloat(a[4])}},write:e}}},{litmus:a.isNumber,conversions:{HEX:{read:function(a){return{space:"HEX",hex:a,conversionName:"HEX"}},write:function(a){return a.hex}}}},{litmus:a.isArray,conversions:{RGB_ARRAY:{read:function(a){return a.length!=
42 | 3?false:{space:"RGB",r:a[0],g:a[1],b:a[2]}},write:function(a){return[a.r,a.g,a.b]}},RGBA_ARRAY:{read:function(a){return a.length!=4?false:{space:"RGB",r:a[0],g:a[1],b:a[2],a:a[3]}},write:function(a){return[a.r,a.g,a.b,a.a]}}}},{litmus:a.isObject,conversions:{RGBA_OBJ:{read:function(b){return a.isNumber(b.r)&&a.isNumber(b.g)&&a.isNumber(b.b)&&a.isNumber(b.a)?{space:"RGB",r:b.r,g:b.g,b:b.b,a:b.a}:false},write:function(a){return{r:a.r,g:a.g,b:a.b,a:a.a}}},RGB_OBJ:{read:function(b){return a.isNumber(b.r)&&
43 | a.isNumber(b.g)&&a.isNumber(b.b)?{space:"RGB",r:b.r,g:b.g,b:b.b}:false},write:function(a){return{r:a.r,g:a.g,b:a.b}}},HSVA_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)&&a.isNumber(b.a)?{space:"HSV",h:b.h,s:b.s,v:b.v,a:b.a}:false},write:function(a){return{h:a.h,s:a.s,v:a.v,a:a.a}}},HSV_OBJ:{read:function(b){return a.isNumber(b.h)&&a.isNumber(b.s)&&a.isNumber(b.v)?{space:"HSV",h:b.h,s:b.s,v:b.v}:false},write:function(a){return{h:a.h,s:a.s,v:a.v}}}}}];return function(){d=
44 | false;var b=arguments.length>1?a.toArray(arguments):arguments[0];a.each(f,function(e){if(e.litmus(b))return a.each(e.conversions,function(e,f){c=e.read(b);if(d===false&&c!==false)return d=c,c.conversionName=f,c.conversion=e,a.BREAK}),a.BREAK});return d}}(dat.color.toString,dat.utils.common);
45 | dat.GUI=dat.gui.GUI=function(e,a,c,d,f,b,n,h,j,m,l,o,y,g,i){function q(a,b,r,c){if(b[r]===void 0)throw Error("Object "+b+' has no property "'+r+'"');c.color?b=new l(b,r):(b=[b,r].concat(c.factoryArgs),b=d.apply(a,b));if(c.before instanceof f)c.before=c.before.__li;t(a,b);g.addClass(b.domElement,"c");r=document.createElement("span");g.addClass(r,"property-name");r.innerHTML=b.property;var e=document.createElement("div");e.appendChild(r);e.appendChild(b.domElement);c=s(a,e,c.before);g.addClass(c,k.CLASS_CONTROLLER_ROW);
46 | g.addClass(c,typeof b.getValue());p(a,c,b);a.__controllers.push(b);return b}function s(a,b,d){var c=document.createElement("li");b&&c.appendChild(b);d?a.__ul.insertBefore(c,params.before):a.__ul.appendChild(c);a.onResize();return c}function p(a,d,c){c.__li=d;c.__gui=a;i.extend(c,{options:function(b){if(arguments.length>1)return c.remove(),q(a,c.object,c.property,{before:c.__li.nextElementSibling,factoryArgs:[i.toArray(arguments)]});if(i.isArray(b)||i.isObject(b))return c.remove(),q(a,c.object,c.property,
47 | {before:c.__li.nextElementSibling,factoryArgs:[b]})},name:function(a){c.__li.firstElementChild.firstElementChild.innerHTML=a;return c},listen:function(){c.__gui.listen(c);return c},remove:function(){c.__gui.remove(c);return c}});if(c instanceof j){var e=new h(c.object,c.property,{min:c.__min,max:c.__max,step:c.__step});i.each(["updateDisplay","onChange","onFinishChange"],function(a){var b=c[a],H=e[a];c[a]=e[a]=function(){var a=Array.prototype.slice.call(arguments);b.apply(c,a);return H.apply(e,a)}});
48 | g.addClass(d,"has-slider");c.domElement.insertBefore(e.domElement,c.domElement.firstElementChild)}else if(c instanceof h){var f=function(b){return i.isNumber(c.__min)&&i.isNumber(c.__max)?(c.remove(),q(a,c.object,c.property,{before:c.__li.nextElementSibling,factoryArgs:[c.__min,c.__max,c.__step]})):b};c.min=i.compose(f,c.min);c.max=i.compose(f,c.max)}else if(c instanceof b)g.bind(d,"click",function(){g.fakeEvent(c.__checkbox,"click")}),g.bind(c.__checkbox,"click",function(a){a.stopPropagation()});
49 | else if(c instanceof n)g.bind(d,"click",function(){g.fakeEvent(c.__button,"click")}),g.bind(d,"mouseover",function(){g.addClass(c.__button,"hover")}),g.bind(d,"mouseout",function(){g.removeClass(c.__button,"hover")});else if(c instanceof l)g.addClass(d,"color"),c.updateDisplay=i.compose(function(a){d.style.borderLeftColor=c.__color.toString();return a},c.updateDisplay),c.updateDisplay();c.setValue=i.compose(function(b){a.getRoot().__preset_select&&c.isModified()&&B(a.getRoot(),true);return b},c.setValue)}
50 | function t(a,b){var c=a.getRoot(),d=c.__rememberedObjects.indexOf(b.object);if(d!=-1){var e=c.__rememberedObjectIndecesToControllers[d];e===void 0&&(e={},c.__rememberedObjectIndecesToControllers[d]=e);e[b.property]=b;if(c.load&&c.load.remembered){c=c.load.remembered;if(c[a.preset])c=c[a.preset];else if(c[w])c=c[w];else return;if(c[d]&&c[d][b.property]!==void 0)d=c[d][b.property],b.initialValue=d,b.setValue(d)}}}function I(a){var b=a.__save_row=document.createElement("li");g.addClass(a.domElement,
51 | "has-save");a.__ul.insertBefore(b,a.__ul.firstChild);g.addClass(b,"save-row");var c=document.createElement("span");c.innerHTML=" ";g.addClass(c,"button gears");var d=document.createElement("span");d.innerHTML="Save";g.addClass(d,"button");g.addClass(d,"save");var e=document.createElement("span");e.innerHTML="New";g.addClass(e,"button");g.addClass(e,"save-as");var f=document.createElement("span");f.innerHTML="Revert";g.addClass(f,"button");g.addClass(f,"revert");var m=a.__preset_select=document.createElement("select");
52 | a.load&&a.load.remembered?i.each(a.load.remembered,function(b,c){C(a,c,c==a.preset)}):C(a,w,false);g.bind(m,"change",function(){for(var b=0;b0){a.preset=this.preset;if(!a.remembered)a.remembered={};a.remembered[this.preset]=z(this)}a.folders={};i.each(this.__folders,function(b,
69 | c){a.folders[c]=b.getSaveObject()});return a},save:function(){if(!this.load.remembered)this.load.remembered={};this.load.remembered[this.preset]=z(this);B(this,false)},saveAs:function(a){if(!this.load.remembered)this.load.remembered={},this.load.remembered[w]=z(this,true);this.load.remembered[a]=z(this);this.preset=a;C(this,a,true)},revert:function(a){i.each(this.__controllers,function(b){this.getRoot().load.remembered?t(a||this.getRoot(),b):b.setValue(b.initialValue)},this);i.each(this.__folders,
70 | function(a){a.revert(a)});a||B(this.getRoot(),false)},listen:function(a){var b=this.__listening.length==0;this.__listening.push(a);b&&E(this.__listening)}});return k}(dat.utils.css,'\n\n Here\'s the new load parameter for your
GUI\'s constructor:\n\n
\n\n
\n\n
Automatically save\n values to
localStorage on exit.\n\n
The values saved to localStorage will\n override those passed to dat.GUI\'s constructor. This makes it\n easier to work incrementally, but localStorage is fragile,\n and your friends may not see the same values you do.\n \n
\n \n
\n\n
',
71 | ".dg ul{list-style:none;margin:0;padding:0;width:100%;clear:both}.dg.ac{position:fixed;top:0;left:0;right:0;height:0;z-index:0}.dg:not(.ac) .main{overflow:hidden}.dg.main{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear}.dg.main.taller-than-window{overflow-y:auto}.dg.main.taller-than-window .close-button{opacity:1;margin-top:-1px;border-top:1px solid #2c2c2c}.dg.main ul.closed .close-button{opacity:1 !important}.dg.main:hover .close-button,.dg.main .close-button.drag{opacity:1}.dg.main .close-button{-webkit-transition:opacity 0.1s linear;-o-transition:opacity 0.1s linear;-moz-transition:opacity 0.1s linear;transition:opacity 0.1s linear;border:0;position:absolute;line-height:19px;height:20px;cursor:pointer;text-align:center;background-color:#000}.dg.main .close-button:hover{background-color:#111}.dg.a{float:right;margin-right:15px;overflow-x:hidden}.dg.a.has-save ul{margin-top:27px}.dg.a.has-save ul.closed{margin-top:0}.dg.a .save-row{position:fixed;top:0;z-index:1002}.dg li{-webkit-transition:height 0.1s ease-out;-o-transition:height 0.1s ease-out;-moz-transition:height 0.1s ease-out;transition:height 0.1s ease-out}.dg li:not(.folder){cursor:auto;height:27px;line-height:27px;overflow:hidden;padding:0 4px 0 5px}.dg li.folder{padding:0;border-left:4px solid rgba(0,0,0,0)}.dg li.title{cursor:pointer;margin-left:-4px}.dg .closed li:not(.title),.dg .closed ul li,.dg .closed ul li > *{height:0;overflow:hidden;border:0}.dg .cr{clear:both;padding-left:3px;height:27px}.dg .property-name{cursor:default;float:left;clear:left;width:40%;overflow:hidden;text-overflow:ellipsis}.dg .c{float:left;width:60%}.dg .c input[type=text]{border:0;margin-top:4px;padding:3px;width:100%;float:right}.dg .has-slider input[type=text]{width:30%;margin-left:0}.dg .slider{float:left;width:66%;margin-left:-5px;margin-right:0;height:19px;margin-top:4px}.dg .slider-fg{height:100%}.dg .c input[type=checkbox]{margin-top:9px}.dg .c select{margin-top:5px}.dg .cr.function,.dg .cr.function .property-name,.dg .cr.function *,.dg .cr.boolean,.dg .cr.boolean *{cursor:pointer}.dg .selector{display:none;position:absolute;margin-left:-9px;margin-top:23px;z-index:10}.dg .c:hover .selector,.dg .selector.drag{display:block}.dg li.save-row{padding:0}.dg li.save-row .button{display:inline-block;padding:0px 6px}.dg.dialogue{background-color:#222;width:460px;padding:15px;font-size:13px;line-height:15px}#dg-new-constructor{padding:10px;color:#222;font-family:Monaco, monospace;font-size:10px;border:0;resize:none;box-shadow:inset 1px 1px 1px #888;word-wrap:break-word;margin:12px 0;display:block;width:440px;overflow-y:scroll;height:100px;position:relative}#dg-local-explain{display:none;font-size:11px;line-height:17px;border-radius:3px;background-color:#333;padding:8px;margin-top:10px}#dg-local-explain code{font-size:10px}#dat-gui-save-locally{display:none}.dg{color:#eee;font:11px 'Lucida Grande', sans-serif;text-shadow:0 -1px 0 #111}.dg.main::-webkit-scrollbar{width:5px;background:#1a1a1a}.dg.main::-webkit-scrollbar-corner{height:0;display:none}.dg.main::-webkit-scrollbar-thumb{border-radius:5px;background:#676767}.dg li:not(.folder){background:#1a1a1a;border-bottom:1px solid #2c2c2c}.dg li.save-row{line-height:25px;background:#dad5cb;border:0}.dg li.save-row select{margin-left:5px;width:108px}.dg li.save-row .button{margin-left:5px;margin-top:1px;border-radius:2px;font-size:9px;line-height:7px;padding:4px 4px 5px 4px;background:#c5bdad;color:#fff;text-shadow:0 1px 0 #b0a58f;box-shadow:0 -1px 0 #b0a58f;cursor:pointer}.dg li.save-row .button.gears{background:#c5bdad url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAANCAYAAAB/9ZQ7AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAQJJREFUeNpiYKAU/P//PwGIC/ApCABiBSAW+I8AClAcgKxQ4T9hoMAEUrxx2QSGN6+egDX+/vWT4e7N82AMYoPAx/evwWoYoSYbACX2s7KxCxzcsezDh3evFoDEBYTEEqycggWAzA9AuUSQQgeYPa9fPv6/YWm/Acx5IPb7ty/fw+QZblw67vDs8R0YHyQhgObx+yAJkBqmG5dPPDh1aPOGR/eugW0G4vlIoTIfyFcA+QekhhHJhPdQxbiAIguMBTQZrPD7108M6roWYDFQiIAAv6Aow/1bFwXgis+f2LUAynwoIaNcz8XNx3Dl7MEJUDGQpx9gtQ8YCueB+D26OECAAQDadt7e46D42QAAAABJRU5ErkJggg==) 2px 1px no-repeat;height:7px;width:8px}.dg li.save-row .button:hover{background-color:#bab19e;box-shadow:0 -1px 0 #b0a58f}.dg li.folder{border-bottom:0}.dg li.title{padding-left:16px;background:#000 url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlI+hKgFxoCgAOw==) 6px 10px no-repeat;cursor:pointer;border-bottom:1px solid rgba(255,255,255,0.2)}.dg .closed li.title{background-image:url(data:image/gif;base64,R0lGODlhBQAFAJEAAP////Pz8////////yH5BAEAAAIALAAAAAAFAAUAAAIIlGIWqMCbWAEAOw==)}.dg .cr.boolean{border-left:3px solid #806787}.dg .cr.function{border-left:3px solid #e61d5f}.dg .cr.number{border-left:3px solid #2fa1d6}.dg .cr.number input[type=text]{color:#2fa1d6}.dg .cr.string{border-left:3px solid #1ed36f}.dg .cr.string input[type=text]{color:#1ed36f}.dg .cr.function:hover,.dg .cr.boolean:hover{background:#111}.dg .c input[type=text]{background:#303030;outline:none}.dg .c input[type=text]:hover{background:#3c3c3c}.dg .c input[type=text]:focus{background:#494949;color:#fff}.dg .c .slider{background:#303030;cursor:ew-resize}.dg .c .slider-fg{background:#2fa1d6}.dg .c .slider:hover{background:#3c3c3c}.dg .c .slider:hover .slider-fg{background:#44abda}\n",
72 | dat.controllers.factory=function(e,a,c,d,f,b,n){return function(h,j,m,l){var o=h[j];if(n.isArray(m)||n.isObject(m))return new e(h,j,m);if(n.isNumber(o))return n.isNumber(m)&&n.isNumber(l)?new c(h,j,m,l):new a(h,j,{min:m,max:l});if(n.isString(o))return new d(h,j);if(n.isFunction(o))return new f(h,j,"");if(n.isBoolean(o))return new b(h,j)}}(dat.controllers.OptionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.StringController=function(e,a,c){var d=
73 | function(c,b){function e(){h.setValue(h.__input.value)}d.superclass.call(this,c,b);var h=this;this.__input=document.createElement("input");this.__input.setAttribute("type","text");a.bind(this.__input,"keyup",e);a.bind(this.__input,"change",e);a.bind(this.__input,"blur",function(){h.__onFinishChange&&h.__onFinishChange.call(h,h.getValue())});a.bind(this.__input,"keydown",function(a){a.keyCode===13&&this.blur()});this.updateDisplay();this.domElement.appendChild(this.__input)};d.superclass=e;c.extend(d.prototype,
74 | e.prototype,{updateDisplay:function(){if(!a.isActive(this.__input))this.__input.value=this.getValue();return d.superclass.prototype.updateDisplay.call(this)}});return d}(dat.controllers.Controller,dat.dom.dom,dat.utils.common),dat.controllers.FunctionController,dat.controllers.BooleanController,dat.utils.common),dat.controllers.Controller,dat.controllers.BooleanController,dat.controllers.FunctionController,dat.controllers.NumberControllerBox,dat.controllers.NumberControllerSlider,dat.controllers.OptionController,
75 | dat.controllers.ColorController=function(e,a,c,d,f){function b(a,b,c,d){a.style.background="";f.each(j,function(e){a.style.cssText+="background: "+e+"linear-gradient("+b+", "+c+" 0%, "+d+" 100%); "})}function n(a){a.style.background="";a.style.cssText+="background: -moz-linear-gradient(top, #ff0000 0%, #ff00ff 17%, #0000ff 34%, #00ffff 50%, #00ff00 67%, #ffff00 84%, #ff0000 100%);";a.style.cssText+="background: -webkit-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";
76 | a.style.cssText+="background: -o-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: -ms-linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);";a.style.cssText+="background: linear-gradient(top, #ff0000 0%,#ff00ff 17%,#0000ff 34%,#00ffff 50%,#00ff00 67%,#ffff00 84%,#ff0000 100%);"}var h=function(e,l){function o(b){q(b);a.bind(window,"mousemove",q);a.bind(window,
77 | "mouseup",j)}function j(){a.unbind(window,"mousemove",q);a.unbind(window,"mouseup",j)}function g(){var a=d(this.value);a!==false?(p.__color.__state=a,p.setValue(p.__color.toOriginal())):this.value=p.__color.toString()}function i(){a.unbind(window,"mousemove",s);a.unbind(window,"mouseup",i)}function q(b){b.preventDefault();var c=a.getWidth(p.__saturation_field),d=a.getOffset(p.__saturation_field),e=(b.clientX-d.left+document.body.scrollLeft)/c,b=1-(b.clientY-d.top+document.body.scrollTop)/c;b>1?b=
78 | 1:b<0&&(b=0);e>1?e=1:e<0&&(e=0);p.__color.v=b;p.__color.s=e;p.setValue(p.__color.toOriginal());return false}function s(b){b.preventDefault();var c=a.getHeight(p.__hue_field),d=a.getOffset(p.__hue_field),b=1-(b.clientY-d.top+document.body.scrollTop)/c;b>1?b=1:b<0&&(b=0);p.__color.h=b*360;p.setValue(p.__color.toOriginal());return false}h.superclass.call(this,e,l);this.__color=new c(this.getValue());this.__temp=new c(0);var p=this;this.domElement=document.createElement("div");a.makeSelectable(this.domElement,
79 | false);this.__selector=document.createElement("div");this.__selector.className="selector";this.__saturation_field=document.createElement("div");this.__saturation_field.className="saturation-field";this.__field_knob=document.createElement("div");this.__field_knob.className="field-knob";this.__field_knob_border="2px solid ";this.__hue_knob=document.createElement("div");this.__hue_knob.className="hue-knob";this.__hue_field=document.createElement("div");this.__hue_field.className="hue-field";this.__input=
80 | document.createElement("input");this.__input.type="text";this.__input_textShadow="0 1px 1px ";a.bind(this.__input,"keydown",function(a){a.keyCode===13&&g.call(this)});a.bind(this.__input,"blur",g);a.bind(this.__selector,"mousedown",function(){a.addClass(this,"drag").bind(window,"mouseup",function(){a.removeClass(p.__selector,"drag")})});var t=document.createElement("div");f.extend(this.__selector.style,{width:"122px",height:"102px",padding:"3px",backgroundColor:"#222",boxShadow:"0px 1px 3px rgba(0,0,0,0.3)"});
81 | f.extend(this.__field_knob.style,{position:"absolute",width:"12px",height:"12px",border:this.__field_knob_border+(this.__color.v<0.5?"#fff":"#000"),boxShadow:"0px 1px 3px rgba(0,0,0,0.5)",borderRadius:"12px",zIndex:1});f.extend(this.__hue_knob.style,{position:"absolute",width:"15px",height:"2px",borderRight:"4px solid #fff",zIndex:1});f.extend(this.__saturation_field.style,{width:"100px",height:"100px",border:"1px solid #555",marginRight:"3px",display:"inline-block",cursor:"pointer"});f.extend(t.style,
82 | {width:"100%",height:"100%",background:"none"});b(t,"top","rgba(0,0,0,0)","#000");f.extend(this.__hue_field.style,{width:"15px",height:"100px",display:"inline-block",border:"1px solid #555",cursor:"ns-resize"});n(this.__hue_field);f.extend(this.__input.style,{outline:"none",textAlign:"center",color:"#fff",border:0,fontWeight:"bold",textShadow:this.__input_textShadow+"rgba(0,0,0,0.7)"});a.bind(this.__saturation_field,"mousedown",o);a.bind(this.__field_knob,"mousedown",o);a.bind(this.__hue_field,"mousedown",
83 | function(b){s(b);a.bind(window,"mousemove",s);a.bind(window,"mouseup",i)});this.__saturation_field.appendChild(t);this.__selector.appendChild(this.__field_knob);this.__selector.appendChild(this.__saturation_field);this.__selector.appendChild(this.__hue_field);this.__hue_field.appendChild(this.__hue_knob);this.domElement.appendChild(this.__input);this.domElement.appendChild(this.__selector);this.updateDisplay()};h.superclass=e;f.extend(h.prototype,e.prototype,{updateDisplay:function(){var a=d(this.getValue());
84 | if(a!==false){var e=false;f.each(c.COMPONENTS,function(b){if(!f.isUndefined(a[b])&&!f.isUndefined(this.__color.__state[b])&&a[b]!==this.__color.__state[b])return e=true,{}},this);e&&f.extend(this.__color.__state,a)}f.extend(this.__temp.__state,this.__color.__state);this.__temp.a=1;var h=this.__color.v<0.5||this.__color.s>0.5?255:0,j=255-h;f.extend(this.__field_knob.style,{marginLeft:100*this.__color.s-7+"px",marginTop:100*(1-this.__color.v)-7+"px",backgroundColor:this.__temp.toString(),border:this.__field_knob_border+
85 | "rgb("+h+","+h+","+h+")"});this.__hue_knob.style.marginTop=(1-this.__color.h/360)*100+"px";this.__temp.s=1;this.__temp.v=1;b(this.__saturation_field,"left","#fff",this.__temp.toString());f.extend(this.__input.style,{backgroundColor:this.__input.value=this.__color.toString(),color:"rgb("+h+","+h+","+h+")",textShadow:this.__input_textShadow+"rgba("+j+","+j+","+j+",.7)"})}});var j=["-moz-","-o-","-webkit-","-ms-",""];return h}(dat.controllers.Controller,dat.dom.dom,dat.color.Color=function(e,a,c,d){function f(a,
86 | b,c){Object.defineProperty(a,b,{get:function(){if(this.__state.space==="RGB")return this.__state[b];n(this,b,c);return this.__state[b]},set:function(a){if(this.__state.space!=="RGB")n(this,b,c),this.__state.space="RGB";this.__state[b]=a}})}function b(a,b){Object.defineProperty(a,b,{get:function(){if(this.__state.space==="HSV")return this.__state[b];h(this);return this.__state[b]},set:function(a){if(this.__state.space!=="HSV")h(this),this.__state.space="HSV";this.__state[b]=a}})}function n(b,c,e){if(b.__state.space===
87 | "HEX")b.__state[c]=a.component_from_hex(b.__state.hex,e);else if(b.__state.space==="HSV")d.extend(b.__state,a.hsv_to_rgb(b.__state.h,b.__state.s,b.__state.v));else throw"Corrupted color state";}function h(b){var c=a.rgb_to_hsv(b.r,b.g,b.b);d.extend(b.__state,{s:c.s,v:c.v});if(d.isNaN(c.h)){if(d.isUndefined(b.__state.h))b.__state.h=0}else b.__state.h=c.h}var j=function(){this.__state=e.apply(this,arguments);if(this.__state===false)throw"Failed to interpret color arguments";this.__state.a=this.__state.a||
88 | 1};j.COMPONENTS="r,g,b,h,s,v,hex,a".split(",");d.extend(j.prototype,{toString:function(){return c(this)},toOriginal:function(){return this.__state.conversion.write(this)}});f(j.prototype,"r",2);f(j.prototype,"g",1);f(j.prototype,"b",0);b(j.prototype,"h");b(j.prototype,"s");b(j.prototype,"v");Object.defineProperty(j.prototype,"a",{get:function(){return this.__state.a},set:function(a){this.__state.a=a}});Object.defineProperty(j.prototype,"hex",{get:function(){if(!this.__state.space!=="HEX")this.__state.hex=
89 | a.rgb_to_hex(this.r,this.g,this.b);return this.__state.hex},set:function(a){this.__state.space="HEX";this.__state.hex=a}});return j}(dat.color.interpret,dat.color.math=function(){var e;return{hsv_to_rgb:function(a,c,d){var e=a/60-Math.floor(a/60),b=d*(1-c),n=d*(1-e*c),c=d*(1-(1-e)*c),a=[[d,c,b],[n,d,b],[b,d,c],[b,n,d],[c,b,d],[d,b,n]][Math.floor(a/60)%6];return{r:a[0]*255,g:a[1]*255,b:a[2]*255}},rgb_to_hsv:function(a,c,d){var e=Math.min(a,c,d),b=Math.max(a,c,d),e=b-e;if(b==0)return{h:NaN,s:0,v:0};
90 | a=a==b?(c-d)/e:c==b?2+(d-a)/e:4+(a-c)/e;a/=6;a<0&&(a+=1);return{h:a*360,s:e/b,v:b/255}},rgb_to_hex:function(a,c,d){a=this.hex_with_component(0,2,a);a=this.hex_with_component(a,1,c);return a=this.hex_with_component(a,0,d)},component_from_hex:function(a,c){return a>>c*8&255},hex_with_component:function(a,c,d){return d<<(e=c*8)|a&~(255<c._times.length)return-1;null==a&&(a=c.getFPS()|0);a=Math.min(c._times.length-1,a);return 1E3/((c._times[0]-c._times[a])/a)};c.setPaused=function(a){c._paused=a};c.getPaused=function(){return c._paused};c.getTime=function(a){return c._getTime()-c._startTime-(a?c._pausedTime:0)};c.getTicks=function(a){return c._ticks-(a?
19 | c._pausedTicks:0)};c._handleAF=function(){c._rafActive=!1;c._setupTick();c._getTime()-c._lastTime>=0.97*(c._interval-1)&&c._tick()};c._handleTimeout=function(){c.timeoutID=null;c._setupTick();c._tick()};c._setupTick=function(){if(!(c._rafActive||null!=c.timeoutID)){if(c.useRAF){var a=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame;if(a){a(c._handleAF);c._rafActive=!0;return}}c.timeoutID=
20 | setTimeout(c._handleTimeout,c._interval)}};c._tick=function(){var a=c._getTime();c._ticks++;var m=a-c._lastTime,b=c._paused;b&&(c._pausedTicks++,c._pausedTime+=m);c._lastTime=a;for(var d=c._pauseable,e=c._listeners.slice(),f=e?e.length:0,h=0;hthis.a&&0<=this.d&&(a.rotation+=0>=a.rotation?180:-180),a.skewX=a.skewY=
30 | 0):(a.skewX=b/c.DEG_TO_RAD,a.skewY=g/c.DEG_TO_RAD);return a};b.reinitialize=function(a,b,g,d,c,f,h,k,j){this.initialize(a,b,g,d,c,f);this.alpha=h||1;this.shadow=k;this.compositeOperation=j;return this};b.appendProperties=function(a,b,g){this.alpha*=a;this.shadow=b||this.shadow;this.compositeOperation=g||this.compositeOperation;return this};b.prependProperties=function(a,b,g){this.alpha*=a;this.shadow=this.shadow||b;this.compositeOperation=this.compositeOperation||g;return this};b.clone=function(){var a=
31 | new c(this.a,this.b,this.c,this.d,this.tx,this.ty);a.shadow=this.shadow;a.alpha=this.alpha;a.compositeOperation=this.compositeOperation;return a};b.toString=function(){return"[Matrix2D (a="+this.a+" b="+this.b+" c="+this.c+" d="+this.d+" tx="+this.tx+" ty="+this.ty+")]"};c.identity=new c(1,0,0,1,0,0);createjs.Matrix2D=c})();this.createjs=this.createjs||{};(function(){var c=function(a,b){this.initialize(a,b)},b=c.prototype;b.x=0;b.y=0;b.initialize=function(a,b){this.x=null==a?0:a;this.y=null==b?0:b};b.clone=function(){return new c(this.x,this.y)};b.toString=function(){return"[Point (x="+this.x+" y="+this.y+")]"};createjs.Point=c})();this.createjs=this.createjs||{};(function(){var c=function(a,b,g,d){this.initialize(a,b,g,d)},b=c.prototype;b.x=0;b.y=0;b.width=0;b.height=0;b.initialize=function(a,b,g,d){this.x=null==a?0:a;this.y=null==b?0:b;this.width=null==g?0:g;this.height=null==d?0:d};b.clone=function(){return new c(this.x,this.y,this.width,this.height)};b.toString=function(){return"[Rectangle (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+")]"};createjs.Rectangle=c})();this.createjs=this.createjs||{};
32 | (function(){var c=function(a,b,g,d,c,f,h){this.initialize(a,b,g,d,c,f,h)},b=c.prototype;b.target=null;b.overLabel=null;b.outLabel=null;b.downLabel=null;b.play=!1;b._isPressed=!1;b._isOver=!1;b.initialize=function(a,b,g,d,c,f,h){a.addEventListener&&(this.target=a,a.cursor="pointer",this.overLabel=null==g?"over":g,this.outLabel=null==b?"out":b,this.downLabel=null==d?"down":d,this.play=c,this.setEnabled(!0),this.handleEvent({}),f&&(h&&(f.actionsEnabled=!1,f.gotoAndStop&&f.gotoAndStop(h)),a.hitArea=f))};
33 | b.setEnabled=function(a){var b=this.target;a?(b.addEventListener("mouseover",this),b.addEventListener("mouseout",this),b.addEventListener("mousedown",this)):(b.removeEventListener("mouseover",this),b.removeEventListener("mouseout",this),b.removeEventListener("mousedown",this))};b.toString=function(){return"[ButtonHelper]"};b.handleEvent=function(a){var b=this.target,g=a.type;"mousedown"==g?(a.addEventListener("mouseup",this),this._isPressed=!0,a=this.downLabel):"mouseup"==g?(this._isPressed=!1,a=
34 | this._isOver?this.overLabel:this.outLabel):"mouseover"==g?(this._isOver=!0,a=this._isPressed?this.downLabel:this.overLabel):(this._isOver=!1,a=this._isPressed?this.overLabel:this.outLabel);this.play?b.gotoAndPlay&&b.gotoAndPlay(a):b.gotoAndStop&&b.gotoAndStop(a)};createjs.ButtonHelper=c})();this.createjs=this.createjs||{};(function(){var c=function(a,b,g,d){this.initialize(a,b,g,d)},b=c.prototype;c.identity=null;b.color=null;b.offsetX=0;b.offsetY=0;b.blur=0;b.initialize=function(a,b,g,d){this.color=a;this.offsetX=b;this.offsetY=g;this.blur=d};b.toString=function(){return"[Shadow]"};b.clone=function(){return new c(this.color,this.offsetX,this.offsetY,this.blur)};c.identity=new c("transparent",0,0,0);createjs.Shadow=c})();this.createjs=this.createjs||{};
35 | (function(){var c=function(a){this.initialize(a)},b=c.prototype;b.complete=!0;b.onComplete=null;b.addEventListener=null;b.removeEventListener=null;b.removeAllEventListeners=null;b.dispatchEvent=null;b.hasEventListener=null;b._listeners=null;createjs.EventDispatcher.initialize(b);b._animations=null;b._frames=null;b._images=null;b._data=null;b._loadCount=0;b._frameHeight=0;b._frameWidth=0;b._numFrames=0;b._regX=0;b._regY=0;b.initialize=function(a){var b,g,d;if(null!=a){if(a.images&&0<(g=a.images.length)){d=
36 | this._images=[];for(b=0;bd.length||!1==a.next?null:null==a.next||!0==a.next?h:a.next;a.frequency||(a.frequency=1);this._animations.push(h);this._data[h]=a}}}};b.getNumFrames=function(a){if(null==a)return this._frames?this._frames.length:this._numFrames;a=this._data[a];return null==a?0:a.frames.length};b.getAnimations=function(){return this._animations.slice(0)};b.getAnimation=function(a){return this._data[a]};b.getFrame=function(a){var b;return this.complete&&this._frames&&(b=this._frames[a])?b:null};
39 | b.getFrameBounds=function(a){return(a=this.getFrame(a))?new createjs.Rectangle(-a.regX,-a.regY,a.rect.width,a.rect.height):null};b.toString=function(){return"[SpriteSheet]"};b.clone=function(){var a=new c;a.complete=this.complete;a._animations=this._animations;a._frames=this._frames;a._images=this._images;a._data=this._data;a._frameHeight=this._frameHeight;a._frameWidth=this._frameWidth;a._numFrames=this._numFrames;a._loadCount=this._loadCount;return a};b._handleImageLoad=function(){0==--this._loadCount&&
40 | (this._calculateFrames(),this.complete=!0,this.onComplete&&this.onComplete(),this.dispatchEvent("complete"))};b._calculateFrames=function(){if(!(this._frames||0==this._frameWidth)){this._frames=[];for(var a=0,b=this._frameWidth,g=this._frameHeight,d=0,c=this._images;d>8&255,a=a>>16&255);return null==c?"rgb("+a+","+b+","+d+")":"rgba("+a+","+b+","+d+","+c+")"};b.getHSL=function(a,b,d,c){return null==c?"hsl("+a%360+","+b+"%,"+d+"%)":"hsla("+a%360+","+b+"%,"+d+"%,"+c+")"};b.BASE_64={A:0,B:1,C:2,D:3,E:4,F:5,G:6,H:7,I:8,J:9,
43 | K:10,L:11,M:12,N:13,O:14,P:15,Q:16,R:17,S:18,T:19,U:20,V:21,W:22,X:23,Y:24,Z:25,a:26,b:27,c:28,d:29,e:30,f:31,g:32,h:33,i:34,j:35,k:36,l:37,m:38,n:39,o:40,p:41,q:42,r:43,s:44,t:45,u:46,v:47,w:48,x:49,y:50,z:51,"0":52,1:53,2:54,3:55,4:56,5:57,6:58,7:59,8:60,9:61,"+":62,"/":63};b.STROKE_CAPS_MAP=["butt","round","square"];b.STROKE_JOINTS_MAP=["miter","round","bevel"];b._ctx=(createjs.createCanvas?createjs.createCanvas():document.createElement("canvas")).getContext("2d");b.beginCmd=new c(b._ctx.beginPath,
44 | [],!1);b.fillCmd=new c(b._ctx.fill,[],!1);b.strokeCmd=new c(b._ctx.stroke,[],!1);a._strokeInstructions=null;a._strokeStyleInstructions=null;a._ignoreScaleStroke=!1;a._fillInstructions=null;a._instructions=null;a._oldInstructions=null;a._activeInstructions=null;a._active=!1;a._dirty=!1;a.initialize=function(){this.clear();this._ctx=b._ctx};a.isEmpty=function(){return!(this._instructions.length||this._oldInstructions.length||this._activeInstructions.length)};a.draw=function(a){this._dirty&&this._updateInstructions();
45 | for(var b=this._instructions,d=0,c=b.length;df&&(f*=n=-1);f>l&&(f=l);0>h&&(h*=q=-1);h>l&&(h=l);0>k&&(k*=p=-1);k>l&&(k=l);0>j&&(j*=s=-1);j>l&&(j=l);this._dirty=this._active=!0;var l=this._ctx.arcTo,r=this._ctx.lineTo;this._activeInstructions.push(new c(this._ctx.moveTo,[a+d-h,b]),new c(l,[a+d+h*q,b-h*q,a+d,b+h,h]),new c(r,[a+d,b+e-k]),new c(l,[a+d+k*p,b+e+k*p,a+d-k,b+e,k]),new c(r,[a+j,b+e]),new c(l,[a-j*s,b+e+j*s,a,b+e-j,j]),new c(r,[a,b+f]),new c(l,[a-f*n,b-f*n,a+f,b,f]),new c(this._ctx.closePath));return this};a.drawCircle=
54 | function(a,b,d){this.arc(a,b,d,0,2*Math.PI);return this};a.drawEllipse=function(a,b,d,e){this._dirty=this._active=!0;var f=0.5522848*(d/2),h=0.5522848*(e/2),k=a+d,j=b+e;d=a+d/2;e=b+e/2;this._activeInstructions.push(new c(this._ctx.moveTo,[a,e]),new c(this._ctx.bezierCurveTo,[a,e-h,d-f,b,d,b]),new c(this._ctx.bezierCurveTo,[d+f,b,k,e-h,k,e]),new c(this._ctx.bezierCurveTo,[k,e+h,d+f,j,d,j]),new c(this._ctx.bezierCurveTo,[d-f,j,a,e+h,a,e]));return this};a.drawPolyStar=function(a,b,d,e,f,h){this._dirty=
55 | this._active=!0;null==f&&(f=0);f=1-f;h=null==h?0:h/(180/Math.PI);var k=Math.PI/e;this._activeInstructions.push(new c(this._ctx.moveTo,[a+Math.cos(h)*d,b+Math.sin(h)*d]));for(var j=0;j>3,s=g[p];if(!s||q&3)throw"bad path data (@"+c+"): "+n;n=d[p];p||(k=j=0);h.length=0;c++;q=(q>>2&1)+2;for(p=0;p>5?-1:1,r=(r&31)<<6|l[a.charAt(c+1)];3==q&&(r=r<<6|l[a.charAt(c+2)]);r=u*r/10;p%2?k=r+=k:j=r+=j;h[p]=r;c+=q}s.apply(this,h)}return this};a.clone=function(){var a=new b;a._instructions=this._instructions.slice();a._activeInstructions=this._activeInstructions.slice();
57 | a._oldInstructions=this._oldInstructions.slice();this._fillInstructions&&(a._fillInstructions=this._fillInstructions.slice());this._strokeInstructions&&(a._strokeInstructions=this._strokeInstructions.slice());this._strokeStyleInstructions&&(a._strokeStyleInstructions=this._strokeStyleInstructions.slice());a._active=this._active;a._dirty=this._dirty;return a};a.toString=function(){return"[Graphics]"};a.mt=a.moveTo;a.lt=a.lineTo;a.at=a.arcTo;a.bt=a.bezierCurveTo;a.qt=a.quadraticCurveTo;a.a=a.arc;a.r=
58 | a.rect;a.cp=a.closePath;a.c=a.clear;a.f=a.beginFill;a.lf=a.beginLinearGradientFill;a.rf=a.beginRadialGradientFill;a.bf=a.beginBitmapFill;a.ef=a.endFill;a.ss=a.setStrokeStyle;a.s=a.beginStroke;a.ls=a.beginLinearGradientStroke;a.rs=a.beginRadialGradientStroke;a.bs=a.beginBitmapStroke;a.es=a.endStroke;a.dr=a.drawRect;a.rr=a.drawRoundRect;a.rc=a.drawRoundRectComplex;a.dc=a.drawCircle;a.de=a.drawEllipse;a.dp=a.drawPolyStar;a.p=a.decodePath;a._updateInstructions=function(){this._instructions=this._oldInstructions.slice();
59 | this._instructions.push(b.beginCmd);this._instructions.push.apply(this._instructions,this._activeInstructions);this._fillInstructions&&this._instructions.push.apply(this._instructions,this._fillInstructions);this._strokeInstructions&&(this._strokeStyleInstructions&&this._instructions.push.apply(this._instructions,this._strokeStyleInstructions),this._instructions.push.apply(this._instructions,this._strokeInstructions),this._ignoreScaleStroke?this._instructions.push(new c(this._ctx.save,[],!1),new c(this._ctx.setTransform,
60 | [1,0,0,1,0,0],!1),b.strokeCmd,new c(this._ctx.restore,[],!1)):this._instructions.push(b.strokeCmd))};a._newPath=function(){this._dirty&&this._updateInstructions();this._oldInstructions=this._instructions;this._activeInstructions=[];this._active=this._dirty=!1};a._setProp=function(a,b){this[a]=b};createjs.Graphics=b})();this.createjs=this.createjs||{};
61 | (function(){var c=function(){this.initialize()},b=c.prototype;c.suppressCrossDomainErrors=!1;c._hitTestCanvas=createjs.createCanvas?createjs.createCanvas():document.createElement("canvas");c._hitTestCanvas.width=c._hitTestCanvas.height=1;c._hitTestContext=c._hitTestCanvas.getContext("2d");c._nextCacheID=1;b.alpha=1;b.cacheCanvas=null;b.id=-1;b.mouseEnabled=!0;b.name=null;b.parent=null;b.regX=0;b.regY=0;b.rotation=0;b.scaleX=1;b.scaleY=1;b.skewX=0;b.skewY=0;b.shadow=null;b.visible=!0;b.x=0;b.y=0;b.compositeOperation=
62 | null;b.snapToPixel=!1;b.onPress=null;b.onClick=null;b.onDoubleClick=null;b.onMouseOver=null;b.onMouseOut=null;b.onTick=null;b.filters=null;b.cacheID=0;b.mask=null;b.hitArea=null;b.cursor=null;b.addEventListener=null;b.removeEventListener=null;b.removeAllEventListeners=null;b.dispatchEvent=null;b.hasEventListener=null;b._listeners=null;createjs.EventDispatcher.initialize(b);b._cacheOffsetX=0;b._cacheOffsetY=0;b._cacheScale=1;b._cacheDataURLID=0;b._cacheDataURL=null;b._matrix=null;b.initialize=function(){this.id=
63 | createjs.UID.get();this._matrix=new createjs.Matrix2D};b.isVisible=function(){return!(!this.visible||!(0d||d>this.children.length)return arguments[c-2];if(2a||a>this.children.length-
77 | 1)return!1;if(b=this.children[a])b.parent=null;this.children.splice(a,1);return!0};b.removeAllChildren=function(){for(var a=this.children;a.length;)a.pop().parent=null};b.getChildAt=function(a){return this.children[a]};b.getChildByName=function(a){for(var b=this.children,c=0,d=b.length;cb||b>=d)){for(var e=0;e=a)return;var b=this;this._mouseOverIntervalID=setInterval(function(){b._testMouseOver()},1E3/Math.min(50,a))};b.enableDOMEvents=function(a){null==a&&(a=!0);var b,c=this._eventListeners;if(!a&&c){for(b in c)a=c[b],a.t.removeEventListener(b,a.f);this._eventListeners=null}else if(a&&!c&&this.canvas){a=window.addEventListener?window:document;var d=this,c=this._eventListeners={};c.mouseup={t:a,f:function(a){d._handleMouseUp(a)}};
87 | c.mousemove={t:a,f:function(a){d._handleMouseMove(a)}};c.dblclick={t:a,f:function(a){d._handleDoubleClick(a)}};c.mousedown={t:this.canvas,f:function(a){d._handleMouseDown(a)}};for(b in c)a=c[b],a.t.addEventListener(b,a.f)}};b.clone=function(){var a=new c(null);this.cloneProps(a);return a};b.toString=function(){return"[Stage (name="+this.name+")]"};b._getPointerData=function(a){var b=this._pointerData[a];if(!b&&(b=this._pointerData[a]={x:0,y:0},null==this._primaryPointerID||-1==this._primaryPointerID))this._primaryPointerID=
88 | a;return b};b._handleMouseMove=function(a){a||(a=window.event);this._handlePointerMove(-1,a,a.pageX,a.pageY)};b._handlePointerMove=function(a,b,c,d){if(this.canvas){var e=this._getPointerData(a),f=e.inBounds;this._updatePointerPosition(a,c,d);if(f||e.inBounds||this.mouseMoveOutside){if(this.onMouseMove||this.hasEventListener("stagemousemove"))c=new createjs.MouseEvent("stagemousemove",e.x,e.y,this,b,a,a==this._primaryPointerID,e.rawX,e.rawY),this.onMouseMove&&this.onMouseMove(c),this.dispatchEvent(c);
89 | if((d=e.event)&&(d.onMouseMove||d.hasEventListener("mousemove")))c=new createjs.MouseEvent("mousemove",e.x,e.y,d.target,b,a,a==this._primaryPointerID,e.rawX,e.rawY),d.onMouseMove&&d.onMouseMove(c),d.dispatchEvent(c,d.target)}}};b._updatePointerPosition=function(a,b,c){var d=this._getElementRect(this.canvas);b-=d.left;c-=d.top;var e=this.canvas.width,f=this.canvas.height;b/=(d.right-d.left)/e;c/=(d.bottom-d.top)/f;d=this._getPointerData(a);(d.inBounds=0<=b&&0<=c&&b<=e-1&&c<=f-1)?(d.x=b,d.y=c):this.mouseMoveOutside&&
90 | (d.x=0>b?0:b>e-1?e-1:b,d.y=0>c?0:c>f-1?f-1:c);d.rawX=b;d.rawY=c;a==this._primaryPointerID&&(this.mouseX=d.x,this.mouseY=d.y,this.mouseInBounds=d.inBounds)};b._getElementRect=function(a){var b;try{b=a.getBoundingClientRect()}catch(c){b={top:a.offsetTop,left:a.offsetLeft,width:a.offsetWidth,height:a.offsetHeight}}var d=(window.pageXOffset||document.scrollLeft||0)-(document.clientLeft||document.body.clientLeft||0),e=(window.pageYOffset||document.scrollTop||0)-(document.clientTop||document.body.clientTop||
91 | 0),f=window.getComputedStyle?getComputedStyle(a):a.currentStyle;a=parseInt(f.paddingLeft)+parseInt(f.borderLeftWidth);var h=parseInt(f.paddingTop)+parseInt(f.borderTopWidth),k=parseInt(f.paddingRight)+parseInt(f.borderRightWidth),f=parseInt(f.paddingBottom)+parseInt(f.borderBottomWidth);return{left:b.left+d+a,right:b.right+d-k,top:b.top+e+h,bottom:b.bottom+e-f}};b._handleMouseUp=function(a){this._handlePointerUp(-1,a,!1)};b._handlePointerUp=function(a,b,c){var d=this._getPointerData(a),e;if(this.onMouseMove||
92 | this.hasEventListener("stagemouseup"))e=new createjs.MouseEvent("stagemouseup",d.x,d.y,this,b,a,a==this._primaryPointerID,d.rawX,d.rawY),this.onMouseUp&&this.onMouseUp(e),this.dispatchEvent(e);var f=d.event;if(f&&(f.onMouseUp||f.hasEventListener("mouseup")))e=new createjs.MouseEvent("mouseup",d.x,d.y,f.target,b,a,a==this._primaryPointerID,d.rawX,d.rawY),f.onMouseUp&&f.onMouseUp(e),f.dispatchEvent(e,f.target);if((f=d.target)&&(f.onClick||f.hasEventListener("click"))&&this._getObjectsUnderPoint(d.x,
93 | d.y,null,!0,this._mouseOverIntervalID?3:1)==f)e=new createjs.MouseEvent("click",d.x,d.y,f,b,a,a==this._primaryPointerID,d.rawX,d.rawY),f.onClick&&f.onClick(e),f.dispatchEvent(e);c?(a==this._primaryPointerID&&(this._primaryPointerID=null),delete this._pointerData[a]):d.event=d.target=null};b._handleMouseDown=function(a){this._handlePointerDown(-1,a,!1)};b._handlePointerDown=function(a,b,c,d){var e=this._getPointerData(a);null!=d&&this._updatePointerPosition(a,c,d);if(this.onMouseDown||this.hasEventListener("stagemousedown"))c=
94 | new createjs.MouseEvent("stagemousedown",e.x,e.y,this,b,a,a==this._primaryPointerID,e.rawX,e.rawY),this.onMouseDown&&this.onMouseDown(c),this.dispatchEvent(c);if(d=this._getObjectsUnderPoint(e.x,e.y,null,this._mouseOverIntervalID?3:1))if(e.target=d,d.onPress||d.hasEventListener("mousedown"))if(c=new createjs.MouseEvent("mousedown",e.x,e.y,d,b,a,a==this._primaryPointerID,e.rawX,e.rawY),d.onPress&&d.onPress(c),d.dispatchEvent(c),c.onMouseMove||c.onMouseUp||c.hasEventListener("mousemove")||c.hasEventListener("mouseup"))e.event=
95 | c};b._testMouseOver=function(){if(-1==this._primaryPointerID&&!(this.mouseX==this._mouseOverX&&this.mouseY==this._mouseOverY&&this.mouseInBounds)){var a=null;this.mouseInBounds&&(a=this._getObjectsUnderPoint(this.mouseX,this.mouseY,null,3),this._mouseOverX=this.mouseX,this._mouseOverY=this.mouseY);var b=this._mouseOverTarget;if(b!=a){var c=this._getPointerData(-1);if(b&&(b.onMouseOut||b.hasEventListener("mouseout"))){var d=new createjs.MouseEvent("mouseout",c.x,c.y,b,null,-1,c.rawX,c.rawY);b.onMouseOut&&
96 | b.onMouseOut(d);b.dispatchEvent(d)}b&&(this.canvas.style.cursor="");if(a&&(a.onMouseOver||a.hasEventListener("mouseover")))d=new createjs.MouseEvent("mouseover",c.x,c.y,a,null,-1,c.rawX,c.rawY),a.onMouseOver&&a.onMouseOver(d),a.dispatchEvent(d);a&&(this.canvas.style.cursor=a.cursor||"");this._mouseOverTarget=a}}};b._handleDoubleClick=function(a){var b=this._getPointerData(-1),c=this._getObjectsUnderPoint(b.x,b.y,null,this._mouseOverIntervalID?3:1);if(c&&(c.onDoubleClick||c.hasEventListener("dblclick")))evt=
97 | new createjs.MouseEvent("dblclick",b.x,b.y,c,a,-1,!0,b.rawX,b.rawY),c.onDoubleClick&&c.onDoubleClick(evt),c.dispatchEvent(evt)};createjs.Stage=c})();this.createjs=this.createjs||{};
98 | (function(){var c=function(a){this.initialize(a)},b=c.prototype=new createjs.DisplayObject;b.image=null;b.snapToPixel=!0;b.sourceRect=null;b.DisplayObject_initialize=b.initialize;b.initialize=function(a){this.DisplayObject_initialize();"string"==typeof a?(this.image=new Image,this.image.src=a):this.image=a};b.isVisible=function(){var a=this.cacheCanvas||this.image&&(this.image.complete||this.image.getContext||2<=this.image.readyState);return!(!this.visible||!(0=d){var e=a.next;this._dispatchAnimationEnd(a,b,c,e,d-1)||(e?this._goto(e):(this.paused=!0,this.currentAnimationFrame=a.frames.length-1,this.currentFrame=
104 | a.frames[this.currentAnimationFrame]))}else this.currentFrame=a.frames[this.currentAnimationFrame];else d=this.spriteSheet.getNumFrames(),b>=d&&!this._dispatchAnimationEnd(a,b,c,d-1)&&(this.currentFrame=0)};b._dispatchAnimationEnd=function(a,b,c,d,e){var f=a?a.name:null;this.onAnimationEnd&&this.onAnimationEnd(this,f,d);this.dispatchEvent({type:"animationend",name:f,next:d});!c&&this.paused&&(this.currentAnimationFrame=e);return this.paused!=c||this._animation!=a||this.currentFrame!=b};b.DisplayObject_cloneProps=
105 | b.cloneProps;b.cloneProps=function(a){this.DisplayObject_cloneProps(a);a.onAnimationEnd=this.onAnimationEnd;a.currentFrame=this.currentFrame;a.currentAnimation=this.currentAnimation;a.paused=this.paused;a.offset=this.offset;a._animation=this._animation;a.currentAnimationFrame=this.currentAnimationFrame};b._goto=function(a){if(isNaN(a)){var b=this.spriteSheet.getAnimation(a);b&&(this.currentAnimationFrame=0,this._animation=b,this.currentAnimation=a,this._normalizeFrame())}else this.currentAnimation=
106 | this._animation=null,this.currentFrame=a};createjs.BitmapAnimation=c})();this.createjs=this.createjs||{};
107 | (function(){var c=function(a){this.initialize(a)},b=c.prototype=new createjs.DisplayObject;b.graphics=null;b.DisplayObject_initialize=b.initialize;b.initialize=function(a){this.DisplayObject_initialize();this.graphics=a?a:new createjs.Graphics};b.isVisible=function(){var a=this.cacheCanvas||this.graphics&&!this.graphics.isEmpty();return!(!this.visible||!(0this.lineWidth?(b&&this._drawTextLine(a,j,e*d),e++,j=k[l+1]):j+=k[l]+k[l+1];b&&this._drawTextLine(a,j,e*d)}e++}return e};b._drawTextLine=function(a,b,c){this.outline?a.strokeText(b,0,c,this.maxWidth||65535):a.fillText(b,0,c,this.maxWidth||65535)};createjs.Text=c})();this.createjs=this.createjs||{};
114 | (function(){var c=function(){throw"SpriteSheetUtils cannot be instantiated";};c._workingCanvas=createjs.createCanvas?createjs.createCanvas():document.createElement("canvas");c._workingContext=c._workingCanvas.getContext("2d");c.addFlippedFrames=function(b,a,m,g){if(a||m||g){var d=0;a&&c._flip(b,++d,!0,!1);m&&c._flip(b,++d,!1,!0);g&&c._flip(b,++d,!0,!0)}};c.extractFrame=function(b,a){isNaN(a)&&(a=b.getAnimation(a).frames[0]);var m=b.getFrame(a);if(!m)return null;var g=m.rect,d=c._workingCanvas;d.width=
115 | g.width;d.height=g.height;c._workingContext.drawImage(m.image,g.x,g.y,g.width,g.height,0,0,g.width,g.height);m=new Image;m.src=d.toDataURL("image/png");return m};c.mergeAlpha=function(b,a,c){c||(c=createjs.createCanvas?createjs.createCanvas():document.createElement("canvas"));c.width=Math.max(a.width,b.width);c.height=Math.max(a.height,b.height);var g=c.getContext("2d");g.save();g.drawImage(b,0,0);g.globalCompositeOperation="destination-in";g.drawImage(a,0,0);g.restore();return c};c._flip=function(b,
116 | a,m,g){for(var d=b._images,e=c._workingCanvas,f=c._workingContext,h=d.length/a,k=0;kthis.maxHeight)throw c.ERR_DIMENSIONS;for(var d=0,e=0,f=0;g.length;){var h=this._fillRow(g,d,f,b,a);h.w>e&&(e=h.w);d+=h.h;if(!h.h||!g.length){var k=createjs.createCanvas?createjs.createCanvas():document.createElement("canvas");k.width=this._getSize(e,this.maxWidth);k.height=this._getSize(d,this.maxHeight);this._data.images[f]=k;h.h||(e=d=0,f++)}}};b._getSize=function(a,b){for(var c=4;Math.pow(2,++c)f)throw c.ERR_DIMENSIONS;t>h||k+p>f||(n.img=g,n.rect=new createjs.Rectangle(k,b,p,t),j=j||t,a.splice(l,1),d[n.index]=[k,b,p,t,g,Math.round(-r+q*s.regX-e),Math.round(-u+q*s.regY-e)],k+=p)}return{w:k,h:j}};b._endBuild=function(){this.spriteSheet=new createjs.SpriteSheet(this._data);
125 | this._data=null;this.progress=1;this.onComplete&&this.onComplete(this);this.dispatchEvent("complete")};b._run=function(){for(var a=50*Math.max(0.01,Math.min(0.99,this.timeSlice||0.3)),b=(new Date).getTime()+a,c=!1;b>(new Date).getTime();)if(!this._drawNext()){c=!0;break}if(c)this._endBuild();else{var d=this;this._timerID=setTimeout(function(){d._run()},50-a)}a=this.progress=this._index/this._frames.length;this.onProgress&&this.onProgress(this,a);this.dispatchEvent({type:"progress",progress:a})};b._drawNext=
126 | function(){var a=this._frames[this._index],b=a.scale*this._scale,c=a.rect,d=a.sourceRect,e=this._data.images[a.img].getContext("2d");a.funct&&a.funct.apply(a.scope,a.params);e.save();e.beginPath();e.rect(c.x,c.y,c.width,c.height);e.clip();e.translate(Math.ceil(c.x-d.x*b),Math.ceil(c.y-d.y*b));e.scale(b,b);a.source.draw(e);e.restore();return++this._index