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.
Files changed (74) hide show
  1. package/LICENSE.md +1 -1
  2. package/README.md +29 -23
  3. package/dist/melonjs.js +2220 -1070
  4. package/dist/melonjs.min.js +4 -4
  5. package/dist/melonjs.module.d.ts +1395 -485
  6. package/dist/melonjs.module.js +2244 -1131
  7. package/package.json +17 -14
  8. package/src/camera/camera2d.js +1 -1
  9. package/src/entity/entity.js +6 -7
  10. package/src/game.js +2 -2
  11. package/src/geometries/ellipse.js +20 -21
  12. package/src/geometries/line.js +7 -7
  13. package/src/geometries/path2d.js +319 -0
  14. package/src/geometries/poly.js +27 -27
  15. package/src/geometries/rectangle.js +19 -19
  16. package/src/geometries/roundrect.js +164 -0
  17. package/src/index.js +12 -2
  18. package/src/input/gamepad.js +2 -2
  19. package/src/input/pointerevent.js +1 -1
  20. package/src/lang/deprecated.js +8 -6
  21. package/src/level/tiled/TMXLayer.js +1 -1
  22. package/src/level/tiled/TMXObject.js +9 -12
  23. package/src/level/tiled/TMXTileMap.js +23 -4
  24. package/src/level/tiled/TMXUtils.js +1 -1
  25. package/src/level/tiled/renderer/TMXHexagonalRenderer.js +1 -1
  26. package/src/level/tiled/renderer/TMXIsometricRenderer.js +1 -1
  27. package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +1 -1
  28. package/src/level/tiled/renderer/TMXRenderer.js +1 -1
  29. package/src/level/tiled/renderer/TMXStaggeredRenderer.js +1 -1
  30. package/src/loader/loader.js +4 -4
  31. package/src/loader/loadingscreen.js +17 -6
  32. package/src/math/color.js +6 -5
  33. package/src/math/matrix2.js +1 -1
  34. package/src/math/matrix3.js +1 -1
  35. package/src/math/observable_vector2.js +1 -1
  36. package/src/math/observable_vector3.js +1 -1
  37. package/src/math/vector2.js +1 -1
  38. package/src/math/vector3.js +1 -1
  39. package/src/particles/emitter.js +34 -26
  40. package/src/particles/particle.js +3 -2
  41. package/src/physics/body.js +67 -51
  42. package/src/physics/bounds.js +8 -9
  43. package/src/physics/world.js +1 -1
  44. package/src/polyfill/index.js +1 -0
  45. package/src/polyfill/roundrect.js +235 -0
  46. package/src/renderable/GUI.js +5 -5
  47. package/src/renderable/collectable.js +9 -2
  48. package/src/renderable/colorlayer.js +1 -1
  49. package/src/renderable/container.js +27 -27
  50. package/src/renderable/imagelayer.js +3 -3
  51. package/src/renderable/light2d.js +115 -0
  52. package/src/renderable/renderable.js +23 -22
  53. package/src/renderable/sprite.js +15 -16
  54. package/src/renderable/trigger.js +10 -4
  55. package/src/state/stage.js +73 -3
  56. package/src/state/state.js +1 -1
  57. package/src/system/device.js +10 -8
  58. package/src/system/pooling.js +156 -149
  59. package/src/text/bitmaptext.js +1 -1
  60. package/src/text/text.js +14 -18
  61. package/src/utils/utils.js +2 -2
  62. package/src/video/canvas/canvas_renderer.js +144 -81
  63. package/src/video/renderer.js +64 -37
  64. package/src/video/{texture.js → texture/atlas.js} +8 -8
  65. package/src/video/{texture_cache.js → texture/cache.js} +4 -4
  66. package/src/video/texture/canvas_texture.js +87 -0
  67. package/src/video/webgl/glshader.js +29 -193
  68. package/src/video/webgl/utils/attributes.js +16 -0
  69. package/src/video/webgl/utils/precision.js +11 -0
  70. package/src/video/webgl/utils/program.js +58 -0
  71. package/src/video/webgl/utils/string.js +16 -0
  72. package/src/video/webgl/utils/uniforms.js +87 -0
  73. package/src/video/webgl/webgl_compositor.js +1 -14
  74. package/src/video/webgl/webgl_renderer.js +191 -231
@@ -1,7 +1,9 @@
1
1
  import Color from "./../../math/color.js";
2
2
  import Renderer from "./../renderer.js";
3
- import TextureCache from "./../texture_cache.js";
3
+ import TextureCache from "./../texture/cache.js";
4
4
  import Ellipse from "./../../geometries/ellipse.js";
5
+ import RoundRect from "./../../geometries/roundrect.js";
6
+ import Bounds from "./../../physics/bounds.js";
5
7
  import { createCanvas } from "./../video.js";
6
8
 
7
9
 
@@ -71,7 +73,7 @@ class CanvasRenderer extends Renderer {
71
73
  /**
72
74
  * Reset context state
73
75
  * @name reset
74
- * @memberof CanvasRenderer.prototype
76
+ * @memberof CanvasRenderer
75
77
  * @function
76
78
  */
77
79
  reset() {
@@ -82,7 +84,7 @@ class CanvasRenderer extends Renderer {
82
84
  /**
83
85
  * Reset the canvas transform to identity
84
86
  * @name resetTransform
85
- * @memberof CanvasRenderer.prototype
87
+ * @memberof CanvasRenderer
86
88
  * @function
87
89
  */
88
90
  resetTransform() {
@@ -102,7 +104,7 @@ class CanvasRenderer extends Renderer {
102
104
  * <img src="images/screen-blendmode.png" width="510"/> <br>
103
105
  * @name setBlendMode
104
106
  * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
105
- * @memberof CanvasRenderer.prototype
107
+ * @memberof CanvasRenderer
106
108
  * @function
107
109
  * @param {string} [mode="normal"] blend mode : "normal", "multiply", "lighter, "additive", "screen"
108
110
  * @param {CanvasRenderingContext2D} [context]
@@ -140,7 +142,7 @@ class CanvasRenderer extends Renderer {
140
142
  /**
141
143
  * prepare the framebuffer for drawing a new frame
142
144
  * @name clear
143
- * @memberof CanvasRenderer.prototype
145
+ * @memberof CanvasRenderer
144
146
  * @function
145
147
  */
146
148
  clear() {
@@ -152,7 +154,7 @@ class CanvasRenderer extends Renderer {
152
154
  /**
153
155
  * render the main framebuffer on screen
154
156
  * @name flush
155
- * @memberof CanvasRenderer.prototype
157
+ * @memberof CanvasRenderer
156
158
  * @function
157
159
  */
158
160
  flush() {
@@ -164,7 +166,7 @@ class CanvasRenderer extends Renderer {
164
166
  /**
165
167
  * Clears the main framebuffer with the given color
166
168
  * @name clearColor
167
- * @memberof CanvasRenderer.prototype
169
+ * @memberof CanvasRenderer
168
170
  * @function
169
171
  * @param {Color|string} [color="#000000"] CSS color.
170
172
  * @param {boolean} [opaque=false] Allow transparency [default] or clear the surface completely [true]
@@ -181,7 +183,7 @@ class CanvasRenderer extends Renderer {
181
183
  /**
182
184
  * Erase the pixels in the given rectangular area by setting them to transparent black (rgba(0,0,0,0)).
183
185
  * @name clearRect
184
- * @memberof CanvasRenderer.prototype
186
+ * @memberof CanvasRenderer
185
187
  * @function
186
188
  * @param {number} x x axis of the coordinate for the rectangle starting point.
187
189
  * @param {number} y y axis of the coordinate for the rectangle starting point.
@@ -189,13 +191,13 @@ class CanvasRenderer extends Renderer {
189
191
  * @param {number} height The rectangle's height.
190
192
  */
191
193
  clearRect(x, y, width, height) {
192
- this.backBufferContext2D.clearRect(x, y, width, height);
194
+ this.getContext().clearRect(x, y, width, height);
193
195
  }
194
196
 
195
197
  /**
196
198
  * Create a pattern with the specified repetition
197
199
  * @name createPattern
198
- * @memberof CanvasRenderer.prototype
200
+ * @memberof CanvasRenderer
199
201
  * @function
200
202
  * @param {Image} image Source image
201
203
  * @param {string} repeat Define how the pattern should be repeated
@@ -208,13 +210,13 @@ class CanvasRenderer extends Renderer {
208
210
  * var basic = renderer.createPattern(image, "no-repeat");
209
211
  */
210
212
  createPattern(image, repeat) {
211
- return this.backBufferContext2D.createPattern(image, repeat);
213
+ return this.getContext().createPattern(image, repeat);
212
214
  }
213
215
 
214
216
  /**
215
217
  * Draw an image onto the main using the canvas api
216
218
  * @name drawImage
217
- * @memberof CanvasRenderer.prototype
219
+ * @memberof CanvasRenderer
218
220
  * @function
219
221
  * @param {Image} image An element to draw into the context. The specification permits any canvas image source (CanvasImageSource), specifically, a CSSImageValue, an HTMLImageElement, an SVGImageElement, an HTMLVideoElement, an HTMLCanvasElement, an ImageBitmap, or an OffscreenCanvas.
220
222
  * @param {number} sx The X coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.
@@ -234,10 +236,11 @@ class CanvasRenderer extends Renderer {
234
236
  * renderer.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
235
237
  */
236
238
  drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
237
- if (this.backBufferContext2D.globalAlpha < 1 / 255) {
239
+ if (this.getGlobalAlpha() < 1 / 255) {
238
240
  // Fast path: don't draw fully transparent
239
241
  return;
240
242
  }
243
+ var context = this.getContext();
241
244
 
242
245
  if (typeof sw === "undefined") {
243
246
  sw = dw = image.width;
@@ -271,13 +274,13 @@ class CanvasRenderer extends Renderer {
271
274
  // get a tinted version of this image from the texture cache
272
275
  source = this.cache.tint(image, this.currentTint.toRGB());
273
276
  }
274
- this.backBufferContext2D.drawImage(source, sx, sy, sw, sh, dx, dy, dw, dh);
277
+ context.drawImage(source, sx, sy, sw, sh, dx, dy, dw, dh);
275
278
  }
276
279
 
277
280
  /**
278
281
  * Draw a pattern within the given rectangle.
279
282
  * @name drawPattern
280
- * @memberof CanvasRenderer.prototype
283
+ * @memberof CanvasRenderer
281
284
  * @function
282
285
  * @param {CanvasPattern} pattern Pattern object
283
286
  * @param {number} x
@@ -287,20 +290,21 @@ class CanvasRenderer extends Renderer {
287
290
  * @see CanvasRenderer#createPattern
288
291
  */
289
292
  drawPattern(pattern, x, y, width, height) {
290
- if (this.backBufferContext2D.globalAlpha < 1 / 255) {
293
+ if (this.getGlobalAlpha() < 1 / 255) {
291
294
  // Fast path: don't draw fully transparent
292
295
  return;
293
296
  }
294
- var fillStyle = this.backBufferContext2D.fillStyle;
295
- this.backBufferContext2D.fillStyle = pattern;
296
- this.backBufferContext2D.fillRect(x, y, width, height);
297
- this.backBufferContext2D.fillStyle = fillStyle;
297
+ var context = this.getContext();
298
+ var fillStyle = context.fillStyle;
299
+ context.fillStyle = pattern;
300
+ context.fillRect(x, y, width, height);
301
+ context.fillStyle = fillStyle;
298
302
  }
299
303
 
300
304
  /**
301
305
  * Stroke an arc at the specified coordinates with given radius, start and end points
302
306
  * @name strokeArc
303
- * @memberof CanvasRenderer.prototype
307
+ * @memberof CanvasRenderer
304
308
  * @function
305
309
  * @param {number} x arc center point x-axis
306
310
  * @param {number} y arc center point y-axis
@@ -311,12 +315,12 @@ class CanvasRenderer extends Renderer {
311
315
  * @param {boolean} [fill=false] also fill the shape with the current color if true
312
316
  */
313
317
  strokeArc(x, y, radius, start, end, antiClockwise, fill = false) {
314
- var context = this.backBufferContext2D;
315
-
316
- if (context.globalAlpha < 1 / 255) {
318
+ if (this.getGlobalAlpha() < 1 / 255) {
317
319
  // Fast path: don't draw fully transparent
318
320
  return;
319
321
  }
322
+ var context = this.getContext();
323
+
320
324
  context.translate(x, y);
321
325
  context.beginPath();
322
326
  context.arc(0, 0, radius, start, end, antiClockwise || false);
@@ -327,7 +331,7 @@ class CanvasRenderer extends Renderer {
327
331
  /**
328
332
  * Fill an arc at the specified coordinates with given radius, start and end points
329
333
  * @name fillArc
330
- * @memberof CanvasRenderer.prototype
334
+ * @memberof CanvasRenderer
331
335
  * @function
332
336
  * @param {number} x arc center point x-axis
333
337
  * @param {number} y arc center point y-axis
@@ -343,7 +347,7 @@ class CanvasRenderer extends Renderer {
343
347
  /**
344
348
  * Stroke an ellipse at the specified coordinates with given radius
345
349
  * @name strokeEllipse
346
- * @memberof CanvasRenderer.prototype
350
+ * @memberof CanvasRenderer
347
351
  * @function
348
352
  * @param {number} x ellipse center point x-axis
349
353
  * @param {number} y ellipse center point y-axis
@@ -352,12 +356,11 @@ class CanvasRenderer extends Renderer {
352
356
  * @param {boolean} [fill=false] also fill the shape with the current color if true
353
357
  */
354
358
  strokeEllipse(x, y, w, h, fill = false) {
355
- var context = this.backBufferContext2D;
356
-
357
- if (context.globalAlpha < 1 / 255) {
359
+ if (this.getGlobalAlpha() < 1 / 255) {
358
360
  // Fast path: don't draw fully transparent
359
361
  return;
360
362
  }
363
+ var context = this.getContext();
361
364
 
362
365
  var hw = w,
363
366
  hh = h,
@@ -386,7 +389,7 @@ class CanvasRenderer extends Renderer {
386
389
  /**
387
390
  * Fill an ellipse at the specified coordinates with given radius
388
391
  * @name fillEllipse
389
- * @memberof CanvasRenderer.prototype
392
+ * @memberof CanvasRenderer
390
393
  * @function
391
394
  * @param {number} x ellipse center point x-axis
392
395
  * @param {number} y ellipse center point y-axis
@@ -400,7 +403,7 @@ class CanvasRenderer extends Renderer {
400
403
  /**
401
404
  * Stroke a line of the given two points
402
405
  * @name strokeLine
403
- * @memberof CanvasRenderer.prototype
406
+ * @memberof CanvasRenderer
404
407
  * @function
405
408
  * @param {number} startX the start x coordinate
406
409
  * @param {number} startY the start y coordinate
@@ -408,9 +411,7 @@ class CanvasRenderer extends Renderer {
408
411
  * @param {number} endY the end y coordinate
409
412
  */
410
413
  strokeLine(startX, startY, endX, endY) {
411
- var context = this.backBufferContext2D;
412
-
413
- if (context < 1 / 255) {
414
+ if (this.getGlobalAlpha() < 1 / 255) {
414
415
  // Fast path: don't draw fully transparent
415
416
  return;
416
417
  }
@@ -424,7 +425,7 @@ class CanvasRenderer extends Renderer {
424
425
  /**
425
426
  * Fill a line of the given two points
426
427
  * @name fillLine
427
- * @memberof CanvasRenderer.prototype
428
+ * @memberof CanvasRenderer
428
429
  * @function
429
430
  * @param {number} startX the start x coordinate
430
431
  * @param {number} startY the start y coordinate
@@ -438,18 +439,17 @@ class CanvasRenderer extends Renderer {
438
439
  /**
439
440
  * Stroke the given me.Polygon on the screen
440
441
  * @name strokePolygon
441
- * @memberof CanvasRenderer.prototype
442
+ * @memberof CanvasRenderer
442
443
  * @function
443
444
  * @param {Polygon} poly the shape to draw
444
445
  * @param {boolean} [fill=false] also fill the shape with the current color if true
445
446
  */
446
447
  strokePolygon(poly, fill = false) {
447
- var context = this.backBufferContext2D;
448
-
449
- if (context.globalAlpha < 1 / 255) {
448
+ if (this.getGlobalAlpha() < 1 / 255) {
450
449
  // Fast path: don't draw fully transparent
451
450
  return;
452
451
  }
452
+ var context = this.getContext();
453
453
 
454
454
  this.translate(poly.pos.x, poly.pos.y);
455
455
  context.beginPath();
@@ -468,7 +468,7 @@ class CanvasRenderer extends Renderer {
468
468
  /**
469
469
  * Fill the given me.Polygon on the screen
470
470
  * @name fillPolygon
471
- * @memberof CanvasRenderer.prototype
471
+ * @memberof CanvasRenderer
472
472
  * @function
473
473
  * @param {Polygon} poly the shape to draw
474
474
  */
@@ -479,7 +479,7 @@ class CanvasRenderer extends Renderer {
479
479
  /**
480
480
  * Stroke a rectangle at the specified coordinates
481
481
  * @name strokeRect
482
- * @memberof CanvasRenderer.prototype
482
+ * @memberof CanvasRenderer
483
483
  * @function
484
484
  * @param {number} x
485
485
  * @param {number} y
@@ -488,21 +488,19 @@ class CanvasRenderer extends Renderer {
488
488
  * @param {boolean} [fill=false] also fill the shape with the current color if true
489
489
  */
490
490
  strokeRect(x, y, width, height, fill = false) {
491
- if (fill === true ) {
492
- this.fillRect(x, y, width, height);
493
- } else {
494
- if (this.backBufferContext2D.globalAlpha < 1 / 255) {
495
- // Fast path: don't draw fully transparent
496
- return;
497
- }
498
- this.backBufferContext2D.strokeRect(x, y, width, height);
491
+ if (this.getGlobalAlpha() < 1 / 255) {
492
+ // Fast path: don't draw fully transparent
493
+ return;
499
494
  }
495
+ var context = this.getContext();
496
+
497
+ context[fill === true ? "fillRect" : "strokeRect"](x, y, width, height);
500
498
  }
501
499
 
502
500
  /**
503
501
  * Draw a filled rectangle at the specified coordinates
504
502
  * @name fillRect
505
- * @memberof CanvasRenderer.prototype
503
+ * @memberof CanvasRenderer
506
504
  * @function
507
505
  * @param {number} x
508
506
  * @param {number} y
@@ -510,18 +508,53 @@ class CanvasRenderer extends Renderer {
510
508
  * @param {number} height
511
509
  */
512
510
  fillRect(x, y, width, height) {
513
- if (this.backBufferContext2D.globalAlpha < 1 / 255) {
511
+ this.strokeRect(x, y, width, height, true);
512
+ }
513
+
514
+ /**
515
+ * Stroke a rounded rectangle at the specified coordinates
516
+ * @name strokeRoundRect
517
+ * @memberof CanvasRenderer
518
+ * @function
519
+ * @param {number} x
520
+ * @param {number} y
521
+ * @param {number} width
522
+ * @param {number} height
523
+ * @param {number} radius
524
+ * @param {boolean} [fill=false] also fill the shape with the current color if true
525
+ */
526
+ strokeRoundRect(x, y, width, height, radius, fill = false) {
527
+ if (this.getGlobalAlpha() < 1 / 255) {
514
528
  // Fast path: don't draw fully transparent
515
529
  return;
516
530
  }
517
- this.backBufferContext2D.fillRect(x, y, width, height);
531
+ var context = this.getContext();
532
+
533
+ context.beginPath();
534
+ context.roundRect(x, y, width, height, radius);
535
+ context[fill === true ? "fill" : "stroke"]();
536
+ }
537
+
538
+ /**
539
+ * Draw a rounded filled rectangle at the specified coordinates
540
+ * @name fillRoundRect
541
+ * @memberof CanvasRenderer
542
+ * @function
543
+ * @param {number} x
544
+ * @param {number} y
545
+ * @param {number} width
546
+ * @param {number} height
547
+ * @param {number} radius
548
+ */
549
+ fillRoundRect(x, y, width, height, radius) {
550
+ this.strokeRoundRect(x, y, width, height, radius, true);
518
551
  }
519
552
 
520
553
 
521
554
  /**
522
555
  * return a reference to the system 2d Context
523
556
  * @name getContext
524
- * @memberof CanvasRenderer.prototype
557
+ * @memberof CanvasRenderer
525
558
  * @function
526
559
  * @returns {CanvasRenderingContext2D}
527
560
  */
@@ -541,7 +574,7 @@ class CanvasRenderer extends Renderer {
541
574
  /**
542
575
  * save the canvas context
543
576
  * @name save
544
- * @memberof CanvasRenderer.prototype
577
+ * @memberof CanvasRenderer
545
578
  * @function
546
579
  */
547
580
  save() {
@@ -551,12 +584,12 @@ class CanvasRenderer extends Renderer {
551
584
  /**
552
585
  * restores the canvas context
553
586
  * @name restore
554
- * @memberof CanvasRenderer.prototype
587
+ * @memberof CanvasRenderer
555
588
  * @function
556
589
  */
557
590
  restore() {
558
591
  this.backBufferContext2D.restore();
559
- this.currentColor.glArray[3] = this.backBufferContext2D.globalAlpha;
592
+ this.currentColor.glArray[3] = this.getGlobalAlpha();
560
593
  this.currentScissor[0] = 0;
561
594
  this.currentScissor[1] = 0;
562
595
  this.currentScissor[2] = this.backBufferCanvas.width;
@@ -566,7 +599,7 @@ class CanvasRenderer extends Renderer {
566
599
  /**
567
600
  * rotates the canvas context
568
601
  * @name rotate
569
- * @memberof CanvasRenderer.prototype
602
+ * @memberof CanvasRenderer
570
603
  * @function
571
604
  * @param {number} angle in radians
572
605
  */
@@ -577,7 +610,7 @@ class CanvasRenderer extends Renderer {
577
610
  /**
578
611
  * scales the canvas context
579
612
  * @name scale
580
- * @memberof CanvasRenderer.prototype
613
+ * @memberof CanvasRenderer
581
614
  * @function
582
615
  * @param {number} x
583
616
  * @param {number} y
@@ -590,7 +623,7 @@ class CanvasRenderer extends Renderer {
590
623
  * Set the current fill & stroke style color.
591
624
  * By default, or upon reset, the value is set to #000000.
592
625
  * @name setColor
593
- * @memberof CanvasRenderer.prototype
626
+ * @memberof CanvasRenderer
594
627
  * @function
595
628
  * @param {Color|string} color css color value
596
629
  */
@@ -604,9 +637,9 @@ class CanvasRenderer extends Renderer {
604
637
  }
605
638
 
606
639
  /**
607
- * Set the global alpha on the canvas context
640
+ * Set the global alpha
608
641
  * @name setGlobalAlpha
609
- * @memberof CanvasRenderer.prototype
642
+ * @memberof CanvasRenderer
610
643
  * @function
611
644
  * @param {number} alpha 0.0 to 1.0 values accepted.
612
645
  */
@@ -614,10 +647,21 @@ class CanvasRenderer extends Renderer {
614
647
  this.backBufferContext2D.globalAlpha = this.currentColor.glArray[3] = alpha;
615
648
  }
616
649
 
650
+ /**
651
+ * Return the global alpha
652
+ * @name getGlobalAlpha
653
+ * @memberof CanvasRenderer
654
+ * @function
655
+ * @returns {number} global alpha value
656
+ */
657
+ getGlobalAlpha() {
658
+ return this.backBufferContext2D.globalAlpha;
659
+ }
660
+
617
661
  /**
618
662
  * Set the line width on the context
619
663
  * @name setLineWidth
620
- * @memberof CanvasRenderer.prototype
664
+ * @memberof CanvasRenderer
621
665
  * @function
622
666
  * @param {number} width Line width
623
667
  */
@@ -629,7 +673,7 @@ class CanvasRenderer extends Renderer {
629
673
  * Reset (overrides) the renderer transformation matrix to the
630
674
  * identity one, and then apply the given transformation matrix.
631
675
  * @name setTransform
632
- * @memberof CanvasRenderer.prototype
676
+ * @memberof CanvasRenderer
633
677
  * @function
634
678
  * @param {Matrix2d} mat2d Matrix to transform by
635
679
  */
@@ -641,7 +685,7 @@ class CanvasRenderer extends Renderer {
641
685
  /**
642
686
  * Multiply given matrix into the renderer tranformation matrix
643
687
  * @name transform
644
- * @memberof CanvasRenderer.prototype
688
+ * @memberof CanvasRenderer
645
689
  * @function
646
690
  * @param {Matrix2d} mat2d Matrix to transform by
647
691
  */
@@ -665,7 +709,7 @@ class CanvasRenderer extends Renderer {
665
709
  /**
666
710
  * Translates the context to the given position
667
711
  * @name translate
668
- * @memberof CanvasRenderer.prototype
712
+ * @memberof CanvasRenderer
669
713
  * @function
670
714
  * @param {number} x
671
715
  * @param {number} y
@@ -685,7 +729,7 @@ class CanvasRenderer extends Renderer {
685
729
  * and restore it (with the restore() method) any time in the future.
686
730
  * (<u>this is an experimental feature !</u>)
687
731
  * @name clipRect
688
- * @memberof CanvasRenderer.prototype
732
+ * @memberof CanvasRenderer
689
733
  * @function
690
734
  * @param {number} x
691
735
  * @param {number} y
@@ -718,19 +762,28 @@ class CanvasRenderer extends Renderer {
718
762
  * So, if the renderable is larger than the mask, only the intersecting part of the renderable will be visible.
719
763
  * Mask are not preserved through renderer context save and restore.
720
764
  * @name setMask
721
- * @memberof CanvasRenderer.prototype
765
+ * @memberof CanvasRenderer
722
766
  * @function
723
- * @param {Rect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
767
+ * @param {Rect|RoundRect|Polygon|Line|Ellipse} [mask] the shape defining the mask to be applied
768
+ * @param {boolean} [invert=false] either the given shape should define what is visible (default) or the opposite
724
769
  */
725
- setMask(mask) {
726
- var context = this.backBufferContext2D;
727
- var _x = mask.pos.x, _y = mask.pos.y;
770
+ setMask(mask, invert = false) {
771
+ var context = this.getContext();
728
772
 
729
- context.save();
773
+ if (this.maskLevel === 0) {
774
+ // only save context on the first mask
775
+ context.save();
776
+ context.beginPath();
777
+ }
730
778
 
731
779
  // https://github.com/melonjs/melonJS/issues/648
732
- if (mask instanceof Ellipse) {
733
- var hw = mask.radiusV.x,
780
+ else if (mask instanceof RoundRect) {
781
+ context.roundRect(mask.top, mask.left, mask.width, mask.height, mask.radius);
782
+ } else if (mask instanceof Rect || mask instanceof Bounds) {
783
+ context.rect(mask.top, mask.left, mask.width, mask.height);
784
+ } else if (mask instanceof Ellipse) {
785
+ const _x = mask.pos.x, _y = mask.pos.y,
786
+ hw = mask.radiusV.x,
734
787
  hh = mask.radiusV.y,
735
788
  lx = _x - hw,
736
789
  rx = _x + hw,
@@ -744,36 +797,46 @@ class CanvasRenderer extends Renderer {
744
797
  ymin = _y - ymagic,
745
798
  ymax = _y + ymagic;
746
799
 
747
- context.beginPath();
748
800
  context.moveTo(_x, ty);
749
801
  context.bezierCurveTo(xmax, ty, rx, ymin, rx, _y);
750
802
  context.bezierCurveTo(rx, ymax, xmax, by, _x, by);
751
803
  context.bezierCurveTo(xmin, by, lx, ymax, lx, _y);
752
804
  context.bezierCurveTo(lx, ymin, xmin, ty, _x, ty);
753
805
  } else {
754
- context.beginPath();
755
- context.moveTo(_x + mask.points[0].x, _y + mask.points[0].y);
806
+ const _x = mask.pos.x, _y = mask.pos.y;
756
807
  var point;
808
+
809
+ context.moveTo(_x + mask.points[0].x, _y + mask.points[0].y);
757
810
  for (var i = 1; i < mask.points.length; i++) {
758
811
  point = mask.points[i];
759
812
  context.lineTo(_x + point.x, _y + point.y);
760
813
  }
761
814
  }
762
815
 
763
- context.clip();
816
+ this.maskLevel++;
817
+
818
+ if (invert === true) {
819
+ context.closePath();
820
+ context.globalCompositeOperation = "destination-atop";
821
+ context.fill();
822
+ } else {
823
+ context.clip();
824
+ }
764
825
  }
765
826
 
766
827
  /**
767
828
  * disable (remove) the rendering mask set through setMask.
768
829
  * @name clearMask
769
830
  * @see CanvasRenderer#setMask
770
- * @memberof CanvasRenderer.prototype
831
+ * @memberof CanvasRenderer
771
832
  * @function
772
833
  */
773
834
  clearMask() {
774
- this.backBufferContext2D.restore();
835
+ if (this.maskLevel > 0) {
836
+ this.maskLevel = 0;
837
+ this.getContext().restore();
838
+ }
775
839
  }
776
-
777
840
  };
778
841
 
779
842
  export default CanvasRenderer;