@vpmedia/phaser 1.0.1 → 1.0.3

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 (112) hide show
  1. package/README.md +20 -3
  2. package/dist/phaser.cjs +1 -1
  3. package/dist/phaser.cjs.LICENSE.txt +1 -1
  4. package/dist/phaser.cjs.map +1 -1
  5. package/dist/phaser.js +1 -1
  6. package/dist/phaser.js.LICENSE.txt +1 -1
  7. package/dist/phaser.js.map +1 -1
  8. package/package.json +23 -17
  9. package/src/index.js +142 -0
  10. package/src/phaser/core/animation.js +355 -0
  11. package/src/phaser/core/animation_manager.js +238 -0
  12. package/src/phaser/core/animation_parser.js +133 -0
  13. package/src/phaser/core/array_set.js +107 -0
  14. package/src/phaser/core/cache.js +558 -0
  15. package/src/phaser/core/const.js +106 -0
  16. package/src/phaser/core/device.js +67 -0
  17. package/src/phaser/core/device_util.js +388 -0
  18. package/src/phaser/core/dom.js +207 -0
  19. package/src/phaser/core/event_manager.js +243 -0
  20. package/src/phaser/core/factory.js +74 -0
  21. package/src/phaser/core/frame.js +75 -0
  22. package/src/phaser/core/frame_data.js +84 -0
  23. package/src/phaser/core/frame_util.js +33 -0
  24. package/src/phaser/core/game.js +412 -0
  25. package/src/phaser/core/input.js +401 -0
  26. package/src/phaser/core/input_button.js +102 -0
  27. package/src/phaser/core/input_handler.js +687 -0
  28. package/src/phaser/core/input_mouse.js +289 -0
  29. package/src/phaser/core/input_mspointer.js +197 -0
  30. package/src/phaser/core/input_pointer.js +427 -0
  31. package/src/phaser/core/input_touch.js +157 -0
  32. package/src/phaser/core/loader.js +1057 -0
  33. package/src/phaser/core/loader_parser.js +109 -0
  34. package/src/phaser/core/raf.js +46 -0
  35. package/src/phaser/core/raf_fb.js +75 -0
  36. package/src/phaser/core/raf_to.js +34 -0
  37. package/src/phaser/core/scale_manager.js +806 -0
  38. package/src/phaser/core/scene.js +65 -0
  39. package/src/phaser/core/scene_manager.js +309 -0
  40. package/src/phaser/core/signal.js +175 -0
  41. package/src/phaser/core/signal_binding.js +69 -0
  42. package/src/phaser/core/sound.js +538 -0
  43. package/src/phaser/core/sound_manager.js +364 -0
  44. package/src/phaser/core/stage.js +108 -0
  45. package/src/phaser/core/time.js +203 -0
  46. package/src/phaser/core/timer.js +276 -0
  47. package/src/phaser/core/timer_event.js +21 -0
  48. package/src/phaser/core/tween.js +329 -0
  49. package/src/phaser/core/tween_data.js +258 -0
  50. package/src/phaser/core/tween_easing.js +341 -0
  51. package/src/phaser/core/tween_manager.js +185 -0
  52. package/src/phaser/core/world.js +18 -0
  53. package/src/phaser/display/bitmap_text.js +322 -0
  54. package/src/phaser/display/button.js +194 -0
  55. package/src/phaser/display/canvas/buffer.js +36 -0
  56. package/src/phaser/display/canvas/graphics.js +227 -0
  57. package/src/phaser/display/canvas/masker.js +39 -0
  58. package/src/phaser/display/canvas/pool.js +126 -0
  59. package/src/phaser/display/canvas/renderer.js +123 -0
  60. package/src/phaser/display/canvas/tinter.js +144 -0
  61. package/src/phaser/display/canvas/util.js +159 -0
  62. package/src/phaser/display/display_object.js +597 -0
  63. package/src/phaser/display/graphics.js +723 -0
  64. package/src/phaser/display/graphics_data.js +27 -0
  65. package/src/phaser/display/graphics_data_util.js +15 -0
  66. package/src/phaser/display/group.js +227 -0
  67. package/src/phaser/display/image.js +288 -0
  68. package/src/phaser/display/sprite_batch.js +15 -0
  69. package/src/phaser/display/sprite_util.js +250 -0
  70. package/src/phaser/display/text.js +1089 -0
  71. package/src/phaser/display/webgl/abstract_filter.js +25 -0
  72. package/src/phaser/display/webgl/base_texture.js +68 -0
  73. package/src/phaser/display/webgl/blend_manager.js +35 -0
  74. package/src/phaser/display/webgl/earcut.js +662 -0
  75. package/src/phaser/display/webgl/earcut_node.js +28 -0
  76. package/src/phaser/display/webgl/fast_sprite_batch.js +242 -0
  77. package/src/phaser/display/webgl/filter_manager.js +46 -0
  78. package/src/phaser/display/webgl/filter_texture.js +61 -0
  79. package/src/phaser/display/webgl/graphics.js +624 -0
  80. package/src/phaser/display/webgl/graphics_data.js +42 -0
  81. package/src/phaser/display/webgl/mask_manager.js +36 -0
  82. package/src/phaser/display/webgl/render_texture.js +81 -0
  83. package/src/phaser/display/webgl/renderer.js +234 -0
  84. package/src/phaser/display/webgl/shader/complex.js +74 -0
  85. package/src/phaser/display/webgl/shader/fast.js +97 -0
  86. package/src/phaser/display/webgl/shader/normal.js +225 -0
  87. package/src/phaser/display/webgl/shader/primitive.js +72 -0
  88. package/src/phaser/display/webgl/shader/strip.js +77 -0
  89. package/src/phaser/display/webgl/shader_manager.js +89 -0
  90. package/src/phaser/display/webgl/sprite_batch.js +320 -0
  91. package/src/phaser/display/webgl/stencil_manager.js +170 -0
  92. package/src/phaser/display/webgl/texture.js +117 -0
  93. package/src/phaser/display/webgl/texture_util.js +34 -0
  94. package/src/phaser/display/webgl/util.js +78 -0
  95. package/src/phaser/geom/circle.js +186 -0
  96. package/src/phaser/geom/ellipse.js +65 -0
  97. package/src/phaser/geom/line.js +190 -0
  98. package/src/phaser/geom/matrix.js +147 -0
  99. package/src/phaser/geom/point.js +164 -0
  100. package/src/phaser/geom/polygon.js +140 -0
  101. package/src/phaser/geom/rectangle.js +306 -0
  102. package/src/phaser/geom/rounded_rectangle.js +36 -0
  103. package/src/phaser/geom/util/circle.js +122 -0
  104. package/src/phaser/geom/util/ellipse.js +34 -0
  105. package/src/phaser/geom/util/line.js +135 -0
  106. package/src/phaser/geom/util/matrix.js +53 -0
  107. package/src/phaser/geom/util/point.js +296 -0
  108. package/src/phaser/geom/util/polygon.js +28 -0
  109. package/src/phaser/geom/util/rectangle.js +229 -0
  110. package/src/phaser/geom/util/rounded_rectangle.js +32 -0
  111. package/src/phaser/util/math.js +297 -0
  112. package/src/phaser/util/string.js +32 -0
@@ -0,0 +1,36 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @author Mat Groves http://matgroves.com/ @Doormat23
5
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
6
+ */
7
+ import { create, removeByCanvas } from './pool';
8
+
9
+ export default class {
10
+
11
+ constructor(width, height) {
12
+ this.width = width;
13
+ this.height = height;
14
+ this.canvas = create(this, this.width, this.height);
15
+ this.context = this.canvas.getContext('2d');
16
+ this.canvas.width = width;
17
+ this.canvas.height = height;
18
+ }
19
+
20
+ clear() {
21
+ this.context.setTransform(1, 0, 0, 1, 0, 0);
22
+ this.context.clearRect(0, 0, this.width, this.height);
23
+ }
24
+
25
+ resize(width, height) {
26
+ this.width = width;
27
+ this.height = height;
28
+ this.canvas.width = width;
29
+ this.canvas.height = height;
30
+ }
31
+
32
+ destroy() {
33
+ removeByCanvas(this.canvas);
34
+ }
35
+
36
+ }
@@ -0,0 +1,227 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @author Mat Groves http://matgroves.com/ @Doormat23
5
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
6
+ */
7
+ import { GEOM_POLYGON, GEOM_RECTANGLE, GEOM_CIRCLE, GEOM_ELLIPSE, GEOM_ROUNDED_RECTANGLE } from '../../core/const';
8
+
9
+ /**
10
+ *
11
+ * @param {object} graphics TBD
12
+ */
13
+ export function updateGraphicsTint(graphics) {
14
+ if (graphics.tint === 0xFFFFFF) {
15
+ return;
16
+ }
17
+ const tintR = (graphics.tint >> 16 & 0xFF) / 255;
18
+ const tintG = (graphics.tint >> 8 & 0xFF) / 255;
19
+ const tintB = (graphics.tint & 0xFF) / 255;
20
+ for (let i = 0; i < graphics.graphicsData.length; i += 1) {
21
+ const data = graphics.graphicsData[i];
22
+ const fillColor = data.fillColor | 0;
23
+ const lineColor = data.lineColor | 0;
24
+ data._fillTint = (((fillColor >> 16 & 0xFF) / 255 * tintR * 255 << 16) + ((fillColor >> 8 & 0xFF) / 255 * tintG * 255 << 8) + (fillColor & 0xFF) / 255 * tintB * 255);
25
+ data._lineTint = (((lineColor >> 16 & 0xFF) / 255 * tintR * 255 << 16) + ((lineColor >> 8 & 0xFF) / 255 * tintG * 255 << 8) + (lineColor & 0xFF) / 255 * tintB * 255);
26
+ }
27
+ }
28
+
29
+ /**
30
+ *
31
+ * @param {object} graphics TBD
32
+ * @param {object} context TBD
33
+ */
34
+ export function renderGraphics(graphics, context) {
35
+ const worldAlpha = graphics.worldAlpha;
36
+ if (graphics.dirty) {
37
+ updateGraphicsTint(graphics);
38
+ graphics.dirty = false;
39
+ }
40
+ for (let i = 0; i < graphics.graphicsData.length; i += 1) {
41
+ const data = graphics.graphicsData[i];
42
+ const shape = data.shape;
43
+ const fillColor = data._fillTint;
44
+ const lineColor = data._lineTint;
45
+ context.lineWidth = data.lineWidth;
46
+ if (data.type === GEOM_POLYGON) {
47
+ context.beginPath();
48
+ const points = shape.points;
49
+ context.moveTo(points[0], points[1]);
50
+ for (let j = 1; j < points.length / 2; j += 1) {
51
+ context.lineTo(points[j * 2], points[j * 2 + 1]);
52
+ }
53
+ if (shape.closed) {
54
+ context.lineTo(points[0], points[1]);
55
+ }
56
+ // if the first and last point are the same close the path - much neater :)
57
+ if (points[0] === points[points.length - 2] && points[1] === points[points.length - 1]) {
58
+ context.closePath();
59
+ }
60
+ if (data.fill) {
61
+ context.globalAlpha = data.fillAlpha * worldAlpha;
62
+ context.fillStyle = '#' + ('00000' + (fillColor | 0).toString(16)).substr(-6);
63
+ context.fill();
64
+ }
65
+ if (data.lineWidth) {
66
+ context.globalAlpha = data.lineAlpha * worldAlpha;
67
+ context.strokeStyle = '#' + ('00000' + (lineColor | 0).toString(16)).substr(-6);
68
+ context.stroke();
69
+ }
70
+ } else if (data.type === GEOM_RECTANGLE) {
71
+ if (data.fillColor || data.fillColor === 0) {
72
+ context.globalAlpha = data.fillAlpha * worldAlpha;
73
+ context.fillStyle = '#' + ('00000' + (fillColor | 0).toString(16)).substr(-6);
74
+ context.fillRect(shape.x, shape.y, shape.width, shape.height);
75
+ }
76
+ if (data.lineWidth) {
77
+ context.globalAlpha = data.lineAlpha * worldAlpha;
78
+ context.strokeStyle = '#' + ('00000' + (lineColor | 0).toString(16)).substr(-6);
79
+ context.strokeRect(shape.x, shape.y, shape.width, shape.height);
80
+ }
81
+ } else if (data.type === GEOM_CIRCLE) {
82
+ context.beginPath();
83
+ context.arc(shape.x, shape.y, shape.radius, 0, 2 * Math.PI);
84
+ context.closePath();
85
+ if (data.fill) {
86
+ context.globalAlpha = data.fillAlpha * worldAlpha;
87
+ context.fillStyle = '#' + ('00000' + (fillColor | 0).toString(16)).substr(-6);
88
+ context.fill();
89
+ }
90
+ if (data.lineWidth) {
91
+ context.globalAlpha = data.lineAlpha * worldAlpha;
92
+ context.strokeStyle = '#' + ('00000' + (lineColor | 0).toString(16)).substr(-6);
93
+ context.stroke();
94
+ }
95
+ } else if (data.type === GEOM_ELLIPSE) {
96
+ // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
97
+ const w = shape.width * 2;
98
+ const h = shape.height * 2;
99
+ const x = shape.x - w / 2;
100
+ const y = shape.y - h / 2;
101
+ context.beginPath();
102
+ const kappa = 0.5522848;
103
+ const ox = (w / 2) * kappa; // control point offset horizontal
104
+ const oy = (h / 2) * kappa; // control point offset vertical
105
+ const xe = x + w; // x-end
106
+ const ye = y + h; // y-end
107
+ const xm = x + w / 2; // x-middle
108
+ const ym = y + h / 2; // y-middle
109
+ context.moveTo(x, ym);
110
+ context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
111
+ context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
112
+ context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
113
+ context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
114
+ context.closePath();
115
+ if (data.fill) {
116
+ context.globalAlpha = data.fillAlpha * worldAlpha;
117
+ context.fillStyle = '#' + ('00000' + (fillColor | 0).toString(16)).substr(-6);
118
+ context.fill();
119
+ }
120
+ if (data.lineWidth) {
121
+ context.globalAlpha = data.lineAlpha * worldAlpha;
122
+ context.strokeStyle = '#' + ('00000' + (lineColor | 0).toString(16)).substr(-6);
123
+ context.stroke();
124
+ }
125
+ } else if (data.type === GEOM_ROUNDED_RECTANGLE) {
126
+ const rx = shape.x;
127
+ const ry = shape.y;
128
+ const width = shape.width;
129
+ const height = shape.height;
130
+ let radius = shape.radius;
131
+ const maxRadius = Math.min(width, height) / 2 | 0;
132
+ radius = radius > maxRadius ? maxRadius : radius;
133
+ context.beginPath();
134
+ context.moveTo(rx, ry + radius);
135
+ context.lineTo(rx, ry + height - radius);
136
+ context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height);
137
+ context.lineTo(rx + width - radius, ry + height);
138
+ context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius);
139
+ context.lineTo(rx + width, ry + radius);
140
+ context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry);
141
+ context.lineTo(rx + radius, ry);
142
+ context.quadraticCurveTo(rx, ry, rx, ry + radius);
143
+ context.closePath();
144
+ if (data.fillColor || data.fillColor === 0) {
145
+ context.globalAlpha = data.fillAlpha * worldAlpha;
146
+ context.fillStyle = '#' + ('00000' + (fillColor | 0).toString(16)).substr(-6);
147
+ context.fill();
148
+ }
149
+ if (data.lineWidth) {
150
+ context.globalAlpha = data.lineAlpha * worldAlpha;
151
+ context.strokeStyle = '#' + ('00000' + (lineColor | 0).toString(16)).substr(-6);
152
+ context.stroke();
153
+ }
154
+ }
155
+ }
156
+ }
157
+
158
+ /**
159
+ *
160
+ * @param {object} graphics TBD
161
+ * @param {object} context TBD
162
+ */
163
+ export function renderGraphicsMask(graphics, context) {
164
+ const len = graphics.graphicsData.length;
165
+ if (len === 0) {
166
+ return;
167
+ }
168
+ context.beginPath();
169
+ for (let i = 0; i < len; i += 1) {
170
+ const data = graphics.graphicsData[i];
171
+ const shape = data.shape;
172
+ if (data.type === GEOM_POLYGON) {
173
+ const points = shape.points;
174
+ context.moveTo(points[0], points[1]);
175
+ for (let j = 1; j < points.length / 2; j += 1) {
176
+ context.lineTo(points[j * 2], points[j * 2 + 1]);
177
+ }
178
+ // if the first and last point are the same close the path - much neater :)
179
+ if (points[0] === points[points.length - 2] && points[1] === points[points.length - 1]) {
180
+ context.closePath();
181
+ }
182
+ } else if (data.type === GEOM_RECTANGLE) {
183
+ context.rect(shape.x, shape.y, shape.width, shape.height);
184
+ context.closePath();
185
+ } else if (data.type === GEOM_CIRCLE) {
186
+ context.arc(shape.x, shape.y, shape.radius, 0, 2 * Math.PI);
187
+ context.closePath();
188
+ } else if (data.type === GEOM_ELLIPSE) {
189
+ // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
190
+ const w = shape.width * 2;
191
+ const h = shape.height * 2;
192
+ const x = shape.x - w / 2;
193
+ const y = shape.y - h / 2;
194
+ const kappa = 0.5522848;
195
+ const ox = (w / 2) * kappa; // control point offset horizontal
196
+ const oy = (h / 2) * kappa; // control point offset vertical
197
+ const xe = x + w; // x-end
198
+ const ye = y + h; // y-end
199
+ const xm = x + w / 2; // x-middle
200
+ const ym = y + h / 2; // y-middle
201
+ context.moveTo(x, ym);
202
+ context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
203
+ context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
204
+ context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
205
+ context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
206
+ context.closePath();
207
+ } else if (data.type === GEOM_ROUNDED_RECTANGLE) {
208
+ const rx = shape.x;
209
+ const ry = shape.y;
210
+ const width = shape.width;
211
+ const height = shape.height;
212
+ let radius = shape.radius;
213
+ const maxRadius = Math.min(width, height) / 2 | 0;
214
+ radius = radius > maxRadius ? maxRadius : radius;
215
+ context.moveTo(rx, ry + radius);
216
+ context.lineTo(rx, ry + height - radius);
217
+ context.quadraticCurveTo(rx, ry + height, rx + radius, ry + height);
218
+ context.lineTo(rx + width - radius, ry + height);
219
+ context.quadraticCurveTo(rx + width, ry + height, rx + width, ry + height - radius);
220
+ context.lineTo(rx + width, ry + radius);
221
+ context.quadraticCurveTo(rx + width, ry, rx + width - radius, ry);
222
+ context.lineTo(rx + radius, ry);
223
+ context.quadraticCurveTo(rx, ry, rx, ry + radius);
224
+ context.closePath();
225
+ }
226
+ }
227
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @author Mat Groves http://matgroves.com/ @Doormat23
5
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
6
+ */
7
+ import { renderGraphicsMask } from './graphics';
8
+
9
+ /**
10
+ *
11
+ * @param {object} maskData TBD
12
+ * @param {object} renderSession TBD
13
+ */
14
+ export function pushMask(maskData, renderSession) {
15
+ const context = renderSession.context;
16
+ context.save();
17
+ const cacheAlpha = maskData.alpha;
18
+ const transform = maskData.worldTransform;
19
+ const resolution = renderSession.resolution;
20
+ context.setTransform(
21
+ transform.a * resolution,
22
+ transform.b * resolution,
23
+ transform.c * resolution,
24
+ transform.d * resolution,
25
+ transform.tx * resolution,
26
+ transform.ty * resolution,
27
+ );
28
+ renderGraphicsMask(maskData, context);
29
+ context.clip();
30
+ maskData.worldAlpha = cacheAlpha;
31
+ }
32
+
33
+ /**
34
+ *
35
+ * @param {object} renderSession TBD
36
+ */
37
+ export function popMask(renderSession) {
38
+ renderSession.context.restore();
39
+ }
@@ -0,0 +1,126 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @author Mat Groves http://matgroves.com/ @Doormat23
5
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
6
+ */
7
+
8
+ /**
9
+ *
10
+ * @returns {object} TBD
11
+ */
12
+ export function getPool() {
13
+ if (!window.PhaserRegistry) {
14
+ window.PhaserRegistry = {};
15
+ }
16
+ if (!window.PhaserRegistry.CANVAS_POOL) {
17
+ window.PhaserRegistry.CANVAS_POOL = [];
18
+ }
19
+ return window.PhaserRegistry.CANVAS_POOL;
20
+ }
21
+
22
+ /**
23
+ *
24
+ * @returns {object} TBD
25
+ */
26
+ export function getFirst() {
27
+ const pool = getPool();
28
+ for (let i = 0; i < pool.length; i += 1) {
29
+ if (!pool[i].parent) {
30
+ return i;
31
+ }
32
+ }
33
+ return -1;
34
+ }
35
+
36
+ /**
37
+ *
38
+ * @param {object} parent TBD
39
+ */
40
+ export function remove(parent) {
41
+ const pool = getPool();
42
+ for (let i = 0; i < pool.length; i += 1) {
43
+ if (pool[i].parent === parent) {
44
+ pool[i].parent = null;
45
+ pool[i].canvas.width = 1;
46
+ pool[i].canvas.height = 1;
47
+ }
48
+ }
49
+ }
50
+
51
+ /**
52
+ *
53
+ * @param {object} canvas TBD
54
+ */
55
+ export function removeByCanvas(canvas) {
56
+ const pool = getPool();
57
+ for (let i = 0; i < pool.length; i += 1) {
58
+ if (pool[i].canvas === canvas) {
59
+ pool[i].parent = null;
60
+ pool[i].canvas.width = 1;
61
+ pool[i].canvas.height = 1;
62
+ }
63
+ }
64
+ }
65
+
66
+ /**
67
+ *
68
+ * @returns {number} TBD
69
+ */
70
+ export function getTotal() {
71
+ const pool = getPool();
72
+ let c = 0;
73
+ for (let i = 0; i < pool.length; i += 1) {
74
+ if (pool[i].parent) {
75
+ c += 1;
76
+ }
77
+ }
78
+ return c;
79
+ }
80
+
81
+ /**
82
+ *
83
+ * @returns {number} TBD
84
+ */
85
+ export function getFree() {
86
+ const pool = getPool();
87
+ let c = 0;
88
+ for (let i = 0; i < pool.length; i += 1) {
89
+ if (!pool[i].parent) {
90
+ c += 1;
91
+ }
92
+ }
93
+ return c;
94
+ }
95
+
96
+ /**
97
+ *
98
+ * @param {object} parent TBD
99
+ * @param {number} width TBD
100
+ * @param {number} height TBD
101
+ * @returns {object} TBD
102
+ */
103
+ export function create(parent, width, height) {
104
+ if (parent === undefined) {
105
+ console.warn('Created CanvasPool element with undefined parent.');
106
+ }
107
+ const idx = getFirst();
108
+ const pool = getPool();
109
+ let canvas;
110
+ if (idx === -1) {
111
+ const container = {
112
+ parent,
113
+ canvas: document.createElement('canvas'),
114
+ };
115
+ pool.push(container);
116
+ canvas = container.canvas;
117
+ } else {
118
+ pool[idx].parent = parent;
119
+ canvas = pool[idx].canvas;
120
+ }
121
+ if (width !== undefined) {
122
+ canvas.width = width;
123
+ canvas.height = height;
124
+ }
125
+ return canvas;
126
+ }
@@ -0,0 +1,123 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @author Mat Groves http://matgroves.com/ @Doormat23
5
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
6
+ */
7
+ import { RENDER_CANVAS, SCALE_LINEAR, BLEND_NORMAL, BLEND_ADD, BLEND_MULTIPLY, BLEND_SCREEN, BLEND_OVERLAY, BLEND_DARKEN, BLEND_LIGHTEN, BLEND_COLOR_DODGE, BLEND_COLOR_BURN, BLEND_HARD_LIGHT, BLEND_SOFT_LIGHT, BLEND_DIFFERENCE, BLEND_EXCLUSION, BLEND_HUE, BLEND_SATURATION, BLEND_COLOR, BLEND_LUMINOSITY } from '../../core/const';
8
+ import { getSmoothingPrefix } from './util';
9
+ import { detectCapabilities } from './tinter';
10
+ import * as CanvasMaskManager from './masker';
11
+
12
+ export default class {
13
+
14
+ constructor(game) {
15
+ detectCapabilities();
16
+ this.type = RENDER_CANVAS;
17
+ this.resolution = game.config.resolution;
18
+ this.clearBeforeRender = game.config.clearBeforeRender;
19
+ this.transparent = game.config.transparent;
20
+ this.autoResize = false;
21
+ this.width = game.width * this.resolution;
22
+ this.height = game.height * this.resolution;
23
+ this.view = game.canvas;
24
+ this.context = this.view.getContext('2d', { alpha: this.transparent });
25
+ if (!this.context) {
26
+ throw new Error('Error creating Canvas 2D context.');
27
+ }
28
+ this.refresh = true;
29
+ this.count = 0;
30
+ this.renderSession = {
31
+ context: this.context,
32
+ maskManager: CanvasMaskManager,
33
+ scaleMode: null,
34
+ smoothProperty: getSmoothingPrefix(this.context),
35
+ roundPixels: false,
36
+ };
37
+ this.mapBlendModes();
38
+ this.resize(this.width, this.height);
39
+ window.PhaserRegistry.DEFAULT_RENDERER = this;
40
+ }
41
+
42
+ render(root) {
43
+ if (!this.context) {
44
+ return;
45
+ }
46
+ this.context.setTransform(1, 0, 0, 1, 0, 0);
47
+ this.context.globalAlpha = 1;
48
+ this.renderSession.currentBlendMode = 0;
49
+ this.renderSession.shakeX = 0;
50
+ this.renderSession.shakeY = 0;
51
+ this.context.globalCompositeOperation = 'source-over';
52
+ if (navigator.isCocoonJS && this.view.screencanvas) {
53
+ this.context.fillStyle = 'black';
54
+ this.context.clear();
55
+ }
56
+ if (this.clearBeforeRender) {
57
+ if (this.transparent) {
58
+ this.context.clearRect(0, 0, this.width, this.height);
59
+ } else if (root._bgColor) {
60
+ this.context.fillStyle = root._bgColor.rgba;
61
+ this.context.fillRect(0, 0, this.width, this.height);
62
+ }
63
+ }
64
+ this.renderDisplayObject(root);
65
+ }
66
+
67
+ destroy(removeView = true) {
68
+ if (removeView && this.view.parent) {
69
+ this.view.parent.removeChild(this.view);
70
+ }
71
+ this.view = null;
72
+ this.context = null;
73
+ this.renderSession = null;
74
+ window.PhaserRegistry.DEFAULT_RENDERER = null;
75
+ }
76
+
77
+ resize(width, height) {
78
+ this.width = width * this.resolution;
79
+ this.height = height * this.resolution;
80
+ this.view.width = this.width;
81
+ this.view.height = this.height;
82
+ if (this.autoResize) {
83
+ this.view.style.width = this.width / this.resolution + 'px';
84
+ this.view.style.height = this.height / this.resolution + 'px';
85
+ }
86
+ if (this.renderSession.smoothProperty) {
87
+ this.context[this.renderSession.smoothProperty] = (this.renderSession.scaleMode === SCALE_LINEAR);
88
+ }
89
+ }
90
+
91
+ renderDisplayObject(displayObject, context, matrix) {
92
+ this.renderSession.context = context || this.context;
93
+ this.renderSession.resolution = this.resolution;
94
+ displayObject.renderCanvas(this.renderSession, matrix);
95
+ }
96
+
97
+ mapBlendModes() {
98
+ if (window.PhaserRegistry.blendModesCanvas) {
99
+ return;
100
+ }
101
+ const b = [];
102
+ const useNew = window.PhaserRegistry.CAN_CANVAS_USE_MULTIPLY;
103
+ b[BLEND_NORMAL] = 'source-over';
104
+ b[BLEND_ADD] = 'lighter';
105
+ b[BLEND_MULTIPLY] = (useNew) ? 'multiply' : 'source-over';
106
+ b[BLEND_SCREEN] = (useNew) ? 'screen' : 'source-over';
107
+ b[BLEND_OVERLAY] = (useNew) ? 'overlay' : 'source-over';
108
+ b[BLEND_DARKEN] = (useNew) ? 'darken' : 'source-over';
109
+ b[BLEND_LIGHTEN] = (useNew) ? 'lighten' : 'source-over';
110
+ b[BLEND_COLOR_DODGE] = (useNew) ? 'color-dodge' : 'source-over';
111
+ b[BLEND_COLOR_BURN] = (useNew) ? 'color-burn' : 'source-over';
112
+ b[BLEND_HARD_LIGHT] = (useNew) ? 'hard-light' : 'source-over';
113
+ b[BLEND_SOFT_LIGHT] = (useNew) ? 'soft-light' : 'source-over';
114
+ b[BLEND_DIFFERENCE] = (useNew) ? 'difference' : 'source-over';
115
+ b[BLEND_EXCLUSION] = (useNew) ? 'exclusion' : 'source-over';
116
+ b[BLEND_HUE] = (useNew) ? 'hue' : 'source-over';
117
+ b[BLEND_SATURATION] = (useNew) ? 'saturation' : 'source-over';
118
+ b[BLEND_COLOR] = (useNew) ? 'color' : 'source-over';
119
+ b[BLEND_LUMINOSITY] = (useNew) ? 'luminosity' : 'source-over';
120
+ window.PhaserRegistry.blendModesCanvas = b;
121
+ }
122
+
123
+ }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * @author Andras Csizmadia <andras@vpmedia.hu>
3
+ * @author Richard Davey <rich@photonstorm.com>
4
+ * @author Mat Groves http://matgroves.com/ @Doormat23
5
+ * @copyright Copyright (c) 2018-present Richard Davey, Photon Storm Ltd., Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)
6
+ */
7
+ import CanvasBuffer from './buffer';
8
+ import { create, removeByCanvas } from './pool';
9
+ import { hex2rgb } from '../../util/math';
10
+
11
+ /**
12
+ *
13
+ * @param {object} sprite TBD
14
+ * @param {object} color TBD
15
+ * @returns {object} TBD
16
+ */
17
+ export function getTintedTexture(sprite, color) {
18
+ const canvas = sprite.tintedTexture || create('CanvasTinter');
19
+ window.PhaserRegistry.CANVAS_TINT_METHOD(sprite.texture, color, canvas);
20
+ return canvas;
21
+ }
22
+
23
+ /**
24
+ *
25
+ * @param {object} texture TBD
26
+ * @param {object} color TBD
27
+ * @param {object} canvas TBD
28
+ */
29
+ export function tintWithMultiply(texture, color, canvas) {
30
+ const context = canvas.getContext('2d');
31
+ const crop = texture.crop;
32
+ if (canvas.width !== crop.width || canvas.height !== crop.height) {
33
+ canvas.width = crop.width;
34
+ canvas.height = crop.height;
35
+ }
36
+ context.clearRect(0, 0, crop.width, crop.height);
37
+ context.fillStyle = '#' + ('00000' + (color | 0).toString(16)).substr(-6);
38
+ context.fillRect(0, 0, crop.width, crop.height);
39
+ context.globalCompositeOperation = 'multiply';
40
+ context.drawImage(texture.baseTexture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
41
+ context.globalCompositeOperation = 'destination-atop';
42
+ context.drawImage(texture.baseTexture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
43
+ }
44
+
45
+ /**
46
+ *
47
+ * @param {object} texture TBD
48
+ * @param {object} color TBD
49
+ * @param {object} canvas TBD
50
+ */
51
+ export function tintWithPerPixel(texture, color, canvas) {
52
+ const context = canvas.getContext('2d');
53
+ const crop = texture.crop;
54
+ canvas.width = crop.width;
55
+ canvas.height = crop.height;
56
+ context.globalCompositeOperation = 'copy';
57
+ context.drawImage(texture.baseTexture.source, crop.x, crop.y, crop.width, crop.height, 0, 0, crop.width, crop.height);
58
+ const rgbValues = hex2rgb(color);
59
+ const r = rgbValues[0];
60
+ const g = rgbValues[1];
61
+ const b = rgbValues[2];
62
+ const pixelData = context.getImageData(0, 0, crop.width, crop.height);
63
+ const pixels = pixelData.data;
64
+ for (let i = 0; i < pixels.length; i += 4) {
65
+ pixels[i + 0] *= r;
66
+ pixels[i + 1] *= g;
67
+ pixels[i + 2] *= b;
68
+ const canHandleAlpha = window.PhaserRegistry.CAN_CANVAS_HANDLE_ALPHA;
69
+ if (!canHandleAlpha) {
70
+ const alpha = pixels[i + 3];
71
+ pixels[i + 0] /= 255 / alpha;
72
+ pixels[i + 1] /= 255 / alpha;
73
+ pixels[i + 2] /= 255 / alpha;
74
+ }
75
+ }
76
+ context.putImageData(pixelData, 0, 0);
77
+ }
78
+
79
+ /**
80
+ *
81
+ * @returns {boolean} TBD
82
+ */
83
+ export function checkInverseAlpha() {
84
+ const canvas = new CanvasBuffer(2, 1);
85
+ canvas.context.fillStyle = 'rgba(10, 20, 30, 0.5)';
86
+ // Draw a single pixel
87
+ canvas.context.fillRect(0, 0, 1, 1);
88
+ // Get the color values
89
+ const s1 = canvas.context.getImageData(0, 0, 1, 1);
90
+ if (s1 === null) {
91
+ return false;
92
+ }
93
+ // Plot them to x2
94
+ canvas.context.putImageData(s1, 1, 0);
95
+ // Get those values
96
+ const s2 = canvas.context.getImageData(1, 0, 1, 1);
97
+ // Compare and return
98
+ return (s2.data[0] === s1.data[0] && s2.data[1] === s1.data[1] && s2.data[2] === s1.data[2] && s2.data[3] === s1.data[3]);
99
+ }
100
+
101
+ /**
102
+ *
103
+ * @returns {boolean} TBD
104
+ */
105
+ export function canUseNewCanvasBlendModes() {
106
+ if (document === undefined) {
107
+ return false;
108
+ }
109
+ const pngHead = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAABAQMAAADD8p2OAAAAA1BMVEX/';
110
+ const pngEnd = 'AAAACklEQVQI12NgAAAAAgAB4iG8MwAAAABJRU5ErkJggg==';
111
+ const magenta = new Image();
112
+ magenta.src = pngHead + 'AP804Oa6' + pngEnd;
113
+ const yellow = new Image();
114
+ yellow.src = pngHead + '/wCKxvRF' + pngEnd;
115
+ const canvas = create('CanvasTinter', 6, 1);
116
+ const context = canvas.getContext('2d');
117
+ context.globalCompositeOperation = 'multiply';
118
+ context.drawImage(magenta, 0, 0);
119
+ context.drawImage(yellow, 2, 0);
120
+ if (!context.getImageData(2, 0, 1, 1)) {
121
+ return false;
122
+ }
123
+ const data = context.getImageData(2, 0, 1, 1).data;
124
+ removeByCanvas(canvas);
125
+ return (data[0] === 255 && data[1] === 0 && data[2] === 0);
126
+ }
127
+
128
+ /**
129
+ * TBD
130
+ */
131
+ export function detectCapabilities() {
132
+ if (!window.PhaserRegistry) {
133
+ window.PhaserRegistry = {};
134
+ }
135
+ if (!window.PhaserRegistry.CAN_CANVAS_HANDLE_ALPHA) {
136
+ window.PhaserRegistry.CAN_CANVAS_HANDLE_ALPHA = checkInverseAlpha();
137
+ }
138
+ if (!window.PhaserRegistry.CAN_CANVAS_USE_MULTIPLY) {
139
+ window.PhaserRegistry.CAN_CANVAS_USE_MULTIPLY = canUseNewCanvasBlendModes();
140
+ }
141
+ if (!window.PhaserRegistry.CANVAS_TINT_METHOD) {
142
+ window.PhaserRegistry.CANVAS_TINT_METHOD = window.PhaserRegistry.CAN_CANVAS_USE_MULTIPLY ? tintWithMultiply : tintWithPerPixel;
143
+ }
144
+ }