melonjs 10.7.1 → 10.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE.md +1 -1
- package/README.md +29 -23
- package/dist/melonjs.js +2220 -1070
- package/dist/melonjs.min.js +4 -4
- package/dist/melonjs.module.d.ts +1395 -485
- package/dist/melonjs.module.js +2244 -1131
- package/package.json +17 -14
- package/src/camera/camera2d.js +1 -1
- package/src/entity/entity.js +6 -7
- package/src/game.js +2 -2
- package/src/geometries/ellipse.js +20 -21
- package/src/geometries/line.js +7 -7
- package/src/geometries/path2d.js +319 -0
- package/src/geometries/poly.js +27 -27
- package/src/geometries/rectangle.js +19 -19
- package/src/geometries/roundrect.js +164 -0
- package/src/index.js +12 -2
- package/src/input/gamepad.js +2 -2
- package/src/input/pointerevent.js +1 -1
- package/src/lang/deprecated.js +8 -6
- package/src/level/tiled/TMXLayer.js +1 -1
- package/src/level/tiled/TMXObject.js +9 -12
- package/src/level/tiled/TMXTileMap.js +23 -4
- package/src/level/tiled/TMXUtils.js +1 -1
- package/src/level/tiled/renderer/TMXHexagonalRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXIsometricRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXStaggeredRenderer.js +1 -1
- package/src/loader/loader.js +4 -4
- package/src/loader/loadingscreen.js +17 -6
- package/src/math/color.js +6 -5
- package/src/math/matrix2.js +1 -1
- package/src/math/matrix3.js +1 -1
- package/src/math/observable_vector2.js +1 -1
- package/src/math/observable_vector3.js +1 -1
- package/src/math/vector2.js +1 -1
- package/src/math/vector3.js +1 -1
- package/src/particles/emitter.js +34 -26
- package/src/particles/particle.js +3 -2
- package/src/physics/body.js +67 -51
- package/src/physics/bounds.js +8 -9
- package/src/physics/world.js +1 -1
- package/src/polyfill/index.js +1 -0
- package/src/polyfill/roundrect.js +235 -0
- package/src/renderable/GUI.js +5 -5
- package/src/renderable/collectable.js +9 -2
- package/src/renderable/colorlayer.js +1 -1
- package/src/renderable/container.js +27 -27
- package/src/renderable/imagelayer.js +3 -3
- package/src/renderable/light2d.js +115 -0
- package/src/renderable/renderable.js +23 -22
- package/src/renderable/sprite.js +15 -16
- package/src/renderable/trigger.js +10 -4
- package/src/state/stage.js +73 -3
- package/src/state/state.js +1 -1
- package/src/system/device.js +10 -8
- package/src/system/pooling.js +156 -149
- package/src/text/bitmaptext.js +1 -1
- package/src/text/text.js +14 -18
- package/src/utils/utils.js +2 -2
- package/src/video/canvas/canvas_renderer.js +144 -81
- package/src/video/renderer.js +64 -37
- package/src/video/{texture.js → texture/atlas.js} +8 -8
- package/src/video/{texture_cache.js → texture/cache.js} +4 -4
- package/src/video/texture/canvas_texture.js +87 -0
- package/src/video/webgl/glshader.js +29 -193
- package/src/video/webgl/utils/attributes.js +16 -0
- package/src/video/webgl/utils/precision.js +11 -0
- package/src/video/webgl/utils/program.js +58 -0
- package/src/video/webgl/utils/string.js +16 -0
- package/src/video/webgl/utils/uniforms.js +87 -0
- package/src/video/webgl/webgl_compositor.js +1 -14
- package/src/video/webgl/webgl_renderer.js +191 -231
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "melonjs",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.10.0",
|
|
4
4
|
"description": "melonJS Game Engine",
|
|
5
5
|
"homepage": "http://www.melonjs.org/",
|
|
6
6
|
"keywords": [
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
"name": "Olivier Biot",
|
|
36
36
|
"email": "contact@melonjs.org"
|
|
37
37
|
},
|
|
38
|
+
"funding": "https://github.com/sponsors/melonjs",
|
|
38
39
|
"engines": {
|
|
39
40
|
"node": ">= 12"
|
|
40
41
|
},
|
|
@@ -46,7 +47,6 @@
|
|
|
46
47
|
"dist/melonjs.min.js",
|
|
47
48
|
"dist/melonjs.module.js",
|
|
48
49
|
"dist/melonjs.module.d.ts",
|
|
49
|
-
"plugins/",
|
|
50
50
|
"src/",
|
|
51
51
|
"package.json",
|
|
52
52
|
"README.md",
|
|
@@ -55,35 +55,37 @@
|
|
|
55
55
|
],
|
|
56
56
|
"dependencies": {
|
|
57
57
|
"@teppeis/multimaps": "^2.0.0",
|
|
58
|
-
"core-js": "^3.22.
|
|
58
|
+
"core-js": "^3.22.8",
|
|
59
59
|
"earcut": "2.2.3",
|
|
60
60
|
"eventemitter3": "^4.0.7",
|
|
61
61
|
"howler": "2.2.3"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
+
"@melonjs/jsdoc-template": "^2.0.2",
|
|
64
65
|
"@rollup/plugin-buble": "^0.21.3",
|
|
65
66
|
"@rollup/plugin-commonjs": "^22.0.0",
|
|
66
67
|
"@rollup/plugin-node-resolve": "^13.3.0",
|
|
67
68
|
"@rollup/plugin-replace": "^4.0.0",
|
|
68
|
-
"@types/offscreencanvas": "^2019.
|
|
69
|
-
"
|
|
69
|
+
"@types/offscreencanvas": "^2019.7.0",
|
|
70
|
+
"@webdoc/cli": "^1.6.0",
|
|
71
|
+
"cheerio": "^1.0.0-rc.11",
|
|
70
72
|
"del-cli": "^4.0.1",
|
|
71
|
-
"eslint": "^8.
|
|
72
|
-
"eslint-plugin-jsdoc": "^39.2
|
|
73
|
-
"jasmine-core": "^4.1.
|
|
73
|
+
"eslint": "^8.17.0",
|
|
74
|
+
"eslint-plugin-jsdoc": "^39.3.2",
|
|
75
|
+
"jasmine-core": "^4.1.1",
|
|
74
76
|
"jsdoc": "^3.6.10",
|
|
75
|
-
"karma": "^6.3.
|
|
77
|
+
"karma": "^6.3.20",
|
|
76
78
|
"karma-chrome-launcher": "^3.1.1",
|
|
77
79
|
"karma-coverage": "^2.2.0",
|
|
78
80
|
"karma-html-detailed-reporter": "^2.1.0",
|
|
79
|
-
"karma-jasmine": "^5.0.
|
|
81
|
+
"karma-jasmine": "^5.0.1",
|
|
80
82
|
"karma-nyan-reporter": "0.2.5",
|
|
81
|
-
"qs": "^6.10.
|
|
82
|
-
"rollup": "^2.
|
|
83
|
+
"qs": "^6.10.5",
|
|
84
|
+
"rollup": "^2.75.5",
|
|
83
85
|
"rollup-plugin-bundle-size": "^1.0.3",
|
|
84
86
|
"rollup-plugin-string": "^3.0.0",
|
|
85
|
-
"terser": "^5.
|
|
86
|
-
"typescript": "^4.
|
|
87
|
+
"terser": "^5.14.0",
|
|
88
|
+
"typescript": "^4.7.3"
|
|
87
89
|
},
|
|
88
90
|
"scripts": {
|
|
89
91
|
"build": "npm run lint && rollup -c --silent",
|
|
@@ -92,6 +94,7 @@
|
|
|
92
94
|
"lint": "eslint src rollup.config.js",
|
|
93
95
|
"test": "npm run build && karma start tests/karma.conf.cjs",
|
|
94
96
|
"doc": "mkdirp docs && jsdoc -c jsdoc_conf.json",
|
|
97
|
+
"webdoc": "mkdirp dist && webdoc --quiet -R README.md",
|
|
95
98
|
"release": "npm run dist && npm publish --access public",
|
|
96
99
|
"clean": "del-cli --force build/*.js dist/*.js dist/*.d.ts docs src/**/*.d.ts",
|
|
97
100
|
"types": "tsc dist/melonjs.module.js --declaration --allowJs --emitDeclarationOnly"
|
package/src/camera/camera2d.js
CHANGED
|
@@ -7,7 +7,7 @@ import Matrix3d from "./../math/matrix3.js";
|
|
|
7
7
|
import Rect from "./../geometries/rectangle.js";
|
|
8
8
|
import { renderer } from "./../video/video.js";
|
|
9
9
|
import * as event from "./../system/event.js";
|
|
10
|
-
import
|
|
10
|
+
import pool from "./../system/pooling.js";
|
|
11
11
|
import Renderable from "./../renderable/renderable.js";
|
|
12
12
|
import {clamp, toBeCloseTo} from "./../math/math.js";
|
|
13
13
|
import { world } from "./../game.js";
|
package/src/entity/entity.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import pool from "./../system/pooling.js";
|
|
2
2
|
import Renderable from "./../renderable/renderable.js";
|
|
3
3
|
import Sprite from "./../renderable/sprite.js";
|
|
4
4
|
import Body from "./../physics/body.js";
|
|
5
|
-
import Polygon from "./../geometries/poly.js";
|
|
6
5
|
|
|
7
6
|
|
|
8
7
|
/**
|
|
@@ -102,11 +101,11 @@ class Entity extends Renderable {
|
|
|
102
101
|
*/
|
|
103
102
|
// initialize the default body
|
|
104
103
|
if (typeof settings.shapes === "undefined") {
|
|
105
|
-
settings.shapes =
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
104
|
+
settings.shapes = pool.pull("Polygon", 0, 0, [
|
|
105
|
+
pool.pull("Vector2d", 0, 0),
|
|
106
|
+
pool.pull("Vector2d", this.width, 0),
|
|
107
|
+
pool.pull("Vector2d", this.width, this.height),
|
|
108
|
+
pool.pull("Vector2d", 0, this.height)
|
|
110
109
|
]);
|
|
111
110
|
}
|
|
112
111
|
this.body = new Body(this, settings.shapes, this.onBodyUpdate.bind(this));
|
package/src/game.js
CHANGED
|
@@ -5,9 +5,9 @@ import state from "./state/state.js";
|
|
|
5
5
|
import World from "./physics/world.js";
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
*
|
|
8
|
+
* game represents your current game, it contains all the objects,
|
|
9
9
|
* tilemap layers, current viewport, collision map, etc...<br>
|
|
10
|
-
*
|
|
10
|
+
* game is also responsible for updating (each frame) the object status and draw them.
|
|
11
11
|
* @namespace game
|
|
12
12
|
*/
|
|
13
13
|
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import * as pool from "./../system/pooling.js";
|
|
1
|
+
import pool from "./../system/pooling.js";
|
|
3
2
|
|
|
4
3
|
/**
|
|
5
4
|
* @classdesc
|
|
@@ -18,9 +17,9 @@ class Ellipse {
|
|
|
18
17
|
* @public
|
|
19
18
|
* @type {Vector2d}
|
|
20
19
|
* @name pos
|
|
21
|
-
* @memberof Ellipse
|
|
20
|
+
* @memberof Ellipse
|
|
22
21
|
*/
|
|
23
|
-
this.pos =
|
|
22
|
+
this.pos = pool.pull("Vector2d");
|
|
24
23
|
|
|
25
24
|
/**
|
|
26
25
|
* The bounding rectangle for this shape
|
|
@@ -42,27 +41,27 @@ class Ellipse {
|
|
|
42
41
|
* @public
|
|
43
42
|
* @type {Vector2d}
|
|
44
43
|
* @name radiusV
|
|
45
|
-
* @memberof Ellipse
|
|
44
|
+
* @memberof Ellipse
|
|
46
45
|
*/
|
|
47
|
-
this.radiusV =
|
|
46
|
+
this.radiusV = pool.pull("Vector2d");
|
|
48
47
|
|
|
49
48
|
/**
|
|
50
49
|
* Radius squared, for pythagorean theorom
|
|
51
50
|
* @public
|
|
52
51
|
* @type {Vector2d}
|
|
53
52
|
* @name radiusSq
|
|
54
|
-
* @memberof Ellipse
|
|
53
|
+
* @memberof Ellipse
|
|
55
54
|
*/
|
|
56
|
-
this.radiusSq =
|
|
55
|
+
this.radiusSq = pool.pull("Vector2d");
|
|
57
56
|
|
|
58
57
|
/**
|
|
59
58
|
* x/y scaling ratio for ellipse
|
|
60
59
|
* @public
|
|
61
60
|
* @type {Vector2d}
|
|
62
61
|
* @name ratio
|
|
63
|
-
* @memberof Ellipse
|
|
62
|
+
* @memberof Ellipse
|
|
64
63
|
*/
|
|
65
|
-
this.ratio =
|
|
64
|
+
this.ratio = pool.pull("Vector2d");
|
|
66
65
|
|
|
67
66
|
// the shape type
|
|
68
67
|
this.shapeType = "Ellipse";
|
|
@@ -77,7 +76,7 @@ class Ellipse {
|
|
|
77
76
|
/**
|
|
78
77
|
* set new value to the Ellipse shape
|
|
79
78
|
* @name setShape
|
|
80
|
-
* @memberof Ellipse
|
|
79
|
+
* @memberof Ellipse
|
|
81
80
|
* @function
|
|
82
81
|
* @param {number} x the center x coordinate of the ellipse
|
|
83
82
|
* @param {number} y the center y coordinate of the ellipse
|
|
@@ -107,7 +106,7 @@ class Ellipse {
|
|
|
107
106
|
/**
|
|
108
107
|
* Rotate this Ellipse (counter-clockwise) by the specified angle (in radians).
|
|
109
108
|
* @name rotate
|
|
110
|
-
* @memberof Ellipse
|
|
109
|
+
* @memberof Ellipse
|
|
111
110
|
* @function
|
|
112
111
|
* @param {number} angle The angle to rotate (in radians)
|
|
113
112
|
* @param {Vector2d|ObservableVector2d} [v] an optional point to rotate around
|
|
@@ -124,7 +123,7 @@ class Ellipse {
|
|
|
124
123
|
/**
|
|
125
124
|
* Scale this Ellipse by the specified scalar.
|
|
126
125
|
* @name scale
|
|
127
|
-
* @memberof Ellipse
|
|
126
|
+
* @memberof Ellipse
|
|
128
127
|
* @function
|
|
129
128
|
* @param {number} x
|
|
130
129
|
* @param {number} [y=x]
|
|
@@ -143,7 +142,7 @@ class Ellipse {
|
|
|
143
142
|
/**
|
|
144
143
|
* Scale this Ellipse by the specified vector.
|
|
145
144
|
* @name scale
|
|
146
|
-
* @memberof Ellipse
|
|
145
|
+
* @memberof Ellipse
|
|
147
146
|
* @function
|
|
148
147
|
* @param {Vector2d} v
|
|
149
148
|
* @returns {Ellipse} Reference to this object for method chaining
|
|
@@ -155,7 +154,7 @@ class Ellipse {
|
|
|
155
154
|
/**
|
|
156
155
|
* apply the given transformation matrix to this ellipse
|
|
157
156
|
* @name transform
|
|
158
|
-
* @memberof Ellipse
|
|
157
|
+
* @memberof Ellipse
|
|
159
158
|
* @function
|
|
160
159
|
* @param {Matrix2d} matrix the transformation matrix
|
|
161
160
|
* @returns {Polygon} Reference to this object for method chaining
|
|
@@ -168,7 +167,7 @@ class Ellipse {
|
|
|
168
167
|
/**
|
|
169
168
|
* translate the circle/ellipse by the specified offset
|
|
170
169
|
* @name translate
|
|
171
|
-
* @memberof Ellipse
|
|
170
|
+
* @memberof Ellipse
|
|
172
171
|
* @function
|
|
173
172
|
* @param {number} x x offset
|
|
174
173
|
* @param {number} y y offset
|
|
@@ -177,7 +176,7 @@ class Ellipse {
|
|
|
177
176
|
/**
|
|
178
177
|
* translate the circle/ellipse by the specified vector
|
|
179
178
|
* @name translate
|
|
180
|
-
* @memberof Ellipse
|
|
179
|
+
* @memberof Ellipse
|
|
181
180
|
* @function
|
|
182
181
|
* @param {Vector2d} v vector offset
|
|
183
182
|
* @returns {Ellipse} this ellipse
|
|
@@ -205,7 +204,7 @@ class Ellipse {
|
|
|
205
204
|
/**
|
|
206
205
|
* check if this circle/ellipse contains the specified point
|
|
207
206
|
* @name contains
|
|
208
|
-
* @memberof Ellipse
|
|
207
|
+
* @memberof Ellipse
|
|
209
208
|
* @function
|
|
210
209
|
* @param {Vector2d} point
|
|
211
210
|
* @returns {boolean} true if contains
|
|
@@ -214,7 +213,7 @@ class Ellipse {
|
|
|
214
213
|
/**
|
|
215
214
|
* check if this circle/ellipse contains the specified point
|
|
216
215
|
* @name contains
|
|
217
|
-
* @memberof Ellipse
|
|
216
|
+
* @memberof Ellipse
|
|
218
217
|
* @function
|
|
219
218
|
* @param {number} x x coordinate
|
|
220
219
|
* @param {number} y y coordinate
|
|
@@ -246,7 +245,7 @@ class Ellipse {
|
|
|
246
245
|
/**
|
|
247
246
|
* returns the bounding box for this shape, the smallest Rectangle object completely containing this shape.
|
|
248
247
|
* @name getBounds
|
|
249
|
-
* @memberof Ellipse
|
|
248
|
+
* @memberof Ellipse
|
|
250
249
|
* @function
|
|
251
250
|
* @returns {Bounds} this shape bounding box Rectangle object
|
|
252
251
|
*/
|
|
@@ -260,7 +259,7 @@ class Ellipse {
|
|
|
260
259
|
/**
|
|
261
260
|
* clone this Ellipse
|
|
262
261
|
* @name clone
|
|
263
|
-
* @memberof Ellipse
|
|
262
|
+
* @memberof Ellipse
|
|
264
263
|
* @function
|
|
265
264
|
* @returns {Ellipse} new Ellipse
|
|
266
265
|
*/
|
package/src/geometries/line.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
1
|
+
import pool from "./../system/pooling.js";
|
|
2
2
|
import Polygon from "./poly.js";
|
|
3
3
|
|
|
4
4
|
/**
|
|
@@ -15,7 +15,7 @@ class Line extends Polygon {
|
|
|
15
15
|
/**
|
|
16
16
|
* Returns true if the Line contains the given point
|
|
17
17
|
* @name contains
|
|
18
|
-
* @memberof Line
|
|
18
|
+
* @memberof Line
|
|
19
19
|
* @function
|
|
20
20
|
* @param {Vector2d} point
|
|
21
21
|
* @returns {boolean} true if contains
|
|
@@ -24,7 +24,7 @@ class Line extends Polygon {
|
|
|
24
24
|
/**
|
|
25
25
|
* Returns true if the Line contains the given point
|
|
26
26
|
* @name contains
|
|
27
|
-
* @memberof Line
|
|
27
|
+
* @memberof Line
|
|
28
28
|
* @function
|
|
29
29
|
* @param {number} x x coordinate
|
|
30
30
|
* @param {number} y y coordinate
|
|
@@ -58,7 +58,7 @@ class Line extends Polygon {
|
|
|
58
58
|
* Computes the calculated collision edges and normals.
|
|
59
59
|
* This **must** be called if the `points` array, `angle`, or `offset` is modified manually.
|
|
60
60
|
* @name recalc
|
|
61
|
-
* @memberof Line
|
|
61
|
+
* @memberof Line
|
|
62
62
|
* @function
|
|
63
63
|
* @returns {Line} this instance for objecf chaining
|
|
64
64
|
*/
|
|
@@ -76,11 +76,11 @@ class Line extends Polygon {
|
|
|
76
76
|
|
|
77
77
|
// Calculate the edges/normals
|
|
78
78
|
if (edges[0] === undefined) {
|
|
79
|
-
edges[0] =
|
|
79
|
+
edges[0] = pool.pull("Vector2d");
|
|
80
80
|
}
|
|
81
81
|
edges[0].copy(points[1]).sub(points[0]);
|
|
82
82
|
if (normals[0] === undefined) {
|
|
83
|
-
normals[0] =
|
|
83
|
+
normals[0] = pool.pull("Vector2d");
|
|
84
84
|
}
|
|
85
85
|
normals[0].copy(edges[0]).perp().normalize();
|
|
86
86
|
|
|
@@ -94,7 +94,7 @@ class Line extends Polygon {
|
|
|
94
94
|
/**
|
|
95
95
|
* clone this line segment
|
|
96
96
|
* @name clone
|
|
97
|
-
* @memberof Line
|
|
97
|
+
* @memberof Line
|
|
98
98
|
* @function
|
|
99
99
|
* @returns {Line} new Line
|
|
100
100
|
*/
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
import pool from "./../system/pooling.js";
|
|
2
|
+
import { TAU } from "./../math/math.js";
|
|
3
|
+
import earcut from "earcut";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @classdesc
|
|
7
|
+
* a simplified path2d implementation, supporting only one path
|
|
8
|
+
*/
|
|
9
|
+
class Path2D {
|
|
10
|
+
constructor() {
|
|
11
|
+
/**
|
|
12
|
+
* the points defining the current path
|
|
13
|
+
* @public
|
|
14
|
+
* @type {Vector2d[]}
|
|
15
|
+
* @name points
|
|
16
|
+
* @memberof Path2D#
|
|
17
|
+
*/
|
|
18
|
+
this.points = [];
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* space between interpolated points for quadratic and bezier curve approx. in pixels.
|
|
22
|
+
* @public
|
|
23
|
+
* @type {number}
|
|
24
|
+
* @name arcResolution
|
|
25
|
+
* @default 5
|
|
26
|
+
* @memberof Path2D#
|
|
27
|
+
*/
|
|
28
|
+
this.arcResolution = 5;
|
|
29
|
+
|
|
30
|
+
/* @ignore */
|
|
31
|
+
this.vertices = [];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* begin a new path
|
|
36
|
+
* @name beginPath
|
|
37
|
+
* @memberof Path2D
|
|
38
|
+
* @function
|
|
39
|
+
*/
|
|
40
|
+
beginPath() {
|
|
41
|
+
// empty the cache and recycle all vectors
|
|
42
|
+
this.points.forEach((point) => {
|
|
43
|
+
pool.push(point);
|
|
44
|
+
});
|
|
45
|
+
this.points.length = 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* causes the point of the pen to move back to the start of the current path.
|
|
50
|
+
* It tries to draw a straight line from the current point to the start.
|
|
51
|
+
* If the shape has already been closed or has only one point, this function does nothing.
|
|
52
|
+
* @name closePath
|
|
53
|
+
* @memberof Path2D
|
|
54
|
+
* @function
|
|
55
|
+
*/
|
|
56
|
+
closePath() {
|
|
57
|
+
var points = this.points;
|
|
58
|
+
if (points.length > 1 && !points[points.length-1].equals(points[0])) {
|
|
59
|
+
points.push(pool.pull("Vector2d", points[0].x, points[0].y));
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* triangulate the shape defined by this path into an array of triangles
|
|
65
|
+
* @name triangulatePath
|
|
66
|
+
* @memberof Path2D
|
|
67
|
+
* @function
|
|
68
|
+
* @returns {Vector2d[]}
|
|
69
|
+
*/
|
|
70
|
+
triangulatePath() {
|
|
71
|
+
var i = 0;
|
|
72
|
+
var points = this.points;
|
|
73
|
+
var vertices = this.vertices;
|
|
74
|
+
var indices = earcut(points.flatMap(p => [p.x, p.y]));
|
|
75
|
+
|
|
76
|
+
// calculate all vertices
|
|
77
|
+
for (i = 0; i < indices.length; i++ ) {
|
|
78
|
+
if (typeof vertices[i] === "undefined") {
|
|
79
|
+
// increase cache buffer if necessary
|
|
80
|
+
vertices[i] = pool.pull("Vector2d");
|
|
81
|
+
}
|
|
82
|
+
vertices[i].set(points[indices[i]].x, points[indices[i]].y);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// recycle overhead from a previous triangulation
|
|
86
|
+
while (vertices.length > indices.length) {
|
|
87
|
+
pool.push(vertices[vertices.length-1]);
|
|
88
|
+
vertices.length -= 1;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return vertices;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* moves the starting point of the current path to the (x, y) coordinates.
|
|
96
|
+
* @name moveTo
|
|
97
|
+
* @memberof Path2D
|
|
98
|
+
* @function
|
|
99
|
+
* @param {number} x the x-axis (horizontal) coordinate of the point.
|
|
100
|
+
* @param {number} y the y-axis (vertical) coordinate of the point.
|
|
101
|
+
*/
|
|
102
|
+
moveTo(x, y) {
|
|
103
|
+
this.points.push(pool.pull("Vector2d", x, y));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* connects the last point in the current patch to the (x, y) coordinates with a straight line.
|
|
108
|
+
* @name lineTo
|
|
109
|
+
* @memberof Path2D
|
|
110
|
+
* @function
|
|
111
|
+
* @param {number} x the x-axis coordinate of the line's end point.
|
|
112
|
+
* @param {number} y the y-axis coordinate of the line's end point.
|
|
113
|
+
*/
|
|
114
|
+
lineTo(x, y) {
|
|
115
|
+
this.points.push(pool.pull("Vector2d", x, y));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* adds an arc to the current path which is centered at (x, y) position with the given radius,
|
|
120
|
+
* starting at startAngle and ending at endAngle going in the given direction by counterclockwise (defaulting to clockwise).
|
|
121
|
+
* @name arc
|
|
122
|
+
* @memberof Path2D
|
|
123
|
+
* @function
|
|
124
|
+
* @param {number} x the horizontal coordinate of the arc's center.
|
|
125
|
+
* @param {number} y the vertical coordinate of the arc's center.
|
|
126
|
+
* @param {number} radius the arc's radius. Must be positive.
|
|
127
|
+
* @param {number} startAngle the angle at which the arc starts in radians, measured from the positive x-axis.
|
|
128
|
+
* @param {number} endAngle the angle at which the arc ends in radians, measured from the positive x-axis.
|
|
129
|
+
* @param {boolean} [anticlockwise=false] an optional boolean value. If true, draws the arc counter-clockwise between the start and end angles.
|
|
130
|
+
*/
|
|
131
|
+
arc(x, y, radius, startAngle, endAngle, anticlockwise = false) {
|
|
132
|
+
var points = this.points;
|
|
133
|
+
// based on from https://github.com/karellodewijk/canvas-webgl/blob/master/canvas-webgl.js
|
|
134
|
+
//bring angles all in [0, 2*PI] range
|
|
135
|
+
if (startAngle === endAngle) return;
|
|
136
|
+
var fullCircle = anticlockwise ? Math.abs(startAngle-endAngle) >= (TAU) : Math.abs(endAngle-startAngle) >= (TAU);
|
|
137
|
+
|
|
138
|
+
startAngle = startAngle % (TAU);
|
|
139
|
+
endAngle = endAngle % (TAU);
|
|
140
|
+
|
|
141
|
+
if (startAngle < 0) startAngle += TAU;
|
|
142
|
+
if (endAngle < 0) endAngle += TAU;
|
|
143
|
+
|
|
144
|
+
if (startAngle >= endAngle) {
|
|
145
|
+
endAngle+= TAU;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
var diff = endAngle - startAngle;
|
|
149
|
+
var direction = 1;
|
|
150
|
+
if (anticlockwise) {
|
|
151
|
+
direction = -1;
|
|
152
|
+
diff = TAU - diff;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
if (fullCircle) diff = TAU;
|
|
156
|
+
|
|
157
|
+
var length = diff * radius;
|
|
158
|
+
var nr_of_interpolation_points = length / this.arcResolution;
|
|
159
|
+
var dangle = diff / nr_of_interpolation_points;
|
|
160
|
+
|
|
161
|
+
var angle = startAngle;
|
|
162
|
+
for (var j = 0; j < nr_of_interpolation_points; j++) {
|
|
163
|
+
points.push(pool.pull("Vector2d", x + radius * Math.cos(angle), y + radius * Math.sin(angle)));
|
|
164
|
+
angle += direction * dangle;
|
|
165
|
+
}
|
|
166
|
+
points.push(pool.pull("Vector2d", x + radius * Math.cos(endAngle), y + radius * Math.sin(endAngle)));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* adds a circular arc to the path with the given control points and radius, connected to the previous point by a straight line.
|
|
171
|
+
* @name arcTo
|
|
172
|
+
* @memberof Path2D
|
|
173
|
+
* @function
|
|
174
|
+
* @param {number} x the x-axis coordinate of the first control point.
|
|
175
|
+
* @param {number} y the y-axis coordinate of the first control point.
|
|
176
|
+
* @param {number} x the x-axis coordinate of the second control point.
|
|
177
|
+
* @param {number} y the y-axis coordinate of the second control point.
|
|
178
|
+
* @param {number} radius the arc's radius. Must be positive.
|
|
179
|
+
*/
|
|
180
|
+
arcTo(x1, y1, x2, y2, radius) {
|
|
181
|
+
var points = this.points;
|
|
182
|
+
// based on from https://github.com/karellodewijk/canvas-webgl/blob/master/canvas-webgl.js
|
|
183
|
+
var x0 = points[points.length-1].x, y0 = points[points.length-1].y;
|
|
184
|
+
|
|
185
|
+
//a = -incoming vector, b = outgoing vector to x1, y1
|
|
186
|
+
var a = [x0 - x1, y0 - y1];
|
|
187
|
+
var b = [x2 - x1, y2 - y1];
|
|
188
|
+
|
|
189
|
+
//normalize
|
|
190
|
+
var l_a = Math.sqrt(Math.pow(a[0], 2) + Math.pow(a[1], 2));
|
|
191
|
+
var l_b = Math.sqrt(Math.pow(b[0], 2) + Math.pow(b[1], 2));
|
|
192
|
+
a[0] /= l_a; a[1] /= l_a; b[0] /= l_b; b[1] /= l_b;
|
|
193
|
+
var angle = Math.atan2(a[1], a[0]) - Math.atan2(b[1], b[0]);
|
|
194
|
+
|
|
195
|
+
//work out tangent points using tan(θ) = opposite / adjacent; angle/2 because hypotenuse is the bisection of a,b
|
|
196
|
+
var tan_angle_div2 = Math.tan(angle/2);
|
|
197
|
+
var adj_l = (radius/tan_angle_div2);
|
|
198
|
+
|
|
199
|
+
var tangent_point1 = [x1 + a[0] * adj_l, y1 + a[1] * adj_l];
|
|
200
|
+
var tangent_point2 = [x1 + b[0] * adj_l, y1 + b[1] * adj_l];
|
|
201
|
+
|
|
202
|
+
points.push(pool.pull("Vector2d", tangent_point1[0], tangent_point1[1]));
|
|
203
|
+
|
|
204
|
+
var bisec = [(a[0] + b[0]) / 2.0, (a[1] + b[1]) / 2.0];
|
|
205
|
+
var bisec_l = Math.sqrt(Math.pow(bisec[0], 2) + Math.pow(bisec[1], 2));
|
|
206
|
+
bisec[0] /= bisec_l; bisec[1] /= bisec_l;
|
|
207
|
+
|
|
208
|
+
var hyp_l = Math.sqrt(Math.pow(radius, 2) + Math.pow(adj_l, 2));
|
|
209
|
+
var center = [x1 + hyp_l * bisec[0], y1 + hyp_l * bisec[1]];
|
|
210
|
+
|
|
211
|
+
var startAngle = Math.atan2(tangent_point1[1] - center[1], tangent_point1[0] - center[0]);
|
|
212
|
+
var endAngle = Math.atan2(tangent_point2[1] - center[1], tangent_point2[0] - center[0]);
|
|
213
|
+
|
|
214
|
+
this.arc(center[0], center[1], radius, startAngle, endAngle);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* adds an elliptical arc to the path which is centered at (x, y) position with the radii radiusX and radiusY
|
|
219
|
+
* starting at startAngle and ending at endAngle going in the given direction by counterclockwise.
|
|
220
|
+
* @name ellipse
|
|
221
|
+
* @memberof Path2D
|
|
222
|
+
* @function
|
|
223
|
+
* @param {number} x the x-axis (horizontal) coordinate of the ellipse's center.
|
|
224
|
+
* @param {number} y the y-axis (vertical) coordinate of the ellipse's center.
|
|
225
|
+
* @param {number} radiusX the ellipse's major-axis radius. Must be non-negative.
|
|
226
|
+
* @param {number} radiusY the ellipse's minor-axis radius. Must be non-negative.
|
|
227
|
+
* @param {number} rotation the rotation of the ellipse, expressed in radians.
|
|
228
|
+
* @param {number} startAngle the angle at which the ellipse starts, measured clockwise from the positive x-axis and expressed in radians.
|
|
229
|
+
* @param {number} endAngle the angle at which the ellipse ends, measured clockwise from the positive x-axis and expressed in radians.
|
|
230
|
+
* @param {boolean} [anticlockwise=false] an optional boolean value which, if true, draws the ellipse counterclockwise (anticlockwise).
|
|
231
|
+
*/
|
|
232
|
+
ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise = false) {
|
|
233
|
+
var points = this.points;
|
|
234
|
+
// based on from https://github.com/karellodewijk/canvas-webgl/blob/master/canvas-webgl.js
|
|
235
|
+
if (startAngle === endAngle) return;
|
|
236
|
+
var fullCircle = anticlockwise ? Math.abs(startAngle-endAngle) >= (TAU) : Math.abs(endAngle-startAngle) >= (TAU);
|
|
237
|
+
|
|
238
|
+
//bring angles all in [0, 2*PI] range
|
|
239
|
+
startAngle = startAngle % (TAU);
|
|
240
|
+
endAngle = endAngle % (TAU);
|
|
241
|
+
if (startAngle < 0) startAngle += TAU;
|
|
242
|
+
if (endAngle < 0) endAngle += TAU;
|
|
243
|
+
|
|
244
|
+
if (startAngle>=endAngle) {
|
|
245
|
+
endAngle += TAU;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
var diff = endAngle - startAngle;
|
|
249
|
+
|
|
250
|
+
var direction = 1;
|
|
251
|
+
if (anticlockwise) {
|
|
252
|
+
direction = -1;
|
|
253
|
+
diff = TAU - diff;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (fullCircle) diff = TAU;
|
|
257
|
+
|
|
258
|
+
var length = (diff * radiusX + diff * radiusY) / 2;
|
|
259
|
+
var nr_of_interpolation_points = length / this.arcResolution;
|
|
260
|
+
var dangle = diff / nr_of_interpolation_points;
|
|
261
|
+
|
|
262
|
+
var angle = startAngle;
|
|
263
|
+
var cos_rotation = Math.cos(rotation);
|
|
264
|
+
var sin_rotation = Math.sin(rotation);
|
|
265
|
+
for (var j = 0; j < nr_of_interpolation_points; j++) {
|
|
266
|
+
var _x1 = radiusX * Math.cos(angle);
|
|
267
|
+
var _y1 = radiusY * Math.sin(angle);
|
|
268
|
+
var _x2 = x + _x1 * cos_rotation - _y1 * sin_rotation;
|
|
269
|
+
var _y2 = y + _x1 * sin_rotation + _y1 * cos_rotation;
|
|
270
|
+
points.push(pool.pull("Vector2d", _x2, _y2));
|
|
271
|
+
angle += direction * dangle;
|
|
272
|
+
}
|
|
273
|
+
//var x1 = radiusX * Math.cos(endAngle);
|
|
274
|
+
//var y1 = radiusY * Math.sin(endAngle);
|
|
275
|
+
//points.push(pool.pull("Vector2d", x + x1 * cos_rotation - y1 * sin_rotation, y + x1 * sin_rotation + y1 * cos_rotation));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* creates a path for a rectangle at position (x, y) with a size that is determined by width and height.
|
|
280
|
+
* @name rect
|
|
281
|
+
* @memberof Path2D
|
|
282
|
+
* @function
|
|
283
|
+
* @param {number} x the x-axis coordinate of the rectangle's starting point.
|
|
284
|
+
* @param {number} y the y-axis coordinate of the rectangle's starting point.
|
|
285
|
+
* @param {number} width the rectangle's width. Positive values are to the right, and negative to the left.
|
|
286
|
+
* @param {number} height the rectangle's height. Positive values are down, and negative are up.
|
|
287
|
+
*/
|
|
288
|
+
rect(x, y, width, height) {
|
|
289
|
+
this.moveTo(x, y);
|
|
290
|
+
this.lineTo(x + width, y);
|
|
291
|
+
this.lineTo(x + width, y + height);
|
|
292
|
+
this.lineTo(x, y + height);
|
|
293
|
+
this.lineTo(x, y);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
/**
|
|
297
|
+
* adds an rounded rectangle to the current path.
|
|
298
|
+
* @name roundRect
|
|
299
|
+
* @memberof Path2D
|
|
300
|
+
* @function
|
|
301
|
+
* @param {number} x the x-axis coordinate of the rectangle's starting point.
|
|
302
|
+
* @param {number} y the y-axis coordinate of the rectangle's starting point.
|
|
303
|
+
* @param {number} width the rectangle's width. Positive values are to the right, and negative to the left.
|
|
304
|
+
* @param {number} height the rectangle's height. Positive values are down, and negative are up.
|
|
305
|
+
* @param {number} radius the arc's radius to draw the borders. Must be positive.
|
|
306
|
+
*/
|
|
307
|
+
roundRect(x, y, width, height, radius) {
|
|
308
|
+
this.moveTo(x + radius, y);
|
|
309
|
+
this.lineTo(x + width - radius, y);
|
|
310
|
+
this.arcTo(x + width, y, x + width, y + radius, radius);
|
|
311
|
+
this.lineTo(x + width, y + height - radius);
|
|
312
|
+
this.arcTo(x + width, y + height, x + width - radius, y + height, radius);
|
|
313
|
+
this.lineTo(x + radius, y + height);
|
|
314
|
+
this.arcTo(x, y + height, x, y + height - radius, radius);
|
|
315
|
+
this.lineTo(x, y + radius);
|
|
316
|
+
this.arcTo(x, y, x + radius, y, radius);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
export default Path2D;
|