Revision: 1048
Author: allain.lalonde
Date: Thu Aug 26 11:02:54 2010
Log: Fixing PText bounds bug, making repaint use the visible region when
clipping, and caching globalFullBounds. Also, fixed bug in the events
example, where the highlighted node wasn't updated until an animation
occured.
http://code.google.com/p/piccolo2d/source/detail?r=1048
Modified:
/piccolo2d.js/trunk/examples/events.html
/piccolo2d.js/trunk/piccolo2d.js
/piccolo2d.js/trunk/test.html
=======================================
--- /piccolo2d.js/trunk/examples/events.html Mon Jan 4 10:15:57 2010
+++ /piccolo2d.js/trunk/examples/events.html Thu Aug 26 11:02:54 2010
@@ -57,13 +57,13 @@
if (this.highlighted) {
ctx.fillStyle = "rgb(0,0,255)";
ctx.lineWidth = 10;
- ctx.strokeRect(0, 0, this.bounds.width, this.bounds.height);
+ ctx.strokeRect(0, 0, this.bounds.width, this.bounds.height);
}
}
})
for (var x=0; x<10; x++) {
- for (var y=0; y<10; y++) {
+ for (var y=0; y<10; y++) {
layer.addChild(new ZoomNode({
fillStyle: "rgb("+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+")",
bounds: new PBounds(0,0, 100, 100),
@@ -81,10 +81,12 @@
mouseout: function(event) {
event.pickedNodes[0].highlighted = false;
+ event.pickedNodes[0].invalidatePaint();
},
mouseover: function(event) {
event.pickedNodes[0].highlighted = true;
+ event.pickedNodes[0].invalidatePaint();
}
});
}
=======================================
--- /piccolo2d.js/trunk/piccolo2d.js Tue Jun 8 07:48:28 2010
+++ /piccolo2d.js/trunk/piccolo2d.js Thu Aug 26 11:02:54 2010
@@ -59,7 +59,7 @@
abs = Math.abs,
sin = Math.sin,
cos = Math.cos;
-
+
PTransform = Class.extend({
init: function (values) {
this.values = values || [1, 0, 0, 1, 0, 0];
@@ -275,6 +275,13 @@
}
return x >= this.x && x < this.x + this.width && y >= this.y
&& y < this.y + this.height;
+ },
+
+ intersects: function(bounds) {
+ return !(bounds.x + bounds.width < this.x
+ || bounds.x > this.x + this.width
+ || bounds.y + bounds.height < this.y
+ || bounds.y > this.y + this.height);
}
});
@@ -284,6 +291,7 @@
this.children = [];
this.listeners = [];
this.fullBounds = null;
+ this.globalFullBounds = null;
this.transform = new PTransform();
this.visible = true;
@@ -314,29 +322,29 @@
paintAfterChildren: function (ctx) {
},
- fullPaint: function (ctx) {
- if (!this.visible) { //TODO:
fullIntersects(paintContext.getLocalClip())) {
- return;
- }
-
- ctx.save();
-
- this.transform.applyTo(ctx);
-
- this.paint(ctx);
-
- for (var i = 0; i < this.children.length; i += 1) {
- this.children[i].fullPaint(ctx);
- }
-
- this.paintAfterChildren(ctx);
-
- ctx.restore();
+ fullPaint: function (ctx) {
+ var inViewport = !ctx.clipBounds ||
ctx.clipBounds.intersects(this.getGlobalFullBounds());
+ if (this.visible && inViewport) {
+ ctx.save();
+
+ this.transform.applyTo(ctx);
+
+ this.paint(ctx);
+
+ for (var i = 0; i < this.children.length; i += 1) {
+ this.children[i].fullPaint(ctx);
+ }
+
+ this.paintAfterChildren(ctx);
+
+ ctx.restore();
+ }
},
scale: function (ratio) {
this.transform.scale(ratio);
this.fullBounds = null;
+ this.globalFullBounds = null;
this.invalidatePaint();
return this;
@@ -345,6 +353,7 @@
translate: function (dx, dy) {
this.transform.translate(dx, dy);
this.fullBounds = null;
+ this.globalFullBounds = null;
this.invalidatePaint();
return this;
@@ -360,6 +369,7 @@
addChild: function (child) {
this.children.push(child);
this.fullBounds = null;
+ this.globalFullBounds = null;
child.parent = this;
this.invalidatePaint();
@@ -369,6 +379,7 @@
removeChild: function (child) {
child.parent = null;
this.fullBounds = null;
+ this.globalFullBounds = null;
this.children = this.children.remove(child);
this.invalidatePaint();
@@ -378,6 +389,7 @@
setTransform: function (transform) {
this.transform = transform;
this.fullBounds = null;
+ this.globalFullBounds = null;
this.invalidatePaint();
return this;
@@ -414,23 +426,27 @@
},
getGlobalFullBounds: function () {
- var fullBounds = this.getFullBounds(),
- currentNode = this,
- tl = new PPoint(fullBounds.x, fullBounds.y),
- br = new PPoint(fullBounds.x + fullBounds.width,
fullBounds.y + fullBounds.height);
-
- while (currentNode.parent) {
- tl = currentNode.transform.transform(tl);
- br = currentNode.transform.transform(br);
- currentNode = currentNode.parent;
- }
-
- return new PBounds(
- min(tl.x, br.x),
- min(tl.y, br.y),
- abs(tl.x - br.x),
- abs(tl.y - br.y)
- );
+ if (!this.globalFullBounds) {
+ var fullBounds = this.getFullBounds(),
+ currentNode = this,
+ tl = new PPoint(fullBounds.x, fullBounds.y),
+ br = new PPoint(fullBounds.x + fullBounds.width,
fullBounds.y + fullBounds.height);
+
+ while (currentNode.parent) {
+ tl = currentNode.transform.transform(tl);
+ br = currentNode.transform.transform(br);
+ currentNode = currentNode.parent;
+ }
+
+ this.globalFullBounds = new PBounds(
+ min(tl.x, br.x),
+ min(tl.y, br.y),
+ abs(tl.x - br.x),
+ abs(tl.y - br.y)
+ );
+ }
+
+ return this.globalFullBounds;
},
getGlobalTransform: function () {
@@ -475,10 +491,11 @@
});
PText = PNode.extend({
- init: function (arg) {
+ init: function (arg) {
if (typeof arg === "string") {
this._super();
this.text = arg;
+ this.recomputeBounds();
} else if (arg) {
this.text = arg.text;
this._super(arg);
@@ -487,7 +504,7 @@
}
},
- paint: function (ctx) {
+ paint: function (ctx) {
if (this.fillStyle) {
ctx.fillStyle = this.fillStyle;
} else {
@@ -495,9 +512,18 @@
}
ctx.textBaseline = "top";
ctx.fillText(this.text, this.bounds.x, this.bounds.y);
+ },
+
+ recomputeBounds: function() {
+ var metric = PText.hiddenContext.measureText(this.text);
+ this.bounds.width = metric.width;
+ this.bounds.height = this.text ? PText.fontSize : 0;
}
});
-
+ PText.hiddenContext =
document.createElement("canvas").getContext("2d");
+ PText.fontSize = 20;
+
+
PImage = PNode.extend({
init: function (arg) {
if (typeof arg === "string") {
@@ -559,7 +585,9 @@
ctx.save();
this.viewTransform.applyTo(ctx);
-
+ var viewInverse = this.viewTransform.getInverse();
+ ctx.clipBounds = viewInverse.transform(this.bounds);
+
for (var i = 0; i < this.layers.length; i += 1) {
this.layers[i].fullPaint(ctx);
}
@@ -636,8 +664,10 @@
throw "Canvas provided to Piccolo is invalid!";
}
- var _pCanvas = this;
+ var _pCanvas = this;
+
this.canvas = canvas;
+ canvas.font = PText.fontSize + "px Arial";
this.root = root || new PRoot();
this.camera = new PCamera();
@@ -726,7 +756,8 @@
paint: function () {
var root = this.camera.getRoot();
if (root.invalidPaint) {
- var ctx = this.canvas.getContext('2d');
+ var ctx = this.canvas.getContext('2d');
+
ctx.font = "16pt Helvetica";
ctx.fillStyle = this.fillStyle || "rgb(255,255,255)";
=======================================
--- /piccolo2d.js/trunk/test.html Thu Aug 26 08:58:51 2010
+++ /piccolo2d.js/trunk/test.html Thu Aug 26 11:02:54 2010
@@ -498,7 +498,21 @@
var ctx = mock("fillText");
t.paint(ctx);
same(ctx.calls.fillText[0], ["Hello", 0, 0]);
- })
+ });
+
+ test("FullBounds are empty when text is empty", function() {
+ var t = new PText("");
+ var bounds = t.getFullBounds();
+ equal(bounds.width, 0, "Bounds should have no weight when text
is empty");
+ equal(bounds.height, 0, "Bounds should have no height when text
is empty");
+ });
+
+ test("FullBounds not empty when text is not empty", function() {
+ var t = new PText("Hello");
+ var bounds = t.getFullBounds();
+ ok(bounds.width != 0, "Bounds should have width when text is not
empty");
+ ok(bounds.height != 0, "Bounds should have height when text is
not empty");
+ });
}
function testPImage() {
--
Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en