Remove Item#apply() and clean up #applyMatrix() and simplify handling.

This commit is contained in:
Jürg Lehni 2012-12-24 00:29:09 +01:00
parent 81b8a57a7c
commit e21ea457a7
3 changed files with 24 additions and 55 deletions

View file

@ -710,7 +710,6 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
center = bounds.getCenter();
matrix.translate(-center.x, -center.y);
// Now execute the transformation
// TODO: do we need to apply too, or just change the matrix?
this.transform(matrix);
}
@ -1681,7 +1680,6 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
*/
// DOCS: Document the different arguments that this function can receive.
// DOCS: Document the apply parameter in all transform functions.
/**
* {@grouptitle Transform Functions}
*
@ -1692,7 +1690,6 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
* @function
* @param {Number} scale the scale factor
* @param {Point} [center={@link Item#position}]
* @param {Boolean} apply
*
* @example {@paperscript}
* // Scaling an item from its center point:
@ -1725,7 +1722,6 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
* @param {Number} hor the horizontal scale factor
* @param {Number} ver the vertical scale factor
* @param {Point} [center={@link Item#position}]
* @param {Boolean} apply
*
* @example {@paperscript}
* // Scaling an item horizontally by 300%:
@ -1738,26 +1734,24 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
* // Scale the path horizontally by 300%
* circle.scale(3, 1);
*/
scale: function(hor, ver /* | scale */, center, apply) {
scale: function(hor, ver /* | scale */, center) {
// See Matrix#scale for explanation of this:
if (arguments.length < 2 || typeof ver === 'object') {
apply = center;
center = ver;
ver = hor;
}
return this.transform(new Matrix().scale(hor, ver,
center || this.getPosition(true)), apply);
center || this.getPosition(true)));
},
/**
* Translates (moves) the item by the given offset point.
*
* @param {Point} delta the offset to translate the item by
* @param {Boolean} apply
*/
translate: function(delta, apply) {
translate: function(delta) {
var mx = new Matrix();
return this.transform(mx.translate.apply(mx, arguments), apply);
return this.transform(mx.translate.apply(mx, arguments));
},
/**
@ -1767,7 +1761,6 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
*
* @param {Number} angle the rotation angle
* @param {Point} [center={@link Item#position}]
* @param {Boolean} apply
* @see Matrix#rotate
*
* @example {@paperscript}
@ -1802,9 +1795,9 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
* path.rotate(3, view.center);
* }
*/
rotate: function(angle, center, apply) {
rotate: function(angle, center) {
return this.transform(new Matrix().rotate(angle,
center || this.getPosition(true)), apply);
center || this.getPosition(true)));
},
// TODO: Add test for item shearing, as it might be behaving oddly.
@ -1816,7 +1809,6 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
* @function
* @param {Point} point
* @param {Point} [center={@link Item#position}]
* @param {Boolean} apply
* @see Matrix#shear
*/
/**
@ -1828,34 +1820,28 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
* @param {Number} hor the horizontal shear factor.
* @param {Number} ver the vertical shear factor.
* @param {Point} [center={@link Item#position}]
* @param {Boolean} apply
* @see Matrix#shear
*/
shear: function(hor, ver, center, apply) {
// PORT: Add support for center and apply back to Scriptographer too!
shear: function(hor, ver, center) {
// See Matrix#scale for explanation of this:
if (arguments.length < 2 || typeof ver === 'object') {
apply = center;
center = ver;
ver = hor;
}
return this.transform(new Matrix().shear(hor, ver,
center || this.getPosition(true)), apply);
center || this.getPosition(true)));
},
/**
* Transform the item.
*
* @param {Matrix} matrix the matrix by which the item shall be transformed.
* @param {Boolean} apply controls wether the transformation should just be
* concatenated to {@link #matrix} ({@code false}) or if it should directly
* be applied to item's content and its children.
*/
// Remove this for now:
// @param {String[]} flags Array of any of the following: 'objects',
// 'children', 'fill-gradients', 'fill-patterns', 'stroke-patterns',
// 'lines'. Default: ['objects', 'children']
transform: function(matrix, apply) {
transform: function(matrix /*, applyMatrix */) {
// Calling _changed will clear _bounds and _position, but depending
// on matrix we can calculate and set them again.
var bounds = this._bounds,
@ -1864,8 +1850,15 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
this._matrix.preConcatenate(matrix);
if (this._transform)
this._transform(matrix);
if (apply)
this.apply();
// If we need to directly apply the accumulated transformations, call
// #applyMatrix() with the internal _,atrix, and set it to the identity
// transformation if it was possible to apply it. Application is not
// possible on Raster, PointText, PlacedSymbol, since the matrix is
// storing the actual location / transformation state.
if ((this._applyMatrix || arguments[1]) && this.applyMatrix(this._matrix))
// TODO: This needs a _changed notification, but the GEOMETRY
// actually doesn't change! What to do?
this._matrix.setIdentity();
// We always need to call _changed since we're caching bounds on all
// items, including Group.
this._changed(/*#=*/ Change.GEOMETRY);
@ -1895,30 +1888,11 @@ var Item = this.Item = Base.extend(Callback, /** @lends Item# */{
return this;
},
// DOCS: Document #apply()
apply: function() {
// Call the internal #_apply(), and set the internal _matrix to the
// identity transformation if it was possible to apply it.
// Application is not possible on Raster, PointText, PlacedSymbol, since
// the matrix is storing the actual location / transformation state.
// Pass on this._matrix to _apply calls, for reasons of faster access
// and code minification.
if (this._apply(this._matrix)) {
// Set _matrix to the identity
this._matrix.setIdentity();
// TODO: This needs a _changed notification, but the GEOMETRY
// actually doesn't change! What to do?
}
},
_apply: function(matrix) {
applyMatrix: function(matrix) {
// Pass on the transformation to the children, and apply it there too:
if (this._children) {
for (var i = 0, l = this._children.length; i < l; i++) {
var child = this._children[i];
child.transform(matrix);
child.apply();
}
for (var i = 0, l = this._children.length; i < l; i++)
this._children[i].transform(matrix, true);
return true;
}
},

View file

@ -24,6 +24,8 @@
// DOCS: Explain that path matrix is always applied with each transformation.
var Path = this.Path = PathItem.extend(/** @lends Path# */{
_type: 'path',
// Paths always directly apply transformation matrices to the Segments.
_applyMatrix: true,
/**
* Creates a new Path item and places it at the top of the active layer.
*
@ -223,11 +225,6 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
// path, with the added benefit that b can be < a, and closed looping is
// taken into account.
// DOCS: Explain that path matrix is always applied with each transformation.
transform: function(matrix) {
return this.base(matrix, true);
},
getMatrix: function() {
// Override matrix getter to always return null, since Paths act as if
// they do not have a matrix, and always directly apply transformations
@ -251,7 +248,7 @@ var Path = this.Path = PathItem.extend(/** @lends Path# */{
return true;
},
_apply: function(matrix) {
applyMatrix: function(matrix) {
var coords = new Array(6);
for (var i = 0, l = this._segments.length; i < l; i++) {
this._segments[i]._transformCoordinates(matrix, coords, true);

View file

@ -54,7 +54,6 @@ test('path.bounds', function() {
// Set new bounds and check segment list as result of resizing / positioning
path.bounds = { x: 100, y: 100, width: 200, height: 200 };
path.apply();
equals(path.segments.toString(),
'{ point: { x: 107.93077, y: 179.56917 }, handleIn: { x: -24.41127, y: 51.30707 }, handleOut: { x: 39.52904, y: -83.08194 } },{ point: { x: 271.10084, y: 160.66656 }, handleIn: { x: -53.96176, y: -99.91377 }, handleOut: { x: 53.96176, y: 99.91377 } },{ point: { x: 215.85428, y: 296.96086 }, handleIn: { x: 85.81084, y: -17.18521 }, handleOut: { x: -101.49949, y: 20.32729 } }',
'resized path.segments');
@ -65,7 +64,6 @@ test('path.bounds', function() {
{ x: 92.38109, y: 106.78957, width: 191.4803, height: 203.66878 },
'rotated path.bounds');
path.apply();
equals(path.segments.toString(),
'{ point: { x: 142.60356, y: 125.16811 }, handleIn: { x: -51.67967, y: 23.61224 }, handleOut: { x: 83.68504, y: -38.23568 } },{ point: { x: 279.74945, y: 215.57158 }, handleIn: { x: 22.88623, y: -111.22434 }, handleOut: { x: -22.88623, y: 111.22434 } },{ point: { x: 149.81984, y: 284.46726 }, handleIn: { x: 76.78135, y: 41.99351 }, handleOut: { x: -90.81925, y: -49.67101 } }',
'roated path.segments');