figureone 0.15.10 → 1.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/figureone.min.js +1 -1
- package/index.js +79167 -0
- package/package.json +15 -1
- package/types/index.d.ts +132 -0
- package/types/js/figure/Animation/Animation.d.ts +36 -0
- package/types/js/figure/Animation/AnimationBuilder.d.ts +173 -0
- package/types/js/figure/Animation/AnimationManager.d.ts +392 -0
- package/types/js/figure/Animation/AnimationStep/CustomStep.d.ts +99 -0
- package/types/js/figure/Animation/AnimationStep/DelayStep.d.ts +24 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/ColorAnimationStep.d.ts +203 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/OpacityAnimationStep.d.ts +220 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/PositionAnimationStep.d.ts +124 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/PulseAnimationStep.d.ts +137 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/PulseTransformAnimationStep.d.ts +52 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/RotationAnimationStep.d.ts +119 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/ScaleAnimationStep.d.ts +93 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/ScenarioAnimationStep.d.ts +204 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep/TransformAnimationStep.d.ts +163 -0
- package/types/js/figure/Animation/AnimationStep/ElementAnimationStep.d.ts +56 -0
- package/types/js/figure/Animation/AnimationStep/ParallelAnimationStep.d.ts +70 -0
- package/types/js/figure/Animation/AnimationStep/SerialAnimationStep.d.ts +84 -0
- package/types/js/figure/Animation/AnimationStep/TriggerStep.d.ts +106 -0
- package/types/js/figure/Animation/AnimationStep.d.ts +110 -0
- package/types/js/figure/DrawContext2D.d.ts +9 -0
- package/types/js/figure/DrawingObjects/DrawingObject.d.ts +45 -0
- package/types/js/figure/DrawingObjects/GLObject/GLObject.d.ts +146 -0
- package/types/js/figure/DrawingObjects/HTMLObject/HTMLObject.d.ts +29 -0
- package/types/js/figure/DrawingObjects/TextObject/TextObject.d.ts +94 -0
- package/types/js/figure/DrawingObjects/TextObject/glyphMeasures.d.ts +7 -0
- package/types/js/figure/DrawingObjects/VertexObject/VertexGeneric.d.ts +21 -0
- package/types/js/figure/DrawingObjects/VertexObject/VertexObject.d.ts +0 -0
- package/types/js/figure/DrawingObjects/VertexObject/VertexText.d.ts +34 -0
- package/types/js/figure/Element.d.ts +1212 -0
- package/types/js/figure/Equation/Elements/BaseAnnotationFunction.d.ts +118 -0
- package/types/js/figure/Equation/Elements/BaseEquationFunction.d.ts +20 -0
- package/types/js/figure/Equation/Elements/Bounds.d.ts +49 -0
- package/types/js/figure/Equation/Elements/Color.d.ts +7 -0
- package/types/js/figure/Equation/Elements/Container.d.ts +5 -0
- package/types/js/figure/Equation/Elements/Element.d.ts +95 -0
- package/types/js/figure/Equation/Elements/Fraction.d.ts +5 -0
- package/types/js/figure/Equation/Elements/Lines.d.ts +5 -0
- package/types/js/figure/Equation/Elements/Matrix.d.ts +5 -0
- package/types/js/figure/Equation/Elements/Offset.d.ts +5 -0
- package/types/js/figure/Equation/Elements/Scale.d.ts +5 -0
- package/types/js/figure/Equation/Equation.d.ts +984 -0
- package/types/js/figure/Equation/EquationForm.d.ts +139 -0
- package/types/js/figure/Equation/EquationFunctions.d.ts +3367 -0
- package/types/js/figure/Equation/EquationSymbols.d.ts +1646 -0
- package/types/js/figure/Equation/HTMLEquation.d.ts +56 -0
- package/types/js/figure/Equation/Symbols/AngleBracket.d.ts +6 -0
- package/types/js/figure/Equation/Symbols/Arrow.d.ts +17 -0
- package/types/js/figure/Equation/Symbols/Bar.d.ts +6 -0
- package/types/js/figure/Equation/Symbols/Box.d.ts +11 -0
- package/types/js/figure/Equation/Symbols/Brace.d.ts +6 -0
- package/types/js/figure/Equation/Symbols/Bracket.d.ts +8 -0
- package/types/js/figure/Equation/Symbols/Division.d.ts +8 -0
- package/types/js/figure/Equation/Symbols/Integral.d.ts +7 -0
- package/types/js/figure/Equation/Symbols/Line.d.ts +5 -0
- package/types/js/figure/Equation/Symbols/Product.d.ts +6 -0
- package/types/js/figure/Equation/Symbols/Radical.d.ts +9 -0
- package/types/js/figure/Equation/Symbols/SquareBracket.d.ts +6 -0
- package/types/js/figure/Equation/Symbols/Strike.d.ts +8 -0
- package/types/js/figure/Equation/Symbols/Sum.d.ts +6 -0
- package/types/js/figure/Equation/Symbols/SymbolNew.d.ts +15 -0
- package/types/js/figure/Equation/Symbols/Vinculum.d.ts +6 -0
- package/types/js/figure/Figure.d.ts +711 -0
- package/types/js/figure/FigureCollections/Angle.d.ts +766 -0
- package/types/js/figure/FigureCollections/Axis.d.ts +517 -0
- package/types/js/figure/FigureCollections/Axis3.d.ts +118 -0
- package/types/js/figure/FigureCollections/Button.d.ts +195 -0
- package/types/js/figure/FigureCollections/EquationLabel.d.ts +77 -0
- package/types/js/figure/FigureCollections/FigureCollections.d.ts +122 -0
- package/types/js/figure/FigureCollections/Legend.d.ts +270 -0
- package/types/js/figure/FigureCollections/Line.d.ts +587 -0
- package/types/js/figure/FigureCollections/Plot.d.ts +558 -0
- package/types/js/figure/FigureCollections/PolyLine.d.ts +487 -0
- package/types/js/figure/FigureCollections/Rectangle.d.ts +235 -0
- package/types/js/figure/FigureCollections/SlideNavigator.d.ts +255 -0
- package/types/js/figure/FigureCollections/Slider.d.ts +155 -0
- package/types/js/figure/FigureCollections/Text.d.ts +307 -0
- package/types/js/figure/FigureCollections/Toggle.d.ts +185 -0
- package/types/js/figure/FigureCollections/Trace.d.ts +237 -0
- package/types/js/figure/FigurePrimitives/FigureElementPrimitive2DText.d.ts +119 -0
- package/types/js/figure/FigurePrimitives/FigureElementPrimitiveGLText.d.ts +94 -0
- package/types/js/figure/FigurePrimitives/FigureElementPrimitiveGesture.d.ts +536 -0
- package/types/js/figure/FigurePrimitives/FigureElementPrimitiveMorph.d.ts +175 -0
- package/types/js/figure/FigurePrimitives/FigurePrimitiveTypes.d.ts +788 -0
- package/types/js/figure/FigurePrimitives/FigurePrimitiveTypes2D.d.ts +1324 -0
- package/types/js/figure/FigurePrimitives/FigurePrimitiveTypes3D.d.ts +1105 -0
- package/types/js/figure/FigurePrimitives/FigurePrimitives.d.ts +173 -0
- package/types/js/figure/FigurePrimitives/Generic.d.ts +5 -0
- package/types/js/figure/FigurePrimitives/Text.d.ts +17 -0
- package/types/js/figure/FontManager.d.ts +113 -0
- package/types/js/figure/Gesture.d.ts +39 -0
- package/types/js/figure/Recorder/Recorder.d.ts +291 -0
- package/types/js/figure/Recorder/parseState.d.ts +3 -0
- package/types/js/figure/Recorder/recorder.worker.d.ts +1 -0
- package/types/js/figure/Recorder/state.d.ts +7 -0
- package/types/js/figure/SlideNavigator.d.ts +606 -0
- package/types/js/figure/TimeKeeper.d.ts +174 -0
- package/types/js/figure/geometries/arc.d.ts +18 -0
- package/types/js/figure/geometries/arrow.d.ts +215 -0
- package/types/js/figure/geometries/buffer.d.ts +4 -0
- package/types/js/figure/geometries/copy/copy.d.ts +178 -0
- package/types/js/figure/geometries/ellipse.d.ts +17 -0
- package/types/js/figure/geometries/line.d.ts +13 -0
- package/types/js/figure/geometries/lines/corners.d.ts +7 -0
- package/types/js/figure/geometries/lines/dashes.d.ts +23 -0
- package/types/js/figure/geometries/lines/lines.d.ts +31 -0
- package/types/js/figure/geometries/polygon/polygon.d.ts +12 -0
- package/types/js/figure/geometries/rectangle.d.ts +19 -0
- package/types/js/figure/geometries/triangle.d.ts +27 -0
- package/types/js/figure/webgl/Atlas.d.ts +42 -0
- package/types/js/figure/webgl/shaders.d.ts +143 -0
- package/types/js/figure/webgl/target.d.ts +9 -0
- package/types/js/figure/webgl/webgl.d.ts +54 -0
- package/types/js/tools/FunctionMap.d.ts +69 -0
- package/types/js/tools/color.d.ts +11 -0
- package/types/js/tools/colorNames.d.ts +2 -0
- package/types/js/tools/d2/polygon.d.ts +60 -0
- package/types/js/tools/d2/triangles.d.ts +0 -0
- package/types/js/tools/d3/cone.d.ts +57 -0
- package/types/js/tools/d3/cube.d.ts +26 -0
- package/types/js/tools/d3/cylinder.d.ts +45 -0
- package/types/js/tools/d3/line3.d.ts +55 -0
- package/types/js/tools/d3/prism.d.ts +49 -0
- package/types/js/tools/d3/revolve.d.ts +87 -0
- package/types/js/tools/d3/sphere.d.ts +33 -0
- package/types/js/tools/d3/surface.d.ts +47 -0
- package/types/js/tools/g2.d.ts +242 -0
- package/types/js/tools/geometry/Bounds.d.ts +446 -0
- package/types/js/tools/geometry/Line.d.ts +314 -0
- package/types/js/tools/geometry/Path.d.ts +67 -0
- package/types/js/tools/geometry/Plane.d.ts +201 -0
- package/types/js/tools/geometry/Point.d.ts +359 -0
- package/types/js/tools/geometry/Rect.d.ts +115 -0
- package/types/js/tools/geometry/Transform.d.ts +623 -0
- package/types/js/tools/geometry/angle.d.ts +105 -0
- package/types/js/tools/geometry/common.d.ts +9 -0
- package/types/js/tools/geometry/coordinates.d.ts +30 -0
- package/types/js/tools/geometry/deceleration.d.ts +13 -0
- package/types/js/tools/geometry/polygon.d.ts +4 -0
- package/types/js/tools/geometry/quaternion.d.ts +15 -0
- package/types/js/tools/geometry/scene.d.ts +282 -0
- package/types/js/tools/geometry/tools.d.ts +8 -0
- package/types/js/tools/geometry/types.d.ts +2 -0
- package/types/js/tools/getCssColors.d.ts +1 -0
- package/types/js/tools/getCssVariables.d.ts +4 -0
- package/types/js/tools/getImageData.d.ts +1 -0
- package/types/js/tools/getScssColors.d.ts +2 -0
- package/types/js/tools/htmlGenerator.d.ts +85 -0
- package/types/js/tools/m2.d.ts +24 -0
- package/types/js/tools/m3.d.ts +71 -0
- package/types/js/tools/math.d.ts +112 -0
- package/types/js/tools/morph.d.ts +651 -0
- package/types/js/tools/styleSheets.d.ts +3 -0
- package/types/js/tools/tools.d.ts +281 -0
- package/types/js/tools/types.d.ts +305 -0
- package/figureone.worker.js +0 -1
|
@@ -0,0 +1,1324 @@
|
|
|
1
|
+
import type { CPY_Step } from '../geometries/copy/copy';
|
|
2
|
+
import type { OBJ_Texture, OBJ_LineStyleSimple, TypeGLPrimitive, OBJ_FigurePrimitive } from './FigurePrimitiveTypes';
|
|
3
|
+
import type { TypeParsablePoint, TypeParsableBorder, Point, TypeParsableRect, TypeParsableBuffer } from '../../tools/g2';
|
|
4
|
+
import type { TypeDash, OBJ_CurvedCorner, OBJ_Font } from '../../tools/types';
|
|
5
|
+
import type { OBJ_LineArrows, TypeArrowHead } from '../geometries/arrow';
|
|
6
|
+
/**
|
|
7
|
+
* 
|
|
8
|
+
*
|
|
9
|
+
* Options object for a {@link FigureElementPrimitive} of a generic shape
|
|
10
|
+
*
|
|
11
|
+
* `points` will define either triangles or lines which combine
|
|
12
|
+
* to make the shape.
|
|
13
|
+
*
|
|
14
|
+
* `drawType` defines what sort of triangles or lines the `points` make.
|
|
15
|
+
* The most useful, common and generic `drawType` is `'TRIANGLES'`
|
|
16
|
+
* which can be used to create any shape.
|
|
17
|
+
*
|
|
18
|
+
* The shape's points can be duplicated using the `copy` property
|
|
19
|
+
* to conveniently create multiple copies (like grids) of shapes.
|
|
20
|
+
*
|
|
21
|
+
* The shape is colored with either `color` or `texture`.
|
|
22
|
+
*
|
|
23
|
+
* When shapes move, or are touched, borders are needed to bound their
|
|
24
|
+
* movement, and figure out if a touch happened within the shape. Shapes
|
|
25
|
+
* that do not move, or are not interactive, do not need borders.
|
|
26
|
+
*
|
|
27
|
+
* A shape can have several kinds of borders. "Draw borders" (`drawBorder` and
|
|
28
|
+
* `drawBorderBuffer`) are sets of points that define reference
|
|
29
|
+
* borders for a shape. The shapes higher level borders `border` and
|
|
30
|
+
* `touchBorder` may then use these draw borders to define how a shape will
|
|
31
|
+
* interact with a figure's bounds, or where a shape can be touched.
|
|
32
|
+
*
|
|
33
|
+
* `drawBorder` and `drawBorderBuffer` are each point arrays
|
|
34
|
+
* that define the outer limits of the shape. For non-contigous shapes
|
|
35
|
+
* (like islands of shapes), an array of point arrays can be used.
|
|
36
|
+
* Both borders can be anything, but typically a `drawBorder` would define the
|
|
37
|
+
* border of the visible shape, and a `drawBorderBuffer` would define some
|
|
38
|
+
* extra space, or buffer, around the visible shape (particulaly useful for
|
|
39
|
+
* defining the `touchBorder` later).
|
|
40
|
+
*
|
|
41
|
+
* `border` is used for checking if the shape is within some bounds. When
|
|
42
|
+
* shapes are moved, if their bounds are limited, this border will define when
|
|
43
|
+
* the shape is at a limit. The `border` property can be:
|
|
44
|
+
* - `draw`: use `drawBorder` points
|
|
45
|
+
* - `buffer`: use `drawBorderBuffer` points
|
|
46
|
+
* - `rect`: use a rectangle bounding `drawBorder`
|
|
47
|
+
* - `number`: use a rectangle that is `number` larger than the rectangle
|
|
48
|
+
* bounding `drawBorder`
|
|
49
|
+
* - `Array<TypeParsablePoint>`: a custom contiguous border
|
|
50
|
+
* - `Array<Array<TypeParsablePoint>>`: a custom border of several contiguous
|
|
51
|
+
* portions
|
|
52
|
+
*
|
|
53
|
+
* `touchBorder` is used for checking if a shape is touched. The `touchBorder`
|
|
54
|
+
* property can be:
|
|
55
|
+
* - `draw`: use `drawBorder` points
|
|
56
|
+
* - `buffer`: use `drawBorderBuffer` points
|
|
57
|
+
* - `border`: use same as `border`
|
|
58
|
+
* - `rect`: use a rectangle bounding `border`
|
|
59
|
+
* - `number`: use a rectangle that is `number` larger than the rectangle
|
|
60
|
+
* bounding `border`
|
|
61
|
+
* - `Array<TypeParsablePoint>`: a custom contiguous border
|
|
62
|
+
* - `Array<Array<TypeParsablePoint>>`: a custom border of several contiguous
|
|
63
|
+
* portions
|
|
64
|
+
*
|
|
65
|
+
*
|
|
66
|
+
* @property {Array<TypeParsablePoint>} points
|
|
67
|
+
* @property {TypeGLPrimitive} [drawType]
|
|
68
|
+
* (`'TRIANGLES'`)
|
|
69
|
+
* @property {Array<CPY_Step | string> | CPY_Step} [copy] use `drawType` as
|
|
70
|
+
* `'TRIANGLES'` when using copy (`[]`)
|
|
71
|
+
* @property {OBJ_Texture} [texture] override `color` with a texture if defined
|
|
72
|
+
* @property {TypeParsableBorder} [drawBorder],
|
|
73
|
+
* @property {TypeParsableBorder} [drawBorderBuffer],
|
|
74
|
+
* @property {TypeParsableBuffer | TypeParsableBorder | 'buffer' | 'draw' | 'rect'} [border]
|
|
75
|
+
* defines border of primitive. Use `draw` to use the `drawBorder` of the
|
|
76
|
+
* element. Use 'buffer' to use the `drawBorderBuffer` property of the element.
|
|
77
|
+
* Use `'rect'` for the bounding rectangle of `drawBorder`. Use
|
|
78
|
+
* `TypeParsableBuffer` for the bounding rectangle of `drawBorder`. Use
|
|
79
|
+
* `TypeParsableBorder` for a custom border. (`'draw'`)
|
|
80
|
+
* @property {TypeParsableBorder | 'rect' | 'border' | 'buffer' | 'draw'} [touchBorder]
|
|
81
|
+
* defines touch border of the primitive. Use `border` to use the same border
|
|
82
|
+
* as `border`. Use `draw` to use the `drawBorder` of the element.
|
|
83
|
+
* Use 'buffer' to use the `drawBorderBuffer` property of the element.
|
|
84
|
+
* Use `'rect'` for the bounding rectangle of `drawBorderBuffer`. Use
|
|
85
|
+
* `TypeParsableBuffer` for the bounding rectangle of `drawBorderBuffer`. Use
|
|
86
|
+
* `TypeParsableBorder` for a custom border. (`'border'`)
|
|
87
|
+
* @property {OBJ_PulseScale | number} [pulse] set default scale pulse options
|
|
88
|
+
* (`OBJ_PulseScale`) or pulse scale directly (`number`)
|
|
89
|
+
*
|
|
90
|
+
* @see To test examples, append them to the
|
|
91
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* // Square and triangle
|
|
95
|
+
* figure.add({
|
|
96
|
+
* name: 'squareAndTri',
|
|
97
|
+
* make: 'generic',
|
|
98
|
+
* points: [
|
|
99
|
+
* [-1, 0.5], [-1, -0.5], [0, 0.5],
|
|
100
|
+
* [0, 0.5], [-1, -0.5], [0, -0.5],
|
|
101
|
+
* [0, -0.5], [1, 0.5], [1, -0.5],
|
|
102
|
+
* ],
|
|
103
|
+
* });
|
|
104
|
+
* @example
|
|
105
|
+
* // rhombus with larger touch borders
|
|
106
|
+
* figure.add({
|
|
107
|
+
* name: 'rhombus',
|
|
108
|
+
* make: 'generic',
|
|
109
|
+
* points: [
|
|
110
|
+
* [-0.5, -0.5], [0, 0.5], [1, 0.5],
|
|
111
|
+
* [-0.5, -0.5], [1, 0.5], [0.5, -0.5],
|
|
112
|
+
* ],
|
|
113
|
+
* border: [[
|
|
114
|
+
* [-1, -1], [-0.5, 1], [1.5, 1], [1, -1],
|
|
115
|
+
* ]],
|
|
116
|
+
* mods: {
|
|
117
|
+
* isMovable: true,
|
|
118
|
+
* move: {
|
|
119
|
+
* bounds: 'figure',
|
|
120
|
+
* },
|
|
121
|
+
* },
|
|
122
|
+
* });
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* // Grid of triangles
|
|
126
|
+
* figure.add({
|
|
127
|
+
* name: 'gridOfTris',
|
|
128
|
+
* make: 'generic',
|
|
129
|
+
* points: [
|
|
130
|
+
* [-1, -1], [-0.7, -1], [-1, -0.7],
|
|
131
|
+
* ],
|
|
132
|
+
* copy: [
|
|
133
|
+
* { along: 'x', num: 5, step: 0.4 },
|
|
134
|
+
* { along: 'y', num: 5, step: 0.4 },
|
|
135
|
+
* ],
|
|
136
|
+
* });
|
|
137
|
+
* @interface
|
|
138
|
+
* @group 2D Shape Primitives
|
|
139
|
+
*/
|
|
140
|
+
export type OBJ_Generic = {
|
|
141
|
+
points?: Array<TypeParsablePoint> | Array<Point>;
|
|
142
|
+
drawType?: TypeGLPrimitive;
|
|
143
|
+
copy?: Array<CPY_Step | string> | CPY_Step;
|
|
144
|
+
texture?: OBJ_Texture;
|
|
145
|
+
drawBorder?: TypeParsableBorder;
|
|
146
|
+
drawBorderBuffer?: TypeParsableBorder;
|
|
147
|
+
border?: TypeParsableBuffer | TypeParsableBorder | 'buffer' | 'draw' | 'rect';
|
|
148
|
+
touchBorder?: TypeParsableBuffer | TypeParsableBorder | 'rect' | 'border' | 'buffer' | 'draw';
|
|
149
|
+
pulse?: number;
|
|
150
|
+
} & OBJ_FigurePrimitive;
|
|
151
|
+
/**
|
|
152
|
+
* Polyline shape options object that extends {@link OBJ_Generic} (without
|
|
153
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
154
|
+
*
|
|
155
|
+
* 
|
|
156
|
+
*
|
|
157
|
+
* A polyline is a series of lines that are connected end to end. It is defined
|
|
158
|
+
* by a series of points which are the ends and corners of the polyline.
|
|
159
|
+
*
|
|
160
|
+
* The series of points is a zero width ideal polyline, and so to see it we must
|
|
161
|
+
* give it some `width`. This width can either be grown on one side of the
|
|
162
|
+
* ideal polyline or grown on both sides of it equally using `widthIs`.
|
|
163
|
+
*
|
|
164
|
+
* A polyline can have a "positive" or "negative" side, and an "inside" or "outside".
|
|
165
|
+
*
|
|
166
|
+
* If a line is defined from p1 to p2, then the *positive* side is the
|
|
167
|
+
* side where the line moves if it is rotated around p1 in the positive (counter
|
|
168
|
+
* clockwise) direction. Thus the order of the points that define the line
|
|
169
|
+
* defines which side is positive and negative. A polyline is made up of many
|
|
170
|
+
* lines end to end, and thus itself will have a positive and negative side
|
|
171
|
+
* dependent on the order of points.
|
|
172
|
+
*
|
|
173
|
+
* Similarly we can define a line's side as either *inside* or *outside*. Each
|
|
174
|
+
* corner in the polyline will have an angle on the negative side of the line
|
|
175
|
+
* and a explementary angle on the positive side of the line. The *inside* side
|
|
176
|
+
* of the line is the same as the *negative* side if the sum of all the negative
|
|
177
|
+
* side angles is smaller than the sum of all *positive* side angles.
|
|
178
|
+
*
|
|
179
|
+
* Both positive/negative and inside/outside are provided to define a line's
|
|
180
|
+
* side as different situations make different side definitions more intuitive.
|
|
181
|
+
* For instance, a closed, simple polygon has an obvious "inside" and "outside",
|
|
182
|
+
* but how the points are ordered would define if the "inside" is "positive" or
|
|
183
|
+
* "negative". In comparison, it would be more intuitive to use "positive" or
|
|
184
|
+
* "negative" for a polyline that has an overall trend in a single direction.
|
|
185
|
+
*
|
|
186
|
+
* Therefore, the polyline width can be grown on either the `'positive'`,
|
|
187
|
+
* `'negative'`, `'inside'`, or `'outside'` side of the line or around the
|
|
188
|
+
* middle of the line with `'mid'`. In addition, a `number` between 0 and 1 can
|
|
189
|
+
* be used where `0` is the same as `'positive'`, `1` the same as `'negative'`
|
|
190
|
+
* and `0.5` the same as `'mid'`.
|
|
191
|
+
*
|
|
192
|
+
* Each point, or line connection, creates a corner that will have an *inside*
|
|
193
|
+
* angle (<180º) and an *outside* angle (>180º or reflex angle).
|
|
194
|
+
*
|
|
195
|
+
* Growing width on an outside corner can be challenging. As the corner becomes
|
|
196
|
+
* sharper, the outside width joins at a point further and further from the
|
|
197
|
+
* ideal corner. Eventually trucating the corner makes more visual sense
|
|
198
|
+
* and therefore, a minimum angle (`minAutoCornerAngle`) is used to
|
|
199
|
+
* specify when the corner should be drawn, and when it should be truncated.
|
|
200
|
+
*
|
|
201
|
+
* By default, the border of the polyline is the line itself (`border` =
|
|
202
|
+
* `'line'`). The border can also just be the points on the positive side of
|
|
203
|
+
* the line, or the negative side of the line. This is useful for capturing
|
|
204
|
+
* the hole shape of a closed polyline within a border. The border can also
|
|
205
|
+
* be the encompassing rectangle of the polyline (`border` = `'rect'`) or
|
|
206
|
+
* defined as a custom set of points.
|
|
207
|
+
*
|
|
208
|
+
* The touch border can either be the same as the border (`'border'`), the
|
|
209
|
+
* encompassing rect (`'rect'`), a custom set of points, or the same as the
|
|
210
|
+
* line but with some buffer that effectively increases the width on both sides
|
|
211
|
+
* of the line.
|
|
212
|
+
*
|
|
213
|
+
* @property {Array<TypeParsablePoint>} points
|
|
214
|
+
* @property {number} [width] (`0.01`)
|
|
215
|
+
* @property {boolean} [close] close the polyline on itself (`false`)
|
|
216
|
+
* @property {boolean} [simple] simple and minimum computation polyline. Good
|
|
217
|
+
* for large numbers of points that need to be updated every animation frame.
|
|
218
|
+
* `widthIs`, `dash`, `arrow` and all corner and line primitive properties are
|
|
219
|
+
* not available when a polyline is simple. (`false`)
|
|
220
|
+
* @property {'mid' | 'outside' | 'inside' | 'positive' | 'negative' | number} [widthIs]
|
|
221
|
+
* defines how the width is grown from the polyline's points.
|
|
222
|
+
* Only `"mid"` is fully compatible with all options in
|
|
223
|
+
* `cornerStyle` and `dash`. (`"mid"`)
|
|
224
|
+
* @property {'line' | 'positive' | 'negative' | TypeParsableBorder} [drawBorder]
|
|
225
|
+
* override OBJ_Generic `drawBorder` with `'line'` to make the drawBorder just
|
|
226
|
+
* the line itself, `'positive'` to make the drawBorder the positive side
|
|
227
|
+
* of the line, and `'negative'` to make the drawBorder the negative side
|
|
228
|
+
* of the line. Use array definition for custom drawBorder (`'line'`)
|
|
229
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
230
|
+
* override OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
231
|
+
* drawBorderBuffer the same as the line with additional `number` thickness
|
|
232
|
+
* on either side (`0`)
|
|
233
|
+
* @property {'auto' | 'none' | 'radius' | 'fill'} [cornerStyle] - `"auto"`:
|
|
234
|
+
* sharp corners sharp when angle is less than `minAutoCornerAngle`, `"none"`: no
|
|
235
|
+
* corners, `"radius"`: curved corners, `"fill"`: fills the gapes between the line
|
|
236
|
+
* ends, (`"auto"`)
|
|
237
|
+
* @property {number} [cornerSize] only used when `cornerStyle` = `radius` (`0.01`)
|
|
238
|
+
* @property {number} [cornerSides] number of sides in curve - only used when
|
|
239
|
+
* `cornerStyle` = `radius` (`10`)
|
|
240
|
+
* @property {boolean} [cornersOnly] draw only the corners with size `cornerSize` (`false`)
|
|
241
|
+
* @property {number} [cornerLength] use only with `cornersOnly` = `true` -
|
|
242
|
+
* length of corner to draw (`0.1`)
|
|
243
|
+
* @property {number} [minAutoCornerAngle] see `cornerStyle` = `auto` (`π/7`)
|
|
244
|
+
* @property {TypeDash} [dash] leave empty for solid line - use array of
|
|
245
|
+
* numbers for dash line where first number is length of line, second number is
|
|
246
|
+
* length of gap and then the pattern repeats - can use more than one dash length
|
|
247
|
+
* and gap - e.g. [0.1, 0.01, 0.02, 0.01] produces a lines with a long dash,
|
|
248
|
+
* short gap, short dash, short gap and then repeats.
|
|
249
|
+
* @property {OBJ_LineArrows | TypeArrowHead} [arrow] either an object defining custom
|
|
250
|
+
* arrows or a string representing the name of an arrow head style can be used.
|
|
251
|
+
* If a string is used, then the line will have an arrow at both ends.
|
|
252
|
+
* Arrows are only available for `close: false`,
|
|
253
|
+
* `widthIs: 'mid'` and `linePrimitives: false`
|
|
254
|
+
* @property {boolean} [linePrimitives] Use WebGL line primitives instead of
|
|
255
|
+
* triangle primitives to draw the line (`false`)
|
|
256
|
+
* @property {number} [lineNum] Number of line primitives to use when
|
|
257
|
+
* `linePrimitivs`: `true` (`2`)
|
|
258
|
+
*
|
|
259
|
+
* @extends OBJ_Generic
|
|
260
|
+
*
|
|
261
|
+
* @see To test examples, append them to the
|
|
262
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* // Line
|
|
266
|
+
* figure.add(
|
|
267
|
+
* {
|
|
268
|
+
* name: 'p',
|
|
269
|
+
* make: 'polyline',
|
|
270
|
+
* points: [[-0.5, -0.5], [-0.1, 0.5], [0.3, -0.2], [0.5, 0.5]],
|
|
271
|
+
* width: 0.05,
|
|
272
|
+
* },
|
|
273
|
+
* );
|
|
274
|
+
*
|
|
275
|
+
* @example
|
|
276
|
+
* // Square with rounded corners and dot-dash line
|
|
277
|
+
* figure.add(
|
|
278
|
+
* {
|
|
279
|
+
* name: 'p',
|
|
280
|
+
* make: 'polyline',
|
|
281
|
+
* points: [[-0.5, -0.5], [0.5, -0.5], [0.5, 0.5], [-0.5, 0.5]],
|
|
282
|
+
* width: 0.05,
|
|
283
|
+
* dash: [0.17, 0.05, 0.05, 0.05],
|
|
284
|
+
* close: true,
|
|
285
|
+
* cornerStyle: 'radius',
|
|
286
|
+
* cornerSize: 0.1,
|
|
287
|
+
* },
|
|
288
|
+
* );
|
|
289
|
+
* @example
|
|
290
|
+
* // Corners only of a triangle
|
|
291
|
+
* figure.add(
|
|
292
|
+
* {
|
|
293
|
+
* name: 'p',
|
|
294
|
+
* make: 'polyline',
|
|
295
|
+
* points: [[-0.5, -0.5], [0.5, -0.5], [0, 0.5]],
|
|
296
|
+
* width: 0.05,
|
|
297
|
+
* close: true,
|
|
298
|
+
* cornersOnly: true,
|
|
299
|
+
* cornerLength: 0.2,
|
|
300
|
+
* },
|
|
301
|
+
*);
|
|
302
|
+
* @example
|
|
303
|
+
* // Zig zag with arrows
|
|
304
|
+
* figure.add({
|
|
305
|
+
* name: 'arrowedLine',
|
|
306
|
+
* make: 'polyline',
|
|
307
|
+
* points: [[0, 0], [1, 0], [0, 0.7], [1, 0.7]],
|
|
308
|
+
* width: 0.05,
|
|
309
|
+
* cornerStyle: 'fill',
|
|
310
|
+
* arrow: {
|
|
311
|
+
* scale: 0.7,
|
|
312
|
+
* start: {
|
|
313
|
+
* head: 'triangle',
|
|
314
|
+
* reverse: true,
|
|
315
|
+
* },
|
|
316
|
+
* end: 'barb',
|
|
317
|
+
* },
|
|
318
|
+
* });
|
|
319
|
+
* @interface
|
|
320
|
+
* @group 2D Shape Primitives
|
|
321
|
+
*/
|
|
322
|
+
export type OBJ_Polyline = {
|
|
323
|
+
points?: Array<TypeParsablePoint> | Array<Point>;
|
|
324
|
+
width?: number;
|
|
325
|
+
close?: boolean;
|
|
326
|
+
simple?: boolean;
|
|
327
|
+
widthIs?: 'mid' | 'outside' | 'inside' | 'positive' | 'negative' | number;
|
|
328
|
+
drawBorder?: 'line' | 'positive' | 'negative' | TypeParsableBorder;
|
|
329
|
+
drawBorderBuffer?: number | TypeParsableBorder;
|
|
330
|
+
cornerStyle?: 'auto' | 'none' | 'radius' | 'fill';
|
|
331
|
+
cornerSize?: number;
|
|
332
|
+
cornerSides?: number;
|
|
333
|
+
cornersOnly?: boolean;
|
|
334
|
+
cornerLength?: number;
|
|
335
|
+
forceCornerLength?: boolean;
|
|
336
|
+
minAutoCornerAngle?: number;
|
|
337
|
+
dash?: TypeDash;
|
|
338
|
+
arrow?: OBJ_LineArrows | TypeArrowHead;
|
|
339
|
+
linePrimitives?: boolean;
|
|
340
|
+
lineNum?: number;
|
|
341
|
+
} & OBJ_Generic;
|
|
342
|
+
/**
|
|
343
|
+
* Line style object
|
|
344
|
+
*
|
|
345
|
+
* These properties are a subset of {@link OBJ_Polyline} which has more details
|
|
346
|
+
* on how a line is defined.
|
|
347
|
+
*
|
|
348
|
+
* @property {'mid' | 'outside' | 'inside' | 'positive' | 'negative'} [widthIs]
|
|
349
|
+
* defines how the width is grown from the polyline's points.
|
|
350
|
+
* Only `"mid"` is fully compatible with all options in
|
|
351
|
+
* `cornerStyle` and `dash`. (`"mid"`)
|
|
352
|
+
* @property {'auto' | 'none' | 'radius' | 'fill'} [cornerStyle] - `"auto"`:
|
|
353
|
+
* sharp corners sharp when angle is less than `minAutoCornerAngle`, `"none"`: no
|
|
354
|
+
* corners, `"radius"`: curved corners, `"fill"`: fills the gapes between the line
|
|
355
|
+
* ends, (`"auto"`)
|
|
356
|
+
* @property {number} [cornerSize] only used when `cornerStyle` = `radius` (`0.01`)
|
|
357
|
+
* @property {number} [cornerSides] number of sides in curve - only used when
|
|
358
|
+
* `cornerStyle` = `radius` (`10`)
|
|
359
|
+
* @property {boolean} [cornersOnly] draw only the corners with size `cornerSize` (`false`)
|
|
360
|
+
* @property {number} [cornerLength] use only with `cornersOnly` = `true` -
|
|
361
|
+
* length of corner to draw (`0.1`)
|
|
362
|
+
* @property {number} [minAutoCornerAngle] see `cornerStyle` = `auto` (`π/7`)
|
|
363
|
+
* @property {Array<number>} [dash] leave empty for solid line - use array of
|
|
364
|
+
* numbers for dash line where first number is length of line, second number is
|
|
365
|
+
* length of gap and then the pattern repeats - can use more than one dash length
|
|
366
|
+
* and gap - e.g. [0.1, 0.01, 0.02, 0.01] produces a lines with a long dash,
|
|
367
|
+
* short gap, short dash, short gap and then repeats.
|
|
368
|
+
* @property {boolean} [linePrimitives] Use WebGL line primitives instead of
|
|
369
|
+
* triangle primitives to draw the line (`false`)
|
|
370
|
+
* @property {boolean} [lineNum] Number of line primitives to use when
|
|
371
|
+
* `linePrimitivs`: `true` (`2`)
|
|
372
|
+
* @interface
|
|
373
|
+
* @group Misc Shapes
|
|
374
|
+
*/
|
|
375
|
+
export type OBJ_LineStyle = {
|
|
376
|
+
widthIs?: 'mid' | 'outside' | 'inside' | 'positive' | 'negative';
|
|
377
|
+
cornerStyle?: 'auto' | 'none' | 'radius' | 'fill';
|
|
378
|
+
cornerSize?: number;
|
|
379
|
+
cornerSides?: number;
|
|
380
|
+
cornersOnly?: boolean;
|
|
381
|
+
cornerLength?: number;
|
|
382
|
+
forceCornerLength?: boolean;
|
|
383
|
+
minAutoCornerAngle?: number;
|
|
384
|
+
dash?: Array<number>;
|
|
385
|
+
linePrimitives?: boolean;
|
|
386
|
+
lineNum?: number;
|
|
387
|
+
};
|
|
388
|
+
/**
|
|
389
|
+
* Polygon or partial polygon shape options object that extends
|
|
390
|
+
* {@link OBJ_Generic} (without `drawType`)
|
|
391
|
+
*
|
|
392
|
+
* 
|
|
393
|
+
*
|
|
394
|
+
* @property {number} [sides] (`4`)
|
|
395
|
+
* @property {number} [radius] (`1`)
|
|
396
|
+
* @property {number} [rotation] shape rotation during vertex definition
|
|
397
|
+
* (different to a rotation step in a trasform) (`0`)
|
|
398
|
+
* @property {TypeParsablePoint} [offset] shape center offset from origin
|
|
399
|
+
* during vertex definition (different to a translation step in a transform)
|
|
400
|
+
* (`[0, 0]`)
|
|
401
|
+
* @property {number} [sidesToDraw] number of sides to draw (all sides)
|
|
402
|
+
* @property {number} [angleToDraw] same as `sidesToDraw` but using angle for
|
|
403
|
+
* the definition (`2π`)
|
|
404
|
+
* @property {-1 | 1} [direction] direction to draw polygon where 1 is
|
|
405
|
+
* counter clockwise and -1 is clockwise (`1`)
|
|
406
|
+
* center. This is different to position or transform as these translate the
|
|
407
|
+
* vertices on each draw. (`[0, 0]`)
|
|
408
|
+
* @property {OBJ_LineStyleSimple} [line] line style options
|
|
409
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
410
|
+
* override the OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
411
|
+
* drawBorderBuffer a polygon that is wider by `number` (`0`)
|
|
412
|
+
*
|
|
413
|
+
* @extends OBJ_Generic
|
|
414
|
+
*
|
|
415
|
+
* @see To test examples, append them to the
|
|
416
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
417
|
+
*
|
|
418
|
+
* @example
|
|
419
|
+
* // Simple filled hexagon
|
|
420
|
+
* figure.add({
|
|
421
|
+
* name: 'hexagon',
|
|
422
|
+
* make: 'polygon',
|
|
423
|
+
* sides: 6,
|
|
424
|
+
* radius: 0.5,
|
|
425
|
+
* });
|
|
426
|
+
*
|
|
427
|
+
* @example
|
|
428
|
+
* // Circle from dashed line
|
|
429
|
+
* const circ = figure.primitives.polygon({
|
|
430
|
+
* sides: 100,
|
|
431
|
+
* radius: 0.5,
|
|
432
|
+
* line: {
|
|
433
|
+
* width: 0.03,
|
|
434
|
+
* dash: [0.1, 0.03 ],
|
|
435
|
+
* },
|
|
436
|
+
* });
|
|
437
|
+
* figure.elements.add('circle', circ);
|
|
438
|
+
*
|
|
439
|
+
* @example
|
|
440
|
+
* // Half octagon rotated
|
|
441
|
+
* figure.add({
|
|
442
|
+
* name: 'halfOctagon',
|
|
443
|
+
* make: 'polygon',
|
|
444
|
+
* sides: 8,
|
|
445
|
+
* radius: 0.5,
|
|
446
|
+
* angleToDraw: Math.PI,
|
|
447
|
+
* line: {
|
|
448
|
+
* width: 0.03,
|
|
449
|
+
* },
|
|
450
|
+
* direction: -1,
|
|
451
|
+
* rotation: Math.PI / 2,
|
|
452
|
+
* });
|
|
453
|
+
* @interface
|
|
454
|
+
* @group 2D Shape Primitives
|
|
455
|
+
*/
|
|
456
|
+
export type OBJ_Polygon = {
|
|
457
|
+
sides?: number;
|
|
458
|
+
radius?: number;
|
|
459
|
+
rotation?: number;
|
|
460
|
+
offset?: TypeParsablePoint;
|
|
461
|
+
sidesToDraw?: number;
|
|
462
|
+
angleToDraw?: number;
|
|
463
|
+
direction?: -1 | 1;
|
|
464
|
+
line?: OBJ_LineStyleSimple;
|
|
465
|
+
drawBorderBuffer?: number | TypeParsableBorder;
|
|
466
|
+
} & OBJ_Generic;
|
|
467
|
+
export type OBJ_Polygon_Defined = {
|
|
468
|
+
sides: number;
|
|
469
|
+
radius: number;
|
|
470
|
+
rotation: number;
|
|
471
|
+
offset: Point;
|
|
472
|
+
sidesToDraw: number;
|
|
473
|
+
angleToDraw: number;
|
|
474
|
+
direction: -1 | 1;
|
|
475
|
+
line?: OBJ_LineStyleSimple;
|
|
476
|
+
innerRadius?: number;
|
|
477
|
+
drawBorderBuffer: number | TypeParsableBorder;
|
|
478
|
+
} & OBJ_Generic;
|
|
479
|
+
/**
|
|
480
|
+
* Star options object that extends {@link OBJ_Generic} (without
|
|
481
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
482
|
+
*
|
|
483
|
+
* 
|
|
484
|
+
*
|
|
485
|
+
* @property {number} [sides] (`4`)
|
|
486
|
+
* @property {number} [radius] (`1`)
|
|
487
|
+
* @property {number} [innerRadius] (`radius / 2`)
|
|
488
|
+
* @property {number} [rotation] shape rotation during vertex definition
|
|
489
|
+
* (different to a rotation step in a trasform) (`0`)
|
|
490
|
+
* @property {TypeParsablePoint} [offset] shape center offset from origin
|
|
491
|
+
* during vertex definition (different to a translation step in a transform)
|
|
492
|
+
* (`[0, 0]`)
|
|
493
|
+
* @property {OBJ_LineStyleSimple} [line] line style options
|
|
494
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
495
|
+
* override the OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
496
|
+
* drawBorderBuffer a polygon that is `number` thicker than the radius (`0`)
|
|
497
|
+
*
|
|
498
|
+
* @extends OBJ_Generic
|
|
499
|
+
*
|
|
500
|
+
* @see To test examples, append them to the
|
|
501
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
502
|
+
*
|
|
503
|
+
* @example
|
|
504
|
+
* // Simple 5 pointed star
|
|
505
|
+
* figure.add({
|
|
506
|
+
* name: 's',
|
|
507
|
+
* make: 'star',
|
|
508
|
+
* radius: 0.5,
|
|
509
|
+
* sides: 5,
|
|
510
|
+
* });
|
|
511
|
+
*
|
|
512
|
+
* @example
|
|
513
|
+
* // 7 pointed dashed line star
|
|
514
|
+
* figure.add({
|
|
515
|
+
* name: 's',
|
|
516
|
+
* make: 'star',
|
|
517
|
+
* radius: 0.5,
|
|
518
|
+
* innerRadius: 0.3,
|
|
519
|
+
* sides: 7,
|
|
520
|
+
* line: {
|
|
521
|
+
* width: 0.02,
|
|
522
|
+
* dash: [0.05, 0.01],
|
|
523
|
+
* },
|
|
524
|
+
* });
|
|
525
|
+
*
|
|
526
|
+
* @example
|
|
527
|
+
* // Star surrounded by stars
|
|
528
|
+
* figure.add({
|
|
529
|
+
* name: 's',
|
|
530
|
+
* make: 'star',
|
|
531
|
+
* radius: 0.1,
|
|
532
|
+
* sides: 5,
|
|
533
|
+
* rotation: -Math.PI / 2,
|
|
534
|
+
* // line: { width: 0.01 },
|
|
535
|
+
* copy: [
|
|
536
|
+
* {
|
|
537
|
+
* to: [0.6, 0],
|
|
538
|
+
* original: false,
|
|
539
|
+
* },
|
|
540
|
+
* {
|
|
541
|
+
* along: 'rotation',
|
|
542
|
+
* num: 16,
|
|
543
|
+
* step: Math.PI * 2 / 16,
|
|
544
|
+
* start: 1,
|
|
545
|
+
* },
|
|
546
|
+
* {
|
|
547
|
+
* to: new Fig.Transform().scale(3, 3).rotate(Math.PI / 2),
|
|
548
|
+
* start: 0,
|
|
549
|
+
* end: 1,
|
|
550
|
+
* },
|
|
551
|
+
* ],
|
|
552
|
+
* });
|
|
553
|
+
* @interface
|
|
554
|
+
* @group 2D Shape Primitives
|
|
555
|
+
*/
|
|
556
|
+
export type OBJ_Star = {
|
|
557
|
+
sides?: number;
|
|
558
|
+
radius?: number;
|
|
559
|
+
innerRadius?: number;
|
|
560
|
+
rotation?: number;
|
|
561
|
+
offset?: TypeParsablePoint;
|
|
562
|
+
line?: OBJ_LineStyleSimple;
|
|
563
|
+
drawBorderBuffer?: TypeParsableBorder | number;
|
|
564
|
+
} & OBJ_Generic;
|
|
565
|
+
export type OBJ_Star_Defined = {
|
|
566
|
+
sides: number;
|
|
567
|
+
radius: number;
|
|
568
|
+
innerRadius: number;
|
|
569
|
+
rotation: number;
|
|
570
|
+
offset: Point;
|
|
571
|
+
line?: OBJ_LineStyleSimple;
|
|
572
|
+
drawBorderBuffer: TypeParsableBorder | number;
|
|
573
|
+
} & OBJ_Generic;
|
|
574
|
+
/**
|
|
575
|
+
* Rectangle shape options object that extends {@link OBJ_Generic} (without
|
|
576
|
+
* `drawType) and {@link OBJ_FigurePrimitive}
|
|
577
|
+
*
|
|
578
|
+
* 
|
|
579
|
+
*
|
|
580
|
+
* @property {number} [width] (`1`)
|
|
581
|
+
* @property {number} [height] (`1`)
|
|
582
|
+
* @property {'bottom' | 'middle' | 'top' | number} [yAlign] (`'middle'`)
|
|
583
|
+
* @property {'left' | 'center' | 'right' | number} [xAlign] (`'center'`)
|
|
584
|
+
* @property {OBJ_CurvedCorner} [corner] define for rounded corners
|
|
585
|
+
* @property {OBJ_LineStyleSimple} [line] line style options
|
|
586
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
587
|
+
* override the OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
588
|
+
* drawBorderBuffer a rectangle that is `number` wider and higher on each side
|
|
589
|
+
* (`0`)
|
|
590
|
+
* @property {TypeParsablePoint} [offset]
|
|
591
|
+
*
|
|
592
|
+
* @extends OBJ_Generic
|
|
593
|
+
*
|
|
594
|
+
* @see To test examples, append them to the
|
|
595
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
596
|
+
*
|
|
597
|
+
* @example
|
|
598
|
+
* // Filled rectangle
|
|
599
|
+
* figure.add({
|
|
600
|
+
* name: 'r',
|
|
601
|
+
* make: 'rectangle',
|
|
602
|
+
* width: 1,
|
|
603
|
+
* height: 0.5,
|
|
604
|
+
* });
|
|
605
|
+
*
|
|
606
|
+
* @example
|
|
607
|
+
* // Corners with radius and dashed line
|
|
608
|
+
* figure.add({
|
|
609
|
+
* name: 'r',
|
|
610
|
+
* make: 'rectangle',
|
|
611
|
+
* width: 0.5,
|
|
612
|
+
* height: 0.5,
|
|
613
|
+
* line: {
|
|
614
|
+
* width: 0.02,
|
|
615
|
+
* dash: [0.05, 0.03]
|
|
616
|
+
* },
|
|
617
|
+
* corner: {
|
|
618
|
+
* radius: 0.1,
|
|
619
|
+
* sides: 10,
|
|
620
|
+
* },
|
|
621
|
+
* });
|
|
622
|
+
*
|
|
623
|
+
* @example
|
|
624
|
+
* // Rectangle copies rotated
|
|
625
|
+
* figure.add({
|
|
626
|
+
* name: 'r',
|
|
627
|
+
* make: 'rectangle',
|
|
628
|
+
* width: 0.5,
|
|
629
|
+
* height: 0.5,
|
|
630
|
+
* line: {
|
|
631
|
+
* width: 0.01,
|
|
632
|
+
* },
|
|
633
|
+
* copy: {
|
|
634
|
+
* along: 'rotation',
|
|
635
|
+
* num: 3,
|
|
636
|
+
* step: Math.PI / 2 / 3
|
|
637
|
+
* },
|
|
638
|
+
* });
|
|
639
|
+
* @interface
|
|
640
|
+
* @group 2D Shape Primitives
|
|
641
|
+
*/
|
|
642
|
+
export type OBJ_Rectangle = {
|
|
643
|
+
width?: number;
|
|
644
|
+
height?: number;
|
|
645
|
+
xAlign?: 'left' | 'center' | 'right' | number;
|
|
646
|
+
yAlign?: 'bottom' | 'middle' | 'top' | number;
|
|
647
|
+
corner?: OBJ_CurvedCorner;
|
|
648
|
+
line?: OBJ_LineStyleSimple;
|
|
649
|
+
drawBorderBuffer?: TypeParsableBorder | number;
|
|
650
|
+
offset?: TypeParsablePoint;
|
|
651
|
+
} & OBJ_Generic;
|
|
652
|
+
export type OBJ_Rectangle_Defined = {
|
|
653
|
+
width: number;
|
|
654
|
+
height: number;
|
|
655
|
+
xAlign: 'left' | 'center' | 'right' | number;
|
|
656
|
+
yAlign: 'bottom' | 'middle' | 'top' | number;
|
|
657
|
+
corner: {
|
|
658
|
+
radius: number;
|
|
659
|
+
sides: number;
|
|
660
|
+
};
|
|
661
|
+
line?: {
|
|
662
|
+
widthIs: 'inside' | 'outside' | 'positive' | 'negative' | 'mid' | number;
|
|
663
|
+
width: number;
|
|
664
|
+
};
|
|
665
|
+
drawBorderBuffer: number | Array<Array<Point>>;
|
|
666
|
+
offset: Point;
|
|
667
|
+
} & OBJ_Generic;
|
|
668
|
+
/**
|
|
669
|
+
* Ellipse shape options object that extends {@link OBJ_Generic} (without
|
|
670
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
671
|
+
*
|
|
672
|
+
* 
|
|
673
|
+
*
|
|
674
|
+
* @property {number} [width] (`1`)
|
|
675
|
+
* @property {number} [height] (`1`)
|
|
676
|
+
* @property {'bottom' | 'middle' | 'top' | number} [yAlign] (`'middle'`)
|
|
677
|
+
* @property {'left' | 'center' | 'right' | number} [xAlign] (`'center'`)
|
|
678
|
+
* @property {number} [sides] number of sides to draw ellipse with (`20`)
|
|
679
|
+
* @property {OBJ_LineStyleSimple} [line] line style options
|
|
680
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
681
|
+
* override the OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
682
|
+
* drawBorderBuffer a ellipse that is `number` thicker around its border (`0`)
|
|
683
|
+
*
|
|
684
|
+
* @extends OBJ_Generic
|
|
685
|
+
*
|
|
686
|
+
* @see To test examples, append them to the
|
|
687
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
688
|
+
*
|
|
689
|
+
* @example
|
|
690
|
+
* // Filled ellipse
|
|
691
|
+
* figure.add({
|
|
692
|
+
* name: 'e',
|
|
693
|
+
* make: 'ellipse',
|
|
694
|
+
* height: 1,
|
|
695
|
+
* width: 0.5,
|
|
696
|
+
* sides: 100,
|
|
697
|
+
* });
|
|
698
|
+
*
|
|
699
|
+
* @example
|
|
700
|
+
* // Dashed line circle
|
|
701
|
+
* figure.add({
|
|
702
|
+
* name: 'e',
|
|
703
|
+
* make: 'ellipse',
|
|
704
|
+
* height: 1,
|
|
705
|
+
* width: 1,
|
|
706
|
+
* sides: 100,
|
|
707
|
+
* line: {
|
|
708
|
+
* width: 0.02,
|
|
709
|
+
* dash: [0.05, 0.02],
|
|
710
|
+
* },
|
|
711
|
+
* });
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* // Ellipse grid
|
|
715
|
+
* figure.add({
|
|
716
|
+
* name: 'e',
|
|
717
|
+
* make: 'ellipse',
|
|
718
|
+
* height: 0.08,
|
|
719
|
+
* width: 0.2,
|
|
720
|
+
* sides: 20,
|
|
721
|
+
* copy: [
|
|
722
|
+
* { along: 'x', step: 0.25, num: 5 },
|
|
723
|
+
* { along: 'y', step: 0.15, num: 5 },
|
|
724
|
+
* ]
|
|
725
|
+
* });
|
|
726
|
+
* @interface
|
|
727
|
+
* @group 2D Shape Primitives
|
|
728
|
+
*/
|
|
729
|
+
export type OBJ_Ellipse = {
|
|
730
|
+
width?: number;
|
|
731
|
+
height?: number;
|
|
732
|
+
xAlign?: 'left' | 'center' | 'right' | number;
|
|
733
|
+
yAlign?: 'bottom' | 'middle' | 'top' | number;
|
|
734
|
+
sides?: number;
|
|
735
|
+
line?: OBJ_LineStyleSimple;
|
|
736
|
+
drawBorderBuffer?: TypeParsableBorder | number;
|
|
737
|
+
} & OBJ_Generic;
|
|
738
|
+
/**
|
|
739
|
+
* Arc shape options object that extends {@link OBJ_Generic} (without
|
|
740
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
741
|
+
*
|
|
742
|
+
* 
|
|
743
|
+
*
|
|
744
|
+
* @property {number} [radius]
|
|
745
|
+
* @property {number} [sides] (`20`)
|
|
746
|
+
* @property {number} [startAngle] (`0`)
|
|
747
|
+
* @property {number} [angle] (`1`)
|
|
748
|
+
* @property {OBJ_LineStyleSimple} [line] line style options
|
|
749
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
750
|
+
* override the OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
751
|
+
* drawBorderBuffer a ellipse that is `number` thicker around its border (`0`)
|
|
752
|
+
*
|
|
753
|
+
* @extends OBJ_Generic
|
|
754
|
+
*
|
|
755
|
+
* @see To test examples, append them to the
|
|
756
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
757
|
+
*
|
|
758
|
+
* @example
|
|
759
|
+
* // Simple fill
|
|
760
|
+
* figure.add({
|
|
761
|
+
* make: 'arc',
|
|
762
|
+
* angle: Math.PI * 2 / 3,
|
|
763
|
+
* radius: 1,
|
|
764
|
+
* });
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* // Fill to center
|
|
768
|
+
* figure.add({
|
|
769
|
+
* make: 'arc',
|
|
770
|
+
* angle: Math.PI * 2 / 3,
|
|
771
|
+
* startAngle: Math.PI / 3,
|
|
772
|
+
* radius: 1,
|
|
773
|
+
* fillCenter: true,
|
|
774
|
+
* });
|
|
775
|
+
*
|
|
776
|
+
* @example
|
|
777
|
+
* // Arc line
|
|
778
|
+
* figure.add({
|
|
779
|
+
* make: 'arc',
|
|
780
|
+
* angle: Math.PI / 3,
|
|
781
|
+
* radius: 1,
|
|
782
|
+
* line: { width: 0.05, widthIs: 'inside' },
|
|
783
|
+
* });
|
|
784
|
+
*
|
|
785
|
+
* @example
|
|
786
|
+
* // Arc dashed line
|
|
787
|
+
* figure.add({
|
|
788
|
+
* make: 'arc',
|
|
789
|
+
* angle: Math.PI * 3 / 2,
|
|
790
|
+
* radius: 1,
|
|
791
|
+
* sides: 100,
|
|
792
|
+
* line: { width: 0.05, dash: [0.3, 0.1, 0.1, 0.1] },
|
|
793
|
+
* });
|
|
794
|
+
* @interface
|
|
795
|
+
* @group 2D Shape Primitives
|
|
796
|
+
*/
|
|
797
|
+
export type OBJ_Arc = {
|
|
798
|
+
radius?: number;
|
|
799
|
+
sides?: number;
|
|
800
|
+
startAngle?: number;
|
|
801
|
+
angle?: number;
|
|
802
|
+
line?: OBJ_LineStyleSimple;
|
|
803
|
+
offset?: TypeParsablePoint;
|
|
804
|
+
drawBorderBuffer?: TypeParsableBorder | number;
|
|
805
|
+
fillCenter?: boolean;
|
|
806
|
+
} & OBJ_Generic;
|
|
807
|
+
/**
|
|
808
|
+
* @property {'s1' | 's2' | 's3'} [side] ('s1')
|
|
809
|
+
* @property {number} [angle] (0)
|
|
810
|
+
* @interface
|
|
811
|
+
* @group Misc Shapes
|
|
812
|
+
*/
|
|
813
|
+
export type OBJ_TriangleSideRotationAlignment = {
|
|
814
|
+
side?: 's1' | 's2' | 's3';
|
|
815
|
+
angle?: number;
|
|
816
|
+
};
|
|
817
|
+
/**
|
|
818
|
+
* Triangle shape options object that extends {@link OBJ_Generic} (without
|
|
819
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
820
|
+
*
|
|
821
|
+
* 
|
|
822
|
+
*
|
|
823
|
+
* The most generic way to define a triangle is with three points (`points`
|
|
824
|
+
* property). When using `points`, all the other properties that can also
|
|
825
|
+
* define a triangle are ignored: `width`, `height`, `top`,
|
|
826
|
+
* `SSS`, `ASA`, `AAS`, `SAS`, `direction`, `rotation`, `xAlign` and `yAlign`.
|
|
827
|
+
*
|
|
828
|
+
* The other ways to define a triangle are (in order of highest override
|
|
829
|
+
* preference to lowest if more than one is defined in the object):
|
|
830
|
+
* - `ASA` or Angle-Side-Angle
|
|
831
|
+
* - `SAS` or Side-Angle-Side
|
|
832
|
+
* - `AAS` or Angle-Angle-Side
|
|
833
|
+
* - `SSS` or Side-Side-Side
|
|
834
|
+
* - `width`, `height` and `top` location
|
|
835
|
+
*
|
|
836
|
+
* All these methods also use `direction` to define the triangles, and
|
|
837
|
+
* `rotation`, `xAlign` and `yAlign` to position the triangles. Each corner
|
|
838
|
+
* and side of the triangle is indexed, and can be used for positioning.
|
|
839
|
+
*
|
|
840
|
+
* 
|
|
841
|
+
*
|
|
842
|
+
* A triangle starts with an angle (a1) at (0, 0) and base side extending along
|
|
843
|
+
* the x axis to a second angle a2. The base side is side 1 (s1).
|
|
844
|
+
*
|
|
845
|
+
* Angles a1 and a2 extend the triangle above s1 if `direction` is `1`, and
|
|
846
|
+
* below s1 when `direction` is `-1`.
|
|
847
|
+
*
|
|
848
|
+
* s2, a3, and s3 are then the consecutive sides and angles.
|
|
849
|
+
*
|
|
850
|
+
* Triangles can be defined with a combination of side length and angle using
|
|
851
|
+
* `ASA`, `SAS`, `AAS` and `SSS`, where the first side or angle is s1 or a1
|
|
852
|
+
* respectively, and the subsequent sides and angles progress consecutively.
|
|
853
|
+
* For instance, `ASA` defines the angle a1, then side length s1, then angle
|
|
854
|
+
* a2. `SSS` defines the side lenghts s1, s2 then s3. All these combinations of
|
|
855
|
+
* three properties are sufficient to define a unique triangle completely.
|
|
856
|
+
*
|
|
857
|
+
* When defining the triangle with `width`, `height` and `top`, the base side
|
|
858
|
+
* s1 is the width, and the top point is either aligned with the `left`,
|
|
859
|
+
* `center` or `right` of the base at some `height` above s1.
|
|
860
|
+
*
|
|
861
|
+
* When defined, a triangle's a1 corner will be at (0, 0), and s1 will be along
|
|
862
|
+
* the x axis. Next, a `rotation` can be applied to the triangle. A `rotation`
|
|
863
|
+
* can either be a `number` rotating it relative to its definition, or relative
|
|
864
|
+
* to one of its sides: s1, s2 or s3.
|
|
865
|
+
*
|
|
866
|
+
* Finally, the triangle can be positioned (in draw space) using `xAlign` and
|
|
867
|
+
* `yAlign`. An `xAlign` of `'left'` will position the triangle so that it's
|
|
868
|
+
* left most point will be at (0, 0). Similarly, a `yAlign` of `'top'` will
|
|
869
|
+
* position the triangle so its top most point is at (0, 0). Triangles
|
|
870
|
+
* can also be aligned by angles (corners) and side mid points. For instance, an
|
|
871
|
+
* `xAlign` of `'a2'`, will position the a2 corner at x = 0. Similarly a
|
|
872
|
+
* `yAlign` of `'s3'` will position the triangle vertically such that the mid
|
|
873
|
+
* point of s3 is at y = 0. `'centroid'` is relative to the geometric center of
|
|
874
|
+
* the triangle.
|
|
875
|
+
*
|
|
876
|
+
* Once a triangle is defined and positioned in draw space, it can then be
|
|
877
|
+
* copied (`copy`) if more than one triangle is desired.
|
|
878
|
+
*
|
|
879
|
+
* The triangle(s) can then be positioned (`position`) or transformed
|
|
880
|
+
* (`transform`) in the FigureElementPrimitive local space.
|
|
881
|
+
*
|
|
882
|
+
* Triangles can either be a solid fill, texture fill or outline. When `line`
|
|
883
|
+
* is not defined, the triangle will be filled.
|
|
884
|
+
*
|
|
885
|
+
* @property {Array<Point>} [points] defining points will take precedence over
|
|
886
|
+
* all other ways to define a triangle.
|
|
887
|
+
* @property {number} [width]
|
|
888
|
+
* @property {number} [height]
|
|
889
|
+
* @property {'left' | 'right' | 'center'} [top] (`center`)
|
|
890
|
+
* @property {[number, number, number]} [SSS]
|
|
891
|
+
* @property {[number, number, number]} [ASA]
|
|
892
|
+
* @property {[number, number, number]} [AAS]
|
|
893
|
+
* @property {[number, number, number]} [SAS]
|
|
894
|
+
* @property {1 | -1} [direction]
|
|
895
|
+
* @property {number | 's1' | 's2' | 's3' | OBJ_TriangleSideRotationAlignment} [rotation]
|
|
896
|
+
* @property {'left' | 'center' | 'right' | number | 'a1' | 'a2' | 'a3' | 's1' | 's2' | 's3' | 'centroid' | 'points'} [xAlign] (`'centroid'`)
|
|
897
|
+
* @property {'bottom' | 'middle' | 'top' | number | 'a1' | 'a2' | 'a3' | 's1'| 's2' | 's3' | 'centroid' | 'points'} [yAlign] (`'centroid'`)
|
|
898
|
+
* @property {OBJ_LineStyleSimple} [line] line style options - do not use any corner
|
|
899
|
+
* options
|
|
900
|
+
*
|
|
901
|
+
* @extends OBJ_Generic
|
|
902
|
+
*
|
|
903
|
+
* @see To test examples, append them to the
|
|
904
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
905
|
+
*
|
|
906
|
+
* @example
|
|
907
|
+
* // Right angle triangle
|
|
908
|
+
* figure.add({
|
|
909
|
+
* name: 't',
|
|
910
|
+
* make: 'triangle',
|
|
911
|
+
* width: 0.5,
|
|
912
|
+
* height: 1,
|
|
913
|
+
* top: 'right',
|
|
914
|
+
* });
|
|
915
|
+
*
|
|
916
|
+
* @example
|
|
917
|
+
* // 30-60-90 triangle with dashed line
|
|
918
|
+
* const t = figure.primitives.triangle({
|
|
919
|
+
* ASA: [Math.PI / 2, 1, Math.PI / 6],
|
|
920
|
+
* line: {
|
|
921
|
+
* width: 0.02,
|
|
922
|
+
* dash: [0.12, 0.04],
|
|
923
|
+
* },
|
|
924
|
+
* });
|
|
925
|
+
* figure.elements.add('t', t);
|
|
926
|
+
*
|
|
927
|
+
* @example
|
|
928
|
+
* // Star from 4 equilateral triangles
|
|
929
|
+
* figure.add({
|
|
930
|
+
* name: 'star',
|
|
931
|
+
* make: 'triangle',
|
|
932
|
+
* SSS: [1, 1, 1],
|
|
933
|
+
* xAlign: 'centroid',
|
|
934
|
+
* yAlign: 'centroid',
|
|
935
|
+
* copy: {
|
|
936
|
+
* along: 'rotation',
|
|
937
|
+
* num: 3,
|
|
938
|
+
* step: Math.PI / 6,
|
|
939
|
+
* },
|
|
940
|
+
* });
|
|
941
|
+
* @interface
|
|
942
|
+
* @group 2D Shape Primitives
|
|
943
|
+
*/
|
|
944
|
+
export type OBJ_Triangle = {
|
|
945
|
+
width?: number;
|
|
946
|
+
height?: number;
|
|
947
|
+
top?: 'left' | 'right' | 'center';
|
|
948
|
+
SSS?: [number, number, number];
|
|
949
|
+
ASA?: [number, number, number];
|
|
950
|
+
AAS?: [number, number, number];
|
|
951
|
+
SAS?: [number, number, number];
|
|
952
|
+
direction?: 1 | -1;
|
|
953
|
+
points?: Array<Point>;
|
|
954
|
+
rotation?: number | 's1' | 's2' | 's3' | {
|
|
955
|
+
side?: 's1' | 's2' | 's3';
|
|
956
|
+
angle?: number;
|
|
957
|
+
};
|
|
958
|
+
xAlign: 'left' | 'center' | 'right' | number | 'c1' | 'c2' | 'c3' | 's1' | 's2' | 's3' | 'centroid' | 'points';
|
|
959
|
+
yAlign: 'bottom' | 'middle' | 'top' | number | 'c1' | 'c2' | 'c3' | 's1' | 's2' | 's3' | 'centroid' | 'points';
|
|
960
|
+
line?: OBJ_LineStyleSimple;
|
|
961
|
+
} & OBJ_Generic;
|
|
962
|
+
/**
|
|
963
|
+
* Line definition options object that extends {@link OBJ_Generic} (without
|
|
964
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
965
|
+
*
|
|
966
|
+
* 
|
|
967
|
+
*
|
|
968
|
+
* A line can either be defined as two points `p1` and `p2`, or
|
|
969
|
+
* a single point `p1`, a `length` and an `angle`.
|
|
970
|
+
*
|
|
971
|
+
* The line has some `width` that will be filled on both sides
|
|
972
|
+
* of the line points evenly (`'mid'`), or on one side only.
|
|
973
|
+
* The line's `'positive'` side is the side to which it rotates toward
|
|
974
|
+
* when rotating in the positive angle direction around `p1`.
|
|
975
|
+
* Similarly the line's `'negative'` side is the opposite.
|
|
976
|
+
*
|
|
977
|
+
* The line can be solid or dashed using the `dash` property.
|
|
978
|
+
*
|
|
979
|
+
* The line can have arrows at one or both ends using the `arrow` property.
|
|
980
|
+
*
|
|
981
|
+
* @property {TypeParsablePoint} [p1] start point of line
|
|
982
|
+
* @property {TypeParsablePoint} [p2] end point of line
|
|
983
|
+
* @property {number} [length] length of line from `p1`
|
|
984
|
+
* @property {number} [angle] angle of line from `p1`
|
|
985
|
+
* @property {number} [width] (`0.01`)
|
|
986
|
+
* @property {'mid' | 'positive' | 'negative' | number} [widthIs]
|
|
987
|
+
* defines how the width is grown from the polyline's points.
|
|
988
|
+
* Only `"mid"` is fully compatible with all options in
|
|
989
|
+
* `arrow`. (`"mid"`)
|
|
990
|
+
* @property {TypeDash} [dash] leave empty for solid line - use array of
|
|
991
|
+
* numbers for dash line where first number is length of line, second number is
|
|
992
|
+
* length of gap and then the pattern repeats - can use more than one dash length
|
|
993
|
+
* and gap - e.g. [0.1, 0.01, 0.02, 0.01] produces a lines with a long dash,
|
|
994
|
+
* short gap, short dash, short gap and then repeats.
|
|
995
|
+
* @property {OBJ_LineArrows | TypeArrowHead} [arrow] either an object defining custom
|
|
996
|
+
* arrows or a string representing the name of an arrow head style can be used.
|
|
997
|
+
* If a string is used, then the line will have an arrow at both ends.
|
|
998
|
+
* Arrows are only available for `widthIs: 'mid'` and `linePrimitives: false`
|
|
999
|
+
* @property {boolean} [linePrimitives] Use WebGL line primitives instead of
|
|
1000
|
+
* triangle primitives to draw the line (`false`)
|
|
1001
|
+
* @property {number} [lineNum] Number of line primitives to use when
|
|
1002
|
+
* `linePrimitivs`: `true` (`2`)
|
|
1003
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
1004
|
+
* override OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
1005
|
+
* drawBorderBuffer the same as the line with additional `number` thickness
|
|
1006
|
+
* on each side and the ends (`0`)
|
|
1007
|
+
*
|
|
1008
|
+
* @extends OBJ_Generic
|
|
1009
|
+
*
|
|
1010
|
+
* @see To test examples, append them to the
|
|
1011
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
1012
|
+
*
|
|
1013
|
+
* @example
|
|
1014
|
+
* // Simple line defined by two points
|
|
1015
|
+
* figure.add({
|
|
1016
|
+
* name: 'l',
|
|
1017
|
+
* make: 'line',
|
|
1018
|
+
* p1: [0, 0],
|
|
1019
|
+
* p2: [0, 1],
|
|
1020
|
+
* width: 0.02,
|
|
1021
|
+
* });
|
|
1022
|
+
*
|
|
1023
|
+
* @example
|
|
1024
|
+
* // Dashed line defined by a point, a length and an angle
|
|
1025
|
+
* figure.add({
|
|
1026
|
+
* name: 'l',
|
|
1027
|
+
* make: 'line',
|
|
1028
|
+
* p1: [0, 0],
|
|
1029
|
+
* length: 1,
|
|
1030
|
+
* angle: Math.PI / 2,
|
|
1031
|
+
* width: 0.03,
|
|
1032
|
+
* dash: [0.1, 0.02, 0.03, 0.02],
|
|
1033
|
+
* });
|
|
1034
|
+
*
|
|
1035
|
+
* @example
|
|
1036
|
+
* // Line with two different arrows on ends
|
|
1037
|
+
* figure.add({
|
|
1038
|
+
* name: 'l',
|
|
1039
|
+
* make: 'line',
|
|
1040
|
+
* p1: [0, 0],
|
|
1041
|
+
* p2: [0, 1],
|
|
1042
|
+
* width: 0.03,
|
|
1043
|
+
* arrow: {
|
|
1044
|
+
* start: 'rectangle',
|
|
1045
|
+
* end: 'barb',
|
|
1046
|
+
* },
|
|
1047
|
+
* });
|
|
1048
|
+
* @interface
|
|
1049
|
+
* @group 2D Shape Primitives
|
|
1050
|
+
*/
|
|
1051
|
+
export type OBJ_Line = {
|
|
1052
|
+
p1?: TypeParsablePoint;
|
|
1053
|
+
p2?: TypeParsablePoint;
|
|
1054
|
+
length?: number;
|
|
1055
|
+
angle?: number;
|
|
1056
|
+
width?: number;
|
|
1057
|
+
widthIs?: 'positive' | 'negative' | 'mid' | number;
|
|
1058
|
+
dash?: TypeDash;
|
|
1059
|
+
arrow?: OBJ_LineArrows | TypeArrowHead;
|
|
1060
|
+
linePrimitives?: boolean;
|
|
1061
|
+
lineNum?: number;
|
|
1062
|
+
drawBorderBuffer?: number | TypeParsableBorder;
|
|
1063
|
+
} & OBJ_Generic;
|
|
1064
|
+
/**
|
|
1065
|
+
* Grid shape options object that extends {@link OBJ_Generic} (without
|
|
1066
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
1067
|
+
*
|
|
1068
|
+
* 
|
|
1069
|
+
*
|
|
1070
|
+
* A grid is a rectangle divided into a series of vertical and horizontal lines.
|
|
1071
|
+
*
|
|
1072
|
+
* The rectangle is defined by `bounds`.
|
|
1073
|
+
*
|
|
1074
|
+
* `xNum` and `yNum` can be used to defined a number of equally spaced lines
|
|
1075
|
+
* in the rectangle (including the edges).
|
|
1076
|
+
*
|
|
1077
|
+
* Alternatively `xStep` and `yStep` can be used to define the spacing between
|
|
1078
|
+
* lines from the bottom left corner.
|
|
1079
|
+
*
|
|
1080
|
+
* The line width and style is defined with `line`.
|
|
1081
|
+
*
|
|
1082
|
+
* @property {TypeParsableRect} [bounds] rectangle definition
|
|
1083
|
+
* @property {number} [step] distance between grid lines
|
|
1084
|
+
* @property {number} [xStep] distance between vertical lines in grid from
|
|
1085
|
+
* left - use this instead of `xNum`. This will override `step`.
|
|
1086
|
+
* @property {number} [yStep] distance between horizontal lines in grid from
|
|
1087
|
+
* bottom - use this instead of `yNum`. This will override `step`.
|
|
1088
|
+
* @property {number} [num] number of grid lines. This will override `step`.
|
|
1089
|
+
* @property {number} [xNum] number of vertical lines in grid including top and
|
|
1090
|
+
* bottom lines - overrides `num` and `xStep`.
|
|
1091
|
+
* @property {number} [yNum] number of horizontal lines in grid including left
|
|
1092
|
+
* and right lines - overrides `num` and `yStep`.
|
|
1093
|
+
* @property {OBJ_LineStyle} [line] line style options - do not use any corner
|
|
1094
|
+
* options
|
|
1095
|
+
* @property {number | TypeParsableBorder} [drawBorderBuffer]
|
|
1096
|
+
* override OBJ_Generic `drawBorderBuffer` with `number` to make the
|
|
1097
|
+
* drawBorderBuffer the same as the grid outline with additional `number`
|
|
1098
|
+
* buffer each side (`0`)
|
|
1099
|
+
*
|
|
1100
|
+
* @extends OBJ_Generic
|
|
1101
|
+
*
|
|
1102
|
+
* @see To test examples, append them to the
|
|
1103
|
+
* <a href="#drawing-boilerplate">boilerplate</a>
|
|
1104
|
+
*
|
|
1105
|
+
* @example
|
|
1106
|
+
* // Grid defined by xStep and yStep
|
|
1107
|
+
* figure.add({
|
|
1108
|
+
* name: 'g',
|
|
1109
|
+
* make: 'grid',
|
|
1110
|
+
* bounds: [-0.5, -0.5, 1, 1],
|
|
1111
|
+
* xStep: 0.25,
|
|
1112
|
+
* yStep: 0.25,
|
|
1113
|
+
* line: {
|
|
1114
|
+
* width: 0.03,
|
|
1115
|
+
* },
|
|
1116
|
+
* });
|
|
1117
|
+
*
|
|
1118
|
+
* @example
|
|
1119
|
+
* // Grid defined by xNum and yNum with dashed lines
|
|
1120
|
+
* const grid = figure.primitives.grid({
|
|
1121
|
+
* bounds: [-0.5, -0.5, 1, 1],
|
|
1122
|
+
* xNum: 4,
|
|
1123
|
+
* yNum: 4,
|
|
1124
|
+
* line: {
|
|
1125
|
+
* width: 0.03,
|
|
1126
|
+
* dash: [0.1, 0.02],
|
|
1127
|
+
* },
|
|
1128
|
+
* });
|
|
1129
|
+
* figure.elements.add('g', grid);
|
|
1130
|
+
*
|
|
1131
|
+
* @example
|
|
1132
|
+
* // Grid of grids
|
|
1133
|
+
* figure.add({
|
|
1134
|
+
* name: 'g',
|
|
1135
|
+
* make: 'grid',
|
|
1136
|
+
* bounds: [-0.7, -0.7, 0.6, 0.6],
|
|
1137
|
+
* xNum: 4,
|
|
1138
|
+
* yNum: 4,
|
|
1139
|
+
* line: {
|
|
1140
|
+
* width: 0.03,
|
|
1141
|
+
* },
|
|
1142
|
+
* copy: [
|
|
1143
|
+
* { along: 'x', num: 1, step: 0.8},
|
|
1144
|
+
* { along: 'y', num: 1, step: 0.8},
|
|
1145
|
+
* ],
|
|
1146
|
+
* });
|
|
1147
|
+
* @interface
|
|
1148
|
+
* @group 2D Shape Primitives
|
|
1149
|
+
*/
|
|
1150
|
+
export type OBJ_Grid = {
|
|
1151
|
+
bounds?: TypeParsableRect;
|
|
1152
|
+
xStep?: number;
|
|
1153
|
+
yStep?: number;
|
|
1154
|
+
xNum?: number;
|
|
1155
|
+
yNum?: number;
|
|
1156
|
+
line?: OBJ_LineStyleSimple;
|
|
1157
|
+
drawBorderBuffer?: number | TypeParsableBorder;
|
|
1158
|
+
} & OBJ_Generic;
|
|
1159
|
+
/**
|
|
1160
|
+
* Arrow options object that extends {@link OBJ_Generic} (without
|
|
1161
|
+
* `drawType`) and {@link OBJ_FigurePrimitive}
|
|
1162
|
+
*
|
|
1163
|
+
* 
|
|
1164
|
+
*
|
|
1165
|
+
* An arrow has a head, tail, length and width. The `head` defines the head
|
|
1166
|
+
* style of the arrow. The `length`, `width` (or `radius` for polygon and circle
|
|
1167
|
+
* head styles) define the size of the arrow and `tail` defines wether it has a
|
|
1168
|
+
* tail and how long it is.
|
|
1169
|
+
*
|
|
1170
|
+
* All properties have default values that can be scaled with the `scale`
|
|
1171
|
+
* property. So a `scale` of 2 will double the size of the default arrow.
|
|
1172
|
+
*
|
|
1173
|
+
* An arrow can be aligned and oriented with `align` and `angle`. `align`
|
|
1174
|
+
* positions the tip, start, tail or middle part of the arrow at (0, 0) in
|
|
1175
|
+
* draw space. This part of the arrow will therefore be at the `position`
|
|
1176
|
+
* or translation of the `transform`. `angle` then gives the arrow some drawn
|
|
1177
|
+
* rotation.
|
|
1178
|
+
*
|
|
1179
|
+
* Alignment definitions are:
|
|
1180
|
+
* - `tip`: arrow tip
|
|
1181
|
+
* - `start`: opposite side of `tip`
|
|
1182
|
+
* - `mid`: mid points between `start` and `tip` - useful for polygon, circle
|
|
1183
|
+
* and bar arrows without tails when the head should be on a point, not next
|
|
1184
|
+
* to it
|
|
1185
|
+
* - `tail`: the end of the tail when a tail exists, or where a tail would start
|
|
1186
|
+
* if it doesn't exist.
|
|
1187
|
+
*
|
|
1188
|
+
* Setting the `tail` property to `false` will draw only the arrow head,
|
|
1189
|
+
* `true` will draw a tail of length 0, and a tail with a custom length
|
|
1190
|
+
* can be defined with a `number`. A tail length of 0 will only extend a tail
|
|
1191
|
+
* to the boundaries of the head. A positive tail, will extend it beyond the
|
|
1192
|
+
* boundaries.
|
|
1193
|
+
*
|
|
1194
|
+
* For arrow heads that use `length` and `width` properties, the `length` is the
|
|
1195
|
+
* dimension along the line. It includes both the head and the tail, so an arrow
|
|
1196
|
+
* with length 1 and tailLength 0.4 will have a head length of 0.6.
|
|
1197
|
+
*
|
|
1198
|
+
* For `polygon` and `circle` arrows, only `radius` and `tail` are used to
|
|
1199
|
+
* determine the dimension of the arrow (`length` and `width` are ignored).
|
|
1200
|
+
*
|
|
1201
|
+
* @property {TypeArrowHead} [head] head style (`'triangle'`)
|
|
1202
|
+
* @property {number} [scale] scale the default dimensions of the arrow
|
|
1203
|
+
* @property {number} [length] dimension of the arrow head along the line
|
|
1204
|
+
* @property {number} [width] dimension of the arrow head along the line width
|
|
1205
|
+
* @property {number} [rotation] rotation of the polygon when `head = 'polygon'`
|
|
1206
|
+
* @property {number} [sides] number of sides in polygon or circle arrow head
|
|
1207
|
+
* @property {number} [radius] radius of polygon or circle arrow head
|
|
1208
|
+
* @property {number} [barb] barb length (along the length of the line) of the
|
|
1209
|
+
* barb arrow head
|
|
1210
|
+
* @property {number} [tailWidth] width of the line that joins the arrow - if
|
|
1211
|
+
* defined this will create minimum dimensions for the arrow
|
|
1212
|
+
* @property {boolean | number} [tail] `true` includes a tail in the arrow of
|
|
1213
|
+
* with `tailWidth`. A `number` gives the tail a length where 0 will not
|
|
1214
|
+
* extend the tail beyond the boundaries of the head
|
|
1215
|
+
* @property {'tip' | 'start' | 'mid' | 'tail'} [align] define which part of
|
|
1216
|
+
* the arrow is aligned at (0, 0) in draw space (`'tip'`)
|
|
1217
|
+
* @property {number} [angle] angle the arrow is drawn at (`0`)
|
|
1218
|
+
*
|
|
1219
|
+
* @extends OBJ_Generic
|
|
1220
|
+
*
|
|
1221
|
+
* @example
|
|
1222
|
+
* // Triangle arrow with tail
|
|
1223
|
+
* figure.add({
|
|
1224
|
+
* name: 'a',
|
|
1225
|
+
* make: 'arrow',
|
|
1226
|
+
* head: 'triangle',
|
|
1227
|
+
* tail: 0.15,
|
|
1228
|
+
* length: 0.5,
|
|
1229
|
+
* });
|
|
1230
|
+
*
|
|
1231
|
+
* @example
|
|
1232
|
+
* // Barb arrow with 0 tail
|
|
1233
|
+
* figure.add({
|
|
1234
|
+
* name: 'a',
|
|
1235
|
+
* make: 'arrow',
|
|
1236
|
+
* head: 'barb',
|
|
1237
|
+
* angle: Math.PI / 2,
|
|
1238
|
+
* tail: 0,
|
|
1239
|
+
* });
|
|
1240
|
+
*
|
|
1241
|
+
* @example
|
|
1242
|
+
* // Create a vector map with arrows by copying an original arrow by a
|
|
1243
|
+
* // transforms defining the position, rotation and scale of the arrows
|
|
1244
|
+
*
|
|
1245
|
+
* // Create transforms to apply to each arrow
|
|
1246
|
+
* const r = Fig.range(0, Math.PI / 2, Math.PI / 18);
|
|
1247
|
+
* const x = [0, 1, 2, 0, 1, 2, 0, 1, 2];
|
|
1248
|
+
* const y = [0, 0, 0, 1, 1, 1, 2, 2, 2];
|
|
1249
|
+
* const s = [0.5, 0.8, 0.4, 0.6, 0.8, 0.6, 0.5, 0.8, 0.6];
|
|
1250
|
+
* const transforms = [];
|
|
1251
|
+
* for (let i = 0; i < 9; i += 1) {
|
|
1252
|
+
* transforms.push(new Fig.Transform().scale(s[i], s[i]).rotate(r[i]).translate(x[i], y[i]));
|
|
1253
|
+
* }
|
|
1254
|
+
*
|
|
1255
|
+
* // Create arrow and copy to transforms
|
|
1256
|
+
* figure.add({
|
|
1257
|
+
* name: 'a',
|
|
1258
|
+
* make: 'arrow',
|
|
1259
|
+
* head: 'barb',
|
|
1260
|
+
* align: 'mid',
|
|
1261
|
+
* length: 0.7,
|
|
1262
|
+
* copy: {
|
|
1263
|
+
* to: transforms,
|
|
1264
|
+
* original: false,
|
|
1265
|
+
* },
|
|
1266
|
+
* });
|
|
1267
|
+
* @interface
|
|
1268
|
+
* @group 2D Shape Primitives
|
|
1269
|
+
*/
|
|
1270
|
+
export type OBJ_Arrow = {
|
|
1271
|
+
head?: TypeArrowHead;
|
|
1272
|
+
scale?: number;
|
|
1273
|
+
length?: number;
|
|
1274
|
+
width?: number;
|
|
1275
|
+
rotation?: number;
|
|
1276
|
+
sides?: number;
|
|
1277
|
+
radius?: number;
|
|
1278
|
+
barb?: number;
|
|
1279
|
+
tailWidth?: number;
|
|
1280
|
+
tail?: boolean;
|
|
1281
|
+
align?: 'tip' | 'start' | 'mid' | 'tail';
|
|
1282
|
+
angle?: number;
|
|
1283
|
+
} & OBJ_Generic;
|
|
1284
|
+
/**
|
|
1285
|
+
* Modifier Text Definition object.
|
|
1286
|
+
*
|
|
1287
|
+
* Used to define the modifiers of a string within a text lines primitive
|
|
1288
|
+
* {@link OBJ_TextLines}.
|
|
1289
|
+
*
|
|
1290
|
+
* @property {string} [text] text to replace `modifierId` with - if `undefined`
|
|
1291
|
+
* then `modifierId` is used
|
|
1292
|
+
* @property {TypeParsablePoint} [offset] text offset
|
|
1293
|
+
* @property {boolean} [followOffsetY] `true` will make any subsequent text
|
|
1294
|
+
* have the same y offset as a starting point (`false`)
|
|
1295
|
+
* @property {OBJ_Font} [font] font changes for modified text
|
|
1296
|
+
* @property {boolean} [inLine] `false` if modified text should not contribute
|
|
1297
|
+
* to line layout (defqult: `true`)
|
|
1298
|
+
* @property {string | function(): void} [onClick] function to execute on click
|
|
1299
|
+
* within the `touchBorder` of the modified text
|
|
1300
|
+
* @property {TypeParsableBuffer | Array<TypeParsablePoint>} [touchBorder]
|
|
1301
|
+
* touch border can be custom (`Array<TypeParsablePoint>`), or be set to some
|
|
1302
|
+
* buffer (`TypeParsableBuffer`) around the rectangle (default: `'0'`)
|
|
1303
|
+
*/
|
|
1304
|
+
export type OBJ_TextModifierDefinition = {
|
|
1305
|
+
text?: string;
|
|
1306
|
+
offset?: TypeParsablePoint;
|
|
1307
|
+
inLine?: boolean;
|
|
1308
|
+
font?: OBJ_Font;
|
|
1309
|
+
touchBorder?: TypeParsableBuffer | Array<TypeParsablePoint>;
|
|
1310
|
+
onClick?: string | (() => void);
|
|
1311
|
+
followOffsetY?: boolean;
|
|
1312
|
+
};
|
|
1313
|
+
/**
|
|
1314
|
+
* Modifier object.
|
|
1315
|
+
*
|
|
1316
|
+
* Used to define the modifiers of a string within a text lines primitive
|
|
1317
|
+
* {@link OBJ_TextLines}.
|
|
1318
|
+
*
|
|
1319
|
+
* @property {OBJ_TextModifierDefinition} [modifierId] modifierId can be any
|
|
1320
|
+
* key
|
|
1321
|
+
*/
|
|
1322
|
+
export type OBJ_TextModifiersDefinition = {
|
|
1323
|
+
[modifierId: string]: OBJ_TextModifierDefinition;
|
|
1324
|
+
};
|