melonjs 14.0.2 → 14.1.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/README.md +2 -0
- package/dist/melonjs.mjs/_virtual/_commonjsHelpers.js +10 -0
- package/dist/melonjs.mjs/_virtual/arraymultimap.js +10 -0
- package/dist/melonjs.mjs/_virtual/earcut.js +10 -0
- package/dist/melonjs.mjs/_virtual/howler.js +10 -0
- package/dist/melonjs.mjs/_virtual/index.js +10 -0
- package/dist/melonjs.mjs/_virtual/index2.js +10 -0
- package/dist/melonjs.mjs/_virtual/multimap.js +10 -0
- package/dist/melonjs.mjs/_virtual/setmultimap.js +10 -0
- package/dist/melonjs.mjs/application/application.js +240 -0
- package/dist/melonjs.mjs/audio/audio.js +536 -0
- package/dist/melonjs.mjs/camera/camera2d.js +732 -0
- package/dist/melonjs.mjs/entity/entity.js +248 -0
- package/dist/melonjs.mjs/game.js +29 -0
- package/dist/melonjs.mjs/geometries/ellipse.js +275 -0
- package/dist/melonjs.mjs/geometries/line.js +116 -0
- package/dist/melonjs.mjs/geometries/path2d.js +319 -0
- package/dist/melonjs.mjs/geometries/point.js +89 -0
- package/dist/melonjs.mjs/geometries/poly.js +500 -0
- package/dist/melonjs.mjs/geometries/rectangle.js +375 -0
- package/dist/melonjs.mjs/geometries/roundrect.js +168 -0
- package/dist/melonjs.mjs/index.js +248 -0
- package/dist/melonjs.mjs/input/gamepad.js +501 -0
- package/dist/melonjs.mjs/input/input.js +26 -0
- package/dist/melonjs.mjs/input/keyboard.js +470 -0
- package/dist/melonjs.mjs/input/pointer.js +393 -0
- package/dist/melonjs.mjs/input/pointerevent.js +818 -0
- package/dist/melonjs.mjs/lang/deprecated.js +157 -0
- package/dist/melonjs.mjs/level/level.js +297 -0
- package/dist/melonjs.mjs/level/tiled/TMXGroup.js +141 -0
- package/dist/melonjs.mjs/level/tiled/TMXLayer.js +448 -0
- package/dist/melonjs.mjs/level/tiled/TMXObject.js +355 -0
- package/dist/melonjs.mjs/level/tiled/TMXTile.js +194 -0
- package/dist/melonjs.mjs/level/tiled/TMXTileMap.js +639 -0
- package/dist/melonjs.mjs/level/tiled/TMXTileset.js +311 -0
- package/dist/melonjs.mjs/level/tiled/TMXTilesetGroup.js +83 -0
- package/dist/melonjs.mjs/level/tiled/TMXUtils.js +367 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXHexagonalRenderer.js +506 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXIsometricRenderer.js +220 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXOrthogonalRenderer.js +157 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXRenderer.js +125 -0
- package/dist/melonjs.mjs/level/tiled/renderer/TMXStaggeredRenderer.js +109 -0
- package/dist/melonjs.mjs/loader/loader.js +801 -0
- package/dist/melonjs.mjs/loader/loadingscreen.js +120 -0
- package/dist/melonjs.mjs/loader/melonjs_logo.png.js +11 -0
- package/dist/melonjs.mjs/math/color.js +618 -0
- package/dist/melonjs.mjs/math/math.js +218 -0
- package/dist/melonjs.mjs/math/matrix2.js +503 -0
- package/dist/melonjs.mjs/math/matrix3.js +681 -0
- package/dist/melonjs.mjs/math/observable_vector2.js +471 -0
- package/dist/melonjs.mjs/math/observable_vector3.js +561 -0
- package/dist/melonjs.mjs/math/vector2.js +528 -0
- package/dist/melonjs.mjs/math/vector3.js +569 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/arraymultimap.js +73 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/index.js +21 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/multimap.js +324 -0
- package/dist/melonjs.mjs/node_modules/@teppeis/multimaps/dist/src/setmultimap.js +69 -0
- package/dist/melonjs.mjs/node_modules/earcut/src/earcut.js +691 -0
- package/dist/melonjs.mjs/node_modules/eventemitter3/index.js +350 -0
- package/dist/melonjs.mjs/node_modules/howler/dist/howler.js +3241 -0
- package/dist/melonjs.mjs/particles/emitter.js +267 -0
- package/dist/melonjs.mjs/particles/particle.js +188 -0
- package/dist/melonjs.mjs/particles/settings.js +319 -0
- package/dist/melonjs.mjs/physics/body.js +704 -0
- package/dist/melonjs.mjs/physics/bounds.js +460 -0
- package/dist/melonjs.mjs/physics/collision.js +132 -0
- package/dist/melonjs.mjs/physics/detector.js +194 -0
- package/dist/melonjs.mjs/physics/quadtree.js +391 -0
- package/dist/melonjs.mjs/physics/response.js +57 -0
- package/dist/melonjs.mjs/physics/sat.js +483 -0
- package/dist/melonjs.mjs/physics/world.js +221 -0
- package/dist/melonjs.mjs/plugin/plugin.js +141 -0
- package/dist/melonjs.mjs/renderable/collectable.js +62 -0
- package/dist/melonjs.mjs/renderable/colorlayer.js +80 -0
- package/dist/melonjs.mjs/renderable/container.js +1018 -0
- package/dist/melonjs.mjs/renderable/dragndrop.js +224 -0
- package/dist/melonjs.mjs/renderable/imagelayer.js +306 -0
- package/dist/melonjs.mjs/renderable/light2d.js +156 -0
- package/dist/melonjs.mjs/renderable/nineslicesprite.js +247 -0
- package/dist/melonjs.mjs/renderable/renderable.js +783 -0
- package/dist/melonjs.mjs/renderable/sprite.js +654 -0
- package/dist/melonjs.mjs/renderable/trigger.js +157 -0
- package/dist/melonjs.mjs/renderable/ui/uibaseelement.js +213 -0
- package/dist/melonjs.mjs/renderable/ui/uispriteelement.js +226 -0
- package/dist/melonjs.mjs/renderable/ui/uitextbutton.js +128 -0
- package/dist/melonjs.mjs/state/stage.js +237 -0
- package/dist/melonjs.mjs/state/state.js +596 -0
- package/dist/melonjs.mjs/system/device.js +909 -0
- package/dist/melonjs.mjs/system/dom.js +78 -0
- package/dist/melonjs.mjs/system/event.js +537 -0
- package/dist/melonjs.mjs/system/platform.js +41 -0
- package/dist/melonjs.mjs/system/pooling.js +209 -0
- package/dist/melonjs.mjs/system/save.js +157 -0
- package/dist/melonjs.mjs/system/timer.js +286 -0
- package/dist/melonjs.mjs/text/bitmaptext.js +364 -0
- package/dist/melonjs.mjs/text/bitmaptextdata.js +199 -0
- package/dist/melonjs.mjs/text/glyph.js +66 -0
- package/dist/melonjs.mjs/text/text.js +453 -0
- package/dist/melonjs.mjs/text/textmetrics.js +176 -0
- package/dist/melonjs.mjs/text/textstyle.js +23 -0
- package/dist/melonjs.mjs/tweens/easing.js +336 -0
- package/dist/melonjs.mjs/tweens/interpolation.js +112 -0
- package/dist/melonjs.mjs/tweens/tween.js +480 -0
- package/dist/melonjs.mjs/utils/agent.js +76 -0
- package/dist/melonjs.mjs/utils/array.js +63 -0
- package/dist/melonjs.mjs/utils/file.js +42 -0
- package/dist/melonjs.mjs/utils/function.js +70 -0
- package/dist/melonjs.mjs/utils/string.js +82 -0
- package/dist/melonjs.mjs/utils/utils.js +173 -0
- package/dist/melonjs.mjs/video/canvas/canvas_renderer.js +807 -0
- package/dist/melonjs.mjs/video/renderer.js +411 -0
- package/dist/melonjs.mjs/video/texture/atlas.js +519 -0
- package/dist/melonjs.mjs/video/texture/cache.js +143 -0
- package/dist/melonjs.mjs/video/texture/canvas_texture.js +144 -0
- package/dist/melonjs.mjs/video/video.js +462 -0
- package/dist/melonjs.mjs/video/webgl/buffer/vertex.js +143 -0
- package/dist/melonjs.mjs/video/webgl/glshader.js +168 -0
- package/dist/melonjs.mjs/video/webgl/shaders/primitive.frag.js +10 -0
- package/dist/melonjs.mjs/video/webgl/shaders/primitive.vert.js +10 -0
- package/dist/melonjs.mjs/video/webgl/shaders/quad.frag.js +10 -0
- package/dist/melonjs.mjs/video/webgl/shaders/quad.vert.js +10 -0
- package/dist/melonjs.mjs/video/webgl/utils/attributes.js +25 -0
- package/dist/melonjs.mjs/video/webgl/utils/precision.js +20 -0
- package/dist/melonjs.mjs/video/webgl/utils/program.js +67 -0
- package/dist/melonjs.mjs/video/webgl/utils/string.js +25 -0
- package/dist/melonjs.mjs/video/webgl/utils/uniforms.js +92 -0
- package/dist/melonjs.mjs/video/webgl/webgl_compositor.js +495 -0
- package/dist/melonjs.mjs/video/webgl/webgl_renderer.js +1036 -0
- package/dist/melonjs.module.d.ts +1163 -1163
- package/dist/melonjs.module.js +1903 -3274
- package/package.json +22 -17
- package/src/application/application.js +3 -3
- package/src/audio/audio.js +32 -32
- package/src/camera/camera2d.js +31 -31
- package/src/entity/entity.js +17 -17
- package/src/geometries/ellipse.js +16 -16
- package/src/geometries/line.js +5 -5
- package/src/geometries/path2d.js +32 -32
- package/src/geometries/poly.js +15 -15
- package/src/geometries/rectangle.js +18 -18
- package/src/geometries/roundrect.js +8 -8
- package/src/input/gamepad.js +15 -15
- package/src/input/keyboard.js +12 -12
- package/src/input/pointer.js +6 -6
- package/src/input/pointerevent.js +12 -12
- package/src/lang/deprecated.js +12 -12
- package/src/level/level.js +25 -25
- package/src/level/tiled/TMXLayer.js +22 -22
- package/src/level/tiled/TMXTile.js +5 -5
- package/src/level/tiled/TMXTileMap.js +6 -6
- package/src/level/tiled/TMXTileset.js +2 -2
- package/src/level/tiled/TMXUtils.js +5 -5
- package/src/level/tiled/renderer/TMXHexagonalRenderer.js +2 -2
- package/src/level/tiled/renderer/TMXIsometricRenderer.js +2 -2
- package/src/level/tiled/renderer/TMXOrthogonalRenderer.js +1 -1
- package/src/level/tiled/renderer/TMXRenderer.js +19 -19
- package/src/loader/loader.js +20 -20
- package/src/math/color.js +20 -20
- package/src/math/math.js +16 -16
- package/src/math/matrix2.js +16 -16
- package/src/math/matrix3.js +25 -25
- package/src/math/observable_vector2.js +14 -14
- package/src/math/observable_vector3.js +16 -16
- package/src/math/vector2.js +9 -9
- package/src/math/vector3.js +10 -10
- package/src/particles/emitter.js +6 -6
- package/src/particles/particle.js +2 -2
- package/src/physics/body.js +28 -28
- package/src/physics/bounds.js +8 -8
- package/src/physics/collision.js +2 -2
- package/src/physics/detector.js +6 -6
- package/src/physics/quadtree.js +11 -11
- package/src/physics/sat.js +31 -31
- package/src/physics/world.js +5 -5
- package/src/plugin/plugin.js +5 -5
- package/src/renderable/collectable.js +3 -3
- package/src/renderable/colorlayer.js +5 -5
- package/src/renderable/container.js +21 -21
- package/src/renderable/dragndrop.js +14 -14
- package/src/renderable/imagelayer.js +13 -13
- package/src/renderable/light2d.js +3 -3
- package/src/renderable/nineslicesprite.js +16 -16
- package/src/renderable/renderable.js +23 -23
- package/src/renderable/sprite.js +28 -28
- package/src/renderable/trigger.js +15 -15
- package/src/renderable/ui/uibaseelement.js +7 -7
- package/src/renderable/ui/uispriteelement.js +6 -6
- package/src/renderable/ui/uitextbutton.js +13 -13
- package/src/state/stage.js +7 -7
- package/src/state/state.js +17 -17
- package/src/system/device.js +11 -11
- package/src/system/event.js +10 -10
- package/src/system/pooling.js +9 -9
- package/src/system/save.js +2 -2
- package/src/system/timer.js +10 -10
- package/src/text/bitmaptext.js +18 -18
- package/src/text/bitmaptextdata.js +2 -2
- package/src/text/text.js +23 -23
- package/src/text/textmetrics.js +8 -8
- package/src/tweens/tween.js +19 -19
- package/src/utils/agent.js +5 -5
- package/src/utils/array.js +4 -4
- package/src/utils/file.js +2 -2
- package/src/utils/function.js +6 -6
- package/src/utils/string.js +5 -5
- package/src/utils/utils.js +4 -4
- package/src/video/canvas/canvas_renderer.js +70 -70
- package/src/video/renderer.js +26 -26
- package/src/video/texture/atlas.js +22 -22
- package/src/video/texture/canvas_texture.js +9 -9
- package/src/video/video.js +17 -17
- package/src/video/webgl/glshader.js +10 -10
- package/src/video/webgl/webgl_compositor.js +41 -41
- package/src/video/webgl/webgl_renderer.js +75 -75
|
@@ -0,0 +1,807 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* melonJS Game Engine - v14.1.0
|
|
3
|
+
* http://www.melonjs.org
|
|
4
|
+
* melonjs is licensed under the MIT License.
|
|
5
|
+
* http://www.opensource.org/licenses/mit-license
|
|
6
|
+
* @copyright (C) 2011 - 2022 Olivier Biot (AltByte Pte Ltd)
|
|
7
|
+
*/
|
|
8
|
+
import Color from '../../math/color.js';
|
|
9
|
+
import Renderer from '../renderer.js';
|
|
10
|
+
import TextureCache from '../texture/cache.js';
|
|
11
|
+
import Ellipse from '../../geometries/ellipse.js';
|
|
12
|
+
import RoundRect from '../../geometries/roundrect.js';
|
|
13
|
+
import Rect from '../../geometries/rectangle.js';
|
|
14
|
+
import Bounds from '../../physics/bounds.js';
|
|
15
|
+
import { emit, ONCONTEXT_LOST, ONCONTEXT_RESTORED } from '../../system/event.js';
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @classdesc
|
|
19
|
+
* a canvas renderer object
|
|
20
|
+
* @augments Renderer
|
|
21
|
+
*/
|
|
22
|
+
class CanvasRenderer extends Renderer {
|
|
23
|
+
/**
|
|
24
|
+
* @param {object} options - The renderer parameters
|
|
25
|
+
* @param {number} options.width - The width of the canvas without scaling
|
|
26
|
+
* @param {number} options.height - The height of the canvas without scaling
|
|
27
|
+
* @param {HTMLCanvasElement} [options.canvas] - The html canvas to draw to on screen
|
|
28
|
+
* @param {boolean} [options.antiAlias=false] - Whether to enable anti-aliasing
|
|
29
|
+
* @param {boolean} [options.transparent=false] - Whether to enable transparency on the canvas (performance hit when enabled)
|
|
30
|
+
* @param {boolean} [options.subPixel=false] - Whether to enable subpixel renderering (performance hit when enabled)
|
|
31
|
+
* @param {boolean} [options.textureSeamFix=true] - enable the texture seam fix when rendering Tile when antiAlias is off for the canvasRenderer
|
|
32
|
+
* @param {number} [options.zoomX=width] - The actual width of the canvas with scaling applied
|
|
33
|
+
* @param {number} [options.zoomY=height] - The actual height of the canvas with scaling applied
|
|
34
|
+
*/
|
|
35
|
+
constructor(options) {
|
|
36
|
+
// parent constructor
|
|
37
|
+
super(options);
|
|
38
|
+
|
|
39
|
+
// defined the 2d context
|
|
40
|
+
this.context = this.getContext2d(this.getCanvas(), this.settings.transparent);
|
|
41
|
+
|
|
42
|
+
this.setBlendMode(this.settings.blendMode);
|
|
43
|
+
|
|
44
|
+
// apply the default color to the 2d context
|
|
45
|
+
this.setColor(this.currentColor);
|
|
46
|
+
|
|
47
|
+
// create a texture cache
|
|
48
|
+
this.cache = new TextureCache();
|
|
49
|
+
|
|
50
|
+
if (this.settings.textureSeamFix !== false && !this.settings.antiAlias) {
|
|
51
|
+
// enable the tile texture seam fix with the canvas renderer
|
|
52
|
+
this.uvOffset = 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// context lost & restore event for canvas
|
|
56
|
+
this.getCanvas().addEventListener("contextlost", (e) => {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
this.isContextValid = false;
|
|
59
|
+
emit(ONCONTEXT_LOST, this);
|
|
60
|
+
}, false );
|
|
61
|
+
// ctx.restoreContext()
|
|
62
|
+
this.getCanvas().addEventListener("contextrestored", () => {
|
|
63
|
+
this.isContextValid = true;
|
|
64
|
+
emit(ONCONTEXT_RESTORED, this);
|
|
65
|
+
}, false );
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Reset context state
|
|
70
|
+
* @name reset
|
|
71
|
+
* @memberof CanvasRenderer
|
|
72
|
+
*/
|
|
73
|
+
reset() {
|
|
74
|
+
super.reset();
|
|
75
|
+
this.clearColor(this.currentColor, this.settings.transparent !== true);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Reset the canvas transform to identity
|
|
80
|
+
* @name resetTransform
|
|
81
|
+
* @memberof CanvasRenderer
|
|
82
|
+
*/
|
|
83
|
+
resetTransform() {
|
|
84
|
+
this.getContext().setTransform(1, 0, 0, 1, 0, 0);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* set a blend mode for the given context. <br>
|
|
89
|
+
* Supported blend mode between Canvas and WebGL remderer : <br>
|
|
90
|
+
* - "normal" : this is the default mode and draws new content on top of the existing content <br>
|
|
91
|
+
* <img src="images/normal-blendmode.png" width="510"/> <br>
|
|
92
|
+
* - "multiply" : the pixels of the top layer are multiplied with the corresponding pixel of the bottom layer. A darker picture is the result. <br>
|
|
93
|
+
* <img src="images/multiply-blendmode.png" width="510"/> <br>
|
|
94
|
+
* - "additive or lighter" : where both content overlap the color is determined by adding color values. <br>
|
|
95
|
+
* <img src="images/lighter-blendmode.png" width="510"/> <br>
|
|
96
|
+
* - "screen" : The pixels are inverted, multiplied, and inverted again. A lighter picture is the result (opposite of multiply) <br>
|
|
97
|
+
* <img src="images/screen-blendmode.png" width="510"/> <br>
|
|
98
|
+
* @name setBlendMode
|
|
99
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/globalCompositeOperation
|
|
100
|
+
* @memberof CanvasRenderer
|
|
101
|
+
* @param {string} [mode="normal"] - blend mode : "normal", "multiply", "lighter, "additive", "screen"
|
|
102
|
+
* @param {CanvasRenderingContext2D} [context]
|
|
103
|
+
*/
|
|
104
|
+
setBlendMode(mode = "normal", context) {
|
|
105
|
+
context = context || this.getContext();
|
|
106
|
+
this.currentBlendMode = mode;
|
|
107
|
+
switch (mode) {
|
|
108
|
+
case "screen" :
|
|
109
|
+
context.globalCompositeOperation = "screen";
|
|
110
|
+
break;
|
|
111
|
+
|
|
112
|
+
case "lighter" :
|
|
113
|
+
case "additive" :
|
|
114
|
+
context.globalCompositeOperation = "lighter";
|
|
115
|
+
break;
|
|
116
|
+
|
|
117
|
+
case "multiply" :
|
|
118
|
+
context.globalCompositeOperation = "multiply";
|
|
119
|
+
break;
|
|
120
|
+
|
|
121
|
+
default : // normal
|
|
122
|
+
context.globalCompositeOperation = "source-over";
|
|
123
|
+
this.currentBlendMode = "normal";
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* prepare the framebuffer for drawing a new frame
|
|
130
|
+
* @name clear
|
|
131
|
+
* @memberof CanvasRenderer
|
|
132
|
+
*/
|
|
133
|
+
clear() {
|
|
134
|
+
if (this.settings.transparent === false) {
|
|
135
|
+
var canvas = this.getCanvas();
|
|
136
|
+
var context = this.getContext();
|
|
137
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Clears the main framebuffer with the given color
|
|
143
|
+
* @name clearColor
|
|
144
|
+
* @memberof CanvasRenderer
|
|
145
|
+
* @param {Color|string} [color="#000000"] - CSS color.
|
|
146
|
+
* @param {boolean} [opaque=false] - Allow transparency [default] or clear the surface completely [true]
|
|
147
|
+
*/
|
|
148
|
+
clearColor(color = "#000000", opaque = false) {
|
|
149
|
+
var canvas = this.getCanvas();
|
|
150
|
+
var context = this.getContext();
|
|
151
|
+
|
|
152
|
+
this.save();
|
|
153
|
+
this.resetTransform();
|
|
154
|
+
context.globalAlpha = 1;
|
|
155
|
+
context.globalCompositeOperation = opaque === true ? "copy" : "source-over";
|
|
156
|
+
context.fillStyle = (color instanceof Color) ? color.toRGBA() : color;
|
|
157
|
+
this.fillRect(0, 0, canvas.width, canvas.height);
|
|
158
|
+
this.restore();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Erase the pixels in the given rectangular area by setting them to transparent black (rgba(0,0,0,0)).
|
|
163
|
+
* @name clearRect
|
|
164
|
+
* @memberof CanvasRenderer
|
|
165
|
+
* @param {number} x - x axis of the coordinate for the rectangle starting point.
|
|
166
|
+
* @param {number} y - y axis of the coordinate for the rectangle starting point.
|
|
167
|
+
* @param {number} width - The rectangle's width.
|
|
168
|
+
* @param {number} height - The rectangle's height.
|
|
169
|
+
*/
|
|
170
|
+
clearRect(x, y, width, height) {
|
|
171
|
+
this.getContext().clearRect(x, y, width, height);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Create a pattern with the specified repetition
|
|
176
|
+
* @name createPattern
|
|
177
|
+
* @memberof CanvasRenderer
|
|
178
|
+
* @param {Image} image - Source image
|
|
179
|
+
* @param {string} repeat - Define how the pattern should be repeated
|
|
180
|
+
* @returns {CanvasPattern}
|
|
181
|
+
* @see ImageLayer#repeat
|
|
182
|
+
* @example
|
|
183
|
+
* var tileable = renderer.createPattern(image, "repeat");
|
|
184
|
+
* var horizontal = renderer.createPattern(image, "repeat-x");
|
|
185
|
+
* var vertical = renderer.createPattern(image, "repeat-y");
|
|
186
|
+
* var basic = renderer.createPattern(image, "no-repeat");
|
|
187
|
+
*/
|
|
188
|
+
createPattern(image, repeat) {
|
|
189
|
+
return this.getContext().createPattern(image, repeat);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Draw an image onto the main using the canvas api
|
|
194
|
+
* @name drawImage
|
|
195
|
+
* @memberof CanvasRenderer
|
|
196
|
+
* @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.
|
|
197
|
+
* @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.
|
|
198
|
+
* @param {number} sy - The Y coordinate of the top left corner of the sub-rectangle of the source image to draw into the destination context.
|
|
199
|
+
* @param {number} sw - The width of the sub-rectangle of the source image to draw into the destination context. If not specified, the entire rectangle from the coordinates specified by sx and sy to the bottom-right corner of the image is used.
|
|
200
|
+
* @param {number} sh - The height of the sub-rectangle of the source image to draw into the destination context.
|
|
201
|
+
* @param {number} dx - The X coordinate in the destination canvas at which to place the top-left corner of the source image.
|
|
202
|
+
* @param {number} dy - The Y coordinate in the destination canvas at which to place the top-left corner of the source image.
|
|
203
|
+
* @param {number} dw - The width to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in width when drawn.
|
|
204
|
+
* @param {number} dh - The height to draw the image in the destination canvas. This allows scaling of the drawn image. If not specified, the image is not scaled in height when drawn.
|
|
205
|
+
* @example
|
|
206
|
+
* // Position the image on the canvas:
|
|
207
|
+
* renderer.drawImage(image, dx, dy);
|
|
208
|
+
* // Position the image on the canvas, and specify width and height of the image:
|
|
209
|
+
* renderer.drawImage(image, dx, dy, dWidth, dHeight);
|
|
210
|
+
* // Clip the image and position the clipped part on the canvas:
|
|
211
|
+
* renderer.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
|
|
212
|
+
*/
|
|
213
|
+
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh) {
|
|
214
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
215
|
+
// Fast path: don't draw fully transparent
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
var context = this.getContext();
|
|
219
|
+
|
|
220
|
+
if (typeof sw === "undefined") {
|
|
221
|
+
sw = dw = image.width;
|
|
222
|
+
sh = dh = image.height;
|
|
223
|
+
dx = sx;
|
|
224
|
+
dy = sy;
|
|
225
|
+
sx = 0;
|
|
226
|
+
sy = 0;
|
|
227
|
+
}
|
|
228
|
+
else if (typeof dx === "undefined") {
|
|
229
|
+
dx = sx;
|
|
230
|
+
dy = sy;
|
|
231
|
+
dw = sw;
|
|
232
|
+
dh = sh;
|
|
233
|
+
sw = image.width;
|
|
234
|
+
sh = image.height;
|
|
235
|
+
sx = 0;
|
|
236
|
+
sy = 0;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (this.settings.subPixel === false) {
|
|
240
|
+
// clamp to pixel grid
|
|
241
|
+
dx = ~~dx;
|
|
242
|
+
dy = ~~dy;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
// apply a tint if required
|
|
246
|
+
var source = image;
|
|
247
|
+
var tint = this.currentTint.toArray();
|
|
248
|
+
if (tint[0] !== 1.0 || tint[1] !== 1.0 || tint[2] !== 1.0) {
|
|
249
|
+
// get a tinted version of this image from the texture cache
|
|
250
|
+
source = this.cache.tint(image, this.currentTint.toRGB());
|
|
251
|
+
}
|
|
252
|
+
context.drawImage(source, sx, sy, sw, sh, dx, dy, dw, dh);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Draw a pattern within the given rectangle.
|
|
257
|
+
* @name drawPattern
|
|
258
|
+
* @memberof CanvasRenderer
|
|
259
|
+
* @param {CanvasPattern} pattern - Pattern object
|
|
260
|
+
* @param {number} x
|
|
261
|
+
* @param {number} y
|
|
262
|
+
* @param {number} width
|
|
263
|
+
* @param {number} height
|
|
264
|
+
* @see CanvasRenderer#createPattern
|
|
265
|
+
*/
|
|
266
|
+
drawPattern(pattern, x, y, width, height) {
|
|
267
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
268
|
+
// Fast path: don't draw fully transparent
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
var context = this.getContext();
|
|
272
|
+
var fillStyle = context.fillStyle;
|
|
273
|
+
context.fillStyle = pattern;
|
|
274
|
+
context.fillRect(x, y, width, height);
|
|
275
|
+
context.fillStyle = fillStyle;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Stroke an arc at the specified coordinates with given radius, start and end points
|
|
280
|
+
* @name strokeArc
|
|
281
|
+
* @memberof CanvasRenderer
|
|
282
|
+
* @param {number} x - arc center point x-axis
|
|
283
|
+
* @param {number} y - arc center point y-axis
|
|
284
|
+
* @param {number} radius
|
|
285
|
+
* @param {number} start - start angle in radians
|
|
286
|
+
* @param {number} end - end angle in radians
|
|
287
|
+
* @param {boolean} [antiClockwise=false] - draw arc anti-clockwise
|
|
288
|
+
* @param {boolean} [fill=false] - also fill the shape with the current color if true
|
|
289
|
+
*/
|
|
290
|
+
strokeArc(x, y, radius, start, end, antiClockwise, fill = false) {
|
|
291
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
292
|
+
// Fast path: don't draw fully transparent
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
var context = this.getContext();
|
|
296
|
+
|
|
297
|
+
context.translate(x, y);
|
|
298
|
+
context.beginPath();
|
|
299
|
+
context.arc(0, 0, radius, start, end, antiClockwise || false);
|
|
300
|
+
context[fill === true ? "fill" : "stroke"]();
|
|
301
|
+
context.translate(-x, -y);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Fill an arc at the specified coordinates with given radius, start and end points
|
|
306
|
+
* @name fillArc
|
|
307
|
+
* @memberof CanvasRenderer
|
|
308
|
+
* @param {number} x - arc center point x-axis
|
|
309
|
+
* @param {number} y - arc center point y-axis
|
|
310
|
+
* @param {number} radius
|
|
311
|
+
* @param {number} start - start angle in radians
|
|
312
|
+
* @param {number} end - end angle in radians
|
|
313
|
+
* @param {boolean} [antiClockwise=false] - draw arc anti-clockwise
|
|
314
|
+
*/
|
|
315
|
+
fillArc(x, y, radius, start, end, antiClockwise) {
|
|
316
|
+
this.strokeArc(x, y, radius, start, end, antiClockwise || false, true);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Stroke an ellipse at the specified coordinates with given radius
|
|
321
|
+
* @name strokeEllipse
|
|
322
|
+
* @memberof CanvasRenderer
|
|
323
|
+
* @param {number} x - ellipse center point x-axis
|
|
324
|
+
* @param {number} y - ellipse center point y-axis
|
|
325
|
+
* @param {number} w - horizontal radius of the ellipse
|
|
326
|
+
* @param {number} h - vertical radius of the ellipse
|
|
327
|
+
* @param {boolean} [fill=false] - also fill the shape with the current color if true
|
|
328
|
+
*/
|
|
329
|
+
strokeEllipse(x, y, w, h, fill = false) {
|
|
330
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
331
|
+
// Fast path: don't draw fully transparent
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
var context = this.getContext();
|
|
335
|
+
|
|
336
|
+
var hw = w,
|
|
337
|
+
hh = h,
|
|
338
|
+
lx = x - hw,
|
|
339
|
+
rx = x + hw,
|
|
340
|
+
ty = y - hh,
|
|
341
|
+
by = y + hh;
|
|
342
|
+
|
|
343
|
+
var xmagic = hw * 0.551784,
|
|
344
|
+
ymagic = hh * 0.551784,
|
|
345
|
+
xmin = x - xmagic,
|
|
346
|
+
xmax = x + xmagic,
|
|
347
|
+
ymin = y - ymagic,
|
|
348
|
+
ymax = y + ymagic;
|
|
349
|
+
|
|
350
|
+
context.beginPath();
|
|
351
|
+
context.moveTo(x, ty);
|
|
352
|
+
context.bezierCurveTo(xmax, ty, rx, ymin, rx, y);
|
|
353
|
+
context.bezierCurveTo(rx, ymax, xmax, by, x, by);
|
|
354
|
+
context.bezierCurveTo(xmin, by, lx, ymax, lx, y);
|
|
355
|
+
context.bezierCurveTo(lx, ymin, xmin, ty, x, ty);
|
|
356
|
+
context[fill === true ? "fill" : "stroke"]();
|
|
357
|
+
context.closePath();
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Fill an ellipse at the specified coordinates with given radius
|
|
362
|
+
* @name fillEllipse
|
|
363
|
+
* @memberof CanvasRenderer
|
|
364
|
+
* @param {number} x - ellipse center point x-axis
|
|
365
|
+
* @param {number} y - ellipse center point y-axis
|
|
366
|
+
* @param {number} w - horizontal radius of the ellipse
|
|
367
|
+
* @param {number} h - vertical radius of the ellipse
|
|
368
|
+
*/
|
|
369
|
+
fillEllipse(x, y, w, h) {
|
|
370
|
+
this.strokeEllipse(x, y, w, h, true);
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/**
|
|
374
|
+
* Stroke a line of the given two points
|
|
375
|
+
* @name strokeLine
|
|
376
|
+
* @memberof CanvasRenderer
|
|
377
|
+
* @param {number} startX - the start x coordinate
|
|
378
|
+
* @param {number} startY - the start y coordinate
|
|
379
|
+
* @param {number} endX - the end x coordinate
|
|
380
|
+
* @param {number} endY - the end y coordinate
|
|
381
|
+
*/
|
|
382
|
+
strokeLine(startX, startY, endX, endY) {
|
|
383
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
384
|
+
// Fast path: don't draw fully transparent
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
var context = this.getContext();
|
|
389
|
+
|
|
390
|
+
context.beginPath();
|
|
391
|
+
context.moveTo(startX, startY);
|
|
392
|
+
context.lineTo(endX, endY);
|
|
393
|
+
context.stroke();
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Fill a line of the given two points
|
|
398
|
+
* @name fillLine
|
|
399
|
+
* @memberof CanvasRenderer
|
|
400
|
+
* @param {number} startX - the start x coordinate
|
|
401
|
+
* @param {number} startY - the start y coordinate
|
|
402
|
+
* @param {number} endX - the end x coordinate
|
|
403
|
+
* @param {number} endY - the end y coordinate
|
|
404
|
+
*/
|
|
405
|
+
fillLine(startX, startY, endX, endY) {
|
|
406
|
+
this.strokeLine(startX, startY, endX, endY);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Stroke the given me.Polygon on the screen
|
|
411
|
+
* @name strokePolygon
|
|
412
|
+
* @memberof CanvasRenderer
|
|
413
|
+
* @param {Polygon} poly - the shape to draw
|
|
414
|
+
* @param {boolean} [fill=false] - also fill the shape with the current color if true
|
|
415
|
+
*/
|
|
416
|
+
strokePolygon(poly, fill = false) {
|
|
417
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
418
|
+
// Fast path: don't draw fully transparent
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
var context = this.getContext();
|
|
422
|
+
|
|
423
|
+
this.translate(poly.pos.x, poly.pos.y);
|
|
424
|
+
context.beginPath();
|
|
425
|
+
context.moveTo(poly.points[0].x, poly.points[0].y);
|
|
426
|
+
var point;
|
|
427
|
+
for (var i = 1; i < poly.points.length; i++) {
|
|
428
|
+
point = poly.points[i];
|
|
429
|
+
context.lineTo(point.x, point.y);
|
|
430
|
+
}
|
|
431
|
+
context.lineTo(poly.points[0].x, poly.points[0].y);
|
|
432
|
+
context[fill === true ? "fill" : "stroke"]();
|
|
433
|
+
context.closePath();
|
|
434
|
+
this.translate(-poly.pos.x, -poly.pos.y);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
/**
|
|
438
|
+
* Fill the given me.Polygon on the screen
|
|
439
|
+
* @name fillPolygon
|
|
440
|
+
* @memberof CanvasRenderer
|
|
441
|
+
* @param {Polygon} poly - the shape to draw
|
|
442
|
+
*/
|
|
443
|
+
fillPolygon(poly) {
|
|
444
|
+
this.strokePolygon(poly, true);
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Stroke a rectangle at the specified coordinates
|
|
449
|
+
* @name strokeRect
|
|
450
|
+
* @memberof CanvasRenderer
|
|
451
|
+
* @param {number} x
|
|
452
|
+
* @param {number} y
|
|
453
|
+
* @param {number} width
|
|
454
|
+
* @param {number} height
|
|
455
|
+
* @param {boolean} [fill=false] - also fill the shape with the current color if true
|
|
456
|
+
*/
|
|
457
|
+
strokeRect(x, y, width, height, fill = false) {
|
|
458
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
459
|
+
// Fast path: don't draw fully transparent
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
var context = this.getContext();
|
|
463
|
+
|
|
464
|
+
context[fill === true ? "fillRect" : "strokeRect"](x, y, width, height);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Draw a filled rectangle at the specified coordinates
|
|
469
|
+
* @name fillRect
|
|
470
|
+
* @memberof CanvasRenderer
|
|
471
|
+
* @param {number} x
|
|
472
|
+
* @param {number} y
|
|
473
|
+
* @param {number} width
|
|
474
|
+
* @param {number} height
|
|
475
|
+
*/
|
|
476
|
+
fillRect(x, y, width, height) {
|
|
477
|
+
this.strokeRect(x, y, width, height, true);
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Stroke a rounded rectangle at the specified coordinates
|
|
482
|
+
* @name strokeRoundRect
|
|
483
|
+
* @memberof CanvasRenderer
|
|
484
|
+
* @param {number} x
|
|
485
|
+
* @param {number} y
|
|
486
|
+
* @param {number} width
|
|
487
|
+
* @param {number} height
|
|
488
|
+
* @param {number} radius
|
|
489
|
+
* @param {boolean} [fill=false] - also fill the shape with the current color if true
|
|
490
|
+
*/
|
|
491
|
+
strokeRoundRect(x, y, width, height, radius, fill = false) {
|
|
492
|
+
if (this.getGlobalAlpha() < 1 / 255) {
|
|
493
|
+
// Fast path: don't draw fully transparent
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
var context = this.getContext();
|
|
497
|
+
|
|
498
|
+
context.beginPath();
|
|
499
|
+
context.roundRect(x, y, width, height, radius);
|
|
500
|
+
context[fill === true ? "fill" : "stroke"]();
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
/**
|
|
504
|
+
* Draw a rounded filled rectangle at the specified coordinates
|
|
505
|
+
* @name fillRoundRect
|
|
506
|
+
* @memberof CanvasRenderer
|
|
507
|
+
* @param {number} x
|
|
508
|
+
* @param {number} y
|
|
509
|
+
* @param {number} width
|
|
510
|
+
* @param {number} height
|
|
511
|
+
* @param {number} radius
|
|
512
|
+
*/
|
|
513
|
+
fillRoundRect(x, y, width, height, radius) {
|
|
514
|
+
this.strokeRoundRect(x, y, width, height, radius, true);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Stroke a Point at the specified coordinates
|
|
519
|
+
* @name strokePoint
|
|
520
|
+
* @memberof CanvasRenderer
|
|
521
|
+
* @param {number} x
|
|
522
|
+
* @param {number} y
|
|
523
|
+
*/
|
|
524
|
+
strokePoint(x, y) {
|
|
525
|
+
this.strokeLine(x, y, x + 1, y + 1);
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
/**
|
|
529
|
+
* Draw a a point at the specified coordinates
|
|
530
|
+
* @name fillPoint
|
|
531
|
+
* @memberof CanvasRenderer
|
|
532
|
+
* @param {number} x
|
|
533
|
+
* @param {number} y
|
|
534
|
+
* @param {number} width
|
|
535
|
+
* @param {number} height
|
|
536
|
+
*/
|
|
537
|
+
fillPoint(x, y) {
|
|
538
|
+
this.strokePoint(x, y);
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* return a reference to the font 2d Context
|
|
543
|
+
* @ignore
|
|
544
|
+
*/
|
|
545
|
+
getFontContext() {
|
|
546
|
+
// in canvas mode we can directly use the 2d context
|
|
547
|
+
return this.getContext();
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* save the canvas context
|
|
552
|
+
* @name save
|
|
553
|
+
* @memberof CanvasRenderer
|
|
554
|
+
*/
|
|
555
|
+
save() {
|
|
556
|
+
this.getContext().save();
|
|
557
|
+
}
|
|
558
|
+
|
|
559
|
+
/**
|
|
560
|
+
* restores the canvas context
|
|
561
|
+
* @name restore
|
|
562
|
+
* @memberof CanvasRenderer
|
|
563
|
+
*/
|
|
564
|
+
restore() {
|
|
565
|
+
this.getContext().restore();
|
|
566
|
+
this.currentColor.glArray[3] = this.getGlobalAlpha();
|
|
567
|
+
this.currentScissor[0] = 0;
|
|
568
|
+
this.currentScissor[1] = 0;
|
|
569
|
+
this.currentScissor[2] = this.getCanvas().width;
|
|
570
|
+
this.currentScissor[3] = this.getCanvas().height;
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* rotates the canvas context
|
|
575
|
+
* @name rotate
|
|
576
|
+
* @memberof CanvasRenderer
|
|
577
|
+
* @param {number} angle - in radians
|
|
578
|
+
*/
|
|
579
|
+
rotate(angle) {
|
|
580
|
+
this.getContext().rotate(angle);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
/**
|
|
584
|
+
* scales the canvas context
|
|
585
|
+
* @name scale
|
|
586
|
+
* @memberof CanvasRenderer
|
|
587
|
+
* @param {number} x
|
|
588
|
+
* @param {number} y
|
|
589
|
+
*/
|
|
590
|
+
scale(x, y) {
|
|
591
|
+
this.getContext().scale(x, y);
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
/**
|
|
595
|
+
* Set the current fill & stroke style color.
|
|
596
|
+
* By default, or upon reset, the value is set to #000000.
|
|
597
|
+
* @name setColor
|
|
598
|
+
* @memberof CanvasRenderer
|
|
599
|
+
* @param {Color|string} color - css color value
|
|
600
|
+
*/
|
|
601
|
+
setColor(color) {
|
|
602
|
+
var context = this.getContext();
|
|
603
|
+
context.strokeStyle =
|
|
604
|
+
context.fillStyle = (
|
|
605
|
+
color instanceof Color ?
|
|
606
|
+
color.toRGBA() :
|
|
607
|
+
color
|
|
608
|
+
);
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
/**
|
|
612
|
+
* Set the global alpha
|
|
613
|
+
* @name setGlobalAlpha
|
|
614
|
+
* @memberof CanvasRenderer
|
|
615
|
+
* @param {number} alpha - 0.0 to 1.0 values accepted.
|
|
616
|
+
*/
|
|
617
|
+
setGlobalAlpha(alpha) {
|
|
618
|
+
this.getContext().globalAlpha = this.currentColor.glArray[3] = alpha;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Return the global alpha
|
|
623
|
+
* @name getGlobalAlpha
|
|
624
|
+
* @memberof CanvasRenderer
|
|
625
|
+
* @returns {number} global alpha value
|
|
626
|
+
*/
|
|
627
|
+
getGlobalAlpha() {
|
|
628
|
+
return this.getContext().globalAlpha;
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
/**
|
|
632
|
+
* Set the line width on the context
|
|
633
|
+
* @name setLineWidth
|
|
634
|
+
* @memberof CanvasRenderer
|
|
635
|
+
* @param {number} width - Line width
|
|
636
|
+
*/
|
|
637
|
+
setLineWidth(width) {
|
|
638
|
+
this.getContext().lineWidth = width;
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/**
|
|
642
|
+
* Reset (overrides) the renderer transformation matrix to the
|
|
643
|
+
* identity one, and then apply the given transformation matrix.
|
|
644
|
+
* @name setTransform
|
|
645
|
+
* @memberof CanvasRenderer
|
|
646
|
+
* @param {Matrix2d} mat2d - Matrix to transform by
|
|
647
|
+
*/
|
|
648
|
+
setTransform(mat2d) {
|
|
649
|
+
this.resetTransform();
|
|
650
|
+
this.transform(mat2d);
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
/**
|
|
654
|
+
* Multiply given matrix into the renderer tranformation matrix
|
|
655
|
+
* @name transform
|
|
656
|
+
* @memberof CanvasRenderer
|
|
657
|
+
* @param {Matrix2d} mat2d - Matrix to transform by
|
|
658
|
+
*/
|
|
659
|
+
transform(mat2d) {
|
|
660
|
+
var m = mat2d.toArray(),
|
|
661
|
+
a = m[0],
|
|
662
|
+
b = m[1],
|
|
663
|
+
c = m[3],
|
|
664
|
+
d = m[4],
|
|
665
|
+
e = m[6],
|
|
666
|
+
f = m[7];
|
|
667
|
+
|
|
668
|
+
if (this.settings.subPixel === false) {
|
|
669
|
+
e |= 0;
|
|
670
|
+
f |= 0;
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
this.getContext().transform(a, b, c, d, e, f);
|
|
674
|
+
}
|
|
675
|
+
|
|
676
|
+
/**
|
|
677
|
+
* Translates the context to the given position
|
|
678
|
+
* @name translate
|
|
679
|
+
* @memberof CanvasRenderer
|
|
680
|
+
* @param {number} x
|
|
681
|
+
* @param {number} y
|
|
682
|
+
*/
|
|
683
|
+
translate(x, y) {
|
|
684
|
+
if (this.settings.subPixel === false) {
|
|
685
|
+
this.getContext().translate(~~x, ~~y);
|
|
686
|
+
} else {
|
|
687
|
+
this.getContext().translate(x, y);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
/**
|
|
692
|
+
* clip the given region from the original canvas. Once a region is clipped,
|
|
693
|
+
* all future drawing will be limited to the clipped region.
|
|
694
|
+
* You can however save the current region using the save(),
|
|
695
|
+
* and restore it (with the restore() method) any time in the future.
|
|
696
|
+
* (<u>this is an experimental feature !</u>)
|
|
697
|
+
* @name clipRect
|
|
698
|
+
* @memberof CanvasRenderer
|
|
699
|
+
* @param {number} x
|
|
700
|
+
* @param {number} y
|
|
701
|
+
* @param {number} width
|
|
702
|
+
* @param {number} height
|
|
703
|
+
*/
|
|
704
|
+
clipRect(x, y, width, height) {
|
|
705
|
+
var canvas = this.getCanvas();
|
|
706
|
+
// if requested box is different from the current canvas size;
|
|
707
|
+
if (x !== 0 || y !== 0 || width !== canvas.width || height !== canvas.height) {
|
|
708
|
+
var currentScissor = this.currentScissor;
|
|
709
|
+
// if different from the current scissor box
|
|
710
|
+
if (currentScissor[0] !== x || currentScissor[1] !== y ||
|
|
711
|
+
currentScissor[2] !== width || currentScissor[3] !== height) {
|
|
712
|
+
var context = this.getContext();
|
|
713
|
+
context.beginPath();
|
|
714
|
+
context.rect(x, y, width, height);
|
|
715
|
+
context.clip();
|
|
716
|
+
// save the new currentScissor box
|
|
717
|
+
currentScissor[0] = x;
|
|
718
|
+
currentScissor[1] = y;
|
|
719
|
+
currentScissor[2] = width;
|
|
720
|
+
currentScissor[3] = height;
|
|
721
|
+
}
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* A mask limits rendering elements to the shape and position of the given mask object.
|
|
727
|
+
* So, if the renderable is larger than the mask, only the intersecting part of the renderable will be visible.
|
|
728
|
+
* Mask are not preserved through renderer context save and restore.
|
|
729
|
+
* @name setMask
|
|
730
|
+
* @memberof CanvasRenderer
|
|
731
|
+
* @param {Rect|RoundRect|Polygon|Line|Ellipse} [mask] - the shape defining the mask to be applied
|
|
732
|
+
* @param {boolean} [invert=false] - either the given shape should define what is visible (default) or the opposite
|
|
733
|
+
*/
|
|
734
|
+
setMask(mask, invert = false) {
|
|
735
|
+
var context = this.getContext();
|
|
736
|
+
|
|
737
|
+
if (this.maskLevel === 0) {
|
|
738
|
+
// only save context on the first mask
|
|
739
|
+
context.save();
|
|
740
|
+
context.beginPath();
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// https://github.com/melonjs/melonJS/issues/648
|
|
744
|
+
if (mask instanceof RoundRect) {
|
|
745
|
+
context.roundRect(mask.top, mask.left, mask.width, mask.height, mask.radius);
|
|
746
|
+
} else if (mask instanceof Rect || mask instanceof Bounds) {
|
|
747
|
+
context.rect(mask.top, mask.left, mask.width, mask.height);
|
|
748
|
+
} else if (mask instanceof Ellipse) {
|
|
749
|
+
const _x = mask.pos.x, _y = mask.pos.y,
|
|
750
|
+
hw = mask.radiusV.x,
|
|
751
|
+
hh = mask.radiusV.y,
|
|
752
|
+
lx = _x - hw,
|
|
753
|
+
rx = _x + hw,
|
|
754
|
+
ty = _y - hh,
|
|
755
|
+
by = _y + hh;
|
|
756
|
+
|
|
757
|
+
var xmagic = hw * 0.551784,
|
|
758
|
+
ymagic = hh * 0.551784,
|
|
759
|
+
xmin = _x - xmagic,
|
|
760
|
+
xmax = _x + xmagic,
|
|
761
|
+
ymin = _y - ymagic,
|
|
762
|
+
ymax = _y + ymagic;
|
|
763
|
+
|
|
764
|
+
context.moveTo(_x, ty);
|
|
765
|
+
context.bezierCurveTo(xmax, ty, rx, ymin, rx, _y);
|
|
766
|
+
context.bezierCurveTo(rx, ymax, xmax, by, _x, by);
|
|
767
|
+
context.bezierCurveTo(xmin, by, lx, ymax, lx, _y);
|
|
768
|
+
context.bezierCurveTo(lx, ymin, xmin, ty, _x, ty);
|
|
769
|
+
} else {
|
|
770
|
+
// polygon
|
|
771
|
+
const _x = mask.pos.x, _y = mask.pos.y;
|
|
772
|
+
var point;
|
|
773
|
+
|
|
774
|
+
context.moveTo(_x + mask.points[0].x, _y + mask.points[0].y);
|
|
775
|
+
for (var i = 1; i < mask.points.length; i++) {
|
|
776
|
+
point = mask.points[i];
|
|
777
|
+
context.lineTo(_x + point.x, _y + point.y);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
this.maskLevel++;
|
|
782
|
+
|
|
783
|
+
if (invert === true) {
|
|
784
|
+
context.closePath();
|
|
785
|
+
context.globalCompositeOperation = "destination-atop";
|
|
786
|
+
context.fill();
|
|
787
|
+
} else {
|
|
788
|
+
context.clip();
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/**
|
|
793
|
+
* disable (remove) the rendering mask set through setMask.
|
|
794
|
+
* @name clearMask
|
|
795
|
+
* @see CanvasRenderer#setMask
|
|
796
|
+
* @memberof CanvasRenderer
|
|
797
|
+
*/
|
|
798
|
+
clearMask() {
|
|
799
|
+
if (this.maskLevel > 0) {
|
|
800
|
+
this.maskLevel = 0;
|
|
801
|
+
this.getContext().restore();
|
|
802
|
+
}
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
var CanvasRenderer$1 = CanvasRenderer;
|
|
806
|
+
|
|
807
|
+
export { CanvasRenderer$1 as default };
|