paper 0.16.0 → 0.17.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.
Files changed (63) hide show
  1. package/CHANGELOG.md +95 -0
  2. package/dist/docs/assets/js/paper.js +4565 -733
  3. package/dist/docs/classes/AreaText.html +720 -242
  4. package/dist/docs/classes/ChangeFlag.html +1 -1
  5. package/dist/docs/classes/Color.html +218 -21
  6. package/dist/docs/classes/CompoundPath.html +1146 -296
  7. package/dist/docs/classes/Curve.html +1 -1
  8. package/dist/docs/classes/CurveLocation.html +1 -1
  9. package/dist/docs/classes/DrawEvent.html +69 -0
  10. package/dist/docs/classes/Effect.html +434 -0
  11. package/dist/docs/classes/EffectInstance.html +304 -0
  12. package/dist/docs/classes/Event.html +1 -1
  13. package/dist/docs/classes/Gradient.html +1 -1
  14. package/dist/docs/classes/GradientStop.html +1 -1
  15. package/dist/docs/classes/Group.html +792 -243
  16. package/dist/docs/classes/HitResult.html +1 -1
  17. package/dist/docs/classes/HostItem.html +720 -242
  18. package/dist/docs/classes/Item.html +777 -242
  19. package/dist/docs/classes/Key.html +1 -1
  20. package/dist/docs/classes/KeyEvent.html +1 -1
  21. package/dist/docs/classes/Layer.html +734 -185
  22. package/dist/docs/classes/Matrix.html +1 -1
  23. package/dist/docs/classes/MouseEvent.html +1 -1
  24. package/dist/docs/classes/PaperScope.html +1 -1
  25. package/dist/docs/classes/PaperScript.html +4 -2
  26. package/dist/docs/classes/Path.html +1195 -252
  27. package/dist/docs/classes/PathItem.html +1148 -298
  28. package/dist/docs/classes/PathText.html +720 -242
  29. package/dist/docs/classes/PatternDefinition.html +367 -0
  30. package/dist/docs/classes/Point.html +1 -1
  31. package/dist/docs/classes/PointText.html +720 -242
  32. package/dist/docs/classes/Project.html +177 -7
  33. package/dist/docs/classes/Raster.html +720 -242
  34. package/dist/docs/classes/Rectangle.html +1 -1
  35. package/dist/docs/classes/Segment.html +3 -3
  36. package/dist/docs/classes/Shape.html +720 -242
  37. package/dist/docs/classes/Size.html +1 -1
  38. package/dist/docs/classes/StrokeProfileStop.html +346 -0
  39. package/dist/docs/classes/Style.html +1 -1
  40. package/dist/docs/classes/SymbolDefinition.html +28 -2
  41. package/dist/docs/classes/SymbolItem.html +720 -242
  42. package/dist/docs/classes/TextItem.html +720 -242
  43. package/dist/docs/classes/TextRange.html +1 -1
  44. package/dist/docs/classes/TextStory.html +1 -1
  45. package/dist/docs/classes/Tool.html +2 -2
  46. package/dist/docs/classes/ToolEvent.html +1 -1
  47. package/dist/docs/classes/Tween.html +1 -1
  48. package/dist/docs/classes/View.html +2 -2
  49. package/dist/docs/classes/global.html +1 -1
  50. package/dist/docs/classes/index.html +2 -2
  51. package/dist/docs/index.html +1 -1
  52. package/dist/node/browser.js +15 -0
  53. package/dist/paper-core.js +4476 -674
  54. package/dist/paper-core.min.js +3 -3
  55. package/dist/paper-full.js +4565 -733
  56. package/dist/paper-full.min.js +3 -3
  57. package/dist/paper-hosted.js +5111 -823
  58. package/dist/paper.d.ts +898 -47
  59. package/examples/Paperjs.org/LiveEffects.html +366 -0
  60. package/examples/Paperjs.org/Offsetting.html +379 -0
  61. package/examples/Paperjs.org/StrokeProfiles.html +706 -0
  62. package/examples/Scripts/Patterns.html +57 -0
  63. package/package.json +5 -3
@@ -0,0 +1,366 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <title>Live Effects</title>
6
+ <link rel="stylesheet" href="../css/style.css">
7
+ <style>
8
+ body {
9
+ background: #f6f4f0;
10
+ font: 13px/1.4 -apple-system, 'Helvetica Neue', Helvetica, Arial, sans-serif;
11
+ color: #333;
12
+ }
13
+ .panel {
14
+ position: absolute;
15
+ top: 12px;
16
+ right: 12px;
17
+ width: 260px;
18
+ max-height: calc(100% - 52px);
19
+ overflow-y: auto;
20
+ padding: 14px 16px;
21
+ background: rgba(255, 255, 255, 0.92);
22
+ border-radius: 12px;
23
+ box-shadow: 0 2px 16px rgba(0, 0, 0, 0.12);
24
+ }
25
+ .panel h1 {
26
+ margin: 0 0 10px;
27
+ font-size: 16px;
28
+ }
29
+ .panel label {
30
+ display: flex;
31
+ align-items: center;
32
+ justify-content: space-between;
33
+ gap: 8px;
34
+ margin: 6px 0;
35
+ }
36
+ .panel input[type=range] {
37
+ width: 120px;
38
+ }
39
+ .panel select {
40
+ width: 128px;
41
+ }
42
+ .effect {
43
+ margin: 8px 0;
44
+ padding: 6px 10px;
45
+ border: 1px solid #ddd;
46
+ border-radius: 8px;
47
+ background: white;
48
+ }
49
+ .effect.hidden {
50
+ opacity: 0.5;
51
+ }
52
+ .effect header {
53
+ display: flex;
54
+ align-items: center;
55
+ gap: 6px;
56
+ font-weight: 600;
57
+ }
58
+ .effect header span {
59
+ flex: 1;
60
+ }
61
+ .effect button {
62
+ padding: 0 6px;
63
+ }
64
+ .panel .info {
65
+ margin-top: 10px;
66
+ color: #888;
67
+ font-size: 11px;
68
+ }
69
+ </style>
70
+ <script type="text/javascript" src="../../dist/paper-full.js"></script>
71
+ <script type="text/paperscript" canvas="canvas">
72
+ var presets = {
73
+ 'Star': function() {
74
+ return new Path.Star({
75
+ center: view.center,
76
+ points: 6,
77
+ radius1: 70,
78
+ radius2: 150,
79
+ fillColor: '#ffcf5c',
80
+ strokeColor: '#e0306a',
81
+ strokeWidth: 16,
82
+ strokeJoin: 'round'
83
+ });
84
+ },
85
+ 'Wave': function() {
86
+ var path = new Path({
87
+ segments: [[-240, 60], [-120, -80], [0, 60], [120, -80],
88
+ [240, 60]],
89
+ strokeColor: '#e0306a',
90
+ strokeWidth: 24,
91
+ strokeCap: 'round'
92
+ });
93
+ path.smooth({ type: 'catmull-rom' });
94
+ path.position = view.center;
95
+ return path;
96
+ },
97
+ 'Pressure': function() {
98
+ var path = presets['Wave']();
99
+ path.strokeProfile = [
100
+ { offset: 0, width: 0.2 },
101
+ { offset: path.length / 2, width: 1.6 },
102
+ { offset: path.length, width: 0.2 }
103
+ ];
104
+ return path;
105
+ },
106
+ 'Blob': function() {
107
+ var path = new Path.Circle({
108
+ center: view.center,
109
+ radius: 120,
110
+ fillColor: '#5ca8ff'
111
+ });
112
+ path.segments[1].point += [60, 30];
113
+ path.segments[3].point -= [40, 50];
114
+ return path;
115
+ }
116
+ };
117
+
118
+ // The ranges of the number parameters, which the effects leave open:
119
+ var ranges = {
120
+ distance: [-60, 60],
121
+ miterLimit: [1, 20]
122
+ };
123
+
124
+ var settings = {
125
+ preset: 'Star',
126
+ showBounds: true
127
+ };
128
+
129
+ var path;
130
+ var drag = null;
131
+ var info = document.getElementById('info');
132
+ var list = document.getElementById('effects');
133
+
134
+ function createPreset(name) {
135
+ var effects = path ? path.effects : [];
136
+ if (path)
137
+ path.remove();
138
+ path = presets[name]();
139
+ path.set({
140
+ fullySelected: true,
141
+ selectedColor: '#222',
142
+ onDrawSelection: drawPreviewBounds
143
+ });
144
+ // Keep the effects when switching paths, as copies:
145
+ path.effects = effects.map(describe);
146
+ update();
147
+ }
148
+
149
+ // Draws the preview bounds over the selection of the path, see
150
+ // Item#onDrawSelection:
151
+ function drawPreviewBounds(event) {
152
+ if (settings.showBounds) {
153
+ var ctx = event.context,
154
+ bounds = path.previewBounds,
155
+ topLeft = event.matrix.transform(bounds.topLeft),
156
+ bottomRight = event.matrix.transform(bounds.bottomRight);
157
+ ctx.setLineDash([4, 3]);
158
+ ctx.strokeStyle = '#1060ff';
159
+ ctx.strokeRect(topLeft.x, topLeft.y, bottomRight.x - topLeft.x,
160
+ bottomRight.y - topLeft.y);
161
+ ctx.setLineDash([]);
162
+ }
163
+ }
164
+
165
+ // Returns the plain object that describes the effect instance, which
166
+ // items take to add it:
167
+ function describe(instance) {
168
+ return {
169
+ type: instance.type,
170
+ parameters: instance.parameters,
171
+ visible: instance.visible
172
+ };
173
+ }
174
+
175
+ // Builds the panel of each effect instance: its visibility, its order
176
+ // and its parameters, with the controls that its effect declares:
177
+ function updatePanel() {
178
+ list.innerHTML = '';
179
+ path.effects.forEach(function(instance) {
180
+ var effect = instance.effect,
181
+ element = document.createElement('div');
182
+ element.className = 'effect'
183
+ + (instance.visible ? '' : ' hidden');
184
+ var header = document.createElement('header');
185
+ var visible = document.createElement('input');
186
+ visible.type = 'checkbox';
187
+ visible.checked = instance.visible;
188
+ visible.title = 'Visible';
189
+ visible.addEventListener('input', function() {
190
+ instance.visible = visible.checked;
191
+ element.classList.toggle('hidden', !instance.visible);
192
+ update(false);
193
+ });
194
+ var title = document.createElement('span');
195
+ title.textContent = effect.label;
196
+ header.appendChild(visible);
197
+ header.appendChild(title);
198
+ // Moves the instance by the amount in the order:
199
+ function move(amount) {
200
+ var index = instance.index + amount;
201
+ if (index >= 0 && index < path.effects.length) {
202
+ instance.remove();
203
+ path.insertEffect(index, describe(instance));
204
+ }
205
+ }
206
+
207
+ [
208
+ ['↑', function() { move(-1); }],
209
+ ['↓', function() { move(1); }],
210
+ ['✕', function() { instance.remove(); }]
211
+ ].forEach(function(entry) {
212
+ var button = document.createElement('button');
213
+ button.textContent = entry[0];
214
+ button.addEventListener('click', function() {
215
+ entry[1]();
216
+ update();
217
+ });
218
+ header.appendChild(button);
219
+ });
220
+ element.appendChild(header);
221
+ Object.keys(effect.parameters).forEach(function(key) {
222
+ var parameter = effect.parameters[key],
223
+ isList = parameter.type === 'list',
224
+ range = ranges[key],
225
+ label = document.createElement('label'),
226
+ input = document.createElement(isList
227
+ ? 'select' : 'input');
228
+ label.textContent = parameter.label;
229
+ if (isList) {
230
+ parameter.options.forEach(function(option) {
231
+ var node = document.createElement('option');
232
+ node.textContent = option;
233
+ input.appendChild(node);
234
+ });
235
+ } else {
236
+ input.type = 'range';
237
+ input.min = range[0];
238
+ input.max = range[1];
239
+ input.step = 0.5;
240
+ }
241
+ input.value = instance[key];
242
+ input.addEventListener('input', function() {
243
+ // Setting a parameter through its property redraws:
244
+ instance[key] = isList ? input.value : +input.value;
245
+ update(false);
246
+ });
247
+ label.appendChild(input);
248
+ element.appendChild(label);
249
+ });
250
+ list.appendChild(element);
251
+ });
252
+ }
253
+
254
+ function update(rebuild) {
255
+ var time = Date.now();
256
+ path.getEffectOutput();
257
+ info.textContent = path.effects.length + ' effects, applied in '
258
+ + (Date.now() - time) + ' ms.';
259
+ if (rebuild !== false)
260
+ updatePanel();
261
+ }
262
+
263
+ document.getElementById('add').addEventListener('input', function() {
264
+ if (this.value) {
265
+ path.addEffect({
266
+ type: this.value,
267
+ parameters: this.value === 'offset'
268
+ ? { distance: 20, join: 'round' } : {}
269
+ });
270
+ this.value = '';
271
+ update();
272
+ }
273
+ });
274
+
275
+ function onMouseDown(event) {
276
+ var hit = path.hitTest(event.point, {
277
+ segments: true,
278
+ handles: true,
279
+ fill: true,
280
+ stroke: true,
281
+ tolerance: 6
282
+ });
283
+ drag = hit && {
284
+ type: hit.type,
285
+ segment: hit.segment
286
+ };
287
+ }
288
+
289
+ function onMouseDrag(event) {
290
+ if (drag) {
291
+ var name = {
292
+ 'segment': 'point',
293
+ 'handle-in': 'handleIn',
294
+ 'handle-out': 'handleOut'
295
+ }[drag.type];
296
+ if (name) {
297
+ drag.segment[name] += event.delta;
298
+ } else {
299
+ path.position += event.delta;
300
+ }
301
+ update(false);
302
+ }
303
+ }
304
+
305
+ function onMouseUp() {
306
+ drag = null;
307
+ }
308
+
309
+ function bind(id, key, convert) {
310
+ var input = document.getElementById(id);
311
+ input.addEventListener('input', function() {
312
+ settings[key] = convert ? convert(input) : input.value;
313
+ if (key === 'preset') {
314
+ createPreset(settings.preset);
315
+ } else {
316
+ view.update(true);
317
+ }
318
+ });
319
+ }
320
+
321
+ bind('preset', 'preset');
322
+ bind('show-bounds', 'showBounds', function(input) {
323
+ return input.checked;
324
+ });
325
+
326
+ createPreset(settings.preset);
327
+ path.addEffect({
328
+ type: 'offset',
329
+ parameters: { distance: 20, join: 'round' }
330
+ });
331
+ update();
332
+ </script>
333
+ </head>
334
+ <body>
335
+ <canvas id="canvas" resize></canvas>
336
+ <div class="panel">
337
+ <h1>Live Effects</h1>
338
+ <label>Path
339
+ <select id="preset">
340
+ <option>Star</option>
341
+ <option>Wave</option>
342
+ <option>Pressure</option>
343
+ <option>Blob</option>
344
+ </select>
345
+ </label>
346
+ <label>Preview bounds <input id="show-bounds" type="checkbox" checked></label>
347
+ <label>Add effect
348
+ <select id="add">
349
+ <option value="">…</option>
350
+ <option value="offset">Offset</option>
351
+ <option value="outline">Outline stroke</option>
352
+ </select>
353
+ </label>
354
+ <div id="effects"></div>
355
+ <div class="info">
356
+ <p id="info"></p>
357
+ <p>The path keeps its own geometry and style, and its effects
358
+ derive what is drawn from it, in order, each from the one before.
359
+ Drag its points and handles, or the path itself, to edit it: the
360
+ effects follow. The dashed rectangle is its
361
+ <code>previewBounds</code>, while hit testing, <code>bounds</code>
362
+ and <code>strokeBounds</code> stay with the path.</p>
363
+ </div>
364
+ </div>
365
+ </body>
366
+ </html>