mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Reflect View#zoom through matrix decomposition, and implement additional decomposed properties.
Closes #1107
This commit is contained in:
parent
4d9c0c9f05
commit
f874b927bf
2 changed files with 112 additions and 62 deletions
|
@ -779,13 +779,11 @@ new function() { // Injection scope for various item event handlers
|
|||
* @type Point
|
||||
* @default null
|
||||
*/
|
||||
getPivot: function(_dontLink) {
|
||||
getPivot: function() {
|
||||
var pivot = this._pivot;
|
||||
if (pivot) {
|
||||
var ctor = _dontLink ? Point : LinkedPoint;
|
||||
pivot = new ctor(pivot.x, pivot.y, this, 'setPivot');
|
||||
}
|
||||
return pivot;
|
||||
return pivot
|
||||
? new LinkedPoint(pivot.x, pivot.y, this, 'setPivot')
|
||||
: null;
|
||||
},
|
||||
|
||||
setPivot: function(/* point */) {
|
||||
|
@ -1088,11 +1086,12 @@ new function() { // Injection scope for various item event handlers
|
|||
* @bean
|
||||
* @type Point
|
||||
*/
|
||||
getScaling: function(_dontLink) {
|
||||
getScaling: function() {
|
||||
var decomposed = this._decompose(),
|
||||
scaling = decomposed && decomposed.scaling,
|
||||
ctor = _dontLink ? Point : LinkedPoint;
|
||||
return scaling && new ctor(scaling.x, scaling.y, this, 'setScaling');
|
||||
scaling = decomposed && decomposed.scaling;
|
||||
return scaling
|
||||
? new LinkedPoint(scaling.x, scaling.y, this, 'setScaling')
|
||||
: undefined;
|
||||
},
|
||||
|
||||
setScaling: function(/* scaling */) {
|
||||
|
|
155
src/view/View.js
155
src/view/View.js
|
@ -107,7 +107,6 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
// Link this id to our view
|
||||
View._viewsById[this._id] = this;
|
||||
(this._matrix = new Matrix())._owner = this;
|
||||
this._zoom = 1;
|
||||
// Make sure the first view is focused for keyboard input straight away
|
||||
if (!View._focused)
|
||||
View._focused = this;
|
||||
|
@ -331,7 +330,7 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
// one thing:
|
||||
this._project._changed(/*#=*/Change.VIEW);
|
||||
// Force recalculation of these values next time they are requested.
|
||||
this._bounds = null;
|
||||
this._bounds = this._decomposed = undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -436,56 +435,6 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
return this.getBounds().getSize();
|
||||
},
|
||||
|
||||
/**
|
||||
* The center of the visible area in project coordinates.
|
||||
*
|
||||
* @bean
|
||||
* @type Point
|
||||
*/
|
||||
getCenter: function() {
|
||||
return this.getBounds().getCenter();
|
||||
},
|
||||
|
||||
setCenter: function(/* center */) {
|
||||
var center = Point.read(arguments);
|
||||
this.translate(this.getCenter().subtract(center));
|
||||
},
|
||||
|
||||
/**
|
||||
* The zoom factor by which the project coordinates are magnified.
|
||||
*
|
||||
* @bean
|
||||
* @type Number
|
||||
*/
|
||||
getZoom: function() {
|
||||
return this._zoom;
|
||||
},
|
||||
|
||||
setZoom: function(zoom) {
|
||||
this.transform(new Matrix().scale(zoom / this._zoom,
|
||||
this.getCenter()));
|
||||
this._zoom = zoom;
|
||||
},
|
||||
|
||||
/**
|
||||
* The view's transformation matrix, defining the view onto the project's
|
||||
* contents (position, zoom level, rotation, etc).
|
||||
*
|
||||
* @bean
|
||||
* @type Matrix
|
||||
*/
|
||||
getMatrix: function() {
|
||||
return this._matrix;
|
||||
},
|
||||
|
||||
setMatrix: function() {
|
||||
// Use Matrix#initialize to easily copy over values.
|
||||
// NOTE: calling initialize() also calls #_changed() for us, through its
|
||||
// call to #set() / #reset(), and this also handles _applyMatrix for us.
|
||||
var matrix = this._matrix;
|
||||
matrix.initialize.apply(matrix, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Checks whether the view is currently visible within the current browser
|
||||
* viewport.
|
||||
|
@ -539,6 +488,10 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
center || this.getCenter(true)));
|
||||
};
|
||||
}, /** @lends View# */{
|
||||
_decompose: function() {
|
||||
return this._decomposed || (this._decomposed = this._matrix.decompose());
|
||||
},
|
||||
|
||||
/**
|
||||
* {@grouptitle Transform Functions}
|
||||
*
|
||||
|
@ -551,6 +504,104 @@ var View = Base.extend(Emitter, /** @lends View# */{
|
|||
return this.transform(mx.translate.apply(mx, arguments));
|
||||
},
|
||||
|
||||
/**
|
||||
* The center of the visible area in project coordinates.
|
||||
*
|
||||
* @bean
|
||||
* @type Point
|
||||
*/
|
||||
getCenter: function() {
|
||||
return this.getBounds().getCenter();
|
||||
},
|
||||
|
||||
setCenter: function(/* center */) {
|
||||
var center = Point.read(arguments);
|
||||
this.translate(this.getCenter().subtract(center));
|
||||
},
|
||||
|
||||
/**
|
||||
* The view's zoom factor by which the project coordinates are magnified.
|
||||
*
|
||||
* @bean
|
||||
* @type Number
|
||||
* @see #getScaling()
|
||||
*/
|
||||
getZoom: function() {
|
||||
var decomposed = this._decompose(),
|
||||
scaling = decomposed && decomposed.scaling;
|
||||
// Use average since it can be non-uniform, and return 0 when it can't
|
||||
// be decomposed.
|
||||
return scaling ? (scaling.x + scaling.y) / 2 : 0;
|
||||
},
|
||||
|
||||
setZoom: function(zoom) {
|
||||
this.transform(new Matrix().scale(zoom / this.getZoom(),
|
||||
this.getCenter()));
|
||||
},
|
||||
|
||||
/**
|
||||
* The current rotation angle of the view, as described by its
|
||||
* {@link #matrix}.
|
||||
*
|
||||
* @bean
|
||||
* @type Number
|
||||
*/
|
||||
getRotation: function() {
|
||||
var decomposed = this._decompose();
|
||||
return decomposed && decomposed.rotation;
|
||||
},
|
||||
|
||||
setRotation: function(rotation) {
|
||||
var current = this.getRotation();
|
||||
if (current != null && rotation != null) {
|
||||
this.rotate(rotation - current);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The current scale factor of the view, as described by its
|
||||
* {@link #matrix}.
|
||||
*
|
||||
* @bean
|
||||
* @type Point
|
||||
* @see #getZoom()
|
||||
*/
|
||||
getScaling: function() {
|
||||
var decomposed = this._decompose(),
|
||||
scaling = decomposed && decomposed.scaling;
|
||||
return scaling
|
||||
? new LinkedPoint(scaling.x, scaling.y, this, 'setScaling')
|
||||
: undefined;
|
||||
},
|
||||
|
||||
setScaling: function(/* scaling */) {
|
||||
var current = this.getScaling(),
|
||||
// Clone existing points since we're caching internally.
|
||||
scaling = Point.read(arguments, 0, { clone: true, readNull: true });
|
||||
if (current && scaling) {
|
||||
this.scale(scaling.x / current.x, scaling.y / current.y);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* The view's transformation matrix, defining the view onto the project's
|
||||
* contents (position, zoom level, rotation, etc).
|
||||
*
|
||||
* @bean
|
||||
* @type Matrix
|
||||
*/
|
||||
getMatrix: function() {
|
||||
return this._matrix;
|
||||
},
|
||||
|
||||
setMatrix: function() {
|
||||
// Use Matrix#initialize to easily copy over values.
|
||||
// NOTE: calling initialize() also calls #_changed() for us, through its
|
||||
// call to #set() / #reset(), and this also handles _applyMatrix for us.
|
||||
var matrix = this._matrix;
|
||||
matrix.initialize.apply(matrix, arguments);
|
||||
},
|
||||
|
||||
/**
|
||||
* Rotates the view by a given angle around the given center point.
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue