|
@@ -695,6 +695,13 @@ function Object2D()
|
|
|
*/
|
|
|
this.parent = null;
|
|
|
|
|
|
+ /**
|
|
|
+ * Depth level in the object tree, objects with higher depth are drawn on top.
|
|
|
+ *
|
|
|
+ * The layer value is considered first.
|
|
|
+ */
|
|
|
+ this.level = 0;
|
|
|
+
|
|
|
/**
|
|
|
* Position of the object.
|
|
|
*/
|
|
@@ -825,6 +832,8 @@ Object2D.prototype.traverse = function(callback)
|
|
|
Object2D.prototype.add = function(object)
|
|
|
{
|
|
|
object.parent = this;
|
|
|
+ object.level = this.level + 1;
|
|
|
+
|
|
|
this.children.push(object);
|
|
|
};
|
|
|
|
|
@@ -836,9 +845,18 @@ Object2D.prototype.add = function(object)
|
|
|
Object2D.prototype.remove = function(object)
|
|
|
{
|
|
|
var index = this.children.indexOf(object);
|
|
|
+
|
|
|
if(index !== -1)
|
|
|
{
|
|
|
- this.children[index].parent = null;
|
|
|
+ var object = this.children[index];
|
|
|
+ object.parent = null;
|
|
|
+ object.level = 0;
|
|
|
+
|
|
|
+ if(object.onDestroy !== null)
|
|
|
+ {
|
|
|
+ object.onDestroy();
|
|
|
+ }
|
|
|
+
|
|
|
this.children.splice(index, 1);
|
|
|
}
|
|
|
};
|
|
@@ -886,6 +904,8 @@ Object2D.prototype.transform = function(context, viewport)
|
|
|
this.globalMatrix.tranformContext(context);
|
|
|
};
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* Draw the object into the canvas.
|
|
|
*
|
|
@@ -897,6 +917,11 @@ Object2D.prototype.transform = function(context, viewport)
|
|
|
*/
|
|
|
Object2D.prototype.draw = function(context, viewport, canvas){};
|
|
|
|
|
|
+/**
|
|
|
+ * Method called when the object gets removed from its parent
|
|
|
+ */
|
|
|
+Object2D.prototype.onDestroy = null;
|
|
|
+
|
|
|
/**
|
|
|
* Callback method called every time before the object is draw into the canvas.
|
|
|
*
|
|
@@ -1434,8 +1459,16 @@ Pointer.dispose = function()
|
|
|
*
|
|
|
* @class
|
|
|
*/
|
|
|
-function Renderer(canvas)
|
|
|
+function Renderer(canvas, options)
|
|
|
{
|
|
|
+ if(options === undefined)
|
|
|
+ {
|
|
|
+ options =
|
|
|
+ {
|
|
|
+ alpha: true
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Canvas DOM element, has to be managed by the user.
|
|
|
*/
|
|
@@ -1444,7 +1477,7 @@ function Renderer(canvas)
|
|
|
/**
|
|
|
* Canvas 2D rendering context used to draw content.
|
|
|
*/
|
|
|
- this.context = canvas.getContext("2d");
|
|
|
+ this.context = canvas.getContext("2d", {alpha: options.alpha});
|
|
|
this.context.imageSmoothingEnabled = true;
|
|
|
this.context.globalCompositeOperation = "source-over";
|
|
|
|
|
@@ -1514,6 +1547,11 @@ Renderer.prototype.update = function(object, viewport)
|
|
|
// Sort objects by layer
|
|
|
objects.sort(function(a, b)
|
|
|
{
|
|
|
+ if(b.layer === a.layer)
|
|
|
+ {
|
|
|
+ return b.level - a.level;
|
|
|
+ }
|
|
|
+
|
|
|
return b.layer - a.layer;
|
|
|
});
|
|
|
|
|
@@ -1641,7 +1679,6 @@ Renderer.prototype.update = function(object, viewport)
|
|
|
{
|
|
|
child.updateMatrix();
|
|
|
});
|
|
|
-
|
|
|
|
|
|
this.context.setTransform(1, 0, 0, 1, 0, 0);
|
|
|
|
|
@@ -1746,6 +1783,13 @@ function Viewport()
|
|
|
* For some application its easier to focus the target if the viewport moves to the pointer location while scalling.
|
|
|
*/
|
|
|
this.moveOnScale = true;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Value of the initial point of rotation if the viewport is being rotated.
|
|
|
+ *
|
|
|
+ * Is set to null when the viewport is not being rotated.
|
|
|
+ */
|
|
|
+ this.rotationPoint = null;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -1768,11 +1812,17 @@ Viewport.prototype.updateControls = function(pointer)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(pointer.buttonPressed(Pointer.RIGHT))
|
|
|
+ if(pointer.buttonPressed(Pointer.RIGHT) && pointer.buttonPressed(Pointer.LEFT))
|
|
|
+ {
|
|
|
+ this.rotation += pointer.delta.angle() * 1e-2;
|
|
|
+ }
|
|
|
+ else if(pointer.buttonPressed(Pointer.RIGHT))
|
|
|
{
|
|
|
this.position.x += pointer.delta.x;
|
|
|
this.position.y += pointer.delta.y;
|
|
|
}
|
|
|
+
|
|
|
+
|
|
|
};
|
|
|
|
|
|
/**
|
|
@@ -2141,17 +2191,14 @@ Circle.prototype.onPointerLeave = function(pointer, viewport)
|
|
|
|
|
|
Circle.prototype.draw = function(context, viewport, canvas)
|
|
|
{
|
|
|
- context.fillStyle = this.fillStyle;
|
|
|
-
|
|
|
context.beginPath();
|
|
|
context.arc(0, 0, this.radius, 0, 2 * Math.PI);
|
|
|
+
|
|
|
+ context.fillStyle = this.fillStyle;
|
|
|
context.fill();
|
|
|
|
|
|
context.lineWidth = 1;
|
|
|
context.strokeStyle = this.strokeStyle;
|
|
|
-
|
|
|
- context.beginPath();
|
|
|
- context.arc(0, 0, this.radius, 0, 2 * Math.PI);
|
|
|
context.stroke();
|
|
|
};
|
|
|
|
|
@@ -2488,6 +2535,11 @@ function DOM(parent, type)
|
|
|
{
|
|
|
Object2D.call(this);
|
|
|
|
|
|
+ /**
|
|
|
+ * Parent element that contains this DOM div.
|
|
|
+ */
|
|
|
+ this.parent = parent;
|
|
|
+
|
|
|
/**
|
|
|
* DOM element contained by this object.
|
|
|
*
|
|
@@ -2501,7 +2553,7 @@ function DOM(parent, type)
|
|
|
this.element.style.transformOrigin = "0px 0px";
|
|
|
this.element.style.overflow = "auto";
|
|
|
this.element.style.pointerEvents = "none";
|
|
|
- parent.appendChild(this.element);
|
|
|
+ this.parent.appendChild(this.element);
|
|
|
|
|
|
/**
|
|
|
* Size of the DOM element (in world coordinates).
|
|
@@ -2511,6 +2563,11 @@ function DOM(parent, type)
|
|
|
|
|
|
DOM.prototype = Object.create(Object2D.prototype);
|
|
|
|
|
|
+DOM.prototype.onDestroy = function()
|
|
|
+{
|
|
|
+ this.parent.removeChild(this.element);
|
|
|
+};
|
|
|
+
|
|
|
DOM.prototype.transform = function(context, viewport, canvas)
|
|
|
{
|
|
|
// CSS trasnformation matrix
|
|
@@ -2590,8 +2647,6 @@ Pattern.prototype.draw = function(context, viewport, canvas)
|
|
|
if(this.image.src.length > 0)
|
|
|
{
|
|
|
var pattern = context.createPattern(this.image, this.repetition);
|
|
|
-
|
|
|
- //pattern.setTransform();
|
|
|
|
|
|
context.fillStyle = pattern;
|
|
|
context.fillRect(this.box.min.x, this.box.min.y, width, height);
|