mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2025-01-05 20:32:00 -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;
|
||||
},
|
||||
|
||||
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() {
|
||||
return '{ x: ' + this.x
|
||||
+ ', y: ' + this.y
|
||||
|
@ -234,6 +207,27 @@ var Rectangle = this.Rectangle = Base.extend({
|
|||
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() {
|
||||
return Base.each([
|
||||
['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() {
|
||||
if (this.canvas) {
|
||||
var ctx = this.context;
|
||||
|
|
|
@ -221,28 +221,28 @@ var Item = this.Item = Base.extend({
|
|||
* The first item contained within this item.
|
||||
*/
|
||||
getFirstChild: function() {
|
||||
return this.children ? this.children[0] : null;
|
||||
return this.children && this.children[0] || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* The last item contained within this item.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
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
|
||||
// used for getPrevious/NextSibling().
|
||||
// We need linked lists instead.
|
||||
// TODO: Return null instead of -1?
|
||||
return this.parent ? this.parent.children.indexOf(this) : -1;
|
||||
return this.parent && this.parent.children.indexOf(this) || null;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -272,7 +271,7 @@ var Item = this.Item = Base.extend({
|
|||
* Removes the item.
|
||||
*/
|
||||
remove: function() {
|
||||
if(this.isSelected())
|
||||
if (this.isSelected())
|
||||
this.setSelected(false);
|
||||
return this.removeFromParent();
|
||||
},
|
||||
|
@ -428,23 +427,35 @@ var Item = this.Item = Base.extend({
|
|||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
|
||||
getStrokeBounds: function() {
|
||||
return this._getBounds(true);
|
||||
},
|
||||
|
||||
getBounds: function() {
|
||||
if (this.children && this.children.length) {
|
||||
var rect = this.children[0].getBounds(),
|
||||
x1 = rect.x,
|
||||
y1 = rect.y,
|
||||
x2 = rect.x + rect.width,
|
||||
y2 = rect.y + rect.height;
|
||||
for (var i = 1, l = this.children.length; i < l; i++) {
|
||||
rect = this.children[i].getBounds();
|
||||
return this._getBounds(false);
|
||||
},
|
||||
|
||||
_getBounds: function(includeStroke) {
|
||||
var children = this.children;
|
||||
if (children && children.length) {
|
||||
var x1, x2;
|
||||
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);
|
||||
y1 = Math.min(rect.y, y1);
|
||||
x2 = Math.max(rect.x + rect.width, x1 + x2 - x1);
|
||||
y2 = Math.max(rect.y + rect.height, y1 + y2 - y1);
|
||||
x2 = Math.max(rect.x + rect.width, x2);
|
||||
y2 = Math.max(rect.y + rect.height, y2);
|
||||
}
|
||||
return LinkedRectangle.create(this, 'setBounds',
|
||||
x1, y1, x2 - x1, y2 - y1);
|
||||
return includeStroke
|
||||
? 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?
|
||||
// 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
|
||||
// Canvas doesn't support it yet. Document colorMode is also out of the
|
||||
// question for now.
|
||||
var bounds = this.getStrokeBounds();
|
||||
var scale = resolution ? resolution / 72 : 1;
|
||||
var canvas = CanvasProvider.getCanvas(bounds.getSize().multiply(scale));
|
||||
var ctx = canvas.getContext('2d');
|
||||
var matrix = new Matrix().scale(scale).translate(-bounds.x, -bounds.y);
|
||||
var bounds = this.getStrokeBounds(),
|
||||
scale = (resolution || 72) / 72,
|
||||
canvas = CanvasProvider.getCanvas(bounds.getSize().multiply(scale)),
|
||||
ctx = canvas.getContext('2d'),
|
||||
matrix = new Matrix().scale(scale).translate(-bounds.x, -bounds.y);
|
||||
matrix.applyToContext(ctx);
|
||||
this.draw(ctx, {});
|
||||
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
|
||||
// antialiased pixels when drawing onto the temporary canvas.
|
||||
var itemOffset = bounds.getTopLeft().floor();
|
||||
var size = bounds.getSize().ceil().add(1, 1);
|
||||
var itemOffset = bounds.getTopLeft().floor(),
|
||||
size = bounds.getSize().ceil().add(1, 1);
|
||||
tempCanvas = CanvasProvider.getCanvas(size);
|
||||
|
||||
// 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) {
|
||||
var item = set[id];
|
||||
item.remove();
|
||||
for(var type in sets) {
|
||||
for (var type in sets) {
|
||||
var other = sets[type];
|
||||
if (other != set && other[item.getId()])
|
||||
delete other[item.getId()];
|
||||
|
|
|
@ -198,6 +198,10 @@ var Raster = this.Raster = Item.extend({
|
|||
}
|
||||
return this._bounds;
|
||||
},
|
||||
|
||||
getStrokeBounds: function() {
|
||||
return this.getBounds();
|
||||
},
|
||||
|
||||
draw: function(ctx, param) {
|
||||
if (param.selection) {
|
||||
|
|
|
@ -16,12 +16,20 @@ test('new Group([item])', function() {
|
|||
|
||||
test('Group bounds', function() {
|
||||
var doc = new Document();
|
||||
doc.currentStyle = {
|
||||
strokeWidth: 5,
|
||||
strokeColor: 'black'
|
||||
};
|
||||
var path = new Path.Circle([150, 150], 60);
|
||||
var secondPath = new Path.Circle([175, 175], 85);
|
||||
var group = new Group([path, secondPath]);
|
||||
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);
|
||||
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));
|
||||
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