melonjs 10.8.0 → 10.9.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/dist/melonjs.js +393 -49
- package/dist/melonjs.min.js +3 -3
- package/dist/melonjs.module.d.ts +24 -137
- package/dist/melonjs.module.js +367 -39
- package/package.json +5 -5
- package/src/geometries/roundrect.js +98 -1
- package/src/input/gamepad.js +2 -2
- package/src/polyfill/index.js +1 -0
- package/src/polyfill/roundrect.js +235 -0
- package/src/renderable/renderable.js +1 -1
- package/src/utils/utils.js +2 -2
- package/src/video/canvas/canvas_renderer.js +8 -18
- package/src/video/renderer.js +15 -7
- package/src/video/webgl/utils/uniforms.js +1 -1
- package/src/video/webgl/webgl_renderer.js +1 -1
|
@@ -52,6 +52,103 @@ class RoundRect extends Rect {
|
|
|
52
52
|
this._radius = value;
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
/**
|
|
56
|
+
* copy the position, size and radius of the given rounded rectangle into this one
|
|
57
|
+
* @name copy
|
|
58
|
+
* @memberof RoundRect.prototype
|
|
59
|
+
* @function
|
|
60
|
+
* @param {RoundRect} rrect source rounded rectangle
|
|
61
|
+
* @returns {RoundRect} new rectangle
|
|
62
|
+
*/
|
|
63
|
+
copy(rrect) {
|
|
64
|
+
super.setShape(rrect.pos.x, rrect.pos.y, rrect.width, rrect.height);
|
|
65
|
+
this.radius = rrect.radius;
|
|
66
|
+
return this;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Returns true if the rounded rectangle contains the given point
|
|
71
|
+
* @name contains
|
|
72
|
+
* @memberof RoundRect.prototype
|
|
73
|
+
* @function
|
|
74
|
+
* @param {number} x x coordinate
|
|
75
|
+
* @param {number} y y coordinate
|
|
76
|
+
* @returns {boolean} true if contains
|
|
77
|
+
*/
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Returns true if the rounded rectangle contains the given point
|
|
81
|
+
* @name contains
|
|
82
|
+
* @memberof RoundRect.prototype
|
|
83
|
+
* @function
|
|
84
|
+
* @param {Vector2d} point
|
|
85
|
+
* @returns {boolean} true if contains
|
|
86
|
+
*/
|
|
87
|
+
contains() {
|
|
88
|
+
var arg0 = arguments[0];
|
|
89
|
+
var _x, _y;
|
|
90
|
+
if (arguments.length === 2) {
|
|
91
|
+
// x, y
|
|
92
|
+
_x = arg0;
|
|
93
|
+
_y = arguments[1];
|
|
94
|
+
} else {
|
|
95
|
+
if (arg0 instanceof Rect) {
|
|
96
|
+
// good enough
|
|
97
|
+
return super.contains(arg0);
|
|
98
|
+
} else {
|
|
99
|
+
// vector
|
|
100
|
+
_x = arg0.x;
|
|
101
|
+
_y = arg0.y;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// check whether point is outside the bounding box
|
|
106
|
+
if (_x < this.left || _x >= this.right || _y < this.top || _y >= this.bottom) {
|
|
107
|
+
return false; // outside bounding box
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// check whether point is within the bounding box minus radius
|
|
111
|
+
if ((_x >= this.left + this.radius && _x <= this.right - this.radius) || (_y >= this.top + this.radius && _y <= this.bottom - this.radius)) {
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// check whether point is in one of the rounded corner areas
|
|
116
|
+
var tx, ty;
|
|
117
|
+
var radiusX = Math.max(0, Math.min(this.radius, this.width / 2));
|
|
118
|
+
var radiusY = Math.max(0, Math.min(this.radius, this.height / 2));
|
|
119
|
+
|
|
120
|
+
if (_x < this.left + radiusX && _y < this.top + radiusY) {
|
|
121
|
+
tx = _x - this.left - radiusX;
|
|
122
|
+
ty = _y - this.top - radiusY;
|
|
123
|
+
} else if (_x > this.right - radiusX && _y < this.top + radiusY) {
|
|
124
|
+
tx = _x - this.right + radiusX;
|
|
125
|
+
ty = _y - this.top - radiusY;
|
|
126
|
+
} else if (_x > this.right - radiusX && _y > this.bottom - radiusY) {
|
|
127
|
+
tx = _x - this.right + radiusX;
|
|
128
|
+
ty = _y - this.bottom + radiusY;
|
|
129
|
+
} else if (_x < this.left + radiusX && _y > this.bottom - radiusY) {
|
|
130
|
+
tx = _x - this.left - radiusX;
|
|
131
|
+
ty = _y - this.bottom + radiusY;
|
|
132
|
+
} else {
|
|
133
|
+
return false; // inside and not within the rounded corner area
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Pythagorean theorem.
|
|
137
|
+
return ((tx * tx) + (ty * ty) <= (radiusX * radiusY));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* check if this RoundRect is identical to the specified one
|
|
142
|
+
* @name equals
|
|
143
|
+
* @memberof RoundRect.prototype
|
|
144
|
+
* @function
|
|
145
|
+
* @param {RoundRect} rrect
|
|
146
|
+
* @returns {boolean} true if equals
|
|
147
|
+
*/
|
|
148
|
+
equals(rrect) {
|
|
149
|
+
return super.equals(rrect) && this.radius === rrect.radius;
|
|
150
|
+
}
|
|
151
|
+
|
|
55
152
|
/**
|
|
56
153
|
* clone this RoundRect
|
|
57
154
|
* @name clone
|
|
@@ -60,7 +157,7 @@ class RoundRect extends Rect {
|
|
|
60
157
|
* @returns {RoundRect} new RoundRect
|
|
61
158
|
*/
|
|
62
159
|
clone() {
|
|
63
|
-
return new RoundRect(this.pos.x, this.pos.y, this.width, this.height,
|
|
160
|
+
return new RoundRect(this.pos.x, this.pos.y, this.width, this.height, radius);
|
|
64
161
|
}
|
|
65
162
|
};
|
|
66
163
|
|
package/src/input/gamepad.js
CHANGED
|
@@ -57,8 +57,8 @@ var leadingZeroRE = /^0+/;
|
|
|
57
57
|
function addMapping(id, mapping) {
|
|
58
58
|
var expanded_id = id.replace(vendorProductRE, function (_, a, b) {
|
|
59
59
|
return (
|
|
60
|
-
"000".
|
|
61
|
-
"000".
|
|
60
|
+
"000".slice(a.length - 1) + a + "-" +
|
|
61
|
+
"000".slice(b.length - 1) + b + "-"
|
|
62
62
|
);
|
|
63
63
|
});
|
|
64
64
|
var sparse_id = id.replace(vendorProductRE, function (_, a, b) {
|
package/src/polyfill/index.js
CHANGED
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* based on https://www.npmjs.com/package/canvas-roundrect-polyfill
|
|
3
|
+
* @version 0.0.1
|
|
4
|
+
*/
|
|
5
|
+
(() => {
|
|
6
|
+
|
|
7
|
+
"use strict";
|
|
8
|
+
|
|
9
|
+
/** @ignore */
|
|
10
|
+
function roundRect(x, y, w, h, radii) {
|
|
11
|
+
|
|
12
|
+
if (!([x, y, w, h].every((input) => Number.isFinite(input)))) {
|
|
13
|
+
|
|
14
|
+
return;
|
|
15
|
+
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
radii = parseRadiiArgument(radii);
|
|
19
|
+
|
|
20
|
+
let upperLeft, upperRight, lowerRight, lowerLeft;
|
|
21
|
+
|
|
22
|
+
if (radii.length === 4) {
|
|
23
|
+
|
|
24
|
+
upperLeft = toCornerPoint(radii[0]);
|
|
25
|
+
upperRight = toCornerPoint(radii[1]);
|
|
26
|
+
lowerRight = toCornerPoint(radii[2]);
|
|
27
|
+
lowerLeft = toCornerPoint(radii[3]);
|
|
28
|
+
|
|
29
|
+
} else if (radii.length === 3) {
|
|
30
|
+
|
|
31
|
+
upperLeft = toCornerPoint(radii[0]);
|
|
32
|
+
upperRight = toCornerPoint(radii[1]);
|
|
33
|
+
lowerLeft = toCornerPoint(radii[1]);
|
|
34
|
+
lowerRight = toCornerPoint(radii[2]);
|
|
35
|
+
|
|
36
|
+
} else if (radii.length === 2) {
|
|
37
|
+
|
|
38
|
+
upperLeft = toCornerPoint(radii[0]);
|
|
39
|
+
lowerRight = toCornerPoint(radii[0]);
|
|
40
|
+
upperRight = toCornerPoint(radii[1]);
|
|
41
|
+
lowerLeft = toCornerPoint(radii[1]);
|
|
42
|
+
|
|
43
|
+
} else if (radii.length === 1) {
|
|
44
|
+
|
|
45
|
+
upperLeft = toCornerPoint(radii[0]);
|
|
46
|
+
upperRight = toCornerPoint(radii[0]);
|
|
47
|
+
lowerRight = toCornerPoint(radii[0]);
|
|
48
|
+
lowerLeft = toCornerPoint(radii[0]);
|
|
49
|
+
|
|
50
|
+
} else {
|
|
51
|
+
|
|
52
|
+
throw new Error(radii.length + " is not a valid size for radii sequence.");
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const corners = [upperLeft, upperRight, lowerRight, lowerLeft];
|
|
57
|
+
const negativeCorner = corners.find(({x, y}) => x < 0 || y < 0);
|
|
58
|
+
//const negativeValue = negativeCorner?.x < 0 ? negativeCorner.x : negativeCorner?.y
|
|
59
|
+
|
|
60
|
+
if (corners.some(({x, y}) => !Number.isFinite(x) || !Number.isFinite(y))) {
|
|
61
|
+
|
|
62
|
+
return;
|
|
63
|
+
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (negativeCorner) {
|
|
67
|
+
|
|
68
|
+
throw new Error("Radius value " + negativeCorner + " is negative.");
|
|
69
|
+
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fixOverlappingCorners(corners);
|
|
73
|
+
|
|
74
|
+
if (w < 0 && h < 0) {
|
|
75
|
+
|
|
76
|
+
this.moveTo(x - upperLeft.x, y);
|
|
77
|
+
this.ellipse(x + w + upperRight.x, y - upperRight.y, upperRight.x, upperRight.y, 0, -Math.PI * 1.5, -Math.PI);
|
|
78
|
+
this.ellipse(x + w + lowerRight.x, y + h + lowerRight.y, lowerRight.x, lowerRight.y, 0, -Math.PI, -Math.PI / 2);
|
|
79
|
+
this.ellipse(x - lowerLeft.x, y + h + lowerLeft.y, lowerLeft.x, lowerLeft.y, 0, -Math.PI / 2, 0);
|
|
80
|
+
this.ellipse(x - upperLeft.x, y - upperLeft.y, upperLeft.x, upperLeft.y, 0, 0, -Math.PI / 2);
|
|
81
|
+
|
|
82
|
+
} else if (w < 0) {
|
|
83
|
+
|
|
84
|
+
this.moveTo(x - upperLeft.x, y);
|
|
85
|
+
this.ellipse(x + w + upperRight.x, y + upperRight.y, upperRight.x, upperRight.y, 0, -Math.PI / 2, -Math.PI, 1);
|
|
86
|
+
this.ellipse(x + w + lowerRight.x, y + h - lowerRight.y, lowerRight.x, lowerRight.y, 0, -Math.PI, -Math.PI * 1.5, 1);
|
|
87
|
+
this.ellipse(x - lowerLeft.x, y + h - lowerLeft.y, lowerLeft.x, lowerLeft.y, 0, Math.PI / 2, 0, 1);
|
|
88
|
+
this.ellipse(x - upperLeft.x, y + upperLeft.y, upperLeft.x, upperLeft.y, 0, 0, -Math.PI / 2, 1);
|
|
89
|
+
|
|
90
|
+
} else if (h < 0) {
|
|
91
|
+
|
|
92
|
+
this.moveTo(x + upperLeft.x, y);
|
|
93
|
+
this.ellipse(x + w - upperRight.x, y - upperRight.y, upperRight.x, upperRight.y, 0, Math.PI / 2, 0, 1);
|
|
94
|
+
this.ellipse(x + w - lowerRight.x, y + h + lowerRight.y, lowerRight.x, lowerRight.y, 0, 0, -Math.PI / 2, 1);
|
|
95
|
+
this.ellipse(x + lowerLeft.x, y + h + lowerLeft.y, lowerLeft.x, lowerLeft.y, 0, -Math.PI / 2, -Math.PI, 1);
|
|
96
|
+
this.ellipse(x + upperLeft.x, y - upperLeft.y, upperLeft.x, upperLeft.y, 0, -Math.PI, -Math.PI * 1.5, 1);
|
|
97
|
+
|
|
98
|
+
} else {
|
|
99
|
+
|
|
100
|
+
this.moveTo(x + upperLeft.x, y);
|
|
101
|
+
this.ellipse(x + w - upperRight.x, y + upperRight.y, upperRight.x, upperRight.y, 0, -Math.PI / 2, 0);
|
|
102
|
+
this.ellipse(x + w - lowerRight.x, y + h - lowerRight.y, lowerRight.x, lowerRight.y, 0, 0, Math.PI / 2);
|
|
103
|
+
this.ellipse(x + lowerLeft.x, y + h - lowerLeft.y, lowerLeft.x, lowerLeft.y, 0, Math.PI / 2, Math.PI);
|
|
104
|
+
this.ellipse(x + upperLeft.x, y + upperLeft.y, upperLeft.x, upperLeft.y, 0, Math.PI, Math.PI * 1.5);
|
|
105
|
+
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this.closePath();
|
|
109
|
+
this.moveTo(x, y);
|
|
110
|
+
|
|
111
|
+
/** @ignore */
|
|
112
|
+
function toDOMPointInit(value) {
|
|
113
|
+
|
|
114
|
+
const {x, y, z, w} = value;
|
|
115
|
+
return {x, y, z, w};
|
|
116
|
+
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** @ignore */
|
|
120
|
+
function parseRadiiArgument(value) {
|
|
121
|
+
|
|
122
|
+
// https://webidl.spec.whatwg.org/#es-union
|
|
123
|
+
// with 'optional (unrestricted double or DOMPointInit
|
|
124
|
+
// or sequence<(unrestricted double or DOMPointInit)>) radii = 0'
|
|
125
|
+
const type = typeof value;
|
|
126
|
+
|
|
127
|
+
if (type === "undefined" || value === null) {
|
|
128
|
+
|
|
129
|
+
return [0];
|
|
130
|
+
|
|
131
|
+
}
|
|
132
|
+
if (type === "function") {
|
|
133
|
+
|
|
134
|
+
return [NaN];
|
|
135
|
+
|
|
136
|
+
}
|
|
137
|
+
if (type === "object") {
|
|
138
|
+
|
|
139
|
+
if (typeof value[Symbol.iterator] === "function") {
|
|
140
|
+
|
|
141
|
+
return [...value].map((elem) => {
|
|
142
|
+
// https://webidl.spec.whatwg.org/#es-union
|
|
143
|
+
// with '(unrestricted double or DOMPointInit)'
|
|
144
|
+
const elemType = typeof elem;
|
|
145
|
+
if (elemType === "undefined" || elem === null) {
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
if (elemType === "function") {
|
|
149
|
+
return NaN;
|
|
150
|
+
}
|
|
151
|
+
if (elemType === "object") {
|
|
152
|
+
return toDOMPointInit(elem);
|
|
153
|
+
}
|
|
154
|
+
return toUnrestrictedNumber(elem);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
return [toDOMPointInit(value)];
|
|
160
|
+
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return [toUnrestrictedNumber(value)];
|
|
164
|
+
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/** @ignore */
|
|
168
|
+
function toUnrestrictedNumber(value) {
|
|
169
|
+
|
|
170
|
+
return +value;
|
|
171
|
+
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** @ignore */
|
|
175
|
+
function toCornerPoint(value) {
|
|
176
|
+
|
|
177
|
+
const asNumber = toUnrestrictedNumber(value);
|
|
178
|
+
if (Number.isFinite(asNumber)) {
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
x: asNumber,
|
|
182
|
+
y: asNumber
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
}
|
|
186
|
+
if (Object(value) === value) {
|
|
187
|
+
|
|
188
|
+
return {
|
|
189
|
+
x: toUnrestrictedNumber(value.x || 0),
|
|
190
|
+
y: toUnrestrictedNumber(value.y || 0)
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
x: NaN,
|
|
197
|
+
y: NaN
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
/** @ignore */
|
|
203
|
+
function fixOverlappingCorners(corners) {
|
|
204
|
+
const [upperLeft, upperRight, lowerRight, lowerLeft] = corners;
|
|
205
|
+
const factors = [
|
|
206
|
+
Math.abs(w) / (upperLeft.x + upperRight.x),
|
|
207
|
+
Math.abs(h) / (upperRight.y + lowerRight.y),
|
|
208
|
+
Math.abs(w) / (lowerRight.x + lowerLeft.x),
|
|
209
|
+
Math.abs(h) / (upperLeft.y + lowerLeft.y)
|
|
210
|
+
];
|
|
211
|
+
const minFactor = Math.min(...factors);
|
|
212
|
+
if (minFactor <= 1) {
|
|
213
|
+
corners.forEach((radii) => {
|
|
214
|
+
radii.x *= minFactor;
|
|
215
|
+
radii.y *= minFactor;
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
if (typeof Path2D.prototype.roundRect === "undefined") {
|
|
222
|
+
Path2D.prototype.roundRect = roundRect;
|
|
223
|
+
}
|
|
224
|
+
if (globalThis.CanvasRenderingContext2D) {
|
|
225
|
+
if (typeof globalThis.CanvasRenderingContext2D.prototype.roundRect === "undefined") {
|
|
226
|
+
globalThis.CanvasRenderingContext2D.prototype.roundRect = roundRect;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (globalThis.OffscreenCanvasRenderingContext2D) {
|
|
230
|
+
if (typeof globalThis.OffscreenCanvasRenderingContext2D.prototype.roundRect === "undefined") {
|
|
231
|
+
globalThis.OffscreenCanvasRenderingContext2D.prototype.roundRect = roundRect;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
})();
|
|
@@ -227,7 +227,7 @@ class Renderable extends Rect {
|
|
|
227
227
|
* A mask limits rendering elements to the shape and position of the given mask object.
|
|
228
228
|
* So, if the renderable is larger than the mask, only the intersecting part of the renderable will be visible.
|
|
229
229
|
* @public
|
|
230
|
-
* @type {Rect|Polygon|Line|Ellipse}
|
|
230
|
+
* @type {Rect|RoundRect|Polygon|Line|Ellipse}
|
|
231
231
|
* @name mask
|
|
232
232
|
* @default undefined
|
|
233
233
|
* @memberof Renderable#
|
package/src/utils/utils.js
CHANGED
|
@@ -120,14 +120,14 @@ var utils = {
|
|
|
120
120
|
// never cache if a url is passed as parameter
|
|
121
121
|
var index = url.indexOf("#");
|
|
122
122
|
if (index !== -1) {
|
|
123
|
-
url = url.
|
|
123
|
+
url = url.slice(index, url.length);
|
|
124
124
|
} else {
|
|
125
125
|
return hash;
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
129
|
// parse the url
|
|
130
|
-
url.
|
|
130
|
+
url.slice(1).split("&").filter(function (value) {
|
|
131
131
|
return (value !== "");
|
|
132
132
|
}).forEach(function (value) {
|
|
133
133
|
var kv = value.split("=");
|
|
@@ -2,6 +2,7 @@ import Color from "./../../math/color.js";
|
|
|
2
2
|
import Renderer from "./../renderer.js";
|
|
3
3
|
import TextureCache from "./../texture_cache.js";
|
|
4
4
|
import Ellipse from "./../../geometries/ellipse.js";
|
|
5
|
+
import RoundRect from "./../../geometries/roundrect.js";
|
|
5
6
|
import { createCanvas } from "./../video.js";
|
|
6
7
|
|
|
7
8
|
|
|
@@ -529,20 +530,7 @@ class CanvasRenderer extends Renderer {
|
|
|
529
530
|
var context = this.getContext();
|
|
530
531
|
|
|
531
532
|
context.beginPath();
|
|
532
|
-
|
|
533
|
-
//https://developer.chrome.com/blog/canvas2d/#round-rect
|
|
534
|
-
context.roundRect(x, y, width, height, radius);
|
|
535
|
-
} else {
|
|
536
|
-
context.moveTo(x + radius, y);
|
|
537
|
-
context.lineTo(x + width - radius, y);
|
|
538
|
-
context.arcTo(x + width, y, x + width, y + radius, radius);
|
|
539
|
-
context.lineTo(x + width, y + height - radius);
|
|
540
|
-
context.arcTo(x + width, y + height, x + width - radius, y + height, radius);
|
|
541
|
-
context.lineTo(x + radius, y + height);
|
|
542
|
-
context.arcTo(x, y + height, x, y + height - radius, radius);
|
|
543
|
-
context.lineTo(x, y + radius);
|
|
544
|
-
context.arcTo(x, y, x + radius, y, radius);
|
|
545
|
-
}
|
|
533
|
+
context.roundRect(x, y, width, height, radius);
|
|
546
534
|
context[fill === true ? "fill" : "stroke"]();
|
|
547
535
|
}
|
|
548
536
|
|
|
@@ -775,7 +763,7 @@ class CanvasRenderer extends Renderer {
|
|
|
775
763
|
* @name setMask
|
|
776
764
|
* @memberof CanvasRenderer.prototype
|
|
777
765
|
* @function
|
|
778
|
-
* @param {Rect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
|
|
766
|
+
* @param {Rect|RoundRect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
|
|
779
767
|
*/
|
|
780
768
|
setMask(mask) {
|
|
781
769
|
var context = this.getContext();
|
|
@@ -783,6 +771,8 @@ class CanvasRenderer extends Renderer {
|
|
|
783
771
|
|
|
784
772
|
context.save();
|
|
785
773
|
|
|
774
|
+
context.beginPath();
|
|
775
|
+
|
|
786
776
|
// https://github.com/melonjs/melonJS/issues/648
|
|
787
777
|
if (mask instanceof Ellipse) {
|
|
788
778
|
var hw = mask.radiusV.x,
|
|
@@ -799,14 +789,14 @@ class CanvasRenderer extends Renderer {
|
|
|
799
789
|
ymin = _y - ymagic,
|
|
800
790
|
ymax = _y + ymagic;
|
|
801
791
|
|
|
802
|
-
context.beginPath();
|
|
803
792
|
context.moveTo(_x, ty);
|
|
804
793
|
context.bezierCurveTo(xmax, ty, rx, ymin, rx, _y);
|
|
805
794
|
context.bezierCurveTo(rx, ymax, xmax, by, _x, by);
|
|
806
795
|
context.bezierCurveTo(xmin, by, lx, ymax, lx, _y);
|
|
807
796
|
context.bezierCurveTo(lx, ymin, xmin, ty, _x, ty);
|
|
797
|
+
} else if (mask instanceof RoundRect) {
|
|
798
|
+
context.roundRect(_x, _y, mask.width, mask.height, mask.radius);
|
|
808
799
|
} else {
|
|
809
|
-
context.beginPath();
|
|
810
800
|
context.moveTo(_x + mask.points[0].x, _y + mask.points[0].y);
|
|
811
801
|
var point;
|
|
812
802
|
for (var i = 1; i < mask.points.length; i++) {
|
|
@@ -826,7 +816,7 @@ class CanvasRenderer extends Renderer {
|
|
|
826
816
|
* @function
|
|
827
817
|
*/
|
|
828
818
|
clearMask() {
|
|
829
|
-
this.
|
|
819
|
+
this.getContext().restore();
|
|
830
820
|
}
|
|
831
821
|
|
|
832
822
|
};
|
package/src/video/renderer.js
CHANGED
|
@@ -345,13 +345,19 @@ class Renderer {
|
|
|
345
345
|
* @param {boolean} [fill=false] fill the shape with the current color if true
|
|
346
346
|
*/
|
|
347
347
|
stroke(shape, fill) {
|
|
348
|
-
if (shape instanceof
|
|
349
|
-
this.strokeRoundRect(shape.left, shape.top, shape.width, shape.height, shape.radius, fill);
|
|
350
|
-
} else if (shape instanceof Rect || shape instanceof Bounds) {
|
|
348
|
+
if (shape instanceof Rect || shape instanceof Bounds) {
|
|
351
349
|
this.strokeRect(shape.left, shape.top, shape.width, shape.height, fill);
|
|
352
|
-
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
if (shape instanceof Line || shape instanceof Polygon) {
|
|
353
353
|
this.strokePolygon(shape, fill);
|
|
354
|
-
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
if (shape instanceof RoundRect) {
|
|
357
|
+
this.strokeRoundRect(shape.left, shape.top, shape.width, shape.height, shape.radius, fill);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (shape instanceof Ellipse) {
|
|
355
361
|
this.strokeEllipse(
|
|
356
362
|
shape.pos.x,
|
|
357
363
|
shape.pos.y,
|
|
@@ -359,7 +365,9 @@ class Renderer {
|
|
|
359
365
|
shape.radiusV.y,
|
|
360
366
|
fill
|
|
361
367
|
);
|
|
368
|
+
return;
|
|
362
369
|
}
|
|
370
|
+
throw new Error("Invalid geometry for fill/stroke");
|
|
363
371
|
}
|
|
364
372
|
|
|
365
373
|
/**
|
|
@@ -367,7 +375,7 @@ class Renderer {
|
|
|
367
375
|
* @name fill
|
|
368
376
|
* @memberof Renderer.prototype
|
|
369
377
|
* @function
|
|
370
|
-
* @param {Rect|Polygon|Line|Ellipse} shape a shape object to fill
|
|
378
|
+
* @param {Rect|RoundRect|Polygon|Line|Ellipse} shape a shape object to fill
|
|
371
379
|
*/
|
|
372
380
|
fill(shape) {
|
|
373
381
|
this.stroke(shape, true);
|
|
@@ -409,7 +417,7 @@ class Renderer {
|
|
|
409
417
|
* @name setMask
|
|
410
418
|
* @memberof Renderer.prototype
|
|
411
419
|
* @function
|
|
412
|
-
* @param {Rect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
|
|
420
|
+
* @param {Rect|RoundRect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
|
|
413
421
|
*/
|
|
414
422
|
// eslint-disable-next-line no-unused-vars
|
|
415
423
|
setMask(mask) {}
|
|
@@ -1097,7 +1097,7 @@ class WebGLRenderer extends Renderer {
|
|
|
1097
1097
|
* @name setMask
|
|
1098
1098
|
* @memberof WebGLRenderer.prototype
|
|
1099
1099
|
* @function
|
|
1100
|
-
* @param {Rect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
|
|
1100
|
+
* @param {Rect|RoundRect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
|
|
1101
1101
|
*/
|
|
1102
1102
|
setMask(mask) {
|
|
1103
1103
|
var gl = this.gl;
|