@design-core/core 0.0.1 → 0.0.3
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/.eslintrc.json +14 -7
- package/.github/workflows/DesignCoreQA.yml +3 -1
- package/README.md +11 -4
- package/TODO.md +19 -0
- package/core/core/core.js +49 -42
- package/core/designCore.js +61 -2
- package/core/dimensions/alignedDimension.js +142 -0
- package/core/dimensions/angularDimension.js +550 -0
- package/core/dimensions/baseCircularDimension.js +244 -0
- package/core/dimensions/baseDimension.js +558 -0
- package/core/dimensions/baseLinearDimension.js +371 -0
- package/core/dimensions/diametricDimension.js +82 -0
- package/core/dimensions/dimension.js +298 -0
- package/core/dimensions/linearDimension.js +29 -0
- package/core/dimensions/radialDimension.js +78 -0
- package/core/dimensions/rotatedDimension.js +167 -0
- package/core/entities/arc.js +314 -60
- package/core/entities/arctext.js +642 -0
- package/core/entities/basePolyline.js +553 -94
- package/core/entities/circle.js +181 -54
- package/core/entities/entity.js +154 -74
- package/core/entities/hatch.js +807 -0
- package/core/entities/insert.js +200 -39
- package/core/entities/line.js +196 -134
- package/core/entities/lwpolyline.js +21 -44
- package/core/entities/point.js +194 -29
- package/core/entities/polyline.js +54 -7
- package/core/entities/rectangle.js +43 -13
- package/core/entities/solid.js +43 -6
- package/core/entities/text.js +324 -181
- package/core/lib/boundingBox.js +73 -13
- package/core/lib/canvas.js +256 -65
- package/core/lib/clipboard.js +198 -0
- package/core/lib/colour.js +144 -0
- package/core/lib/colours.js +367 -301
- package/core/lib/commandLine.js +16 -28
- package/core/lib/commandManager.js +115 -58
- package/core/lib/constants.js +23 -0
- package/core/lib/dxf/dxf.js +249 -34
- package/core/lib/dxf/dxfFile.js +23 -38
- package/core/lib/dxf/dxfIterator.js +17 -5
- package/core/lib/dxf/dxfRead.js +23 -7
- package/core/lib/dxf/dxfWrite.js +39 -129
- package/core/lib/dxf/handleManager.js +97 -0
- package/core/lib/dxf/sections/blocks.js +16 -2
- package/core/lib/dxf/sections/entities.js +17 -3
- package/core/lib/dxf/sections/header.js +10 -1
- package/core/lib/dxf/sections/objects.js +36 -0
- package/core/lib/dxf/sections/section.js +43 -5
- package/core/lib/dxf/sections/tables.js +17 -3
- package/core/lib/entityManager.js +178 -0
- package/core/lib/fileio.js +14 -4
- package/core/lib/headers.js +229 -0
- package/core/lib/input.js +46 -0
- package/core/lib/inputManager.js +199 -194
- package/core/lib/intersect.js +341 -468
- package/core/lib/logging.js +25 -1
- package/core/lib/matrix.js +6 -8
- package/core/lib/mouse.js +24 -79
- package/core/lib/patterns.js +690 -0
- package/core/lib/promptOptions.js +133 -0
- package/core/lib/scene.js +71 -174
- package/core/lib/selectionManager.js +74 -48
- package/core/lib/selectionWindow.js +24 -10
- package/core/lib/settings.js +18 -11
- package/core/lib/snapping.js +129 -21
- package/core/lib/stateManager.js +288 -0
- package/core/lib/strings.js +57 -5
- package/core/lib/utils.js +95 -11
- package/core/objects/dictionary.js +43 -0
- package/core/objects/dictionaryManager.js +80 -0
- package/core/properties/dimType.js +117 -0
- package/core/properties/flags.js +66 -0
- package/core/properties/property.js +26 -0
- package/core/properties/propertyManager.js +65 -19
- package/core/tables/appId.js +31 -0
- package/core/tables/appIdManager.js +44 -0
- package/core/tables/block.js +323 -0
- package/core/tables/blockManager.js +48 -0
- package/core/tables/blockRecord.js +29 -0
- package/core/tables/blockRecordManager.js +37 -0
- package/core/tables/dimStyle.js +627 -0
- package/core/tables/dimStyleManager.js +187 -0
- package/core/tables/endblk.js +28 -0
- package/core/tables/layer.js +219 -0
- package/core/tables/layerManager.js +47 -0
- package/core/tables/ltype.js +85 -0
- package/core/tables/ltypeManager.js +65 -0
- package/core/tables/style.js +145 -0
- package/core/tables/styleManager.js +55 -0
- package/core/tables/styleManagerBase.js +110 -0
- package/core/tables/tableManagerBase.js +354 -0
- package/core/tables/ucs.js +28 -0
- package/core/tables/ucsManager.js +44 -0
- package/core/tables/view.js +28 -0
- package/core/tables/viewManager.js +44 -0
- package/core/tables/vport.js +70 -0
- package/core/tables/vportManager.js +65 -0
- package/core/tools/chamfer.js +343 -0
- package/core/tools/chamferFilletBase.js +162 -0
- package/core/tools/copy.js +68 -40
- package/core/tools/copybase.js +65 -0
- package/core/tools/copyclip.js +59 -0
- package/core/tools/cornerEntity.js +138 -0
- package/core/tools/cutclip.js +72 -0
- package/core/tools/distance.js +37 -9
- package/core/tools/erase.js +43 -13
- package/core/tools/explode.js +117 -0
- package/core/tools/extend.js +71 -32
- package/core/tools/fillet.js +336 -0
- package/core/tools/identify.js +33 -6
- package/core/tools/matchProp.js +106 -0
- package/core/tools/mirror.js +141 -0
- package/core/tools/move.js +65 -32
- package/core/tools/offset.js +321 -0
- package/core/tools/pan.js +54 -0
- package/core/tools/pasteclip.js +93 -0
- package/core/tools/purge.js +90 -0
- package/core/tools/rotate.js +105 -70
- package/core/tools/scale.js +166 -0
- package/core/tools/tool.js +14 -4
- package/core/tools/trim.js +71 -32
- package/core/tools/zoom.js +152 -0
- package/package.json +3 -305
- package/test/dimensions/alignedDimension.test.js +211 -0
- package/test/dimensions/angularDimension.test.js +243 -0
- package/test/dimensions/baseDimension.test.js +239 -0
- package/test/dimensions/diametricDimension.test.js +203 -0
- package/test/dimensions/dimension.test.js +102 -0
- package/test/dimensions/radialDimension.test.js +203 -0
- package/test/dimensions/rotatedDimension.test.js +224 -0
- package/test/entities/arc.test.js +463 -41
- package/test/entities/arctext.test.js +329 -0
- package/test/entities/basePolyline.test.js +459 -10
- package/test/entities/circle.test.js +312 -7
- package/test/entities/entity.test.js +28 -9
- package/test/entities/hatch.test.js +606 -0
- package/test/entities/insert.test.js +90 -0
- package/test/entities/line.test.js +182 -6
- package/test/entities/point.test.js +375 -37
- package/test/entities/solid.test.js +156 -0
- package/test/entities/text.test.js +533 -7
- package/test/integration/exportIntegration.reference.dxf +1706 -0
- package/test/integration/exportIntegration.test.js +186 -0
- package/test/integration/importExportIntegration.test.js +126 -0
- package/test/integration/intersectionIntegration.test.js +880 -0
- package/test/integration/userInputIntegration.reference.dxf +1410 -0
- package/test/integration/userInputIntegration.test.js +269 -0
- package/test/lib/boundingBox.test.js +26 -2
- package/test/lib/canvas.test.js +613 -5
- package/test/lib/clipboard.test.js +70 -0
- package/test/lib/colour.test.js +114 -0
- package/test/lib/colours.test.js +63 -18
- package/test/lib/commandLine.test.js +159 -22
- package/test/lib/commandManager.test.js +4 -4
- package/test/lib/constants.test.js +9 -0
- package/test/lib/dxf/dxfFile.test.js +6 -2
- package/test/lib/dxf/dxfIterator.test.js +1 -1
- package/test/lib/dxf/dxfWrite.test.js +173 -0
- package/test/lib/dxf/handleManager.test.js +137 -0
- package/test/lib/dxf/sections/blocks.test.js +5 -5
- package/test/lib/dxf/sections/entities.test.js +4 -4
- package/test/lib/dxf/sections/header.test.js +18 -4
- package/test/lib/dxf/sections/objects.test.js +132 -0
- package/test/lib/dxf/sections/section.test.js +29 -29
- package/test/lib/dxf/sections/tables.test.js +3 -3
- package/test/lib/entityManager.test.js +163 -0
- package/test/lib/headers.test.js +233 -0
- package/test/lib/inputManager.test.js +1144 -5
- package/test/lib/intersect.test.js +454 -331
- package/test/lib/logging.test.js +1 -1
- package/test/lib/matrix.test.js +1 -1
- package/test/lib/mouse.test.js +327 -4
- package/test/lib/patterns.test.js +105 -0
- package/test/lib/promptOptions.test.js +179 -0
- package/test/lib/scene.test.js +16 -52
- package/test/lib/selectionManager.test.js +17 -5
- package/test/lib/settings.test.js +111 -5
- package/test/lib/snapping.test.js +142 -4
- package/test/lib/stateManager.test.js +155 -0
- package/test/lib/utils.test.js +81 -1
- package/test/objects/dictionary.test.js +81 -0
- package/test/objects/dictionaryManager.test.js +34 -0
- package/test/properties/dimType.test.js +62 -0
- package/test/properties/flags.test.js +164 -0
- package/test/properties/property.test.js +13 -0
- package/test/properties/propertyManager.test.js +10 -11
- package/test/tables/appId.test.js +46 -0
- package/test/tables/appIdManager.test.js +72 -0
- package/test/tables/block.test.js +157 -0
- package/test/tables/blockManager.test.js +52 -0
- package/test/tables/blockRecord.test.js +39 -0
- package/test/tables/blockRecordManager.test.js +60 -0
- package/test/tables/dimstyle.test.js +72 -0
- package/test/tables/endblk.test.js +30 -0
- package/test/tables/layer.test.js +95 -0
- package/test/tables/layerManager.test.js +172 -0
- package/test/{styles → tables}/ltype.test.js +7 -7
- package/test/{styles → tables}/ltypeManager.test.js +2 -2
- package/test/tables/style.test.js +44 -0
- package/test/tables/stylemanagerbase.test.js +220 -0
- package/test/tables/tableManagerBase.test.js +194 -0
- package/test/tables/ucs.test.js +37 -0
- package/test/tables/ucsManager.test.js +48 -0
- package/test/tables/view.test.js +37 -0
- package/test/tables/viewManager.test.js +48 -0
- package/test/tables/vport.test.js +117 -0
- package/test/tables/vportManager.test.js +54 -0
- package/test/test-helpers/test-helpers.js +66 -0
- package/test/tools/chamfer.test.js +970 -0
- package/test/tools/chamferFilletBase.test.js +446 -0
- package/test/tools/copy.test.js +22 -14
- package/test/tools/copybase.test.js +93 -0
- package/test/tools/copyclip.test.js +92 -0
- package/test/tools/cornerEntity.test.js +201 -0
- package/test/tools/cutclip.test.js +94 -0
- package/test/tools/distance.test.js +140 -18
- package/test/tools/erase.test.js +12 -12
- package/test/tools/explode.test.js +45 -0
- package/test/tools/extend.test.js +326 -44
- package/test/tools/fillet.test.js +831 -0
- package/test/tools/identify.test.js +115 -16
- package/test/tools/matchProp.test.js +84 -0
- package/test/tools/mirror.test.js +475 -0
- package/test/tools/move.test.js +75 -19
- package/test/tools/offset.test.js +748 -0
- package/test/tools/pan.test.js +72 -0
- package/test/tools/pasteclip.test.js +100 -0
- package/test/tools/purge.test.js +89 -0
- package/test/tools/rotate.test.js +89 -23
- package/test/tools/scale.test.js +529 -0
- package/test/tools/trim.test.js +419 -84
- package/test/tools/zoom.test.js +504 -0
- package/core/entities/alignedDimension.js +0 -279
- package/core/entities/angularDimension.js +0 -194
- package/core/entities/baseDimension.js +0 -227
- package/core/entities/block.js +0 -247
- package/core/entities/diametricDimension.js +0 -133
- package/core/entities/dimension.js +0 -202
- package/core/entities/radialDimension.js +0 -126
- package/core/styles/dimStyle.js +0 -719
- package/core/styles/dimStyleManager.js +0 -47
- package/core/styles/layer.js +0 -133
- package/core/styles/layerManager.js +0 -40
- package/core/styles/ltype.js +0 -86
- package/core/styles/ltypeManager.js +0 -50
- package/core/styles/style.js +0 -158
- package/core/styles/styleManager.js +0 -43
- package/core/styles/styleManagerBase.js +0 -299
- package/test/entities/block.test.js +0 -22
- package/test/styles/dimstyle.test.js +0 -19
- package/test/styles/layerManager.test.js +0 -150
- package/test/styles/style.test.js +0 -33
- package/test/styles/stylemanagerbase.test.js +0 -219
package/core/lib/boundingBox.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
|
-
import {Point} from '../entities/point.js';
|
|
1
|
+
import { Point } from '../entities/point.js';
|
|
2
2
|
|
|
3
|
+
/** BoundingBox Class */
|
|
3
4
|
export class BoundingBox {
|
|
5
|
+
/**
|
|
6
|
+
* Create BoundingBox
|
|
7
|
+
* @param {Point} firstCorner
|
|
8
|
+
* @param {Point} secondCorner
|
|
9
|
+
*/
|
|
4
10
|
constructor(firstCorner = new Point(), secondCorner = new Point()) {
|
|
5
11
|
this.pt1 = firstCorner;
|
|
6
12
|
this.pt2 = secondCorner;
|
|
@@ -48,9 +54,32 @@ export class BoundingBox {
|
|
|
48
54
|
return this.yMax - this.yMin;
|
|
49
55
|
}
|
|
50
56
|
|
|
57
|
+
/**
|
|
58
|
+
* return bounding box center point
|
|
59
|
+
*/
|
|
60
|
+
get centerPoint() {
|
|
61
|
+
return new Point(this.xMin + this.xLength / 2, this.yMin + this.yLength / 2);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Determine if point is inside bounding box
|
|
66
|
+
* @param {Object} point
|
|
67
|
+
* @return {boolean} true if point is inside false if not
|
|
68
|
+
*/
|
|
69
|
+
isInside(point) {
|
|
70
|
+
// get bounding box corners
|
|
71
|
+
const bottomLeft = new Point(this.xMin, this.yMin);
|
|
72
|
+
const bottomRight = new Point(this.xMax, this.yMin);
|
|
73
|
+
const topRight = new Point(this.xMax, this.yMax);
|
|
74
|
+
const topLeft = new Point(this.xMin, this.yMax);
|
|
75
|
+
// check if point is in rectangle
|
|
76
|
+
return point.isInRectangle(bottomLeft, bottomRight, topRight, topLeft);
|
|
77
|
+
}
|
|
78
|
+
|
|
51
79
|
/**
|
|
52
80
|
* Return the bounding box for points
|
|
53
81
|
* @param {Array} points
|
|
82
|
+
* @return {BoundingBox}
|
|
54
83
|
*/
|
|
55
84
|
static fromPoints(points) {
|
|
56
85
|
if (!points.length) {
|
|
@@ -64,25 +93,56 @@ export class BoundingBox {
|
|
|
64
93
|
return new BoundingBox(new Point(xMin, yMin), new Point(xMax, yMax));
|
|
65
94
|
}
|
|
66
95
|
|
|
96
|
+
/**
|
|
97
|
+
* Generate bounding box from entities
|
|
98
|
+
* @param {Array} entities
|
|
99
|
+
* @return {BoundingBox}
|
|
100
|
+
*/
|
|
101
|
+
static fromEntities(entities) {
|
|
102
|
+
if (!entities.length) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let xmin = Infinity;
|
|
107
|
+
let xmax = -Infinity;
|
|
108
|
+
let ymin = Infinity;
|
|
109
|
+
let ymax = -Infinity;
|
|
110
|
+
|
|
111
|
+
for (const ent of entities) {
|
|
112
|
+
const bbox = ent.boundingBox();
|
|
113
|
+
|
|
114
|
+
if (!bbox) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
xmin = Math.min(xmin, bbox.xMin);
|
|
119
|
+
xmax = Math.max(xmax, bbox.xMax);
|
|
120
|
+
ymin = Math.min(ymin, bbox.yMin);
|
|
121
|
+
ymax = Math.max(ymax, bbox.yMax);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return new BoundingBox(new Point(xmin, ymin), new Point(xmax, ymax));
|
|
125
|
+
}
|
|
126
|
+
|
|
67
127
|
/**
|
|
68
128
|
* Calculate the boundingbox for a line
|
|
69
|
-
* @param {
|
|
70
|
-
* @param {
|
|
71
|
-
* @
|
|
129
|
+
* @param {Point} startPoint
|
|
130
|
+
* @param {Point} endPoint
|
|
131
|
+
* @return {BoundingBox}
|
|
72
132
|
*/
|
|
73
|
-
static lineBoundingBox(
|
|
133
|
+
static lineBoundingBox(startPoint, endPoint) {
|
|
74
134
|
return new BoundingBox(startPoint, endPoint);
|
|
75
135
|
}
|
|
76
136
|
|
|
77
137
|
/**
|
|
78
138
|
* Calculate the boundingbox for an arc
|
|
79
|
-
* @param {
|
|
80
|
-
* @param {
|
|
81
|
-
* @param {
|
|
139
|
+
* @param {Point} centerPoint
|
|
140
|
+
* @param {Point} startPoint
|
|
141
|
+
* @param {Point} endPoint
|
|
82
142
|
* @param {number} direction - ccw > 0, cw < 0
|
|
83
|
-
* @
|
|
143
|
+
* @return {BoundingBox}
|
|
84
144
|
*/
|
|
85
|
-
static arcBoundingBox(centerPoint, startPoint, endPoint, direction=1) {
|
|
145
|
+
static arcBoundingBox(centerPoint, startPoint, endPoint, direction = 1) {
|
|
86
146
|
const startAngle = centerPoint.angle(startPoint);
|
|
87
147
|
const endAngle = centerPoint.angle(endPoint);
|
|
88
148
|
const radius = centerPoint.distance(startPoint);
|
|
@@ -122,12 +182,12 @@ export class BoundingBox {
|
|
|
122
182
|
* @param {number} endAngle - angle in radians
|
|
123
183
|
* @param {number} axisAngle - angle in radians. i.e 90 deg = Math.PI / 2.
|
|
124
184
|
* @param {number} direction - ccw > 0, cw < 0
|
|
125
|
-
* @
|
|
185
|
+
* @return {boolean}
|
|
126
186
|
*/
|
|
127
|
-
static crossesAxis(startAngle, endAngle, axisAngle, direction=1) {
|
|
187
|
+
static crossesAxis(startAngle, endAngle, axisAngle, direction = 1) {
|
|
128
188
|
const circle = Math.PI * 2;
|
|
129
189
|
const referenceStartAngle = (startAngle - axisAngle + circle) % circle;
|
|
130
|
-
const referenceEndAngle = (endAngle - axisAngle + circle
|
|
190
|
+
const referenceEndAngle = (endAngle - axisAngle + circle) % circle;
|
|
131
191
|
|
|
132
192
|
// if refStartAngle > refEndAngle then the arc crosses the axis
|
|
133
193
|
let crosses = referenceStartAngle >= referenceEndAngle;
|
package/core/lib/canvas.js
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
|
-
import {Matrix} from './matrix.js';
|
|
2
|
-
import {Colours} from './colours.js';
|
|
3
|
-
import {Point} from '../entities/point.js';
|
|
1
|
+
import { Matrix } from './matrix.js';
|
|
2
|
+
import { Colours } from './colours.js';
|
|
3
|
+
import { Point } from '../entities/point.js';
|
|
4
|
+
import { Input } from './input.js';
|
|
4
5
|
|
|
5
|
-
import {DesignCore} from '../designCore.js';
|
|
6
|
+
import { DesignCore } from '../designCore.js';
|
|
6
7
|
|
|
8
|
+
/** Canvas Class */
|
|
7
9
|
export class Canvas {
|
|
10
|
+
#panCursorTimeout;
|
|
11
|
+
#baseCursorState = 'DEFAULT';
|
|
12
|
+
|
|
13
|
+
/** Create Canvas */
|
|
8
14
|
constructor() {
|
|
9
15
|
this.cvs = null;
|
|
10
16
|
this.matrix = new Matrix();
|
|
@@ -19,38 +25,101 @@ export class Canvas {
|
|
|
19
25
|
this.lastDelta = new Point();
|
|
20
26
|
this.flipped = false;
|
|
21
27
|
|
|
28
|
+
this.paintState;
|
|
29
|
+
|
|
30
|
+
this.paintStates = {
|
|
31
|
+
ENTITIES: 'ENTITIES',
|
|
32
|
+
TEMPORARY: 'TEMPORARY',
|
|
33
|
+
SELECTED: 'SELECTED',
|
|
34
|
+
AUXILLARY: 'AUXILLARY',
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
this.cursorStates = Input.Cursor;
|
|
38
|
+
|
|
39
|
+
this.cursorState = Input.Cursor.DEFAULT;
|
|
40
|
+
this.#baseCursorState = Input.Cursor.DEFAULT;
|
|
41
|
+
|
|
22
42
|
// function to call external pain command for the ui
|
|
23
43
|
this.externalPaintCallbackFunction;
|
|
44
|
+
this.externalCursorCallbackFunction;
|
|
24
45
|
}
|
|
25
46
|
|
|
47
|
+
/**
|
|
48
|
+
* Get canvas scale
|
|
49
|
+
* @return {number}
|
|
50
|
+
*/
|
|
26
51
|
getScale() {
|
|
27
52
|
return this.matrix.getScale();
|
|
28
53
|
}
|
|
29
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Set external paint callback
|
|
57
|
+
* This is called when painting is required
|
|
58
|
+
* @param {Object} callback
|
|
59
|
+
*/
|
|
30
60
|
setExternalPaintCallbackFunction(callback) {
|
|
31
61
|
// set the callback
|
|
32
62
|
this.externalPaintCallbackFunction = callback;
|
|
33
63
|
}
|
|
34
64
|
|
|
35
|
-
|
|
36
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Set external cursor callback
|
|
67
|
+
* Called when the cursor state changes.
|
|
68
|
+
* Pass undefined or null to unregister the callback.
|
|
69
|
+
* @param {Function|undefined|null} callback
|
|
70
|
+
*/
|
|
71
|
+
setCursorCallbackFunction(callback) {
|
|
72
|
+
this.externalCursorCallbackFunction = callback;
|
|
37
73
|
}
|
|
38
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Update the cursor state and notify the UI
|
|
77
|
+
* @param {string} state - one of this.cursorStates
|
|
78
|
+
*/
|
|
79
|
+
#setCursor(state) {
|
|
80
|
+
if (this.cursorState === state) return;
|
|
81
|
+
this.cursorState = state;
|
|
82
|
+
this.externalCursorCallbackFunction?.(state);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Set the cursor based on the input types requested by a command prompt.
|
|
87
|
+
* If a cursorHint is provided it is used directly; otherwise the cursor is
|
|
88
|
+
* derived from the cursor property of each type (first non-null wins),
|
|
89
|
+
* falling back to DEFAULT.
|
|
90
|
+
* @param {Array} types - array of Input.Type values
|
|
91
|
+
* @param {string|null} cursorHint - optional override from PromptOptions.cursor
|
|
92
|
+
*/
|
|
93
|
+
setCursorForInputTypes(types, cursorHint = null) {
|
|
94
|
+
this.#baseCursorState = cursorHint ??
|
|
95
|
+
types.map((t) => t.cursor).find(Boolean) ??
|
|
96
|
+
Input.Cursor.DEFAULT;
|
|
97
|
+
this.#setCursor(this.#baseCursorState);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Handle mouse movement
|
|
102
|
+
*/
|
|
39
103
|
mouseMoved() {
|
|
40
104
|
if (DesignCore.Mouse.buttonTwoDown) {
|
|
41
105
|
this.pan();
|
|
106
|
+
return;
|
|
42
107
|
}
|
|
43
108
|
|
|
44
109
|
DesignCore.Scene.inputManager.mouseMoved();
|
|
45
110
|
}
|
|
46
111
|
|
|
112
|
+
/**
|
|
113
|
+
* Handle mouse downs
|
|
114
|
+
* @param {number} button
|
|
115
|
+
*/
|
|
47
116
|
mouseDown(button) {
|
|
48
117
|
switch (button) {
|
|
49
118
|
case 0: // left button
|
|
50
119
|
break;
|
|
51
120
|
case 1: // middle button
|
|
52
|
-
|
|
53
|
-
|
|
121
|
+
clearTimeout(this.#panCursorTimeout);
|
|
122
|
+
this.#panCursorTimeout = setTimeout(() => this.#setCursor(Input.Cursor.GRABBING), 250);
|
|
54
123
|
break;
|
|
55
124
|
case 2: // right button
|
|
56
125
|
break;
|
|
@@ -59,14 +128,19 @@ export class Canvas {
|
|
|
59
128
|
DesignCore.Scene.inputManager.mouseDown(button);
|
|
60
129
|
};
|
|
61
130
|
|
|
131
|
+
/**
|
|
132
|
+
* Handle mouse up
|
|
133
|
+
* @param {number} button
|
|
134
|
+
*/
|
|
62
135
|
mouseUp(button) {
|
|
63
136
|
switch (button) {
|
|
64
|
-
case 0: // left
|
|
137
|
+
case 0: // left button
|
|
138
|
+
break;
|
|
65
139
|
case 1: // middle button
|
|
140
|
+
clearTimeout(this.#panCursorTimeout);
|
|
66
141
|
this.lastDelta = new Point();
|
|
67
142
|
this.requestPaint();
|
|
68
|
-
|
|
69
|
-
// ev.target.style.cursor = "crosshair";
|
|
143
|
+
this.#setCursor(this.#baseCursorState);
|
|
70
144
|
break;
|
|
71
145
|
case 2: // right button
|
|
72
146
|
break;
|
|
@@ -75,6 +149,10 @@ export class Canvas {
|
|
|
75
149
|
DesignCore.Scene.inputManager.mouseUp(button);
|
|
76
150
|
};
|
|
77
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Handle double click
|
|
154
|
+
* @param {number} button
|
|
155
|
+
*/
|
|
78
156
|
doubleClick(button) {
|
|
79
157
|
switch (button) {
|
|
80
158
|
case 0: // left button
|
|
@@ -87,6 +165,9 @@ export class Canvas {
|
|
|
87
165
|
}
|
|
88
166
|
};
|
|
89
167
|
|
|
168
|
+
/**
|
|
169
|
+
* Pan the canvas
|
|
170
|
+
*/
|
|
90
171
|
pan() {
|
|
91
172
|
// pandelta: mouse drag distance in scene scale
|
|
92
173
|
this.panDelta = DesignCore.Mouse.pointOnScene().subtract(DesignCore.Mouse.transformToScene(DesignCore.Mouse.mouseDownCanvasPoint));
|
|
@@ -99,13 +180,22 @@ export class Canvas {
|
|
|
99
180
|
this.requestPaint();
|
|
100
181
|
}
|
|
101
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Handle mouse wheel - Zoom
|
|
185
|
+
* @param {number} delta
|
|
186
|
+
*/
|
|
102
187
|
wheel(delta) {
|
|
188
|
+
if (DesignCore.Mouse.buttonTwoDown) return;
|
|
103
189
|
const scale = Math.pow(1 + Math.abs(delta), delta > 0 ? 1 : -1);
|
|
104
190
|
if (scale < 1 && this.getScale() > this.minScaleFactor || scale > 1 && this.getScale() < this.maxScaleFactor) {
|
|
105
191
|
this.zoom(scale);
|
|
106
192
|
}
|
|
107
193
|
};
|
|
108
194
|
|
|
195
|
+
/**
|
|
196
|
+
* Zoom the canvas
|
|
197
|
+
* @param {number} scale
|
|
198
|
+
*/
|
|
109
199
|
zoom(scale) {
|
|
110
200
|
const zoomPoint = DesignCore.Mouse.pointOnScene();
|
|
111
201
|
this.matrix.scale(scale, scale);
|
|
@@ -113,31 +203,50 @@ export class Canvas {
|
|
|
113
203
|
this.requestPaint();
|
|
114
204
|
}
|
|
115
205
|
|
|
206
|
+
/**
|
|
207
|
+
* Zoom to a window
|
|
208
|
+
* @param {Point} pt1
|
|
209
|
+
* @param {Point} pt2
|
|
210
|
+
*/
|
|
211
|
+
zoomToWindow(pt1, pt2) {
|
|
212
|
+
const xMin = Math.min(pt1.x, pt2.x);
|
|
213
|
+
const yMin = Math.min(pt1.y, pt2.y);
|
|
214
|
+
const xMax = Math.max(pt1.x, pt2.x);
|
|
215
|
+
const yMax = Math.max(pt1.y, pt2.y);
|
|
216
|
+
|
|
217
|
+
const width = xMax - xMin;
|
|
218
|
+
const height = yMax - yMin;
|
|
219
|
+
|
|
220
|
+
if (width === 0 || height === 0) {
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
const selectionCenter = new Point(xMin + width / 2, yMin + height / 2);
|
|
225
|
+
const screenCenter = new Point(this.width / 2, this.height / 2);
|
|
226
|
+
const translateDelta = DesignCore.Mouse.transformToScene(screenCenter).subtract(selectionCenter);
|
|
227
|
+
const targetScale = Math.min((this.width / width), (this.height / height));
|
|
228
|
+
const scaleDelta = targetScale / this.getScale() * 0.9;
|
|
229
|
+
|
|
230
|
+
this.matrix.scale(scaleDelta, scaleDelta);
|
|
231
|
+
this.matrix.translate((selectionCenter.x / scaleDelta) - selectionCenter.x, (selectionCenter.y / scaleDelta) - selectionCenter.y);
|
|
232
|
+
this.matrix.translate(translateDelta.x / scaleDelta, translateDelta.y / scaleDelta);
|
|
233
|
+
this.requestPaint();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* Set the zoom to include all scene items
|
|
238
|
+
*/
|
|
116
239
|
zoomExtents() {
|
|
117
240
|
const extents = DesignCore.Scene.boundingBox();
|
|
118
241
|
|
|
119
242
|
if (extents) {
|
|
120
|
-
|
|
121
|
-
const selectionCenter = new Point(extents.xMin + (extents.xLength / 2), extents.yMin + (extents.yLength / 2));
|
|
122
|
-
// get the center of the screen transformed to a scene position
|
|
123
|
-
const screenCenter = new Point(this.width / 2, this.height / 2);
|
|
124
|
-
// calculate the translation delta required to center on screen
|
|
125
|
-
const translateDelta = DesignCore.Mouse.transformToScene(screenCenter).subtract(selectionCenter);
|
|
126
|
-
// calculate the scale required to fill the screen
|
|
127
|
-
const targetScale = Math.min((this.width / extents.xLength), (this.height / extents.yLength));
|
|
128
|
-
// calculate the scale delta required to fill 90% of the screen
|
|
129
|
-
const scaleDelta = targetScale / this.getScale() * 0.9;
|
|
130
|
-
// apply scale
|
|
131
|
-
this.matrix.scale(scaleDelta, scaleDelta);
|
|
132
|
-
// translate to counteract the scale
|
|
133
|
-
this.matrix.translate((selectionCenter.x / scaleDelta) - selectionCenter.x, (selectionCenter.y / scaleDelta) - selectionCenter.y);
|
|
134
|
-
// translate to the center of the screen
|
|
135
|
-
this.matrix.translate(translateDelta.x / scaleDelta, translateDelta.y / scaleDelta);
|
|
136
|
-
// request paint to update
|
|
137
|
-
this.requestPaint();
|
|
243
|
+
this.zoomToWindow(new Point(extents.xMin, extents.yMin), new Point(extents.xMax, extents.yMax));
|
|
138
244
|
}
|
|
139
245
|
}
|
|
140
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Request the canvas is painted
|
|
249
|
+
*/
|
|
141
250
|
requestPaint() {
|
|
142
251
|
// paint request is passed to an external paint function
|
|
143
252
|
// This function then calls this.paint(), the canvas paint function
|
|
@@ -147,6 +256,12 @@ export class Canvas {
|
|
|
147
256
|
}
|
|
148
257
|
}
|
|
149
258
|
|
|
259
|
+
/**
|
|
260
|
+
* Paint the canvas
|
|
261
|
+
* @param {object} context
|
|
262
|
+
* @param {number} width
|
|
263
|
+
* @param {number} height
|
|
264
|
+
*/
|
|
150
265
|
paint(context, width, height) {
|
|
151
266
|
// This paint request is called by an external paint function
|
|
152
267
|
// some ui framework create and destroy the context for every paint
|
|
@@ -163,12 +278,12 @@ export class Canvas {
|
|
|
163
278
|
this.flipped = true;
|
|
164
279
|
}
|
|
165
280
|
|
|
166
|
-
// set the
|
|
281
|
+
// set the transform for the context
|
|
167
282
|
// this will set all the pan and zoom actions
|
|
168
283
|
try {
|
|
169
284
|
context.setTransform(this.matrix);
|
|
170
285
|
} catch {
|
|
171
|
-
|
|
286
|
+
// context.setMatrix(this.matrix)
|
|
172
287
|
context.translate(this.matrix.e, this.matrix.f);
|
|
173
288
|
context.scale(this.matrix.a, this.matrix.d);
|
|
174
289
|
}
|
|
@@ -179,11 +294,11 @@ export class Canvas {
|
|
|
179
294
|
// Paint the scene background
|
|
180
295
|
try {// HTML
|
|
181
296
|
// this.clear()
|
|
182
|
-
context.fillStyle = DesignCore.Settings.canvasbackgroundcolour;
|
|
297
|
+
context.fillStyle = Colours.rgbToString(DesignCore.Settings.canvasbackgroundcolour);
|
|
183
298
|
context.fillRect(origin.x, origin.y, width / this.getScale(), height / this.getScale());
|
|
184
299
|
// context.globalAlpha = this.cvs.alpha
|
|
185
300
|
} catch { // Cairo
|
|
186
|
-
const rgbColour = Colours.
|
|
301
|
+
const rgbColour = Colours.rgbToScaledRGB(DesignCore.Settings.canvasbackgroundcolour);
|
|
187
302
|
context.setSourceRGB(rgbColour.r, rgbColour.g, rgbColour.b);
|
|
188
303
|
const scaled = new Point(width, height);
|
|
189
304
|
const sc = DesignCore.Mouse.transformToScene(scaled);
|
|
@@ -197,74 +312,140 @@ export class Canvas {
|
|
|
197
312
|
|
|
198
313
|
this.paintGrid(context, width, height);
|
|
199
314
|
|
|
315
|
+
const scale = this.getScale();
|
|
316
|
+
|
|
200
317
|
// Paint the primary scene items
|
|
201
|
-
|
|
202
|
-
|
|
318
|
+
this.paintState = this.paintStates.ENTITIES;
|
|
319
|
+
|
|
320
|
+
const entityCount = DesignCore.Scene.entities.count();
|
|
321
|
+
for (let i = 0; i < entityCount; i++) {
|
|
322
|
+
const entity = DesignCore.Scene.entities.get(i);
|
|
323
|
+
const layer = DesignCore.LayerManager.getItemByName(entity.layer);
|
|
203
324
|
|
|
204
|
-
if (!layer
|
|
325
|
+
if (!layer?.isVisible) {
|
|
205
326
|
continue;
|
|
206
327
|
}
|
|
207
328
|
|
|
208
|
-
this.setContext(
|
|
209
|
-
|
|
329
|
+
this.setContext(entity, context, undefined, scale);
|
|
330
|
+
entity.draw(context, scale);
|
|
210
331
|
}
|
|
211
332
|
|
|
212
333
|
// Paint the temporary scene items
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
334
|
+
this.paintState = this.paintStates.TEMPORARY;
|
|
335
|
+
const tempCount = DesignCore.Scene.tempEntities.count();
|
|
336
|
+
for (let j = 0; j < tempCount; j++) {
|
|
337
|
+
const entity = DesignCore.Scene.tempEntities.get(j);
|
|
338
|
+
this.setContext(entity, context, undefined, scale);
|
|
339
|
+
entity.draw(context, scale);
|
|
216
340
|
}
|
|
217
341
|
|
|
218
342
|
// Paint the selected scene items
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
343
|
+
this.paintState = this.paintStates.SELECTED;
|
|
344
|
+
const selectedItems = DesignCore.Scene.selectionManager.selectedItems;
|
|
345
|
+
for (let k = 0; k < selectedItems.length; k++) {
|
|
346
|
+
const entity = selectedItems[k];
|
|
347
|
+
this.setContext(entity, context, undefined, scale);
|
|
348
|
+
entity.draw(context, scale);
|
|
222
349
|
}
|
|
223
350
|
|
|
224
351
|
// Paint the auxiliary scene items
|
|
225
352
|
// auxiliary items include things like the selection window, snap points etc
|
|
226
353
|
// these items have their own draw routine
|
|
227
|
-
|
|
228
|
-
|
|
354
|
+
this.paintState = this.paintStates.AUXILLARY;
|
|
355
|
+
const auxCount = DesignCore.Scene.auxiliaryEntities.count();
|
|
356
|
+
for (let l = 0; l < auxCount; l++) {
|
|
357
|
+
DesignCore.Scene.auxiliaryEntities.get(l).draw(context, scale);
|
|
229
358
|
}
|
|
359
|
+
|
|
360
|
+
this.paintState = undefined;
|
|
230
361
|
}
|
|
231
362
|
|
|
232
363
|
/**
|
|
233
364
|
* Set the scene context
|
|
234
365
|
* @param {entity} item
|
|
235
|
-
* @param {
|
|
236
|
-
* @param {
|
|
366
|
+
* @param {Object} context - scene painting context from ui
|
|
367
|
+
* @param {Object} block - insert or dimension element for the current block, required for colour ByBlock
|
|
237
368
|
*/
|
|
238
|
-
setContext(item, context) {
|
|
239
|
-
const
|
|
369
|
+
setContext(item, context, block = undefined) {
|
|
370
|
+
const scale = this.getScale();
|
|
371
|
+
let colour = item.getDrawColour();
|
|
240
372
|
const lineType = item.getLineType();
|
|
241
|
-
|
|
373
|
+
let lineWidth = item.lineWidth / scale;
|
|
374
|
+
|
|
375
|
+
if (this.paintState === this.paintStates.SELECTED) {
|
|
376
|
+
// Set Context for selected items
|
|
377
|
+
colour = DesignCore.Core.settings.selecteditemscolour;
|
|
378
|
+
lineWidth = (item.lineWidth * 2) / scale;
|
|
379
|
+
} else if (this.paintState === this.paintStates.TEMPORARY) {
|
|
380
|
+
// Set context for temp items
|
|
381
|
+
lineWidth = (item.lineWidth * 2) / scale;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
if (block && this.paintState != this.paintStates.SELECTED) {
|
|
385
|
+
// set colour for items with colour byblock
|
|
386
|
+
if (item.entityColour.aci === 0) {
|
|
387
|
+
colour = block.getDrawColour();
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
// ACI 7: white on dark background, black on light background
|
|
392
|
+
if (this.paintState !== this.paintStates.SELECTED && this.#isAci7(item, block)) {
|
|
393
|
+
const bg = DesignCore.Settings.canvasbackgroundcolour;
|
|
394
|
+
colour = (bg.r + bg.g + bg.b) / 3 < 128 ? { r: 255, g: 255, b: 255 } : { r: 0, g: 0, b: 0 };
|
|
395
|
+
}
|
|
242
396
|
|
|
243
397
|
try { // HTML Canvas
|
|
244
|
-
context.strokeStyle = colour;
|
|
245
|
-
context.fillStyle = colour;
|
|
398
|
+
context.strokeStyle = Colours.rgbToString(colour);
|
|
399
|
+
context.fillStyle = Colours.rgbToString(colour);
|
|
246
400
|
context.lineWidth = lineWidth;
|
|
247
|
-
context.setLineDash(lineType.getPattern(
|
|
401
|
+
context.setLineDash(lineType.getPattern(scale));
|
|
248
402
|
context.beginPath();
|
|
249
403
|
} catch { // Cairo
|
|
250
|
-
const rgbColour = Colours.
|
|
404
|
+
const rgbColour = Colours.rgbToScaledRGB(colour);
|
|
251
405
|
context.setSourceRGB(rgbColour.r, rgbColour.g, rgbColour.b);
|
|
252
|
-
context.setDash(lineType.getPattern(
|
|
406
|
+
context.setDash(lineType.getPattern(scale), 1);
|
|
253
407
|
context.setLineWidth(lineWidth);
|
|
254
408
|
}
|
|
255
409
|
}
|
|
256
410
|
|
|
411
|
+
/**
|
|
412
|
+
* Resolve whether the effective draw colour for an item is ACI 7.
|
|
413
|
+
* Follows ByLayer and ByBlock indirection.
|
|
414
|
+
* @param {entity} item
|
|
415
|
+
* @param {entity} block - enclosing insert/dimension, or undefined
|
|
416
|
+
* @return {boolean}
|
|
417
|
+
*/
|
|
418
|
+
#isAci7(item, block) {
|
|
419
|
+
let colour;
|
|
420
|
+
if (item.entityColour.byBlock && block) {
|
|
421
|
+
colour = block.entityColour.byLayer ?
|
|
422
|
+
DesignCore.LayerManager.getItemByName(block.layer)?.layerColour :
|
|
423
|
+
block.entityColour;
|
|
424
|
+
} else if (item.entityColour.byLayer) {
|
|
425
|
+
colour = DesignCore.LayerManager.getItemByName(item.layer)?.layerColour;
|
|
426
|
+
} else {
|
|
427
|
+
colour = item.entityColour;
|
|
428
|
+
}
|
|
429
|
+
return colour?.aci === 7 && !colour?.isTrueColour;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* Paint the background grid
|
|
434
|
+
* @param {object} context
|
|
435
|
+
*/
|
|
257
436
|
paintGrid(context) {
|
|
437
|
+
const scale = this.getScale();
|
|
438
|
+
|
|
258
439
|
// TODO: Move grid linewidth to settings?
|
|
259
440
|
let lineWidth = 0.75;
|
|
260
441
|
|
|
261
442
|
try { // HTML Canvas
|
|
262
|
-
context.strokeStyle = DesignCore.Settings.gridcolour;
|
|
263
|
-
context.lineWidth = lineWidth /
|
|
443
|
+
context.strokeStyle = Colours.rgbToString(DesignCore.Settings.gridcolour);
|
|
444
|
+
context.lineWidth = lineWidth / scale;
|
|
264
445
|
context.beginPath();
|
|
265
446
|
} catch { // Cairo
|
|
266
|
-
context.setLineWidth(lineWidth /
|
|
267
|
-
const rgbColour = Colours.
|
|
447
|
+
context.setLineWidth(lineWidth / scale);
|
|
448
|
+
const rgbColour = Colours.rgbToScaledRGB(DesignCore.Settings.gridcolour);
|
|
268
449
|
context.setSourceRGB(rgbColour.r, rgbColour.g, rgbColour.b);
|
|
269
450
|
}
|
|
270
451
|
|
|
@@ -284,26 +465,31 @@ export class Canvas {
|
|
|
284
465
|
context.lineTo(0, ygridmin);
|
|
285
466
|
context.stroke();
|
|
286
467
|
|
|
468
|
+
// only draw the grid if within scale limits
|
|
469
|
+
if (scale < this.minScaleFactor || scale > this.maxScaleFactor) {
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
|
|
287
473
|
if (DesignCore.Settings['drawgrid']) {
|
|
288
474
|
// set a feint linewidth for the grid
|
|
289
475
|
lineWidth = lineWidth * 0.25;
|
|
290
476
|
|
|
291
477
|
try { // HTML Canvas
|
|
292
|
-
context.lineWidth = lineWidth /
|
|
478
|
+
context.lineWidth = lineWidth / scale;
|
|
293
479
|
context.beginPath();
|
|
294
480
|
} catch { // Cairo
|
|
295
|
-
context.setLineWidth(lineWidth /
|
|
481
|
+
context.setLineWidth(lineWidth / scale);
|
|
296
482
|
}
|
|
297
483
|
|
|
298
484
|
// TODO: add setting for grid spacing
|
|
299
485
|
let gridInterval = 100;
|
|
300
486
|
|
|
301
487
|
// define the grid spacing based on zoom level
|
|
302
|
-
if (
|
|
488
|
+
if (scale > 50) {
|
|
303
489
|
gridInterval = 1;
|
|
304
|
-
} else if (
|
|
490
|
+
} else if (scale > 5) {
|
|
305
491
|
gridInterval = 10;
|
|
306
|
-
} else if (
|
|
492
|
+
} else if (scale < 0.6) {
|
|
307
493
|
gridInterval = 1000;
|
|
308
494
|
} else {
|
|
309
495
|
gridInterval = 100;
|
|
@@ -334,6 +520,11 @@ export class Canvas {
|
|
|
334
520
|
}
|
|
335
521
|
}
|
|
336
522
|
|
|
523
|
+
/**
|
|
524
|
+
* Calculate the scene offset from the canvas size
|
|
525
|
+
* i.e at 1:1 its the same as the canvas
|
|
526
|
+
* @return {number}
|
|
527
|
+
*/
|
|
337
528
|
getSceneOffset() {
|
|
338
529
|
// Calculate the scene offset from the canvas size
|
|
339
530
|
// i.e at 1:1 its the same as the canvas
|