diff --git a/examples/Games/Paperoids.html b/examples/Games/Paperoids.html new file mode 100644 index 00000000..e4f27722 --- /dev/null +++ b/examples/Games/Paperoids.html @@ -0,0 +1,571 @@ + + + + + + Paperoids + + + + + + + + +
FPS
+ + + +
Game Over. Play again?
+ + diff --git a/src/basic/Matrix.js b/src/basic/Matrix.js index 16bc87e7..4dbf59f5 100644 --- a/src/basic/Matrix.js +++ b/src/basic/Matrix.js @@ -422,7 +422,10 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{ }, /** - * @return {Number} The determinant of this transform + * The determinant of this transform. + * + * @type Number + * @bean */ getDeterminant: function() { return this._a * this._d - this._b * this._c; @@ -439,11 +442,12 @@ var Matrix = this.Matrix = Base.extend(/** @lends Matrix# */{ }, /** - * Returns the rotation angle of the matrix. If a non-uniform - * rotation is applied as a result of a shear() or scale() command, - * undefined is returned, as the resulting transformation cannot be - * expressed in one rotation angle - * @return {Number} The rotation angle of the matrix + * The rotation angle of the matrix. If a non-uniform rotation is applied as + * a result of a shear() or scale() command, undefined is returned, as the + * resulting transformation cannot be expressed in one rotation angle. + * + * @type Number + * @bean */ getRotation: function() { var angle1 = -Math.atan2(this._b, this._d), diff --git a/src/basic/Point.js b/src/basic/Point.js index b8d0dc1a..5f36e26d 100644 --- a/src/basic/Point.js +++ b/src/basic/Point.js @@ -949,7 +949,12 @@ var LinkedPoint = Point.extend({ }, statics: { - create: function(owner, setter, x, y) { + create: function(owner, setter, x, y, dontLink) { + // Support creation of normal Points rather than LinkedPoints + // through an optional parameter that can be passed to the getters. + // See e.g. Rectangle#getPoint(true). + if (dontLink) + return Point.create(x, y); var point = new LinkedPoint(LinkedPoint.dont); point._x = x; point._y = y; diff --git a/src/basic/Rectangle.js b/src/basic/Rectangle.js index a7b884ba..6f3275f7 100644 --- a/src/basic/Rectangle.js +++ b/src/basic/Rectangle.js @@ -145,7 +145,10 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{ * @bean */ getPoint: function() { - return LinkedPoint.create(this, 'setPoint', this.x, this.y); + // Pass on the optional argument dontLink which tells LinkedPoint to + // produce a normal point instead. Used internally for speed reasons. + return LinkedPoint.create(this, 'setPoint', this.x, this.y, + arguments[0]); }, setPoint: function(point) { @@ -162,7 +165,9 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{ * @bean */ getSize: function() { - return LinkedSize.create(this, 'setSize', this.width, this.height); + // See Rectangle#getPoint() about arguments[0] + return LinkedSize.create(this, 'setSize', this.width, this.height, + arguments[0]); }, setSize: function(size) { @@ -282,7 +287,7 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{ */ getCenter: function() { return LinkedPoint.create(this, 'setCenter', - this.getCenterX(), this.getCenterY()); + this.getCenterX(), this.getCenterY(), arguments[0]); }, setCenter: function(point) { @@ -665,7 +670,7 @@ var Rectangle = this.Rectangle = Base.extend(/** @lends Rectangle# */{ set = 'set' + part; this[get] = function() { return LinkedPoint.create(this, set, - this[getX](), this[getY]()); + this[getX](), this[getY](), arguments[0]); }; this[set] = function(point) { point = Point.read(arguments); diff --git a/src/basic/Size.js b/src/basic/Size.js index bc231289..2ffdbad1 100644 --- a/src/basic/Size.js +++ b/src/basic/Size.js @@ -535,13 +535,16 @@ var LinkedSize = Size.extend({ }, statics: { - create: function(owner, setter, width, height) { - var point = new LinkedSize(LinkedSize.dont); - point._width = width; - point._height = height; - point._owner = owner; - point._setter = setter; - return point; + create: function(owner, setter, width, height, dontLink) { + // See LinkedPoint.create() for an explanation about dontLink. + if (dontLink) + return Size.create(width, height); + var size = new LinkedSize(LinkedSize.dont); + size._width = width; + size._height = height; + size._owner = owner; + size._setter = setter; + return size; } } }); diff --git a/src/color/Color.js b/src/color/Color.js index 6e296653..dc39cb02 100644 --- a/src/color/Color.js +++ b/src/color/Color.js @@ -148,14 +148,15 @@ var Color = this.Color = Base.extend(new function() { max = Math.max(r, g, b), min = Math.min(r, g, b), delta = max - min, - h = delta == 0 ? 0 + achromatic = delta == 0, + h = achromatic ? 0 : ( max == r ? (g - b) / delta + (g < b ? 6 : 0) : max == g ? (b - r) / delta + 2 : (r - g) / delta + 4) * 60, // max == b l = (max + min) / 2, - s = l < 0.5 - ? delta / (max + min) - : delta / (2 - max - min); + s = achromatic ? 0 : l < 0.5 + ? delta / (max + min) + : delta / (2 - max - min); return new HSLColor(h, s, l, color._alpha); }, diff --git a/src/path/Path.Constructors.js b/src/path/Path.Constructors.js index 47241fef..d861c47a 100644 --- a/src/path/Path.Constructors.js +++ b/src/path/Path.Constructors.js @@ -95,13 +95,17 @@ Path.inject({ statics: new function() { */ Rectangle: function(rect) { rect = Rectangle.read(arguments); - var path = new Path(), - corners = ['getBottomLeft', 'getTopLeft', 'getTopRight', - 'getBottomRight'], - segments = new Array(4); - for (var i = 0; i < 4; i++) - segments[i] = new Segment(rect[corners[i]]()); - path._add(segments); + var left = rect.x, + top = rect.y + right = left + rect.width, + bottom = top + rect.height, + path = new Path(); + path._add([ + new Segment(Point.create(left, bottom)), + new Segment(Point.create(left, top)), + new Segment(Point.create(right, top)), + new Segment(Point.create(right, bottom)) + ]); path._closed = true; return path; }, @@ -128,13 +132,13 @@ Path.inject({ statics: new function() { rect = Rectangle.read(arguments, 0, 4); size = Size.read(arguments, 4, 2); } - size = Size.min(size, rect.getSize().divide(2)); + size = Size.min(size, rect.getSize(true).divide(2)); var path = new Path(), uSize = size.multiply(kappa * 2), - bl = rect.getBottomLeft(), - tl = rect.getTopLeft(), - tr = rect.getTopRight(), - br = rect.getBottomRight(); + bl = rect.getBottomLeft(true), + tl = rect.getTopLeft(true), + tr = rect.getTopRight(true), + br = rect.getBottomRight(true); path._add([ new Segment(bl.add(size.width, 0), null, [-uSize.width, 0]), new Segment(bl.subtract(0, size.height), [0, uSize.height], null), @@ -172,13 +176,13 @@ Path.inject({ statics: new function() { Oval: function(rect) { rect = Rectangle.read(arguments); var path = new Path(), - topLeft = rect.getTopLeft(), - size = new Size(rect.width, rect.height), + point = rect.getPoint(true), + size = rect.getSize(true), segments = new Array(4); for (var i = 0; i < 4; i++) { var segment = ovalSegments[i]; segments[i] = new Segment( - segment._point.multiply(size).add(topLeft), + segment._point.multiply(size).add(point), segment._handleIn.multiply(size), segment._handleOut.multiply(size) ); @@ -206,7 +210,7 @@ Path.inject({ statics: new function() { center = Point.read(arguments, 0, 1); } return Path.Oval(new Rectangle(center.subtract(radius), - new Size(radius * 2, radius * 2))); + Size.create(radius * 2, radius * 2))); }, /** diff --git a/src/path/Path.js b/src/path/Path.js index adacd97c..3a184b2a 100644 --- a/src/path/Path.js +++ b/src/path/Path.js @@ -1286,10 +1286,10 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ // objects that were read from segments. This is because the SegmentPoint // class overrides the plain x / y properties with getter / setters and // stores the values in these private properties internally. To avoid - // of getter functions all the time we directly access these private + // calling of getter functions all the time we directly access these private // properties here. The distinction between normal Point objects and - // SegmentPoint objects maybe seem a bit tedious but is worth the - // performance benefit. + // SegmentPoint objects maybe seem a bit tedious but is worth the benefit in + // performance. function drawHandles(ctx, segments) { for (var i = 0, l = segments.length; i < l; i++) { @@ -2028,7 +2028,7 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{ return this._handleBounds; var coords = new Array(6), stroke = arguments[1] / 2 || 0, // Stroke padding - join = arguments[2] / 2 || 0, // Join padding, for miterLimiet + join = arguments[2] / 2 || 0, // Join padding, for miterLimit open = !this._closed, x1 = Infinity, x2 = -x1, diff --git a/src/path/SegmentPoint.js b/src/path/SegmentPoint.js index ec7a74f7..c0492796 100644 --- a/src/path/SegmentPoint.js +++ b/src/path/SegmentPoint.js @@ -47,6 +47,13 @@ var SegmentPoint = Point.extend({ this._owner._changed(this); }, + isZero: function() { + // Provide our own version of Point#isZero() that does not use the x / y + // accessors but the internal properties directly, for performance + // reasons, since it is used a lot internally. + return this._x == 0 && this._y == 0; + }, + setSelected: function(selected) { this._owner._setSelected(this, selected); }, diff --git a/test/tests/Color.js b/test/tests/Color.js index 04417b24..2619a60b 100644 --- a/test/tests/Color.js +++ b/test/tests/Color.js @@ -196,4 +196,10 @@ test('Color#convert', function() { equals(function() { return converted.equals(color); }, true); +}); + +test('Saturation from black rgb', function() { + equals(function() { + return new RGBColor(0, 0, 0).saturation == 0; + }, true); }); \ No newline at end of file