paperjs-offset 1.0.8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +2 -2
- package/README.md +673 -46
- package/dist/index.cjs +769 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.mjs +760 -0
- package/dist/index.mjs.map +1 -0
- package/dist/index.umd.js +773 -405
- package/dist/index.umd.js.map +1 -1
- package/dist/index.umd.min.js +1 -0
- package/dist/types/index.d.ts +22 -15
- package/dist/types/offset_core.d.ts +20 -5
- package/package.json +56 -25
- package/build.js +0 -57
- package/demo/debug.html +0 -12
- package/demo/debug.js +0 -26
- package/demo/demo.css +0 -16
- package/demo/demo.js +0 -125
- package/demo/index.html +0 -12
- package/demo/paperjs-offset.js +0 -410
- package/demo/paperjs-offset.min.js +0 -1
- package/dist/index.es5.js +0 -403
- package/dist/index.es5.js.map +0 -1
- package/dist/lib/bundle.js +0 -10
- package/dist/lib/bundle.js.map +0 -1
- package/dist/lib/index.js +0 -51
- package/dist/lib/index.js.map +0 -1
- package/dist/lib/offset_core.js +0 -359
- package/dist/lib/offset_core.js.map +0 -1
- package/dist/paperjs-offset.js +0 -410
- package/dist/paperjs-offset.min.js +0 -1
- package/dist/types/bundle.d.ts +0 -9
- package/public/preview.jpg +0 -0
- package/src/bundle.ts +0 -18
- package/src/index.ts +0 -56
- package/src/offset_core.ts +0 -369
- package/tsconfig.json +0 -20
- package/tslint.json +0 -17
package/demo/demo.js
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
(function() {
|
|
2
|
-
function RunDemo() {
|
|
3
|
-
let canvas = document.querySelector('canvas')
|
|
4
|
-
paper.setup(canvas)
|
|
5
|
-
paper.view.center = [0, 0]
|
|
6
|
-
|
|
7
|
-
// simple polygon
|
|
8
|
-
let r = new paper.Path.Rectangle({ point: [-500, -300], size: [80, 80], fillColor: 'rgb(191, 91, 91, 0.5)', strokeColor: 'black' })
|
|
9
|
-
PaperOffset.offset(r, 10)
|
|
10
|
-
r.bringToFront()
|
|
11
|
-
PaperOffset.offset(PaperOffset.offset(PaperOffset.offset(r, -10), -10), -10);
|
|
12
|
-
|
|
13
|
-
// simple polygon + bevel
|
|
14
|
-
let r11 = new paper.Path.Rectangle({ point: [-500, -150], size: [60, 60], fillColor: 'rgb(191, 91, 91, 0.5)', strokeColor: 'black' })
|
|
15
|
-
let r12 = PaperOffset.offset(r11, -10, { insert: false })
|
|
16
|
-
let r1 = r11.subtract(r12, { insert: true })
|
|
17
|
-
r11.remove()
|
|
18
|
-
PaperOffset.offset(r1, 15, { join: 'bevel' })
|
|
19
|
-
r1.bringToFront()
|
|
20
|
-
|
|
21
|
-
// simple polygon + round
|
|
22
|
-
let r21 = new paper.Path.Rectangle({ point: [-350, -150], size: [60, 60], fillColor: 'rgb(191, 91, 91, 0.5)', strokeColor: 'black' })
|
|
23
|
-
let r22 = PaperOffset.offset(r21, -10, { insert: false })
|
|
24
|
-
let r2 = r21.subtract(r22, { insert: true })
|
|
25
|
-
r21.remove()
|
|
26
|
-
PaperOffset.offset(r2, 15, { join: 'round' })
|
|
27
|
-
r2.bringToFront()
|
|
28
|
-
|
|
29
|
-
// simple polygon
|
|
30
|
-
let s = new paper.Path.Star({ center: [-300, -260], points: 12, radius1: 40, radius2: 30, fillColor: 'rgba(234, 154, 100, 0.5)', strokeColor: 'black' })
|
|
31
|
-
PaperOffset.offset(s, 10)
|
|
32
|
-
s.bringToFront()
|
|
33
|
-
PaperOffset.offset(PaperOffset.offset(s, -10), -10);
|
|
34
|
-
|
|
35
|
-
// smooth
|
|
36
|
-
let s2 = new paper.Path.Star({ center: [-150, -260], points: 7, radius1: 40, radius2: 30, fillColor: 'rgba(239, 209, 88, 0.5)', strokeColor: 'black' })
|
|
37
|
-
s2.smooth()
|
|
38
|
-
PaperOffset.offset(s2, 10);
|
|
39
|
-
s2.bringToFront()
|
|
40
|
-
PaperOffset.offset(PaperOffset.offset(s2, -10), -10)
|
|
41
|
-
|
|
42
|
-
// complex
|
|
43
|
-
let c1 = new paper.Path.Circle({ center: [-20, -260], radius: 40, fillColor: 'rgba(165, 193, 93, 0.5)', strokeColor: 'black' })
|
|
44
|
-
let c2 = new paper.Path.Circle({ center: [50, -260], radius: 40, fillColor: 'rgba(165, 193, 93, 0.5)', strokeColor: 'black' })
|
|
45
|
-
let c = c1.unite(c2, { insert: true })
|
|
46
|
-
c1.remove()
|
|
47
|
-
c2.remove()
|
|
48
|
-
PaperOffset.offset(c, 10);
|
|
49
|
-
c.bringToFront()
|
|
50
|
-
PaperOffset.offset(PaperOffset.offset(PaperOffset.offset(c, -10), -10), -10)
|
|
51
|
-
|
|
52
|
-
let c3 = new paper.Path.Circle({ center: [180, -260], radius: 40, fillColor: 'rgba(117, 170, 173, 0.5)', strokeColor: 'black' })
|
|
53
|
-
let c4 = new paper.Path.Circle({ center: [230, -260], radius: 40, fillColor: 'rgba(117, 170, 173, 0.5)', strokeColor: 'black' })
|
|
54
|
-
let c5 = new paper.Path.Circle({ center: [205, -200], radius: 40, fillColor: 'rgba(117, 170, 173, 0.5)', strokeColor: 'black' })
|
|
55
|
-
let cc1 = c3.unite(c4, { insert: true })
|
|
56
|
-
let cc = cc1.unite(c5, { insert: true })
|
|
57
|
-
c3.remove()
|
|
58
|
-
c4.remove()
|
|
59
|
-
c5.remove()
|
|
60
|
-
cc1.remove()
|
|
61
|
-
PaperOffset.offset(cc, 10)
|
|
62
|
-
cc.bringToFront()
|
|
63
|
-
PaperOffset.offset(PaperOffset.offset(PaperOffset.offset(PaperOffset.offset(cc, -10), -10), -10), -5)
|
|
64
|
-
|
|
65
|
-
// complex+
|
|
66
|
-
let c6 = new paper.Path.Circle({ center: [380, -260], radius: 40, fillColor: 'rgba(156, 104, 193, 0.5)', strokeColor: 'black' })
|
|
67
|
-
let c7 = new paper.Path.Circle({ center: [430, -260], radius: 40, fillColor: 'rgba(156, 104, 193, 0.5)', strokeColor: 'black' })
|
|
68
|
-
let c8 = new paper.Path.Circle({ center: [405, -200], radius: 40, fillColor: 'rgba(156, 104, 193, 0.5)', strokeColor: 'black' })
|
|
69
|
-
let ccc1 = c6.unite(c7, { insert: true })
|
|
70
|
-
let ccc = ccc1.unite(c8, { insert: true })
|
|
71
|
-
c6.remove()
|
|
72
|
-
c7.remove()
|
|
73
|
-
c8.remove()
|
|
74
|
-
ccc1.remove()
|
|
75
|
-
ccc.smooth()
|
|
76
|
-
ccc.offset(10)
|
|
77
|
-
ccc.bringToFront()
|
|
78
|
-
PaperOffset.offset(PaperOffset.offset(ccc, -10), -10)
|
|
79
|
-
PaperOffset.offset(PaperOffset.offset(ccc, -30), -5)
|
|
80
|
-
|
|
81
|
-
// stroke
|
|
82
|
-
let rs = new paper.Path.Rectangle({ point: [-200, -150], size: [80, 80], fillColor: null, strokeColor: 'rgb(191, 91, 91, 0.5)' })
|
|
83
|
-
PaperOffset.offsetStroke(rs, 10)
|
|
84
|
-
rs.bringToFront()
|
|
85
|
-
|
|
86
|
-
// stroke
|
|
87
|
-
let st1 = new paper.Path.Line({ from: [-50, -100], to: [0, -100], strokeColor: 'rgba(156, 104, 193, 0.5)', strokeWidth: 3 })
|
|
88
|
-
PaperOffset.offsetStroke(st1, 20, { cap: 'round' })
|
|
89
|
-
st1.bringToFront()
|
|
90
|
-
|
|
91
|
-
// stroke complex
|
|
92
|
-
let cs = c.clone()
|
|
93
|
-
cs.strokeColor = cs.fillColor
|
|
94
|
-
cs.strokeWidth = 3
|
|
95
|
-
cs.fillColor = null
|
|
96
|
-
cs.position = [150, -50]
|
|
97
|
-
cs.closed = false
|
|
98
|
-
PaperOffset.offsetStroke(cs, 20)
|
|
99
|
-
cs.bringToFront()
|
|
100
|
-
let cs2 = cs.clone()
|
|
101
|
-
cs2.position = [400, -50]
|
|
102
|
-
cs2.strokeColor = 'rgba(117, 170, 173, 0.5)'
|
|
103
|
-
PaperOffset.offsetStroke(cs2, 25, { cap: 'round' })
|
|
104
|
-
cs2.bringToFront()
|
|
105
|
-
|
|
106
|
-
// edge cases
|
|
107
|
-
let ec1 = new paper.Path({ pathData: 'M466,467c0,0 -105,-235 0,0c-376.816,-119.63846 -469.06596,-146.09389 -650.61329,-266.59735c-282.68388,-230.49081 300.86045,-10.26825 452.77726,121.52815z', fillColor: 'rgba(156, 104, 193, 0.5)' })
|
|
108
|
-
ec1.translate(-450, -250)
|
|
109
|
-
ec1.scale(0.4)
|
|
110
|
-
PaperOffset.offset(ec1, 10)
|
|
111
|
-
PaperOffset.offset(PaperOffset.offset(PaperOffset.offset(ec1, -10), -10), -10)
|
|
112
|
-
|
|
113
|
-
let ec2 = new paper.Path({ pathData: 'M466,467c-65,-34 136,64 0,0c-391,-270 62,-670 62,-670l-463,370z', strokeColor: 'rgba(239, 209, 88, 0.5)', strokeWidth: 3 })
|
|
114
|
-
ec2.scale(0.4)
|
|
115
|
-
ec2.translate(-350, 20)
|
|
116
|
-
PaperOffset.offsetStroke(ec2, 10)
|
|
117
|
-
|
|
118
|
-
let ec3 = new paper.Path({ pathData: 'M466,467c-65,-34 136,64 0,0c-391,-270 520,-471 522,-137c-214,-144 -1489,123 -923,-163z', fillColor: 'rgb(191, 91, 91, 0.5)' })
|
|
119
|
-
ec3.scale(0.4)
|
|
120
|
-
ec3.translate(-100, -150)
|
|
121
|
-
PaperOffset.offset(ec3, -10)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
window.onload = RunDemo
|
|
125
|
-
})()
|
package/demo/index.html
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
<html>
|
|
2
|
-
<head>
|
|
3
|
-
<title>Demo</title>
|
|
4
|
-
<link rel="stylesheet" href="./demo.css"/>
|
|
5
|
-
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/paper@0.12.4/dist/paper-full.min.js"></script>
|
|
6
|
-
<script type="text/javascript" src="./paperjs-offset.js"></script>
|
|
7
|
-
<script type="text/javascript" src="./demo.js"></script>
|
|
8
|
-
</head>
|
|
9
|
-
<body>
|
|
10
|
-
<canvas width="1200" height="768"></canvas>
|
|
11
|
-
</body>
|
|
12
|
-
</html>
|
package/demo/paperjs-offset.js
DELETED
|
@@ -1,410 +0,0 @@
|
|
|
1
|
-
(function (paper) {
|
|
2
|
-
'use strict';
|
|
3
|
-
|
|
4
|
-
paper = paper && Object.prototype.hasOwnProperty.call(paper, 'default') ? paper['default'] : paper;
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Offset the start/terminal segment of a bezier curve
|
|
8
|
-
* @param segment segment to offset
|
|
9
|
-
* @param curve curve to offset
|
|
10
|
-
* @param handleNormal the normal of the the line formed of two handles
|
|
11
|
-
* @param offset offset value
|
|
12
|
-
*/
|
|
13
|
-
function offsetSegment(segment, curve, handleNormal, offset) {
|
|
14
|
-
var isFirst = segment.curve === curve;
|
|
15
|
-
// get offset vector
|
|
16
|
-
var offsetVector = (curve.getNormalAtTime(isFirst ? 0 : 1)).multiply(offset);
|
|
17
|
-
// get offset point
|
|
18
|
-
var point = segment.point.add(offsetVector);
|
|
19
|
-
var newSegment = new paper.Segment(point);
|
|
20
|
-
// handleOut for start segment & handleIn for terminal segment
|
|
21
|
-
var handle = (isFirst ? 'handleOut' : 'handleIn');
|
|
22
|
-
newSegment[handle] = segment[handle].add(handleNormal.subtract(offsetVector).divide(2));
|
|
23
|
-
return newSegment;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Adaptive offset a curve by repeatly apply the approximation proposed by Tiller and Hanson.
|
|
27
|
-
* @param curve curve to offset
|
|
28
|
-
* @param offset offset value
|
|
29
|
-
*/
|
|
30
|
-
function adaptiveOffsetCurve(curve, offset) {
|
|
31
|
-
var hNormal = (new paper.Curve(curve.segment1.handleOut.add(curve.segment1.point), new paper.Point(0, 0), new paper.Point(0, 0), curve.segment2.handleIn.add(curve.segment2.point))).getNormalAtTime(0.5).multiply(offset);
|
|
32
|
-
var segment1 = offsetSegment(curve.segment1, curve, hNormal, offset);
|
|
33
|
-
var segment2 = offsetSegment(curve.segment2, curve, hNormal, offset);
|
|
34
|
-
// divide && re-offset
|
|
35
|
-
var offsetCurve = new paper.Curve(segment1, segment2);
|
|
36
|
-
// if the offset curve is not self intersected, divide it
|
|
37
|
-
if (offsetCurve.getIntersections(offsetCurve).length === 0) {
|
|
38
|
-
var threshold = Math.min(Math.abs(offset) / 10, 1);
|
|
39
|
-
var midOffset = offsetCurve.getPointAtTime(0.5).getDistance(curve.getPointAtTime(0.5));
|
|
40
|
-
if (Math.abs(midOffset - Math.abs(offset)) > threshold) {
|
|
41
|
-
var subCurve = curve.divideAtTime(0.5);
|
|
42
|
-
if (subCurve != null) {
|
|
43
|
-
return adaptiveOffsetCurve(curve, offset).concat(adaptiveOffsetCurve(subCurve, offset));
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
return [segment1, segment2];
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* Create a round join segment between two adjacent segments.
|
|
51
|
-
*/
|
|
52
|
-
function makeRoundJoin(segment1, segment2, originPoint, radius) {
|
|
53
|
-
var through = segment1.point.subtract(originPoint).add(segment2.point.subtract(originPoint))
|
|
54
|
-
.normalize(Math.abs(radius)).add(originPoint);
|
|
55
|
-
var arc = new paper.Path.Arc({ from: segment1.point, to: segment2.point, through: through, insert: false });
|
|
56
|
-
segment1.handleOut = arc.firstSegment.handleOut;
|
|
57
|
-
segment2.handleIn = arc.lastSegment.handleIn;
|
|
58
|
-
return arc.segments.length === 3 ? arc.segments[1] : null;
|
|
59
|
-
}
|
|
60
|
-
function det(p1, p2) {
|
|
61
|
-
return p1.x * p2.y - p1.y * p2.x;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Get the intersection point of point based lines
|
|
65
|
-
*/
|
|
66
|
-
function getPointLineIntersections(p1, p2, p3, p4) {
|
|
67
|
-
var l1 = p1.subtract(p2);
|
|
68
|
-
var l2 = p3.subtract(p4);
|
|
69
|
-
var dl1 = det(p1, p2);
|
|
70
|
-
var dl2 = det(p3, p4);
|
|
71
|
-
return new paper.Point(dl1 * l2.x - l1.x * dl2, dl1 * l2.y - l1.y * dl2).divide(det(l1, l2));
|
|
72
|
-
}
|
|
73
|
-
/**
|
|
74
|
-
* Connect two adjacent bezier curve, each curve is represented by two segments,
|
|
75
|
-
* create different types of joins or simply removal redundant segment.
|
|
76
|
-
*/
|
|
77
|
-
function connectAdjacentBezier(segments1, segments2, origin, joinType, offset, limit) {
|
|
78
|
-
var curve1 = new paper.Curve(segments1[0], segments1[1]);
|
|
79
|
-
var curve2 = new paper.Curve(segments2[0], segments2[1]);
|
|
80
|
-
var intersection = curve1.getIntersections(curve2);
|
|
81
|
-
var distance = segments1[1].point.getDistance(segments2[0].point);
|
|
82
|
-
if (origin.isSmooth()) {
|
|
83
|
-
segments2[0].handleOut = segments2[0].handleOut.project(origin.handleOut);
|
|
84
|
-
segments2[0].handleIn = segments1[1].handleIn.project(origin.handleIn);
|
|
85
|
-
segments2[0].point = segments1[1].point.add(segments2[0].point).divide(2);
|
|
86
|
-
segments1.pop();
|
|
87
|
-
}
|
|
88
|
-
else {
|
|
89
|
-
if (intersection.length === 0) {
|
|
90
|
-
if (distance > Math.abs(offset) * 0.1) {
|
|
91
|
-
// connect
|
|
92
|
-
switch (joinType) {
|
|
93
|
-
case 'miter':
|
|
94
|
-
var join = getPointLineIntersections(curve1.point2, curve1.point2.add(curve1.getTangentAtTime(1)), curve2.point1, curve2.point1.add(curve2.getTangentAtTime(0)));
|
|
95
|
-
// prevent sharp angle
|
|
96
|
-
var joinOffset = Math.max(join.getDistance(curve1.point2), join.getDistance(curve2.point1));
|
|
97
|
-
if (joinOffset < Math.abs(offset) * limit) {
|
|
98
|
-
segments1.push(new paper.Segment(join));
|
|
99
|
-
}
|
|
100
|
-
break;
|
|
101
|
-
case 'round':
|
|
102
|
-
var mid = makeRoundJoin(segments1[1], segments2[0], origin.point, offset);
|
|
103
|
-
if (mid) {
|
|
104
|
-
segments1.push(mid);
|
|
105
|
-
}
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
else {
|
|
110
|
-
segments2[0].handleIn = segments1[1].handleIn;
|
|
111
|
-
segments1.pop();
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
else {
|
|
115
|
-
var second1 = curve1.divideAt(intersection[0]);
|
|
116
|
-
if (second1) {
|
|
117
|
-
var join = second1.segment1;
|
|
118
|
-
var second2 = curve2.divideAt(curve2.getIntersections(curve1)[0]);
|
|
119
|
-
join.handleOut = second2 ? second2.segment1.handleOut : segments2[0].handleOut;
|
|
120
|
-
segments1.pop();
|
|
121
|
-
segments2[0] = join;
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
segments2[0].handleIn = segments1[1].handleIn;
|
|
125
|
-
segments1.pop();
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
/**
|
|
131
|
-
* Connect all the segments together.
|
|
132
|
-
*/
|
|
133
|
-
function connectBeziers(rawSegments, join, source, offset, limit) {
|
|
134
|
-
var originSegments = source.segments;
|
|
135
|
-
var first = rawSegments[0].slice();
|
|
136
|
-
for (var i = 0; i < rawSegments.length - 1; ++i) {
|
|
137
|
-
connectAdjacentBezier(rawSegments[i], rawSegments[i + 1], originSegments[i + 1], join, offset, limit);
|
|
138
|
-
}
|
|
139
|
-
if (source.closed) {
|
|
140
|
-
connectAdjacentBezier(rawSegments[rawSegments.length - 1], first, originSegments[0], join, offset, limit);
|
|
141
|
-
rawSegments[0][0] = first[0];
|
|
142
|
-
}
|
|
143
|
-
return rawSegments;
|
|
144
|
-
}
|
|
145
|
-
function reduceSingleChildCompoundPath(path) {
|
|
146
|
-
if (path.children.length === 1) {
|
|
147
|
-
path = path.children[0];
|
|
148
|
-
path.remove(); // remove from parent, this is critical, or the style attributes will be ignored
|
|
149
|
-
}
|
|
150
|
-
return path;
|
|
151
|
-
}
|
|
152
|
-
/** Normalize a path, always clockwise, non-self-intersection, ignore really small components, and no one-component compound path. */
|
|
153
|
-
function normalize(path, areaThreshold) {
|
|
154
|
-
if (areaThreshold === void 0) { areaThreshold = 0.01; }
|
|
155
|
-
if (path.closed) {
|
|
156
|
-
var ignoreArea_1 = Math.abs(path.area * areaThreshold);
|
|
157
|
-
if (!path.clockwise) {
|
|
158
|
-
path.reverse();
|
|
159
|
-
}
|
|
160
|
-
path = path.unite(path, { insert: false });
|
|
161
|
-
if (path instanceof paper.CompoundPath) {
|
|
162
|
-
path.children.filter(function (c) { return Math.abs(c.area) < ignoreArea_1; }).forEach(function (c) { return c.remove(); });
|
|
163
|
-
if (path.children.length === 1) {
|
|
164
|
-
return reduceSingleChildCompoundPath(path);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
return path;
|
|
169
|
-
}
|
|
170
|
-
function isSameDirection(partialPath, fullPath) {
|
|
171
|
-
var offset1 = partialPath.segments[0].location.offset;
|
|
172
|
-
var offset2 = partialPath.segments[Math.max(1, Math.floor(partialPath.segments.length / 2))].location.offset;
|
|
173
|
-
var sampleOffset = (offset1 + offset2) / 3;
|
|
174
|
-
var originOffset1 = fullPath.getNearestLocation(partialPath.getPointAt(sampleOffset)).offset;
|
|
175
|
-
var originOffset2 = fullPath.getNearestLocation(partialPath.getPointAt(2 * sampleOffset)).offset;
|
|
176
|
-
return originOffset1 < originOffset2;
|
|
177
|
-
}
|
|
178
|
-
/** Remove self intersection when offset is negative by point direction dectection. */
|
|
179
|
-
function removeIntersection(path) {
|
|
180
|
-
if (path.closed) {
|
|
181
|
-
var newPath = path.unite(path, { insert: false });
|
|
182
|
-
if (newPath instanceof paper.CompoundPath) {
|
|
183
|
-
newPath.children.filter(function (c) {
|
|
184
|
-
if (c.segments.length > 1) {
|
|
185
|
-
return !isSameDirection(c, path);
|
|
186
|
-
}
|
|
187
|
-
else {
|
|
188
|
-
return true;
|
|
189
|
-
}
|
|
190
|
-
}).forEach(function (c) { return c.remove(); });
|
|
191
|
-
return reduceSingleChildCompoundPath(newPath);
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
return path;
|
|
195
|
-
}
|
|
196
|
-
function getSegments(path) {
|
|
197
|
-
if (path instanceof paper.CompoundPath) {
|
|
198
|
-
return path.children.map(function (c) { return c.segments; }).flat();
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
return path.segments;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
/**
|
|
205
|
-
* Remove impossible segments in negative offset condition.
|
|
206
|
-
*/
|
|
207
|
-
function removeOutsiders(newPath, path) {
|
|
208
|
-
var segments = getSegments(newPath).slice();
|
|
209
|
-
segments.forEach(function (segment) {
|
|
210
|
-
if (!path.contains(segment.point)) {
|
|
211
|
-
segment.remove();
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
}
|
|
215
|
-
function preparePath(path, offset) {
|
|
216
|
-
var source = path.clone({ insert: false });
|
|
217
|
-
source.reduce({});
|
|
218
|
-
if (!path.clockwise) {
|
|
219
|
-
source.reverse();
|
|
220
|
-
offset = -offset;
|
|
221
|
-
}
|
|
222
|
-
return [source, offset];
|
|
223
|
-
}
|
|
224
|
-
function offsetSimpleShape(path, offset, join, limit) {
|
|
225
|
-
var _a;
|
|
226
|
-
var source;
|
|
227
|
-
_a = preparePath(path, offset), source = _a[0], offset = _a[1];
|
|
228
|
-
var curves = source.curves.slice();
|
|
229
|
-
var offsetCurves = curves.map(function (curve) { return adaptiveOffsetCurve(curve, offset); }).flat();
|
|
230
|
-
var raws = [];
|
|
231
|
-
for (var i = 0; i < offsetCurves.length; i += 2) {
|
|
232
|
-
raws.push(offsetCurves.slice(i, i + 2));
|
|
233
|
-
}
|
|
234
|
-
var segments = connectBeziers(raws, join, source, offset, limit).flat();
|
|
235
|
-
var newPath = removeIntersection(new paper.Path({ segments: segments, insert: false, closed: path.closed }));
|
|
236
|
-
newPath.reduce({});
|
|
237
|
-
if (source.closed && ((source.clockwise && offset < 0) || (!source.clockwise && offset > 0))) {
|
|
238
|
-
removeOutsiders(newPath, path);
|
|
239
|
-
}
|
|
240
|
-
// recovery path
|
|
241
|
-
if (source.clockwise !== path.clockwise) {
|
|
242
|
-
newPath.reverse();
|
|
243
|
-
}
|
|
244
|
-
return normalize(newPath);
|
|
245
|
-
}
|
|
246
|
-
function makeRoundCap(from, to, offset) {
|
|
247
|
-
var origin = from.point.add(to.point).divide(2);
|
|
248
|
-
var normal = to.point.subtract(from.point).rotate(-90, new paper.Point(0, 0)).normalize(offset);
|
|
249
|
-
var through = origin.add(normal);
|
|
250
|
-
var arc = new paper.Path.Arc({ from: from.point, to: to.point, through: through, insert: false });
|
|
251
|
-
return arc.segments;
|
|
252
|
-
}
|
|
253
|
-
function connectSide(outer, inner, offset, cap) {
|
|
254
|
-
if (outer instanceof paper.CompoundPath) {
|
|
255
|
-
var cs = outer.children.map(function (c) { return ({ c: c, a: Math.abs(c.area) }); });
|
|
256
|
-
cs = cs.sort(function (c1, c2) { return c2.a - c1.a; });
|
|
257
|
-
outer = cs[0].c;
|
|
258
|
-
}
|
|
259
|
-
var oSegments = outer.segments.slice();
|
|
260
|
-
var iSegments = inner.segments.slice();
|
|
261
|
-
switch (cap) {
|
|
262
|
-
case 'round':
|
|
263
|
-
var heads = makeRoundCap(iSegments[iSegments.length - 1], oSegments[0], offset);
|
|
264
|
-
var tails = makeRoundCap(oSegments[oSegments.length - 1], iSegments[0], offset);
|
|
265
|
-
var result = new paper.Path({ segments: heads.concat(oSegments, tails, iSegments), closed: true, insert: false });
|
|
266
|
-
result.reduce({});
|
|
267
|
-
return result;
|
|
268
|
-
default: return new paper.Path({ segments: oSegments.concat(iSegments), closed: true, insert: false });
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
function offsetSimpleStroke(path, offset, join, cap, limit) {
|
|
272
|
-
offset = path.clockwise ? offset : -offset;
|
|
273
|
-
var positiveOffset = offsetSimpleShape(path, offset, join, limit);
|
|
274
|
-
var negativeOffset = offsetSimpleShape(path, -offset, join, limit);
|
|
275
|
-
if (path.closed) {
|
|
276
|
-
return positiveOffset.subtract(negativeOffset, { insert: false });
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
var inner = negativeOffset;
|
|
280
|
-
var holes = new Array();
|
|
281
|
-
if (negativeOffset instanceof paper.CompoundPath) {
|
|
282
|
-
holes = negativeOffset.children.filter(function (c) { return c.closed; });
|
|
283
|
-
holes.forEach(function (h) { return h.remove(); });
|
|
284
|
-
inner = negativeOffset.children[0];
|
|
285
|
-
}
|
|
286
|
-
inner.reverse();
|
|
287
|
-
var final = connectSide(positiveOffset, inner, offset, cap);
|
|
288
|
-
if (holes.length > 0) {
|
|
289
|
-
for (var _i = 0, holes_1 = holes; _i < holes_1.length; _i++) {
|
|
290
|
-
var hole = holes_1[_i];
|
|
291
|
-
final = final.subtract(hole, { insert: false });
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
return final;
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
function getNonSelfItersectionPath(path) {
|
|
298
|
-
if (path.closed) {
|
|
299
|
-
return path.unite(path, { insert: false });
|
|
300
|
-
}
|
|
301
|
-
return path;
|
|
302
|
-
}
|
|
303
|
-
function offsetPath(path, offset, join, limit) {
|
|
304
|
-
var nonSIPath = getNonSelfItersectionPath(path);
|
|
305
|
-
var result = nonSIPath;
|
|
306
|
-
if (nonSIPath instanceof paper.Path) {
|
|
307
|
-
result = offsetSimpleShape(nonSIPath, offset, join, limit);
|
|
308
|
-
}
|
|
309
|
-
else {
|
|
310
|
-
var offsetParts = nonSIPath.children.map(function (c) {
|
|
311
|
-
if (c.segments.length > 1) {
|
|
312
|
-
if (!isSameDirection(c, path)) {
|
|
313
|
-
c.reverse();
|
|
314
|
-
}
|
|
315
|
-
var offseted = offsetSimpleShape(c, offset, join, limit);
|
|
316
|
-
offseted = normalize(offseted);
|
|
317
|
-
if (offseted.clockwise !== c.clockwise) {
|
|
318
|
-
offseted.reverse();
|
|
319
|
-
}
|
|
320
|
-
if (offseted instanceof paper.CompoundPath) {
|
|
321
|
-
offseted.applyMatrix = true;
|
|
322
|
-
return offseted.children;
|
|
323
|
-
}
|
|
324
|
-
else {
|
|
325
|
-
return offseted;
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
else {
|
|
329
|
-
return null;
|
|
330
|
-
}
|
|
331
|
-
});
|
|
332
|
-
var children = offsetParts.flat().filter(function (c) { return !!c; });
|
|
333
|
-
result = new paper.CompoundPath({ children: children, insert: false });
|
|
334
|
-
}
|
|
335
|
-
result.copyAttributes(nonSIPath, false);
|
|
336
|
-
result.remove();
|
|
337
|
-
return result;
|
|
338
|
-
}
|
|
339
|
-
function offsetStroke(path, offset, join, cap, limit) {
|
|
340
|
-
var nonSIPath = getNonSelfItersectionPath(path);
|
|
341
|
-
var result = nonSIPath;
|
|
342
|
-
if (nonSIPath instanceof paper.Path) {
|
|
343
|
-
result = offsetSimpleStroke(nonSIPath, offset, join, cap, limit);
|
|
344
|
-
}
|
|
345
|
-
else {
|
|
346
|
-
var children = nonSIPath.children.flatMap(function (c) {
|
|
347
|
-
return offsetSimpleStroke(c, offset, join, cap, limit);
|
|
348
|
-
});
|
|
349
|
-
result = children.reduce(function (c1, c2) { return c1.unite(c2, { insert: false }); });
|
|
350
|
-
}
|
|
351
|
-
result.strokeWidth = 0;
|
|
352
|
-
result.fillColor = nonSIPath.strokeColor;
|
|
353
|
-
result.shadowBlur = nonSIPath.shadowBlur;
|
|
354
|
-
result.shadowColor = nonSIPath.shadowColor;
|
|
355
|
-
result.shadowOffset = nonSIPath.shadowOffset;
|
|
356
|
-
return result;
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
var PaperOffset = /** @class */ (function () {
|
|
360
|
-
function PaperOffset() {
|
|
361
|
-
}
|
|
362
|
-
PaperOffset.offset = function (path, offset, options) {
|
|
363
|
-
options = options || {};
|
|
364
|
-
var newPath = offsetPath(path, offset, options.join || 'miter', options.limit || 10);
|
|
365
|
-
if (options.insert === undefined) {
|
|
366
|
-
options.insert = true;
|
|
367
|
-
}
|
|
368
|
-
if (options.insert) {
|
|
369
|
-
(path.parent || paper.project.activeLayer).addChild(newPath);
|
|
370
|
-
}
|
|
371
|
-
return newPath;
|
|
372
|
-
};
|
|
373
|
-
PaperOffset.offsetStroke = function (path, offset, options) {
|
|
374
|
-
options = options || {};
|
|
375
|
-
var newPath = offsetStroke(path, offset, options.join || 'miter', options.cap || 'butt', options.limit || 10);
|
|
376
|
-
if (options.insert === undefined) {
|
|
377
|
-
options.insert = true;
|
|
378
|
-
}
|
|
379
|
-
if (options.insert) {
|
|
380
|
-
(path.parent || paper.project.activeLayer).addChild(newPath);
|
|
381
|
-
}
|
|
382
|
-
return newPath;
|
|
383
|
-
};
|
|
384
|
-
return PaperOffset;
|
|
385
|
-
}());
|
|
386
|
-
/**
|
|
387
|
-
* @deprecated EXTEND existing paper module is not recommend anymore
|
|
388
|
-
*/
|
|
389
|
-
function ExtendPaperJs(paperNs) {
|
|
390
|
-
paperNs.Path.prototype.offset = function (offset, options) {
|
|
391
|
-
return PaperOffset.offset(this, offset, options);
|
|
392
|
-
};
|
|
393
|
-
paperNs.Path.prototype.offsetStroke = function (offset, options) {
|
|
394
|
-
return PaperOffset.offsetStroke(this, offset, options);
|
|
395
|
-
};
|
|
396
|
-
paperNs.CompoundPath.prototype.offset = function (offset, options) {
|
|
397
|
-
return PaperOffset.offset(this, offset, options);
|
|
398
|
-
};
|
|
399
|
-
paperNs.CompoundPath.prototype.offsetStroke = function (offset, options) {
|
|
400
|
-
return PaperOffset.offsetStroke(this, offset, options);
|
|
401
|
-
};
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
ExtendPaperJs(paper);
|
|
405
|
-
window.PaperOffset = {
|
|
406
|
-
offset: PaperOffset.offset,
|
|
407
|
-
offsetStroke: PaperOffset.offsetStroke,
|
|
408
|
-
};
|
|
409
|
-
|
|
410
|
-
}(paper));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
!function(S){"use strict";function p(e,t,n,r){var o=e.curve===t,i=t.getNormalAtTime(o?0:1).multiply(r),a=e.point.add(i),s=new S.Segment(a),c=o?"handleOut":"handleIn";return s[c]=e[c].add(n.subtract(i).divide(2)),s}function T(e,t){return e.x*t.y-e.y*t.x}function m(e,t,n,r,o,i){var a,s,c,u,f,l,d,h,p,m,g,v,w,P,b=new S.Curve(e[0],e[1]),k=new S.Curve(t[0],t[1]),C=b.getIntersections(k),y=e[1].point.getDistance(t[0].point);if(n.isSmooth())t[0].handleOut=t[0].handleOut.project(n.handleOut),t[0].handleIn=e[1].handleIn.project(n.handleIn),t[0].point=e[1].point.add(t[0].point).divide(2),e.pop();else if(0===C.length)if(y>.1*Math.abs(o))switch(r){case"miter":var A=(d=b.point2,h=b.point2.add(b.getTangentAtTime(1)),p=k.point1,m=k.point1.add(k.getTangentAtTime(0)),g=d.subtract(h),v=p.subtract(m),w=T(d,h),P=T(p,m),new S.Point(w*v.x-g.x*P,w*v.y-g.y*P).divide(T(g,v)));Math.max(A.getDistance(b.point2),A.getDistance(k.point1))<Math.abs(o)*i&&e.push(new S.Segment(A));break;case"round":var M=(a=e[1],s=t[0],c=n.point,u=o,f=a.point.subtract(c).add(s.point.subtract(c)).normalize(Math.abs(u)).add(c),l=new S.Path.Arc({from:a.point,to:s.point,through:f,insert:!1}),a.handleOut=l.firstSegment.handleOut,s.handleIn=l.lastSegment.handleIn,3===l.segments.length?l.segments[1]:null);M&&e.push(M)}else t[0].handleIn=e[1].handleIn,e.pop();else{var O=b.divideAt(C[0]);if(O){A=O.segment1;var I=k.divideAt(k.getIntersections(b)[0]);A.handleOut=I?I.segment1.handleOut:t[0].handleOut,e.pop(),t[0]=A}else t[0].handleIn=e[1].handleIn,e.pop()}}function g(e){return 1===e.children.length&&(e=e.children[0]).remove(),e}function v(e,t){if(void 0===t&&(t=.01),e.closed){var n=Math.abs(e.area*t);if(e.clockwise||e.reverse(),(e=e.unite(e,{insert:!1}))instanceof S.CompoundPath&&(e.children.filter(function(e){return Math.abs(e.area)<n}).forEach(function(e){return e.remove()}),1===e.children.length))return g(e)}return e}function w(e,t){var n=(e.segments[0].location.offset+e.segments[Math.max(1,Math.floor(e.segments.length/2))].location.offset)/3;return t.getNearestLocation(e.getPointAt(n)).offset<t.getNearestLocation(e.getPointAt(2*n)).offset}function P(e,t){var n;((n=e)instanceof S.CompoundPath?n.children.map(function(e){return e.segments}).flat():n.segments).slice().forEach(function(e){t.contains(e.point)||e.remove()})}function h(e,t,n,r){var o,i,a,s,c;s=t,(c=(a=e).clone({insert:!1})).reduce({}),a.clockwise||(c.reverse(),s=-s),t=(o=[c,s])[1];for(var u=(i=o[0]).curves.slice().map(function(e){return function e(t,n){var r=new S.Curve(t.segment1.handleOut.add(t.segment1.point),new S.Point(0,0),new S.Point(0,0),t.segment2.handleIn.add(t.segment2.point)).getNormalAtTime(.5).multiply(n),o=p(t.segment1,t,r,n),i=p(t.segment2,t,r,n),a=new S.Curve(o,i);if(0===a.getIntersections(a).length){var s=Math.min(Math.abs(n)/10,1),c=a.getPointAtTime(.5).getDistance(t.getPointAtTime(.5));if(Math.abs(c-Math.abs(n))>s){var u=t.divideAtTime(.5);if(null!=u)return e(t,n).concat(e(u,n))}}return[o,i]}(e,t)}).flat(),f=[],l=0;l<u.length;l+=2)f.push(u.slice(l,l+2));var d=function(e,t,n,r,o){for(var i=n.segments,a=e[0].slice(),s=0;s<e.length-1;++s)m(e[s],e[s+1],i[s+1],t,r,o);return n.closed&&(m(e[e.length-1],a,i[0],t,r,o),e[0][0]=a[0]),e}(f,n,i,t,r).flat(),h=function(t){if(t.closed){var e=t.unite(t,{insert:!1});if(e instanceof S.CompoundPath)return e.children.filter(function(e){return!(1<e.segments.length)||!w(e,t)}).forEach(function(e){return e.remove()}),g(e)}return t}(new S.Path({segments:d,insert:!1,closed:e.closed}));return h.reduce({}),i.closed&&(i.clockwise&&t<0||!i.clockwise&&0<t)&&P(h,e),i.clockwise!==e.clockwise&&h.reverse(),v(h)}function b(e,t,n){var r=e.point.add(t.point).divide(2),o=t.point.subtract(e.point).rotate(-90,new S.Point(0,0)).normalize(n),i=r.add(o);return new S.Path.Arc({from:e.point,to:t.point,through:i,insert:!1}).segments}function l(e,t,n,r,o){var i=h(e,t=e.clockwise?t:-t,n,o),a=h(e,-t,n,o);if(e.closed)return i.subtract(a,{insert:!1});var s=a,c=new Array;a instanceof S.CompoundPath&&((c=a.children.filter(function(e){return e.closed})).forEach(function(e){return e.remove()}),s=a.children[0]),s.reverse();var u=function(e,t,n,r){if(e instanceof S.CompoundPath){var o=e.children.map(function(e){return{c:e,a:Math.abs(e.area)}});e=(o=o.sort(function(e,t){return t.a-e.a}))[0].c}var i=e.segments.slice(),a=t.segments.slice();switch(r){case"round":var s=b(a[a.length-1],i[0],n),c=b(i[i.length-1],a[0],n),u=new S.Path({segments:s.concat(i,c,a),closed:!0,insert:!1});return u.reduce({}),u;default:return new S.Path({segments:i.concat(a),closed:!0,insert:!1})}}(i,s,t,r);if(0<c.length)for(var f=0,l=c;f<l.length;f++){var d=l[f];u=u.subtract(d,{insert:!1})}return u}function d(e){return e.closed?e.unite(e,{insert:!1}):e}S=S&&Object.prototype.hasOwnProperty.call(S,"default")?S.default:S;var e,n=(t.offset=function(e,t,n){var r=function(n,r,o,i){var e=d(n),t=e;if(e instanceof S.Path)t=h(e,r,o,i);else{var a=e.children.map(function(e){if(1<e.segments.length){w(e,n)||e.reverse();var t=h(e,r,o,i);return(t=v(t)).clockwise!==e.clockwise&&t.reverse(),t instanceof S.CompoundPath?(t.applyMatrix=!0,t.children):t}return null}).flat().filter(function(e){return!!e});t=new S.CompoundPath({children:a,insert:!1})}return t.copyAttributes(e,!1),t.remove(),t}(e,t,(n=n||{}).join||"miter",n.limit||10);return void 0===n.insert&&(n.insert=!0),n.insert&&(e.parent||S.project.activeLayer).addChild(r),r},t.offsetStroke=function(e,t,n){var r,o,i,a,s,c,u,f=(r=e,o=t,i=(n=n||{}).join||"miter",a=n.cap||"butt",s=n.limit||10,c=d(r),(u=(u=c)instanceof S.Path?l(c,o,i,a,s):c.children.flatMap(function(e){return l(e,o,i,a,s)}).reduce(function(e,t){return e.unite(t,{insert:!1})})).strokeWidth=0,u.fillColor=c.strokeColor,u.shadowBlur=c.shadowBlur,u.shadowColor=c.shadowColor,u.shadowOffset=c.shadowOffset,u);return void 0===n.insert&&(n.insert=!0),n.insert&&(e.parent||S.project.activeLayer).addChild(f),f},t);function t(){}(e=S).Path.prototype.offset=function(e,t){return n.offset(this,e,t)},e.Path.prototype.offsetStroke=function(e,t){return n.offsetStroke(this,e,t)},e.CompoundPath.prototype.offset=function(e,t){return n.offset(this,e,t)},e.CompoundPath.prototype.offsetStroke=function(e,t){return n.offsetStroke(this,e,t)},window.PaperOffset={offset:n.offset,offsetStroke:n.offsetStroke}}(paper);
|