js-draw 0.0.3 → 0.0.6
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/CHANGELOG.md +17 -0
- package/README.md +108 -0
- package/build_tools/BundledFile.ts +167 -0
- package/build_tools/bundle.ts +11 -0
- package/dist/build_tools/BundledFile.d.ts +13 -0
- package/dist/build_tools/BundledFile.js +157 -0
- package/dist/build_tools/bundle.d.ts +1 -0
- package/dist/build_tools/bundle.js +5 -0
- package/dist/bundle.js +1 -0
- package/dist/src/Display.js +4 -1
- package/dist/src/Editor.d.ts +9 -2
- package/dist/src/Editor.js +36 -7
- package/dist/src/EditorImage.d.ts +4 -2
- package/dist/src/EditorImage.js +29 -5
- package/dist/src/Pointer.js +1 -1
- package/dist/src/SVGLoader.js +3 -1
- package/dist/src/Viewport.d.ts +2 -2
- package/dist/src/bundle/bundled.d.ts +4 -0
- package/dist/src/bundle/bundled.js +5 -0
- package/dist/src/components/AbstractComponent.d.ts +1 -1
- package/dist/src/components/Stroke.d.ts +1 -1
- package/dist/src/components/Stroke.js +1 -1
- package/dist/src/components/UnknownSVGObject.d.ts +1 -1
- package/dist/src/components/builders/ArrowBuilder.d.ts +17 -0
- package/dist/src/components/builders/ArrowBuilder.js +83 -0
- package/dist/src/{StrokeBuilder.d.ts → components/builders/FreehandLineBuilder.d.ts} +9 -13
- package/dist/src/{StrokeBuilder.js → components/builders/FreehandLineBuilder.js} +42 -12
- package/dist/src/components/builders/LineBuilder.d.ts +16 -0
- package/dist/src/components/builders/LineBuilder.js +57 -0
- package/dist/src/components/builders/RectangleBuilder.d.ts +18 -0
- package/dist/src/components/builders/RectangleBuilder.js +41 -0
- package/dist/src/components/builders/types.d.ts +12 -0
- package/dist/src/components/builders/types.js +1 -0
- package/dist/src/geometry/Path.d.ts +1 -0
- package/dist/src/geometry/Path.js +43 -0
- package/dist/src/geometry/Vec3.d.ts +2 -0
- package/dist/src/geometry/Vec3.js +13 -0
- package/dist/src/localization.d.ts +1 -1
- package/dist/src/localization.js +2 -2
- package/dist/src/rendering/AbstractRenderer.js +3 -25
- package/dist/src/toolbar/HTMLToolbar.d.ts +5 -3
- package/dist/src/toolbar/HTMLToolbar.js +139 -30
- package/dist/src/toolbar/localization.d.ts +20 -0
- package/dist/src/toolbar/localization.js +19 -0
- package/dist/src/toolbar/types.d.ts +0 -13
- package/dist/src/tools/Pen.d.ts +13 -3
- package/dist/src/tools/Pen.js +37 -28
- package/dist/src/tools/SelectionTool.js +1 -1
- package/dist/src/tools/ToolController.js +3 -3
- package/dist/src/types.d.ts +14 -2
- package/dist/src/types.js +1 -0
- package/dist-test/test-dist-bundle.html +35 -0
- package/package.json +15 -5
- package/src/Display.ts +3 -1
- package/src/Editor.css +0 -1
- package/src/Editor.ts +62 -13
- package/src/EditorImage.test.ts +5 -3
- package/src/EditorImage.ts +31 -3
- package/src/Pointer.ts +1 -1
- package/src/SVGLoader.ts +5 -1
- package/src/Viewport.ts +1 -1
- package/src/bundle/bundled.ts +7 -0
- package/src/components/AbstractComponent.ts +1 -1
- package/src/components/Stroke.ts +2 -2
- package/src/components/UnknownSVGObject.ts +1 -1
- package/src/components/builders/ArrowBuilder.ts +104 -0
- package/src/{StrokeBuilder.ts → components/builders/FreehandLineBuilder.ts} +59 -22
- package/src/components/builders/LineBuilder.ts +75 -0
- package/src/components/builders/RectangleBuilder.ts +59 -0
- package/src/components/builders/types.ts +15 -0
- package/src/geometry/Path.fromString.test.ts +11 -24
- package/src/geometry/Path.ts +56 -0
- package/src/geometry/Vec2.test.ts +1 -0
- package/src/geometry/Vec3.test.ts +14 -0
- package/src/geometry/Vec3.ts +16 -0
- package/src/localization.ts +2 -3
- package/src/rendering/AbstractRenderer.ts +3 -32
- package/src/{editorStyles.js → styles.js} +0 -0
- package/src/toolbar/HTMLToolbar.ts +167 -39
- package/src/toolbar/localization.ts +44 -0
- package/src/toolbar/toolbar.css +12 -0
- package/src/toolbar/types.ts +0 -16
- package/src/tools/Pen.ts +56 -34
- package/src/tools/SelectionTool.test.ts +1 -1
- package/src/tools/SelectionTool.ts +1 -1
- package/src/tools/ToolController.ts +3 -3
- package/src/types.ts +16 -1
@@ -0,0 +1,75 @@
|
|
1
|
+
import { PathCommandType } from '../../geometry/Path';
|
2
|
+
import Rect2 from '../../geometry/Rect2';
|
3
|
+
import AbstractRenderer from '../../rendering/AbstractRenderer';
|
4
|
+
import { StrokeDataPoint } from '../../types';
|
5
|
+
import Viewport from '../../Viewport';
|
6
|
+
import AbstractComponent from '../AbstractComponent';
|
7
|
+
import Stroke from '../Stroke';
|
8
|
+
import { ComponentBuilder, ComponentBuilderFactory } from './types';
|
9
|
+
|
10
|
+
export const makeLineBuilder: ComponentBuilderFactory = (initialPoint: StrokeDataPoint, _viewport: Viewport) => {
|
11
|
+
return new LineBuilder(initialPoint);
|
12
|
+
};
|
13
|
+
|
14
|
+
export default class LineBuilder implements ComponentBuilder {
|
15
|
+
private endPoint: StrokeDataPoint;
|
16
|
+
|
17
|
+
public constructor(private readonly startPoint: StrokeDataPoint) {
|
18
|
+
this.endPoint = startPoint;
|
19
|
+
}
|
20
|
+
|
21
|
+
public getBBox(): Rect2 {
|
22
|
+
const preview = this.buildPreview();
|
23
|
+
return preview.getBBox();
|
24
|
+
}
|
25
|
+
|
26
|
+
private buildPreview(): Stroke {
|
27
|
+
const startPoint = this.startPoint.pos;
|
28
|
+
const endPoint = this.endPoint.pos;
|
29
|
+
const toEnd = endPoint.minus(startPoint).normalized();
|
30
|
+
|
31
|
+
const startSize = this.startPoint.width / 2;
|
32
|
+
const endSize = this.endPoint.width / 2;
|
33
|
+
|
34
|
+
const lineNormal = toEnd.orthog();
|
35
|
+
const scaledStartNormal = lineNormal.times(startSize);
|
36
|
+
const scaledEndNormal = lineNormal.times(endSize);
|
37
|
+
|
38
|
+
const preview = new Stroke([
|
39
|
+
{
|
40
|
+
startPoint: startPoint.minus(scaledStartNormal),
|
41
|
+
commands: [
|
42
|
+
{
|
43
|
+
kind: PathCommandType.LineTo,
|
44
|
+
point: startPoint.plus(scaledStartNormal),
|
45
|
+
},
|
46
|
+
{
|
47
|
+
kind: PathCommandType.LineTo,
|
48
|
+
point: endPoint.plus(scaledEndNormal),
|
49
|
+
},
|
50
|
+
{
|
51
|
+
kind: PathCommandType.LineTo,
|
52
|
+
point: endPoint.minus(scaledEndNormal),
|
53
|
+
},
|
54
|
+
],
|
55
|
+
style: {
|
56
|
+
fill: this.startPoint.color,
|
57
|
+
}
|
58
|
+
}
|
59
|
+
]);
|
60
|
+
|
61
|
+
return preview;
|
62
|
+
}
|
63
|
+
|
64
|
+
public build(): AbstractComponent {
|
65
|
+
return this.buildPreview();
|
66
|
+
}
|
67
|
+
|
68
|
+
public preview(renderer: AbstractRenderer): void {
|
69
|
+
this.buildPreview().render(renderer);
|
70
|
+
}
|
71
|
+
|
72
|
+
public addPoint(point: StrokeDataPoint): void {
|
73
|
+
this.endPoint = point;
|
74
|
+
}
|
75
|
+
}
|
@@ -0,0 +1,59 @@
|
|
1
|
+
import Path from '../../geometry/Path';
|
2
|
+
import Rect2 from '../../geometry/Rect2';
|
3
|
+
import AbstractRenderer from '../../rendering/AbstractRenderer';
|
4
|
+
import { StrokeDataPoint } from '../../types';
|
5
|
+
import Viewport from '../../Viewport';
|
6
|
+
import AbstractComponent from '../AbstractComponent';
|
7
|
+
import Stroke from '../Stroke';
|
8
|
+
import { ComponentBuilder, ComponentBuilderFactory } from './types';
|
9
|
+
|
10
|
+
export const makeFilledRectangleBuilder: ComponentBuilderFactory = (initialPoint: StrokeDataPoint, _viewport: Viewport) => {
|
11
|
+
return new RectangleBuilder(initialPoint, true);
|
12
|
+
};
|
13
|
+
|
14
|
+
export const makeOutlinedRectangleBuilder: ComponentBuilderFactory = (initialPoint: StrokeDataPoint, _viewport: Viewport) => {
|
15
|
+
return new RectangleBuilder(initialPoint, false);
|
16
|
+
};
|
17
|
+
|
18
|
+
export default class RectangleBuilder implements ComponentBuilder {
|
19
|
+
private endPoint: StrokeDataPoint;
|
20
|
+
|
21
|
+
public constructor(private readonly startPoint: StrokeDataPoint, private filled: boolean) {
|
22
|
+
// Initially, the start and end points are the same.
|
23
|
+
this.endPoint = startPoint;
|
24
|
+
}
|
25
|
+
|
26
|
+
public getBBox(): Rect2 {
|
27
|
+
const preview = this.buildPreview();
|
28
|
+
return preview.getBBox();
|
29
|
+
}
|
30
|
+
|
31
|
+
private buildPreview(): Stroke {
|
32
|
+
const startPoint = this.startPoint.pos;
|
33
|
+
const endPoint = this.endPoint.pos;
|
34
|
+
const path = Path.fromRect(
|
35
|
+
Rect2.fromCorners(startPoint, endPoint),
|
36
|
+
this.filled ? null : this.endPoint.width,
|
37
|
+
);
|
38
|
+
|
39
|
+
const preview = new Stroke([
|
40
|
+
path.toRenderable({
|
41
|
+
fill: this.endPoint.color
|
42
|
+
}),
|
43
|
+
]);
|
44
|
+
|
45
|
+
return preview;
|
46
|
+
}
|
47
|
+
|
48
|
+
public build(): AbstractComponent {
|
49
|
+
return this.buildPreview();
|
50
|
+
}
|
51
|
+
|
52
|
+
public preview(renderer: AbstractRenderer): void {
|
53
|
+
this.buildPreview().render(renderer);
|
54
|
+
}
|
55
|
+
|
56
|
+
public addPoint(point: StrokeDataPoint): void {
|
57
|
+
this.endPoint = point;
|
58
|
+
}
|
59
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import Rect2 from '../../geometry/Rect2';
|
2
|
+
import AbstractRenderer from '../../rendering/AbstractRenderer';
|
3
|
+
import { StrokeDataPoint } from '../../types';
|
4
|
+
import Viewport from '../../Viewport';
|
5
|
+
import AbstractComponent from '../AbstractComponent';
|
6
|
+
|
7
|
+
export interface ComponentBuilder {
|
8
|
+
getBBox(): Rect2;
|
9
|
+
build(): AbstractComponent;
|
10
|
+
preview(renderer: AbstractRenderer): void;
|
11
|
+
|
12
|
+
addPoint(point: StrokeDataPoint): void;
|
13
|
+
}
|
14
|
+
|
15
|
+
export type ComponentBuilderFactory = (startPoint: StrokeDataPoint, viewport: Viewport)=> ComponentBuilder;
|
@@ -14,17 +14,13 @@ describe('Path.fromString', () => {
|
|
14
14
|
const path2 = Path.fromString('M 0 0');
|
15
15
|
const path3 = Path.fromString('M 1,1M 2,2 M 3,3');
|
16
16
|
|
17
|
-
expect(path1.parts
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
expect(path2.
|
17
|
+
expect(path1.parts.length).toBe(0);
|
18
|
+
expect(path1.startPoint).toMatchObject(Vec2.zero);
|
19
|
+
|
20
|
+
expect(path2.parts.length).toBe(0);
|
21
|
+
expect(path2.startPoint).toMatchObject(Vec2.zero);
|
22
22
|
|
23
23
|
expect(path3.parts).toMatchObject([
|
24
|
-
{
|
25
|
-
kind: PathCommandType.MoveTo,
|
26
|
-
point: Vec2.of(1, 1),
|
27
|
-
},
|
28
24
|
{
|
29
25
|
kind: PathCommandType.MoveTo,
|
30
26
|
point: Vec2.of(2, 2),
|
@@ -44,27 +40,22 @@ describe('Path.fromString', () => {
|
|
44
40
|
kind: PathCommandType.MoveTo,
|
45
41
|
point: Vec2.of(1, 1),
|
46
42
|
},
|
47
|
-
{
|
48
|
-
kind: PathCommandType.MoveTo,
|
49
|
-
point: Vec2.of(1, 1),
|
50
|
-
},
|
51
43
|
{
|
52
44
|
kind: PathCommandType.MoveTo,
|
53
45
|
point: Vec2.of(4, 4),
|
54
46
|
},
|
55
47
|
]);
|
48
|
+
expect(path.startPoint).toMatchObject(Vec2.of(1, 1));
|
56
49
|
});
|
57
50
|
|
58
51
|
it('should handle lineTo commands', () => {
|
59
52
|
const path = Path.fromString('l1,2L-1,0l0.1,-1.0');
|
53
|
+
// l is a relative lineTo, but because there
|
54
|
+
// is no previous command, it should act like an
|
55
|
+
// absolute moveTo.
|
56
|
+
expect(path.startPoint).toMatchObject(Vec2.of(1, 2));
|
57
|
+
|
60
58
|
expect(path.parts).toMatchObject([
|
61
|
-
{
|
62
|
-
kind: PathCommandType.LineTo,
|
63
|
-
// l is a relative lineTo, but because there
|
64
|
-
// is no previous command, it should act like an
|
65
|
-
// absolute moveTo.
|
66
|
-
point: Vec2.of(1, 2),
|
67
|
-
},
|
68
59
|
{
|
69
60
|
kind: PathCommandType.LineTo,
|
70
61
|
point: Vec2.of(-1, 0),
|
@@ -84,10 +75,6 @@ describe('Path.fromString', () => {
|
|
84
75
|
expect(path2.startPoint).toMatchObject(path1.startPoint);
|
85
76
|
expect(path1.parts).toMatchObject(path2.parts);
|
86
77
|
expect(path1.parts).toMatchObject([
|
87
|
-
{
|
88
|
-
kind: PathCommandType.MoveTo,
|
89
|
-
point: Vec2.of(3, 3),
|
90
|
-
},
|
91
78
|
{
|
92
79
|
kind: PathCommandType.LineTo,
|
93
80
|
point: Vec2.of(4, 5),
|
package/src/geometry/Path.ts
CHANGED
@@ -223,6 +223,49 @@ export default class Path {
|
|
223
223
|
]);
|
224
224
|
}
|
225
225
|
|
226
|
+
// Returns a path that outlines [rect]. If [lineWidth] is not given, the resultant path is
|
227
|
+
// the outline of [rect]. Otherwise, the resultant path represents a line of width [lineWidth]
|
228
|
+
// that traces [rect].
|
229
|
+
public static fromRect(rect: Rect2, lineWidth: number|null = null): Path {
|
230
|
+
const commands: PathCommand[] = [];
|
231
|
+
|
232
|
+
let corners;
|
233
|
+
let startPoint;
|
234
|
+
|
235
|
+
if (lineWidth !== null) {
|
236
|
+
// Vector from the top left corner or bottom right corner to the edge of the
|
237
|
+
// stroked region.
|
238
|
+
const cornerToEdge = Vec2.of(lineWidth, lineWidth).times(0.5);
|
239
|
+
const innerRect = Rect2.fromCorners(
|
240
|
+
rect.topLeft.plus(cornerToEdge),
|
241
|
+
rect.bottomRight.minus(cornerToEdge)
|
242
|
+
);
|
243
|
+
const outerRect = Rect2.fromCorners(
|
244
|
+
rect.topLeft.minus(cornerToEdge),
|
245
|
+
rect.bottomRight.plus(cornerToEdge)
|
246
|
+
);
|
247
|
+
|
248
|
+
corners = [
|
249
|
+
innerRect.corners[3],
|
250
|
+
...innerRect.corners,
|
251
|
+
...outerRect.corners.reverse(),
|
252
|
+
];
|
253
|
+
startPoint = outerRect.corners[3];
|
254
|
+
} else {
|
255
|
+
corners = rect.corners.slice(1);
|
256
|
+
startPoint = rect.corners[0];
|
257
|
+
}
|
258
|
+
|
259
|
+
for (const corner of corners) {
|
260
|
+
commands.push({
|
261
|
+
kind: PathCommandType.LineTo,
|
262
|
+
point: corner,
|
263
|
+
});
|
264
|
+
}
|
265
|
+
|
266
|
+
return new Path(startPoint, commands);
|
267
|
+
}
|
268
|
+
|
226
269
|
public static fromRenderable(renderable: RenderablePathSpec): Path {
|
227
270
|
return new Path(renderable.startPoint, renderable.commands);
|
228
271
|
}
|
@@ -324,16 +367,28 @@ export default class Path {
|
|
324
367
|
|
325
368
|
let lastPos: Point2 = Vec2.zero;
|
326
369
|
let firstPos: Point2|null = null;
|
370
|
+
let isFirstCommand: boolean = true;
|
327
371
|
const commands: PathCommand[] = [];
|
328
372
|
|
329
373
|
|
330
374
|
const moveTo = (point: Point2) => {
|
375
|
+
// The first moveTo/lineTo is already handled by the [startPoint] parameter of the Path constructor.
|
376
|
+
if (isFirstCommand) {
|
377
|
+
isFirstCommand = false;
|
378
|
+
return;
|
379
|
+
}
|
380
|
+
|
331
381
|
commands.push({
|
332
382
|
kind: PathCommandType.MoveTo,
|
333
383
|
point,
|
334
384
|
});
|
335
385
|
};
|
336
386
|
const lineTo = (point: Point2) => {
|
387
|
+
if (isFirstCommand) {
|
388
|
+
isFirstCommand = false;
|
389
|
+
return;
|
390
|
+
}
|
391
|
+
|
337
392
|
commands.push({
|
338
393
|
kind: PathCommandType.LineTo,
|
339
394
|
point,
|
@@ -449,6 +504,7 @@ export default class Path {
|
|
449
504
|
if (args.length > 0) {
|
450
505
|
firstPos ??= args[0];
|
451
506
|
}
|
507
|
+
isFirstCommand = false;
|
452
508
|
}
|
453
509
|
|
454
510
|
return new Path(firstPos ?? Vec2.zero, commands);
|
@@ -26,4 +26,18 @@ describe('Vec3', () => {
|
|
26
26
|
expect(vec1.cross(vec2)).objEq(Vec3.unitZ);
|
27
27
|
expect(vec2.cross(vec1)).objEq(Vec3.unitZ.times(-1));
|
28
28
|
});
|
29
|
+
|
30
|
+
it('.orthog should return an orthogonal vector', () => {
|
31
|
+
expect(Vec3.unitZ.orthog().dot(Vec3.unitZ)).toBe(0);
|
32
|
+
|
33
|
+
// Should return some orthogonal vector, even if given the zero vector
|
34
|
+
expect(Vec3.zero.orthog().dot(Vec3.zero)).toBe(0);
|
35
|
+
});
|
36
|
+
|
37
|
+
it('.orthog should return a unit vector', () => {
|
38
|
+
expect(Vec3.zero.orthog().magnitude()).toBe(1);
|
39
|
+
expect(Vec3.unitZ.orthog().magnitude()).toBe(1);
|
40
|
+
expect(Vec3.unitX.orthog().magnitude()).toBe(1);
|
41
|
+
expect(Vec3.unitY.orthog().magnitude()).toBe(1);
|
42
|
+
});
|
29
43
|
});
|
package/src/geometry/Vec3.ts
CHANGED
@@ -31,6 +31,11 @@ export default class Vec3 {
|
|
31
31
|
throw new Error(`${idx} out of bounds!`);
|
32
32
|
}
|
33
33
|
|
34
|
+
// Alias for this.magnitude
|
35
|
+
public length(): number {
|
36
|
+
return this.magnitude();
|
37
|
+
}
|
38
|
+
|
34
39
|
public magnitude(): number {
|
35
40
|
return Math.sqrt(this.dot(this));
|
36
41
|
}
|
@@ -76,6 +81,17 @@ export default class Vec3 {
|
|
76
81
|
);
|
77
82
|
}
|
78
83
|
|
84
|
+
// Returns a vector orthogonal to this. If this is a Vec2, returns [this] rotated
|
85
|
+
// 90 degrees counter-clockwise.
|
86
|
+
public orthog(): Vec3 {
|
87
|
+
// If parallel to the z-axis
|
88
|
+
if (this.dot(Vec3.unitX) === 0 && this.dot(Vec3.unitY) === 0) {
|
89
|
+
return this.dot(Vec3.unitX) === 0 ? Vec3.unitX : this.cross(Vec3.unitX).normalized();
|
90
|
+
}
|
91
|
+
|
92
|
+
return this.cross(Vec3.unitZ.times(-1)).normalized();
|
93
|
+
}
|
94
|
+
|
79
95
|
// Returns this plus a vector of length [distance] in [direction]
|
80
96
|
public extend(distance: number, direction: Vec3): Vec3 {
|
81
97
|
return this.plus(direction.normalized().times(distance));
|
package/src/localization.ts
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
import { CommandLocalization, defaultCommandLocalization } from './commands/localization';
|
2
2
|
import { defaultComponentLocalization, ImageComponentLocalization } from './components/localization';
|
3
|
-
import
|
4
|
-
import { ToolbarLocalization } from './toolbar/types';
|
3
|
+
import { defaultToolbarLocalization, ToolbarLocalization } from './toolbar/localization';
|
5
4
|
import { defaultToolLocalization, ToolLocalization } from './tools/localization';
|
6
5
|
|
7
6
|
|
@@ -14,7 +13,7 @@ export interface EditorLocalization extends ToolbarLocalization, ToolLocalizatio
|
|
14
13
|
}
|
15
14
|
|
16
15
|
export const defaultEditorLocalization: EditorLocalization = {
|
17
|
-
...
|
16
|
+
...defaultToolbarLocalization,
|
18
17
|
...defaultToolLocalization,
|
19
18
|
...defaultCommandLocalization,
|
20
19
|
...defaultComponentLocalization,
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import Color4 from '../Color4';
|
2
|
-
import { PathCommand, PathCommandType } from '../geometry/Path';
|
2
|
+
import Path, { PathCommand, PathCommandType } from '../geometry/Path';
|
3
3
|
import Rect2 from '../geometry/Rect2';
|
4
4
|
import { Point2, Vec2 } from '../geometry/Vec2';
|
5
5
|
import Viewport from '../Viewport';
|
@@ -103,37 +103,8 @@ export default abstract class AbstractRenderer {
|
|
103
103
|
|
104
104
|
// Draw a rectangle. Boundary lines have width [lineWidth] and are filled with [lineFill]
|
105
105
|
public drawRect(rect: Rect2, lineWidth: number, lineFill: RenderingStyle): void {
|
106
|
-
const
|
107
|
-
|
108
|
-
// Vector from the top left corner or bottom right corner to the edge of the
|
109
|
-
// stroked region.
|
110
|
-
const cornerToEdge = Vec2.of(lineWidth, lineWidth).times(0.5);
|
111
|
-
const innerRect = Rect2.fromCorners(
|
112
|
-
rect.topLeft.plus(cornerToEdge),
|
113
|
-
rect.bottomRight.minus(cornerToEdge)
|
114
|
-
);
|
115
|
-
const outerRect = Rect2.fromCorners(
|
116
|
-
rect.topLeft.minus(cornerToEdge),
|
117
|
-
rect.bottomRight.plus(cornerToEdge)
|
118
|
-
);
|
119
|
-
|
120
|
-
const corners = [
|
121
|
-
innerRect.corners[3],
|
122
|
-
...innerRect.corners,
|
123
|
-
...outerRect.corners.reverse(),
|
124
|
-
];
|
125
|
-
for (const corner of corners) {
|
126
|
-
commands.push({
|
127
|
-
kind: PathCommandType.LineTo,
|
128
|
-
point: corner,
|
129
|
-
});
|
130
|
-
}
|
131
|
-
|
132
|
-
this.drawPath({
|
133
|
-
startPoint: outerRect.corners[3],
|
134
|
-
commands,
|
135
|
-
style: lineFill,
|
136
|
-
});
|
106
|
+
const path = Path.fromRect(rect, lineWidth);
|
107
|
+
this.drawPath(path.toRenderable(lineFill));
|
137
108
|
}
|
138
109
|
|
139
110
|
// Note the start/end of an object with the given bounding box.
|
File without changes
|