mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-19 14:10:14 -05:00
Merge remote-tracking branch 'origin/master'
Conflicts: src/basic/Matrix.js src/item/Raster.js
This commit is contained in:
commit
3f972be500
13 changed files with 263 additions and 96 deletions
|
@ -458,10 +458,18 @@ var Matrix = Base.extend({
|
|||
// Canvas contexts seem to use another orientation: The scaleX (m00) and
|
||||
// scaleY (m11) values need to be flipped to get correct behaviour e.g.
|
||||
// when using rotation or shearing.
|
||||
if (reset) {
|
||||
context.setTransform(
|
||||
-this._m00, this._m01, this._m10,
|
||||
-this._m11, this._m02, this._m12
|
||||
);
|
||||
} else {
|
||||
context.transform(
|
||||
-this._m00, this._m01, this._m10,
|
||||
-this._m11, this._m02, this._m12
|
||||
);
|
||||
}
|
||||
>>>>>>> origin/master
|
||||
},
|
||||
|
||||
statics: {
|
||||
|
|
|
@ -2,17 +2,25 @@ Doc = Base.extend({
|
|||
beans: true,
|
||||
|
||||
initialize: function(canvas) {
|
||||
if (canvas) {
|
||||
if (canvas && canvas instanceof HTMLCanvasElement) {
|
||||
this.canvas = canvas;
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
this.size = new Size(canvas.offsetWidth, canvas.offsetHeight);
|
||||
} else {
|
||||
this.size = Size.read(arguments) || new Size(1024, 768);
|
||||
this.canvas = document.createElement('canvas');
|
||||
this.canvas.width = this.size.width;
|
||||
this.canvas.height = this.size.height;
|
||||
}
|
||||
this.bounds = new Rectangle(new Point(0, 0), this.size);
|
||||
this.ctx = this.canvas.getContext('2d');
|
||||
Paper.documents.push(this);
|
||||
this.activate();
|
||||
this.layers = [];
|
||||
this.activeLayer = new Layer();
|
||||
this.currentStyle = null;
|
||||
this.symbols = [];
|
||||
this.views = [new DocumentView(this)];
|
||||
this.activeView = this.views[0];
|
||||
},
|
||||
|
||||
getCurrentStyle: function() {
|
||||
|
@ -29,13 +37,18 @@ Doc = Base.extend({
|
|||
|
||||
redraw: function() {
|
||||
if (this.canvas) {
|
||||
// Initial tests conclude that clearing the canvas is always
|
||||
// faster than using clearRect:
|
||||
// Initial tests conclude that clearing the canvas using clearRect
|
||||
// is always faster than setting canvas.width = canvas.width
|
||||
// http://jsperf.com/clearrect-vs-setting-width/7
|
||||
var view = this.activeView;
|
||||
var bounds = view.bounds;
|
||||
this.ctx.clearRect(0, 0, this.size.width + 1, this.size.height + 1);
|
||||
this.ctx.save();
|
||||
view.matrix.applyToContext(this.ctx, true);
|
||||
for (var i = 0, l = this.layers.length; i < l; i++) {
|
||||
this.layers[i].draw(this.ctx, {});
|
||||
}
|
||||
this.ctx.restore();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
97
src/document/DocumentView.js
Normal file
97
src/document/DocumentView.js
Normal file
|
@ -0,0 +1,97 @@
|
|||
DocumentView = Base.extend({
|
||||
beans: true,
|
||||
|
||||
initialize: function(document) {
|
||||
this.document = document;
|
||||
this._bounds = this.document.bounds.clone();
|
||||
this.matrix = new Matrix();
|
||||
this._zoom = 1;
|
||||
this._center = this._bounds.center;
|
||||
},
|
||||
|
||||
// TODO: test this.
|
||||
getCenter: function() {
|
||||
return this._center;
|
||||
},
|
||||
|
||||
setCenter: function() {
|
||||
var center = Point.read(arguments);
|
||||
if (center) {
|
||||
var delta = center.subtract(this._center);
|
||||
this.scrollBy(delta);
|
||||
this._center = center;
|
||||
}
|
||||
},
|
||||
|
||||
getZoom: function() {
|
||||
return this._zoom;
|
||||
},
|
||||
|
||||
setZoom: function(zoom) {
|
||||
// TODO: clamp the view between 1/32 and 64?
|
||||
var mx = new Matrix();
|
||||
mx.scale(zoom / this._zoom, this.center);
|
||||
this.transform(mx);
|
||||
this._zoom = zoom;
|
||||
},
|
||||
|
||||
scrollBy: function() {
|
||||
var point = Point.read(arguments).negate();
|
||||
var mx = new Matrix().translate(point);
|
||||
this.transform(mx);
|
||||
},
|
||||
|
||||
getBounds: function() {
|
||||
return this._bounds;
|
||||
},
|
||||
|
||||
// TODO:
|
||||
// setBounds: function(rect) {
|
||||
//
|
||||
// },
|
||||
|
||||
// TODO: getInvalidBounds
|
||||
// TODO: invalidate(rect)
|
||||
// TODO: style: artwork / preview / raster / opaque / ink
|
||||
// TODO: getShowGrid
|
||||
// TODO: getMousePoint
|
||||
// TODO: artworkToView(rect)
|
||||
artworkToView: function(point) {
|
||||
return this.matrix.transform(point);
|
||||
},
|
||||
|
||||
viewToArtwork: function(point) {
|
||||
// TODO: cache the inverse matrix:
|
||||
return this.matrix.createInverse().transform(point);
|
||||
},
|
||||
|
||||
// TODO: inherit this code somehow?
|
||||
transform: function(matrix, flags) {
|
||||
var width = this.document.bounds.width;
|
||||
var height = this.document.bounds.height;
|
||||
var x = width * -0.5;
|
||||
var y = height * -0.5;
|
||||
var coords = [
|
||||
x, y,
|
||||
x + width, y,
|
||||
x + width, y + height,
|
||||
x, y + height];
|
||||
this.matrix.preConcatenate(matrix);
|
||||
this.matrix.createInverse().transform(coords, 0, coords, 0, 4);
|
||||
var xMin = coords[0], xMax = coords[0];
|
||||
var yMin = coords[1], yMax = coords[1];
|
||||
for (var i = 2; i < 8; i += 2) {
|
||||
var x = coords[i];
|
||||
var y = coords[i + 1];
|
||||
xMin = Math.min(x, xMin);
|
||||
xMax = Math.max(x, xMax);
|
||||
yMin = Math.min(y, yMin);
|
||||
yMax = Math.max(y, yMax);
|
||||
};
|
||||
var bounds = this._bounds;
|
||||
bounds.x = xMin;
|
||||
bounds.y = yMin;
|
||||
bounds.width = xMax - xMin;
|
||||
bounds.height = yMax - yMin;
|
||||
}
|
||||
});
|
|
@ -30,14 +30,17 @@ BlendMode = {
|
|||
process: function(documentContext, item, param) {
|
||||
// TODO: use strokeBounds
|
||||
var itemBounds = item.bounds;
|
||||
if (!itemBounds)
|
||||
return;
|
||||
var top = Math.floor(itemBounds.top);
|
||||
var left = Math.floor(itemBounds.left);
|
||||
var size = itemBounds.size.ceil();
|
||||
var size = itemBounds.size.ceil().add(1, 1);
|
||||
var width = size.width;
|
||||
var height = size.height;
|
||||
|
||||
var itemCanvas = CanvasProvider.getCanvas(size);
|
||||
var itemContext = itemCanvas.getContext('2d');
|
||||
itemContext.save();
|
||||
if (item.matrix) {
|
||||
var matrix = item.matrix.clone();
|
||||
var transMatrix = Matrix.getTranslateInstance(-left, -top);
|
||||
|
@ -210,6 +213,7 @@ BlendMode = {
|
|||
}
|
||||
}
|
||||
documentContext.putImageData(dstD, left, top);
|
||||
itemContext.restore();
|
||||
CanvasProvider.returnCanvas(itemCanvas);
|
||||
}
|
||||
};
|
|
@ -27,6 +27,8 @@ Group = Item.extend({
|
|||
// TODO: use strokeBounds for this, when implemented:
|
||||
tempCanvas = CanvasProvider.getCanvas(this.document.size);
|
||||
ctx = tempCanvas.getContext('2d');
|
||||
ctx.save();
|
||||
this.document.activeView.matrix.applyToContext(ctx);
|
||||
}
|
||||
for (var i = 0, l = this.children.length; i < l; i++) {
|
||||
this.children[i].draw(ctx, param);
|
||||
|
@ -34,11 +36,18 @@ Group = Item.extend({
|
|||
ctx.clip();
|
||||
}
|
||||
if (tempCanvas) {
|
||||
// restore the activeView.matrix transformation,
|
||||
// so we can draw the image without transformation.
|
||||
originalCtx.restore();
|
||||
originalCtx.save();
|
||||
originalCtx.globalAlpha = this.opacity;
|
||||
originalCtx.drawImage(tempCanvas, 0, 0);
|
||||
originalCtx.restore();
|
||||
// Return the canvas, so it can be reused
|
||||
// apply the view transformation again.
|
||||
this.document.activeView.matrix.applyToContext(ctx);
|
||||
// Restore the state of the temp canvas:
|
||||
ctx.restore();
|
||||
// Return the temp canvas, so it can be reused
|
||||
CanvasProvider.returnCanvas(tempCanvas);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -547,7 +547,7 @@ Item = Base.extend({
|
|||
var context = canvas.getContext('2d');
|
||||
var matrix = new Matrix().scale(scale).translate(-bounds.x, -bounds.y);
|
||||
matrix.applyToContext(context);
|
||||
this.draw(context);
|
||||
this.draw(context, {});
|
||||
var raster = new Raster(canvas);
|
||||
raster.position = this.bounds.center;
|
||||
raster.scale(1 / scale);
|
||||
|
|
|
@ -63,6 +63,16 @@ PlacedSymbol = Item.extend({
|
|||
if (this.blendMode != 'normal' && !param.ignoreBlendMode) {
|
||||
BlendMode.process(ctx, this, param);
|
||||
} else {
|
||||
var tempCanvas, originalCtx;
|
||||
if (this.opacity < 1) {
|
||||
originalCtx = ctx;
|
||||
// TODO: use strokeBounds for this, when implemented:
|
||||
tempCanvas = CanvasProvider.getCanvas(this.document.size);
|
||||
ctx = tempCanvas.getContext('2d');
|
||||
ctx.save();
|
||||
this.document.activeView.matrix.applyToContext(ctx);
|
||||
}
|
||||
|
||||
// TODO: we need to preserve strokewidth, but still transform the fill
|
||||
ctx.save();
|
||||
if (param.ignoreBlendMode !== true)
|
||||
|
@ -70,6 +80,22 @@ PlacedSymbol = Item.extend({
|
|||
param.ignoreBlendMode = false;
|
||||
this.symbol.definition.draw(ctx, param);
|
||||
ctx.restore();
|
||||
|
||||
if (tempCanvas) {
|
||||
// restore the activeView.matrix transformation,
|
||||
// so we can draw the image without transformation.
|
||||
originalCtx.restore();
|
||||
originalCtx.save();
|
||||
originalCtx.globalAlpha = this.opacity;
|
||||
originalCtx.drawImage(tempCanvas, 0, 0);
|
||||
originalCtx.restore();
|
||||
// apply the view transformation again.
|
||||
this.document.activeView.matrix.applyToContext(ctx, true);
|
||||
// Restore the state of the temp canvas:
|
||||
ctx.restore();
|
||||
// Return the temp canvas, so it can be reused
|
||||
CanvasProvider.returnCanvas(tempCanvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO:
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
Tool = ToolHandler.extend({
|
||||
Tool = ToolHandler.extend(new function() {
|
||||
function viewToArtwork(event, document) {
|
||||
var point = Point.create(event.offset.x, event.offset.y);
|
||||
// TODO: always the active view?
|
||||
return document.activeView.viewToArtwork(point);
|
||||
};
|
||||
|
||||
return {
|
||||
beans: true,
|
||||
|
||||
initialize: function(handlers, doc) {
|
||||
|
@ -15,7 +22,7 @@ Tool = ToolHandler.extend({
|
|||
var dragging = false;
|
||||
var events = {
|
||||
dragstart: function(e) {
|
||||
curPoint = new Point(e.offset);
|
||||
curPoint = viewToArtwork(e, that._document);
|
||||
that.onHandleEvent('MOUSE_DOWN', curPoint, null, null);
|
||||
if (that.onMouseDown)
|
||||
that._document.redraw();
|
||||
|
@ -24,7 +31,7 @@ Tool = ToolHandler.extend({
|
|||
dragging = true;
|
||||
},
|
||||
drag: function(e) {
|
||||
if (e) curPoint = new Point(e.offset);
|
||||
if (e) curPoint = viewToArtwork(e, that._document);
|
||||
if (curPoint) {
|
||||
that.onHandleEvent('MOUSE_DRAG', curPoint, null, null);
|
||||
if (that.onMouseDrag)
|
||||
|
@ -35,14 +42,16 @@ Tool = ToolHandler.extend({
|
|||
curPoint = null;
|
||||
if (this.eventInterval != -1)
|
||||
clearInterval(this.intervalId);
|
||||
that.onHandleEvent('MOUSE_UP', new Point(e.offset), null, null);
|
||||
that.onHandleEvent('MOUSE_UP',
|
||||
viewToArtwork(e, that._document), null, null);
|
||||
if (that.onMouseUp)
|
||||
that._document.redraw();
|
||||
dragging = false;
|
||||
},
|
||||
mousemove: function(e) {
|
||||
if (!dragging) {
|
||||
that.onHandleEvent('MOUSE_MOVE', new Point(e.offset), null, null);
|
||||
that.onHandleEvent('MOUSE_MOVE',
|
||||
viewToArtwork(e, that._document), null, null);
|
||||
if (that.onMouseMove)
|
||||
that._document.redraw();
|
||||
}
|
||||
|
@ -71,4 +80,5 @@ Tool = ToolHandler.extend({
|
|||
getDocument: function() {
|
||||
return this._document;
|
||||
}
|
||||
};
|
||||
});
|
Loading…
Reference in a new issue