mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-07 13:22:07 -05:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
7dce6f3a6c
5 changed files with 92 additions and 55 deletions
|
@ -193,33 +193,6 @@ var Rectangle = this.Rectangle = Base.extend({
|
||||||
&& rect.y < this.y + this.height;
|
&& rect.y < this.y + this.height;
|
||||||
},
|
},
|
||||||
|
|
||||||
intersect: function(rect) {
|
|
||||||
rect = Rectangle.read(arguments);
|
|
||||||
var x1 = Math.max(this.x, rect.x),
|
|
||||||
y1 = Math.max(this.y, rect.y),
|
|
||||||
x2 = Math.min(this.x + this.width, rect.x + rect.width),
|
|
||||||
y2 = Math.min(this.y + this.height, rect.y + rect.height);
|
|
||||||
return Rectangle.create(x1, y1, x2 - x1, y2 - y1);
|
|
||||||
},
|
|
||||||
|
|
||||||
unite: function(rect) {
|
|
||||||
rect = Rectangle.read(arguments);
|
|
||||||
var x1 = Math.min(this.x, rect.x),
|
|
||||||
y1 = Math.min(this.y, rect.y),
|
|
||||||
x2 = Math.max(this.x + this.width, rect.x + rect.width),
|
|
||||||
y2 = Math.max(this.y + this.height, rect.y + rect.height);
|
|
||||||
return Rectangle.create(x1, y1, x2 - x1, y2 - y1);
|
|
||||||
},
|
|
||||||
|
|
||||||
include: function(point) {
|
|
||||||
point = Point.read(arguments);
|
|
||||||
var x1 = Math.min(this.x, point.x),
|
|
||||||
y1 = Math.min(this.y, point.y),
|
|
||||||
x2 = Math.max(this.x + this.width, point.x),
|
|
||||||
y2 = Math.max(this.y + this.height, point.y);
|
|
||||||
return Rectangle.create(x1, y1, x2 - x1, y2 - y1);
|
|
||||||
},
|
|
||||||
|
|
||||||
toString: function() {
|
toString: function() {
|
||||||
return '{ x: ' + this.x
|
return '{ x: ' + this.x
|
||||||
+ ', y: ' + this.y
|
+ ', y: ' + this.y
|
||||||
|
@ -234,6 +207,27 @@ var Rectangle = this.Rectangle = Base.extend({
|
||||||
return new Rectangle(Rectangle.dont).set(x, y, width, height);
|
return new Rectangle(Rectangle.dont).set(x, y, width, height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}, new function() { // Scope for injecting intersect, unite and include.
|
||||||
|
return Base.each({
|
||||||
|
intersect: [true, false],
|
||||||
|
unite: [false, false],
|
||||||
|
include: [false, true]
|
||||||
|
}, function(values, name) {
|
||||||
|
var intersect = values[0],
|
||||||
|
isPoint = values[1],
|
||||||
|
math1 = Math[intersect ? 'max' : 'min'],
|
||||||
|
math2 = Math[intersect ? 'min' : 'max'];
|
||||||
|
this[name] = function() {
|
||||||
|
var object = (isPoint ? Point : Rectangle).read(arguments),
|
||||||
|
x1 = math1(this.x, object.x),
|
||||||
|
y1 = math1(this.y, object.y),
|
||||||
|
x2 = math2(this.x + this.width,
|
||||||
|
object.x + (isPoint ? 0 : object.width)),
|
||||||
|
y2 = math2(this.y + this.height,
|
||||||
|
object.y + (isPoint ? 0 : object.height));
|
||||||
|
return Rectangle.create(x1, y1, x2 - x1, y2 - y1);
|
||||||
|
};
|
||||||
|
}, {});
|
||||||
}, new function() {
|
}, new function() {
|
||||||
return Base.each([
|
return Base.each([
|
||||||
['Top', 'Left'], ['Top', 'Right'],
|
['Top', 'Left'], ['Top', 'Right'],
|
||||||
|
|
|
@ -80,6 +80,26 @@ var Document = this.Document = Base.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects all items in the document.
|
||||||
|
*/
|
||||||
|
selectAll: function() {
|
||||||
|
// TODO: is using for var i in good practice?
|
||||||
|
// or should we use Base.each? (JP)
|
||||||
|
for (var i = 0, l = this.layers.length; i < l; i++)
|
||||||
|
this.layers[i].setSelected(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deselects all selected items in the document.
|
||||||
|
*/
|
||||||
|
deselectAll: function() {
|
||||||
|
// TODO: is using for var i in good practice?
|
||||||
|
// or should we use Base.each? (JP)
|
||||||
|
for (var i in this._selectedItems)
|
||||||
|
this._selectedItems[i].setSelected(false);
|
||||||
|
},
|
||||||
|
|
||||||
draw: function() {
|
draw: function() {
|
||||||
if (this.canvas) {
|
if (this.canvas) {
|
||||||
var ctx = this.context;
|
var ctx = this.context;
|
||||||
|
|
|
@ -221,28 +221,28 @@ var Item = this.Item = Base.extend({
|
||||||
* The first item contained within this item.
|
* The first item contained within this item.
|
||||||
*/
|
*/
|
||||||
getFirstChild: function() {
|
getFirstChild: function() {
|
||||||
return this.children ? this.children[0] : null;
|
return this.children && this.children[0] || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The last item contained within this item.
|
* The last item contained within this item.
|
||||||
*/
|
*/
|
||||||
getLastChild: function() {
|
getLastChild: function() {
|
||||||
return this.children ? this.children[this.children.length - 1] : null;
|
return this.children && this.children[this.children.length - 1] || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The next item on the same level as this item.
|
* The next item on the same level as this item.
|
||||||
*/
|
*/
|
||||||
getNextSibling: function() {
|
getNextSibling: function() {
|
||||||
return this.parent ? this.parent.children[this.getIndex() + 1] : null;
|
return this.parent && this.parent.children[this.getIndex() + 1] || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The previous item on the same level as this item.
|
* The previous item on the same level as this item.
|
||||||
*/
|
*/
|
||||||
getPreviousSibling: function() {
|
getPreviousSibling: function() {
|
||||||
return this.parent ? this.parent.children[this.getIndex() - 1] : null;
|
return this.parent && this.parent.children[this.getIndex() - 1] || null;
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -252,8 +252,7 @@ var Item = this.Item = Base.extend({
|
||||||
// TODO: Relying on indexOf() here is slow, especially since it is
|
// TODO: Relying on indexOf() here is slow, especially since it is
|
||||||
// used for getPrevious/NextSibling().
|
// used for getPrevious/NextSibling().
|
||||||
// We need linked lists instead.
|
// We need linked lists instead.
|
||||||
// TODO: Return null instead of -1?
|
return this.parent && this.parent.children.indexOf(this) || null;
|
||||||
return this.parent ? this.parent.children.indexOf(this) : -1;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -272,7 +271,7 @@ var Item = this.Item = Base.extend({
|
||||||
* Removes the item.
|
* Removes the item.
|
||||||
*/
|
*/
|
||||||
remove: function() {
|
remove: function() {
|
||||||
if(this.isSelected())
|
if (this.isSelected())
|
||||||
this.setSelected(false);
|
this.setSelected(false);
|
||||||
return this.removeFromParent();
|
return this.removeFromParent();
|
||||||
},
|
},
|
||||||
|
@ -428,23 +427,35 @@ var Item = this.Item = Base.extend({
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getStrokeBounds: function() {
|
||||||
|
return this._getBounds(true);
|
||||||
|
},
|
||||||
|
|
||||||
getBounds: function() {
|
getBounds: function() {
|
||||||
if (this.children && this.children.length) {
|
return this._getBounds(false);
|
||||||
var rect = this.children[0].getBounds(),
|
},
|
||||||
x1 = rect.x,
|
|
||||||
y1 = rect.y,
|
_getBounds: function(includeStroke) {
|
||||||
x2 = rect.x + rect.width,
|
var children = this.children;
|
||||||
y2 = rect.y + rect.height;
|
if (children && children.length) {
|
||||||
for (var i = 1, l = this.children.length; i < l; i++) {
|
var x1, x2;
|
||||||
rect = this.children[i].getBounds();
|
var y1 = x1 = Infinity;
|
||||||
|
var y2 = x2 = -Infinity;
|
||||||
|
for (var i = 0, l = children.length; i < l; i++) {
|
||||||
|
var child = children[i],
|
||||||
|
rect = includeStroke
|
||||||
|
? child.getStrokeBounds()
|
||||||
|
: child.getBounds();
|
||||||
x1 = Math.min(rect.x, x1);
|
x1 = Math.min(rect.x, x1);
|
||||||
y1 = Math.min(rect.y, y1);
|
y1 = Math.min(rect.y, y1);
|
||||||
x2 = Math.max(rect.x + rect.width, x1 + x2 - x1);
|
x2 = Math.max(rect.x + rect.width, x2);
|
||||||
y2 = Math.max(rect.y + rect.height, y1 + y2 - y1);
|
y2 = Math.max(rect.y + rect.height, y2);
|
||||||
}
|
}
|
||||||
return LinkedRectangle.create(this, 'setBounds',
|
return includeStroke
|
||||||
x1, y1, x2 - x1, y2 - y1);
|
? Rectangle.create(x1, y1, x2 - x1, y2 - y1)
|
||||||
|
: LinkedRectangle.create(this, 'setBounds',
|
||||||
|
x1, y1, x2 - x1, y2 - y1);
|
||||||
}
|
}
|
||||||
// TODO: What to return if nothing is defined, e.g. empty Groups?
|
// TODO: What to return if nothing is defined, e.g. empty Groups?
|
||||||
// Scriptographer behaves weirdly then too.
|
// Scriptographer behaves weirdly then too.
|
||||||
|
@ -494,11 +505,11 @@ var Item = this.Item = Base.extend({
|
||||||
// weird results on Scriptographer. Also we can't use antialiasing, since
|
// weird results on Scriptographer. Also we can't use antialiasing, since
|
||||||
// Canvas doesn't support it yet. Document colorMode is also out of the
|
// Canvas doesn't support it yet. Document colorMode is also out of the
|
||||||
// question for now.
|
// question for now.
|
||||||
var bounds = this.getStrokeBounds();
|
var bounds = this.getStrokeBounds(),
|
||||||
var scale = resolution ? resolution / 72 : 1;
|
scale = (resolution || 72) / 72,
|
||||||
var canvas = CanvasProvider.getCanvas(bounds.getSize().multiply(scale));
|
canvas = CanvasProvider.getCanvas(bounds.getSize().multiply(scale)),
|
||||||
var ctx = canvas.getContext('2d');
|
ctx = canvas.getContext('2d'),
|
||||||
var matrix = new Matrix().scale(scale).translate(-bounds.x, -bounds.y);
|
matrix = new Matrix().scale(scale).translate(-bounds.x, -bounds.y);
|
||||||
matrix.applyToContext(ctx);
|
matrix.applyToContext(ctx);
|
||||||
this.draw(ctx, {});
|
this.draw(ctx, {});
|
||||||
var raster = new Raster(canvas);
|
var raster = new Raster(canvas);
|
||||||
|
@ -720,8 +731,8 @@ var Item = this.Item = Base.extend({
|
||||||
|
|
||||||
// Floor the offset and ceil the size, so we don't cut off any
|
// Floor the offset and ceil the size, so we don't cut off any
|
||||||
// antialiased pixels when drawing onto the temporary canvas.
|
// antialiased pixels when drawing onto the temporary canvas.
|
||||||
var itemOffset = bounds.getTopLeft().floor();
|
var itemOffset = bounds.getTopLeft().floor(),
|
||||||
var size = bounds.getSize().ceil().add(1, 1);
|
size = bounds.getSize().ceil().add(1, 1);
|
||||||
tempCanvas = CanvasProvider.getCanvas(size);
|
tempCanvas = CanvasProvider.getCanvas(size);
|
||||||
|
|
||||||
// Save the parent context, so we can draw onto it later
|
// Save the parent context, so we can draw onto it later
|
||||||
|
@ -894,7 +905,7 @@ var Item = this.Item = Base.extend({
|
||||||
for(var id in set) {
|
for(var id in set) {
|
||||||
var item = set[id];
|
var item = set[id];
|
||||||
item.remove();
|
item.remove();
|
||||||
for(var type in sets) {
|
for (var type in sets) {
|
||||||
var other = sets[type];
|
var other = sets[type];
|
||||||
if (other != set && other[item.getId()])
|
if (other != set && other[item.getId()])
|
||||||
delete other[item.getId()];
|
delete other[item.getId()];
|
||||||
|
|
|
@ -198,6 +198,10 @@ var Raster = this.Raster = Item.extend({
|
||||||
}
|
}
|
||||||
return this._bounds;
|
return this._bounds;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getStrokeBounds: function() {
|
||||||
|
return this.getBounds();
|
||||||
|
},
|
||||||
|
|
||||||
draw: function(ctx, param) {
|
draw: function(ctx, param) {
|
||||||
if (param.selection) {
|
if (param.selection) {
|
||||||
|
|
|
@ -16,12 +16,20 @@ test('new Group([item])', function() {
|
||||||
|
|
||||||
test('Group bounds', function() {
|
test('Group bounds', function() {
|
||||||
var doc = new Document();
|
var doc = new Document();
|
||||||
|
doc.currentStyle = {
|
||||||
|
strokeWidth: 5,
|
||||||
|
strokeColor: 'black'
|
||||||
|
};
|
||||||
var path = new Path.Circle([150, 150], 60);
|
var path = new Path.Circle([150, 150], 60);
|
||||||
var secondPath = new Path.Circle([175, 175], 85);
|
var secondPath = new Path.Circle([175, 175], 85);
|
||||||
var group = new Group([path, secondPath]);
|
var group = new Group([path, secondPath]);
|
||||||
compareRectangles(group.bounds, { x: 90, y: 90, width: 170, height: 170 });
|
compareRectangles(group.bounds, { x: 90, y: 90, width: 170, height: 170 });
|
||||||
|
compareRectangles(group.strokeBounds, { x: 87.5, y: 87.5, width: 175, height: 175 });
|
||||||
|
|
||||||
group.rotate(20);
|
group.rotate(20);
|
||||||
compareRectangles(group.bounds, { x: 89.97681, y: 82.94095, width: 170.04639, height: 177.08224 });
|
compareRectangles(group.bounds, { x: 89.97681, y: 82.94095, width: 170.04639, height: 177.08224 });
|
||||||
|
compareRectangles(group.strokeBounds, { x: 87.47681, y: 80.44095, width: 175.04639, height: 182.08224 });
|
||||||
group.rotate(20, new Point(50, 50));
|
group.rotate(20, new Point(50, 50));
|
||||||
compareRectangles(group.bounds, { x: 39.70692, y: 114.99196, width: 170.00412, height: 180.22401 });
|
compareRectangles(group.bounds, { x: 39.70692, y: 114.99196, width: 170.00412, height: 180.22401 });
|
||||||
|
compareRectangles(group.strokeBounds, { x: 37.20692, y: 112.49196, width: 175.00412, height: 185.22401 });
|
||||||
});
|
});
|
Loading…
Reference in a new issue