mirror of
https://github.com/scratchfoundation/paper.js.git
synced 2024-12-29 09:22:22 -05:00
parent
4ba406bfe3
commit
3177c7ac46
3 changed files with 51 additions and 39 deletions
|
@ -13,6 +13,7 @@
|
||||||
- Do not ignore `Group#clipItem.matrix` in `Group#internalBounds` (#1427).
|
- Do not ignore `Group#clipItem.matrix` in `Group#internalBounds` (#1427).
|
||||||
- Correctly calculate bounds with nested empty items (#1467).
|
- Correctly calculate bounds with nested empty items (#1467).
|
||||||
- Fix color change propagation on groups (#1152).
|
- Fix color change propagation on groups (#1152).
|
||||||
|
- Fix `Path#arcTo()` where `from` and `to` points are equal (#1613).
|
||||||
- SVG Export: Fix error when `Item#matrix` is not invertible (#1580).
|
- SVG Export: Fix error when `Item#matrix` is not invertible (#1580).
|
||||||
- SVG Export: Include missing viewBox attribute (#1576).
|
- SVG Export: Include missing viewBox attribute (#1576).
|
||||||
- SVG Import: Use correct default values for gradients (#1632, #1661).
|
- SVG Import: Use correct default values for gradients (#1632, #1661).
|
||||||
|
|
|
@ -2467,9 +2467,10 @@ new function() { // PostScript-style drawing commands
|
||||||
// #2: arcTo(through, to)
|
// #2: arcTo(through, to)
|
||||||
through = to;
|
through = to;
|
||||||
to = Point.read(arguments);
|
to = Point.read(arguments);
|
||||||
} else {
|
} else if (!from.equals(to)) {
|
||||||
// #3: arcTo(to, radius, rotation, clockwise, large)
|
// #3: arcTo(to, radius, rotation, clockwise, large)
|
||||||
// Drawing arcs in SVG style:
|
// Draw arc in SVG style, but only if `from` and `to` are not
|
||||||
|
// equal (#1613).
|
||||||
var radius = Size.read(arguments),
|
var radius = Size.read(arguments),
|
||||||
isZero = Numerical.isZero;
|
isZero = Numerical.isZero;
|
||||||
// If rx = 0 or ry = 0 then this arc is treated as a
|
// If rx = 0 or ry = 0 then this arc is treated as a
|
||||||
|
@ -2565,47 +2566,49 @@ new function() { // PostScript-style drawing commands
|
||||||
extent += extent < 0 ? 360 : -360;
|
extent += extent < 0 ? 360 : -360;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var epsilon = /*#=*/Numerical.GEOMETRIC_EPSILON,
|
if (extent) {
|
||||||
ext = abs(extent),
|
var epsilon = /*#=*/Numerical.GEOMETRIC_EPSILON,
|
||||||
// Calculate the amount of segments required to approximate over
|
ext = abs(extent),
|
||||||
// `extend` degrees (extend / 90), but prevent ceil() from
|
// Calculate amount of segments required to approximate over
|
||||||
// rounding up small imprecisions by subtracting epsilon first.
|
// `extend` degrees (extend / 90), but prevent ceil() from
|
||||||
count = ext >= 360 ? 4 : Math.ceil((ext - epsilon) / 90),
|
// rounding up small imprecisions by subtracting epsilon.
|
||||||
inc = extent / count,
|
count = ext >= 360 ? 4 : Math.ceil((ext - epsilon) / 90),
|
||||||
half = inc * Math.PI / 360,
|
inc = extent / count,
|
||||||
z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)),
|
half = inc * Math.PI / 360,
|
||||||
segments = [];
|
z = 4 / 3 * Math.sin(half) / (1 + Math.cos(half)),
|
||||||
for (var i = 0; i <= count; i++) {
|
segments = [];
|
||||||
// Explicitly use to point for last segment, since depending
|
for (var i = 0; i <= count; i++) {
|
||||||
// on values the calculation adds imprecision:
|
// Explicitly use to point for last segment, since depending
|
||||||
var pt = to,
|
// on values the calculation adds imprecision:
|
||||||
out = null;
|
var pt = to,
|
||||||
if (i < count) {
|
out = null;
|
||||||
out = vector.rotate(90).multiply(z);
|
if (i < count) {
|
||||||
if (matrix) {
|
out = vector.rotate(90).multiply(z);
|
||||||
pt = matrix._transformPoint(vector);
|
if (matrix) {
|
||||||
out = matrix._transformPoint(vector.add(out))
|
pt = matrix._transformPoint(vector);
|
||||||
.subtract(pt);
|
out = matrix._transformPoint(vector.add(out))
|
||||||
|
.subtract(pt);
|
||||||
|
} else {
|
||||||
|
pt = center.add(vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!i) {
|
||||||
|
// Modify startSegment
|
||||||
|
current.setHandleOut(out);
|
||||||
} else {
|
} else {
|
||||||
pt = center.add(vector);
|
// Add new Segment
|
||||||
|
var _in = vector.rotate(-90).multiply(z);
|
||||||
|
if (matrix) {
|
||||||
|
_in = matrix._transformPoint(vector.add(_in))
|
||||||
|
.subtract(pt);
|
||||||
|
}
|
||||||
|
segments.push(new Segment(pt, _in, out));
|
||||||
}
|
}
|
||||||
|
vector = vector.rotate(inc);
|
||||||
}
|
}
|
||||||
if (!i) {
|
// Add all segments at once at the end for higher performance
|
||||||
// Modify startSegment
|
this._add(segments);
|
||||||
current.setHandleOut(out);
|
|
||||||
} else {
|
|
||||||
// Add new Segment
|
|
||||||
var _in = vector.rotate(-90).multiply(z);
|
|
||||||
if (matrix) {
|
|
||||||
_in = matrix._transformPoint(vector.add(_in))
|
|
||||||
.subtract(pt);
|
|
||||||
}
|
|
||||||
segments.push(new Segment(pt, _in, out));
|
|
||||||
}
|
|
||||||
vector = vector.rotate(inc);
|
|
||||||
}
|
}
|
||||||
// Add all segments at once at the end for higher performance
|
|
||||||
this._add(segments);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
lineBy: function(/* to */) {
|
lineBy: function(/* to */) {
|
||||||
|
|
|
@ -645,3 +645,11 @@ test('Path#arcTo(through, to) is on through point side (#1477)', function() {
|
||||||
path.arcTo(p2, p3);
|
path.arcTo(p2, p3);
|
||||||
equals(true, path.segments[1].point.x > p1.x);
|
equals(true, path.segments[1].point.x > p1.x);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Path#arcTo(to, radius, rotation, clockwise, large) when from and to are equal (#1613)', function(){
|
||||||
|
var point = new Point(10,10);
|
||||||
|
var path = new Path();
|
||||||
|
path.moveTo(point);
|
||||||
|
path.arcTo(point, new Size(10), 0, true, true);
|
||||||
|
expect(0);
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in a new issue