mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-03 19:45:44 -05:00
Do not keep the view's matrix baked into _globalMatrix, since we might allow multiple views soon.
This commit is contained in:
parent
66b1087d33
commit
60f6eca6c4
4 changed files with 49 additions and 44 deletions
|
@ -1152,25 +1152,20 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
* @type Matrix
|
||||
* @bean
|
||||
*/
|
||||
getGlobalMatrix: function(_internal) {
|
||||
getGlobalMatrix: function(_dontClone) {
|
||||
var matrix = this._globalMatrix,
|
||||
updateVersion = this._project._updateVersion,
|
||||
viewMatrix = this.getView()._matrix;
|
||||
// Internally we actually do factor in the view's transformations as
|
||||
// well, but these are removed again in the return statement below.
|
||||
// This way it is easier to draw selections and handle non-direct
|
||||
// blitting, see Item#draw().
|
||||
updateVersion = this._project._updateVersion;
|
||||
// If #_globalMatrix is out of sync, recalculate it now.
|
||||
if (matrix && matrix._updateVersion !== updateVersion)
|
||||
matrix = null;
|
||||
if (!matrix) {
|
||||
matrix = this._globalMatrix = this._matrix.clone();
|
||||
matrix.preConcatenate(this._parent
|
||||
? this._parent.getGlobalMatrix(true)
|
||||
: viewMatrix);
|
||||
var parent = this._parent;
|
||||
if (parent)
|
||||
matrix.preConcatenate(parent.getGlobalMatrix(true));
|
||||
matrix._updateVersion = updateVersion;
|
||||
}
|
||||
return _internal ? matrix : viewMatrix.inverted().concatenate(matrix);
|
||||
return _dontClone ? matrix : matrix.clone();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1591,7 +1586,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
ctx.save();
|
||||
matrix.applyToContext(ctx);
|
||||
// See Project#draw() for an explanation of new Base()
|
||||
this.draw(ctx, new Base({ transforms: [matrix] }));
|
||||
this.draw(ctx, new Base({ matrices: [matrix] }));
|
||||
ctx.restore();
|
||||
var raster = new Raster(Item.NO_INSERT);
|
||||
raster.setCanvas(canvas);
|
||||
|
@ -1706,8 +1701,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
? parentTotalMatrix.clone().concatenate(matrix)
|
||||
// If this is the first one in the recursion, factor in the
|
||||
// zoom of the view and the globalMatrix of the item.
|
||||
: this.getGlobalMatrix().clone().preConcatenate(
|
||||
view._matrix),
|
||||
: this.getGlobalMatrix().preConcatenate(view._matrix),
|
||||
// Calculate the transformed padding as 2D size that describes the
|
||||
// transformed tolerance circle / ellipse. Make sure it's never 0
|
||||
// since we're using it for division.
|
||||
|
@ -2911,8 +2905,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
* @return {Point} the transformed point as a new instance
|
||||
*/
|
||||
globalToLocal: function(/* point */) {
|
||||
var matrix = this.getGlobalMatrix();
|
||||
return matrix && matrix._inverseTransform(Point.read(arguments));
|
||||
return this.getGlobalMatrix(true)._inverseTransform(
|
||||
Point.read(arguments));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -2923,8 +2917,8 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
* @return {Point} the transformed point as a new instance
|
||||
*/
|
||||
localToGlobal: function(/* point */) {
|
||||
var matrix = this.getGlobalMatrix();
|
||||
return matrix && matrix._transformPoint(Point.read(arguments));
|
||||
return this.getGlobalMatrix(true)._transformPoint(
|
||||
Point.read(arguments));
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -3520,10 +3514,10 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
var updateVersion = this._updateVersion = this._project._updateVersion;
|
||||
// Keep calculating the current global matrix, by keeping a history
|
||||
// and pushing / popping as we go along.
|
||||
var trackTransforms = param.trackTransforms,
|
||||
transforms = param.transforms,
|
||||
var matrices = param.matrices,
|
||||
parentMatrix = matrices[matrices.length - 1],
|
||||
viewMatrix = param.viewMatrix,
|
||||
matrix = this._matrix,
|
||||
parentMatrix = transforms[transforms.length - 1],
|
||||
globalMatrix = parentMatrix.clone().concatenate(matrix);
|
||||
// If this item is not invertible, do not draw it, since it would cause
|
||||
// empty ctx.currentPath and mess up caching. It appears to also be a
|
||||
|
@ -3531,11 +3525,21 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
// handles it the same way.
|
||||
if (!globalMatrix.isInvertible())
|
||||
return;
|
||||
|
||||
// Since globalMatrix does not take the view's matrix into account (we
|
||||
// could have multiple views with different zooms), we may have to
|
||||
// pre-concatenate the view's matrix.
|
||||
// Note that it's only provided if it isn't the identity matrix.
|
||||
function getViewMatrix(matrix) {
|
||||
return viewMatrix ? viewMatrix.clone().concatenate(matrix) : matrix;
|
||||
}
|
||||
|
||||
// Only keep track of transformation if told so. See Project#draw()
|
||||
if (trackTransforms) {
|
||||
transforms.push(this._globalMatrix = globalMatrix);
|
||||
// We also keep the cached _globalMatrix versioned.
|
||||
matrices.push(globalMatrix);
|
||||
if (param.updateMatrix) {
|
||||
// Update the cached _globalMatrix and keep it versioned.
|
||||
globalMatrix._updateVersion = updateVersion;
|
||||
this._globalMatrix = globalMatrix;
|
||||
}
|
||||
|
||||
// If the item has a blendMode or is defining an opacity, draw it on
|
||||
|
@ -3561,7 +3565,7 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
if (!direct) {
|
||||
// Apply the parent's global matrix to the calculation of correct
|
||||
// bounds.
|
||||
var bounds = this.getStrokeBounds(parentMatrix);
|
||||
var bounds = this.getStrokeBounds(getViewMatrix(parentMatrix));
|
||||
if (!bounds.width || !bounds.height)
|
||||
return;
|
||||
// Store previous offset and save the main context, so we can
|
||||
|
@ -3590,15 +3594,14 @@ var Item = Base.extend(Callback, /** @lends Item# */{
|
|||
ctx.translate(-itemOffset.x, -itemOffset.y);
|
||||
}
|
||||
// Apply globalMatrix when drawing into temporary canvas.
|
||||
(direct ? matrix : globalMatrix).applyToContext(ctx);
|
||||
(direct ? matrix : getViewMatrix(globalMatrix)).applyToContext(ctx);
|
||||
// If we're drawing into a separate canvas and a clipItem is defined for
|
||||
// the current rendering loop, we need to draw the clip item again.
|
||||
if (!direct && param.clipItem)
|
||||
param.clipItem.draw(ctx, param.extend({ clip: true }));
|
||||
this._draw(ctx, param);
|
||||
ctx.restore();
|
||||
if (trackTransforms)
|
||||
transforms.pop();
|
||||
matrices.pop();
|
||||
if (param.clip && !param.dontFinish)
|
||||
ctx.clip();
|
||||
// If a temporary canvas was created, composite it onto the main canvas:
|
||||
|
|
|
@ -489,7 +489,7 @@ var Raster = Item.extend(/** @lends Raster# */{
|
|||
// If a path was passed, draw it as a clipping mask:
|
||||
// See Project#draw() for an explanation of new Base()
|
||||
if (path)
|
||||
path.draw(ctx, new Base({ clip: true, transforms: [matrix] }));
|
||||
path.draw(ctx, new Base({ clip: true, matrices: [matrix] }));
|
||||
// Now draw the image clipped into it.
|
||||
this._matrix.applyToContext(ctx);
|
||||
ctx.drawImage(this.getElement(),
|
||||
|
|
|
@ -150,6 +150,8 @@ PathItem.inject(new function() {
|
|||
// See if the CompoundPath can be reduced to just a simple Path.
|
||||
result = result.reduce();
|
||||
// Copy over the left-hand item's style and we're done.
|
||||
// TODO: Consider using Item#_clone() for this, but find a way to not
|
||||
// clone children / name (content).
|
||||
result.setStyle(path1._style);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -426,12 +426,12 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
|
|||
var param = new Base({
|
||||
offset: new Point(0, 0),
|
||||
pixelRatio: pixelRatio,
|
||||
// Tell the drawing routine that we want to track nested matrices
|
||||
// in param.transforms, and that we want it to set _globalMatrix
|
||||
// as used below. Item#rasterize() and Raster#getAverageColor() do
|
||||
// not need to set this.
|
||||
trackTransforms: true,
|
||||
transforms: [matrix]
|
||||
viewMatrix: matrix.isIdentity() ? null : matrix,
|
||||
matrices: [new Matrix()], // Start with the identity matrix.
|
||||
// Tell the drawing routine that we want to keep _globalMatrix up to
|
||||
// date. Item#rasterize() and Raster#getAverageColor() should not
|
||||
// set this.
|
||||
updateMatrix: true
|
||||
});
|
||||
for (var i = 0, l = this.layers.length; i < l; i++)
|
||||
this.layers[i].draw(ctx, param);
|
||||
|
@ -441,24 +441,24 @@ var Project = PaperScopeItem.extend(/** @lends Project# */{
|
|||
if (this._selectedItemCount > 0) {
|
||||
ctx.save();
|
||||
ctx.strokeWidth = 1;
|
||||
var size = this._scope.settings.handleSize,
|
||||
half = size / 2;
|
||||
for (var id in this._selectedItems) {
|
||||
var item = this._selectedItems[id],
|
||||
globalMatrix = item._globalMatrix,
|
||||
size = this._scope.settings.handleSize,
|
||||
half = size / 2;
|
||||
var item = this._selectedItems[id];
|
||||
if (item._updateVersion === this._updateVersion
|
||||
&& (item._drawSelected || item._boundsSelected)
|
||||
&& globalMatrix) {
|
||||
&& (item._drawSelected || item._boundsSelected)) {
|
||||
// Allow definition of selected color on a per item and per
|
||||
// layer level, with a fallback to #009dec
|
||||
var color = item.getSelectedColor()
|
||||
|| item.getLayer().getSelectedColor();
|
||||
|| item.getLayer().getSelectedColor(),
|
||||
mx = matrix.clone().concatenate(
|
||||
item.getGlobalMatrix(true));
|
||||
ctx.strokeStyle = ctx.fillStyle = color
|
||||
? color.toCanvasStyle(ctx) : '#009dec';
|
||||
if (item._drawSelected)
|
||||
item._drawSelected(ctx, globalMatrix);
|
||||
item._drawSelected(ctx, mx);
|
||||
if (item._boundsSelected) {
|
||||
var coords = globalMatrix._transformCorners(
|
||||
var coords = mx._transformCorners(
|
||||
item.getInternalBounds());
|
||||
// Now draw a rectangle that connects the transformed
|
||||
// bounds corners, and draw the corners.
|
||||
|
|
Loading…
Reference in a new issue