xmedia-project 0.1.4 → 0.1.5

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 (186) hide show
  1. package/demo/index.html +16 -0
  2. package/demo/server.mjs +6 -1
  3. package/package.json +2 -1
  4. package/xMediaSDK/filter/background/halloween/bloodMoon.js +257 -0
  5. package/xMediaSDK/filter/background/halloween/bloodMoon.min.js +1 -0
  6. package/xMediaSDK/filter/background/halloween/bloodMoon.min.mjs +1 -0
  7. package/xMediaSDK/filter/background/halloween/bloodMoon.mjs +248 -0
  8. package/xMediaSDK/filter/background/halloween/darkForest.js +264 -0
  9. package/xMediaSDK/filter/background/halloween/darkForest.min.js +1 -0
  10. package/xMediaSDK/filter/background/halloween/darkForest.min.mjs +1 -0
  11. package/xMediaSDK/filter/background/halloween/darkForest.mjs +255 -0
  12. package/xMediaSDK/filter/background/halloween/graveyard.js +272 -0
  13. package/xMediaSDK/filter/background/halloween/graveyard.min.js +1 -0
  14. package/xMediaSDK/filter/background/halloween/graveyard.min.mjs +1 -0
  15. package/xMediaSDK/filter/background/halloween/graveyard.mjs +263 -0
  16. package/xMediaSDK/filter/background/halloween/hauntedHouse.js +270 -0
  17. package/xMediaSDK/filter/background/halloween/hauntedHouse.min.js +1 -0
  18. package/xMediaSDK/filter/background/halloween/hauntedHouse.min.mjs +1 -0
  19. package/xMediaSDK/filter/background/halloween/hauntedHouse.mjs +261 -0
  20. package/xMediaSDK/filter/background/halloween/pumpkinPatch.js +282 -0
  21. package/xMediaSDK/filter/background/halloween/pumpkinPatch.min.js +1 -0
  22. package/xMediaSDK/filter/background/halloween/pumpkinPatch.min.mjs +1 -0
  23. package/xMediaSDK/filter/background/halloween/pumpkinPatch.mjs +273 -0
  24. package/xMediaSDK/filter/background.js +135 -0
  25. package/xMediaSDK/filter/background.min.js +1 -0
  26. package/xMediaSDK/filter/background.min.mjs +1 -0
  27. package/xMediaSDK/filter/background.mjs +126 -0
  28. package/xMediaSDK/filter/face.js +269 -0
  29. package/xMediaSDK/filter/face.min.js +1 -0
  30. package/xMediaSDK/filter/face.min.mjs +1 -0
  31. package/xMediaSDK/filter/face.mjs +259 -0
  32. package/xMediaSDK/filter/mask/cat.js +271 -0
  33. package/xMediaSDK/filter/mask/cat.min.js +1 -0
  34. package/xMediaSDK/filter/mask/cat.min.mjs +1 -0
  35. package/xMediaSDK/filter/mask/cat.mjs +262 -0
  36. package/xMediaSDK/filter/mask/clown.js +254 -0
  37. package/xMediaSDK/filter/mask/clown.min.js +1 -0
  38. package/xMediaSDK/filter/mask/clown.min.mjs +1 -0
  39. package/xMediaSDK/filter/mask/clown.mjs +245 -0
  40. package/xMediaSDK/filter/mask/costume.js +280 -0
  41. package/xMediaSDK/filter/mask/costume.min.js +1 -0
  42. package/xMediaSDK/filter/mask/costume.min.mjs +1 -0
  43. package/xMediaSDK/filter/mask/costume.mjs +271 -0
  44. package/xMediaSDK/filter/mask/general/bunny.js +282 -0
  45. package/xMediaSDK/filter/mask/general/bunny.min.js +1 -0
  46. package/xMediaSDK/filter/mask/general/bunny.min.mjs +1 -0
  47. package/xMediaSDK/filter/mask/general/bunny.mjs +273 -0
  48. package/xMediaSDK/filter/mask/general/butterflies.js +267 -0
  49. package/xMediaSDK/filter/mask/general/butterflies.min.js +1 -0
  50. package/xMediaSDK/filter/mask/general/butterflies.min.mjs +1 -0
  51. package/xMediaSDK/filter/mask/general/butterflies.mjs +258 -0
  52. package/xMediaSDK/filter/mask/general/flowerCrown.js +274 -0
  53. package/xMediaSDK/filter/mask/general/flowerCrown.min.js +1 -0
  54. package/xMediaSDK/filter/mask/general/flowerCrown.min.mjs +1 -0
  55. package/xMediaSDK/filter/mask/general/flowerCrown.mjs +265 -0
  56. package/xMediaSDK/filter/mask/general/freckles.js +261 -0
  57. package/xMediaSDK/filter/mask/general/freckles.min.js +1 -0
  58. package/xMediaSDK/filter/mask/general/freckles.min.mjs +1 -0
  59. package/xMediaSDK/filter/mask/general/freckles.mjs +252 -0
  60. package/xMediaSDK/filter/mask/general/hearts.js +257 -0
  61. package/xMediaSDK/filter/mask/general/hearts.min.js +1 -0
  62. package/xMediaSDK/filter/mask/general/hearts.min.mjs +1 -0
  63. package/xMediaSDK/filter/mask/general/hearts.mjs +248 -0
  64. package/xMediaSDK/filter/mask/general/makeup.js +284 -0
  65. package/xMediaSDK/filter/mask/general/makeup.min.js +1 -0
  66. package/xMediaSDK/filter/mask/general/makeup.min.mjs +1 -0
  67. package/xMediaSDK/filter/mask/general/makeup.mjs +275 -0
  68. package/xMediaSDK/filter/mask/general/puppy.js +283 -0
  69. package/xMediaSDK/filter/mask/general/puppy.min.js +1 -0
  70. package/xMediaSDK/filter/mask/general/puppy.min.mjs +1 -0
  71. package/xMediaSDK/filter/mask/general/puppy.mjs +274 -0
  72. package/xMediaSDK/filter/mask/general/sparkles.js +255 -0
  73. package/xMediaSDK/filter/mask/general/sparkles.min.js +1 -0
  74. package/xMediaSDK/filter/mask/general/sparkles.min.mjs +1 -0
  75. package/xMediaSDK/filter/mask/general/sparkles.mjs +246 -0
  76. package/xMediaSDK/filter/mask/general/tiara.js +280 -0
  77. package/xMediaSDK/filter/mask/general/tiara.min.js +1 -0
  78. package/xMediaSDK/filter/mask/general/tiara.min.mjs +1 -0
  79. package/xMediaSDK/filter/mask/general/tiara.mjs +271 -0
  80. package/xMediaSDK/filter/mask/general/unicorn.js +270 -0
  81. package/xMediaSDK/filter/mask/general/unicorn.min.js +1 -0
  82. package/xMediaSDK/filter/mask/general/unicorn.min.mjs +1 -0
  83. package/xMediaSDK/filter/mask/general/unicorn.mjs +261 -0
  84. package/xMediaSDK/filter/mask/glasses.js +271 -0
  85. package/xMediaSDK/filter/mask/glasses.min.js +1 -0
  86. package/xMediaSDK/filter/mask/glasses.min.mjs +1 -0
  87. package/xMediaSDK/filter/mask/glasses.mjs +262 -0
  88. package/xMediaSDK/filter/mask/halloween/bats.js +269 -0
  89. package/xMediaSDK/filter/mask/halloween/bats.min.js +1 -0
  90. package/xMediaSDK/filter/mask/halloween/bats.min.mjs +1 -0
  91. package/xMediaSDK/filter/mask/halloween/bats.mjs +260 -0
  92. package/xMediaSDK/filter/mask/halloween/blood.js +256 -0
  93. package/xMediaSDK/filter/mask/halloween/blood.min.js +1 -0
  94. package/xMediaSDK/filter/mask/halloween/blood.min.mjs +1 -0
  95. package/xMediaSDK/filter/mask/halloween/blood.mjs +247 -0
  96. package/xMediaSDK/filter/mask/halloween/fangs.js +256 -0
  97. package/xMediaSDK/filter/mask/halloween/fangs.min.js +1 -0
  98. package/xMediaSDK/filter/mask/halloween/fangs.min.mjs +1 -0
  99. package/xMediaSDK/filter/mask/halloween/fangs.mjs +247 -0
  100. package/xMediaSDK/filter/mask/halloween/frankenstein.js +300 -0
  101. package/xMediaSDK/filter/mask/halloween/frankenstein.min.js +1 -0
  102. package/xMediaSDK/filter/mask/halloween/frankenstein.min.mjs +1 -0
  103. package/xMediaSDK/filter/mask/halloween/frankenstein.mjs +291 -0
  104. package/xMediaSDK/filter/mask/halloween/ghost.js +277 -0
  105. package/xMediaSDK/filter/mask/halloween/ghost.min.js +1 -0
  106. package/xMediaSDK/filter/mask/halloween/ghost.min.mjs +1 -0
  107. package/xMediaSDK/filter/mask/halloween/ghost.mjs +268 -0
  108. package/xMediaSDK/filter/mask/halloween/horns.js +250 -0
  109. package/xMediaSDK/filter/mask/halloween/horns.min.js +1 -0
  110. package/xMediaSDK/filter/mask/halloween/horns.min.mjs +1 -0
  111. package/xMediaSDK/filter/mask/halloween/horns.mjs +241 -0
  112. package/xMediaSDK/filter/mask/halloween/mummy.js +267 -0
  113. package/xMediaSDK/filter/mask/halloween/mummy.min.js +1 -0
  114. package/xMediaSDK/filter/mask/halloween/mummy.min.mjs +1 -0
  115. package/xMediaSDK/filter/mask/halloween/mummy.mjs +258 -0
  116. package/xMediaSDK/filter/mask/halloween/pumpkin.js +296 -0
  117. package/xMediaSDK/filter/mask/halloween/pumpkin.min.js +1 -0
  118. package/xMediaSDK/filter/mask/halloween/pumpkin.min.mjs +1 -0
  119. package/xMediaSDK/filter/mask/halloween/pumpkin.mjs +287 -0
  120. package/xMediaSDK/filter/mask/halloween/skull.js +277 -0
  121. package/xMediaSDK/filter/mask/halloween/skull.min.js +1 -0
  122. package/xMediaSDK/filter/mask/halloween/skull.min.mjs +1 -0
  123. package/xMediaSDK/filter/mask/halloween/skull.mjs +268 -0
  124. package/xMediaSDK/filter/mask/halloween/spiderweb.js +300 -0
  125. package/xMediaSDK/filter/mask/halloween/spiderweb.min.js +1 -0
  126. package/xMediaSDK/filter/mask/halloween/spiderweb.min.mjs +1 -0
  127. package/xMediaSDK/filter/mask/halloween/spiderweb.mjs +291 -0
  128. package/xMediaSDK/filter/mask/halloween/witchHat.js +262 -0
  129. package/xMediaSDK/filter/mask/halloween/witchHat.min.js +1 -0
  130. package/xMediaSDK/filter/mask/halloween/witchHat.min.mjs +1 -0
  131. package/xMediaSDK/filter/mask/halloween/witchHat.mjs +253 -0
  132. package/xMediaSDK/filter/mask/halloween/zombie.js +278 -0
  133. package/xMediaSDK/filter/mask/halloween/zombie.min.js +1 -0
  134. package/xMediaSDK/filter/mask/halloween/zombie.min.mjs +1 -0
  135. package/xMediaSDK/filter/mask/halloween/zombie.mjs +269 -0
  136. package/xMediaSDK/filter/mask/hat.js +250 -0
  137. package/xMediaSDK/filter/mask/hat.min.js +1 -0
  138. package/xMediaSDK/filter/mask/hat.min.mjs +1 -0
  139. package/xMediaSDK/filter/mask/hat.mjs +241 -0
  140. package/xMediaSDK/filter/mask/image.js +286 -0
  141. package/xMediaSDK/filter/mask/image.min.js +1 -0
  142. package/xMediaSDK/filter/mask/image.min.mjs +1 -0
  143. package/xMediaSDK/filter/mask/image.mjs +277 -0
  144. package/xMediaSDK/filter/mask/mustache.js +245 -0
  145. package/xMediaSDK/filter/mask/mustache.min.js +1 -0
  146. package/xMediaSDK/filter/mask/mustache.min.mjs +1 -0
  147. package/xMediaSDK/filter/mask/mustache.mjs +236 -0
  148. package/xMediaSDK/filter/mask/pixel.js +249 -0
  149. package/xMediaSDK/filter/mask/pixel.min.js +1 -0
  150. package/xMediaSDK/filter/mask/pixel.min.mjs +1 -0
  151. package/xMediaSDK/filter/mask/pixel.mjs +240 -0
  152. package/xMediaSDK/filter/mask/witch/broom.js +292 -0
  153. package/xMediaSDK/filter/mask/witch/broom.min.js +1 -0
  154. package/xMediaSDK/filter/mask/witch/broom.min.mjs +1 -0
  155. package/xMediaSDK/filter/mask/witch/broom.mjs +283 -0
  156. package/xMediaSDK/filter/mask/witch/cauldron.js +271 -0
  157. package/xMediaSDK/filter/mask/witch/cauldron.min.js +1 -0
  158. package/xMediaSDK/filter/mask/witch/cauldron.min.mjs +1 -0
  159. package/xMediaSDK/filter/mask/witch/cauldron.mjs +262 -0
  160. package/xMediaSDK/filter/mask/witch/magic.js +251 -0
  161. package/xMediaSDK/filter/mask/witch/magic.min.js +1 -0
  162. package/xMediaSDK/filter/mask/witch/magic.min.mjs +1 -0
  163. package/xMediaSDK/filter/mask/witch/magic.mjs +242 -0
  164. package/xMediaSDK/filter/mask/witch/raven.js +276 -0
  165. package/xMediaSDK/filter/mask/witch/raven.min.js +1 -0
  166. package/xMediaSDK/filter/mask/witch/raven.min.mjs +1 -0
  167. package/xMediaSDK/filter/mask/witch/raven.mjs +267 -0
  168. package/xMediaSDK/filter/mask/witch/witchMakeup.js +258 -0
  169. package/xMediaSDK/filter/mask/witch/witchMakeup.min.js +1 -0
  170. package/xMediaSDK/filter/mask/witch/witchMakeup.min.mjs +1 -0
  171. package/xMediaSDK/filter/mask/witch/witchMakeup.mjs +249 -0
  172. package/xMediaSDK/filter/mask/witch/witchNose.js +273 -0
  173. package/xMediaSDK/filter/mask/witch/witchNose.min.js +1 -0
  174. package/xMediaSDK/filter/mask/witch/witchNose.min.mjs +1 -0
  175. package/xMediaSDK/filter/mask/witch/witchNose.mjs +264 -0
  176. package/xMediaSDK/filter/retouch.js +230 -0
  177. package/xMediaSDK/filter/retouch.min.js +1 -0
  178. package/xMediaSDK/filter/retouch.min.mjs +1 -0
  179. package/xMediaSDK/filter/retouch.mjs +221 -0
  180. package/xMediaSDK/xMediaPlayer.css +226 -45
  181. package/xMediaSDK/xMediaPlayer.min.css +1 -1
  182. package/xMediaSDK/xMediaPlayer.min.css.map +1 -1
  183. package/xMediaSDK/xMediaSDK.js +1085 -41
  184. package/xMediaSDK/xMediaSDK.min.js +1 -1
  185. package/xMediaSDK/xMediaSDK.min.js.map +1 -1
  186. package/xMediaSDK/xMediaSDK.mjs +1085 -42
package/demo/index.html CHANGED
@@ -51,6 +51,22 @@
51
51
 
52
52
  <script src="/xmedia/xMediaSDK.js"></script>
53
53
  <script>
54
+ const FILTER_MODULE_LIST = {
55
+ '': ['background', 'retouch', 'face'],
56
+ 'background/halloween/': ['graveyard', 'hauntedHouse', 'bloodMoon', 'pumpkinPatch', 'darkForest'],
57
+ 'mask/': ['glasses', 'mustache', 'hat', 'costume', 'clown', 'cat', 'pixel', 'image'],
58
+ 'mask/general/': ['flowerCrown', 'bunny', 'tiara', 'hearts', 'butterflies', 'makeup', 'freckles', 'unicorn', 'puppy', 'sparkles'],
59
+ 'mask/witch/': ['witchMakeup', 'witchNose', 'broom', 'magic', 'raven', 'cauldron'],
60
+ 'mask/halloween/': ['pumpkin', 'skull', 'zombie', 'frankenstein', 'ghost', 'mummy', 'witchHat', 'horns', 'fangs', 'blood', 'bats', 'spiderweb'],
61
+ };
62
+ for (const [modulePath, moduleNameList] of Object.entries(FILTER_MODULE_LIST)) {
63
+ for (const moduleName of moduleNameList) {
64
+ const scriptEl = document.createElement('script');
65
+ scriptEl.src = `/xmedia/filter/${modulePath}${moduleName}.min.js`;
66
+ document.head.append(scriptEl);
67
+ }
68
+ }
69
+
54
70
  const $ = id => document.getElementById(id);
55
71
  const log = (...args) => {
56
72
  const line = `${new Date().toISOString().slice(11, 23)} ${args.map(a => typeof a === 'string' ? a : JSON.stringify(a)).join(' ')}`;
package/demo/server.mjs CHANGED
@@ -100,8 +100,13 @@ const SDK_FILE_MAP = {
100
100
  '/xmedia/xMediaSDK.js': {url: import.meta.resolve('xmedia-project/xMediaSDK/xMediaSDK.js'), type: 'text/javascript; charset=utf-8'},
101
101
  '/xmedia/xMediaPlayer.css': {url: import.meta.resolve('xmedia-project/sdk/xMediaPlayer.css'), type: 'text/css; charset=utf-8'},
102
102
  };
103
+ const getFilterFile = (urlPath) => {
104
+ const match = urlPath.match(/^\/xmedia\/filter\/([\w/]+\.min\.js)$/);
105
+ return match && {url: import.meta.resolve(`xmedia-project/xMediaSDK/filter/${match[1]}`), type: 'text/javascript; charset=utf-8'};
106
+ };
103
107
  const server = http.createServer((req, res) => {
104
- const sdkFile = SDK_FILE_MAP[req.url.split('?')[0]];
108
+ const urlPath = req.url.split('?')[0];
109
+ const sdkFile = SDK_FILE_MAP[urlPath] || getFilterFile(urlPath);
105
110
  if (sdkFile) {
106
111
  fs.readFile(new URL(sdkFile.url), (e, body) => {
107
112
  res.writeHead(e ? 404 : 200, {'content-type': sdkFile.type});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xmedia-project",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "xMedia-Project",
5
5
  "keywords": [
6
6
  "xmedia",
@@ -36,6 +36,7 @@
36
36
  "xMediaSDK/xMediaPlayer.css",
37
37
  "xMediaSDK/xMediaPlayer.min.css",
38
38
  "xMediaSDK/xMediaPlayer.min.css.map",
39
+ "xMediaSDK/filter",
39
40
  "demo/server.mjs",
40
41
  "demo/index.html",
41
42
  "demo/.env.example",
@@ -0,0 +1,257 @@
1
+ var xMediaFilterModule = (function (exports) {
2
+ 'use strict';
3
+
4
+ var xMediaScene = function(__xMediaFilter, __options, __sceneOptions) {
5
+
6
+ var $this = this;
7
+ var __sceneCanvas;
8
+ var __sceneCtx;
9
+ var __personCanvas;
10
+ var __personCtx;
11
+ var __sceneData = null;
12
+
13
+ this.getOrder = function() {
14
+ return 10;
15
+ };
16
+
17
+ this.getGroup = function() {
18
+ return 'background';
19
+ };
20
+
21
+ this.isExclusive = function() {
22
+ return true;
23
+ };
24
+
25
+ this.getOptions = function() {
26
+ return __options;
27
+ };
28
+
29
+ this.setOptions = function(options) {
30
+ for(var key in options){
31
+ if(options.hasOwnProperty(key)){
32
+ __options[key] = options[key];
33
+ }
34
+ }
35
+ };
36
+
37
+ this.load = function() {
38
+ return __xMediaFilter.loadSegmenter().then(function() {
39
+ return $this;
40
+ });
41
+ };
42
+
43
+ this.process = function(frame) {
44
+ var person = __xMediaFilter.segmentPerson(frame);
45
+ if(!person){
46
+ return;
47
+ }
48
+ var width = frame['width'];
49
+ var height = frame['height'];
50
+ var ctx = frame['ctx'];
51
+ if(__sceneCanvas.width !== width || __sceneCanvas.height !== height || !__sceneData){
52
+ __xMediaFilter.resizeCanvas(__sceneCanvas, width, height);
53
+ __sceneData = __sceneOptions['drawStatic'](__sceneCtx, width, height, xMediaScene.createRandom(__sceneOptions['seed'] || 7)) || {};
54
+ }
55
+ __xMediaFilter.resizeCanvas(__personCanvas, width, height);
56
+ __personCtx.globalCompositeOperation = 'copy';
57
+ __personCtx.drawImage(person['canvas'], 0, 0, width, height);
58
+ __personCtx.globalCompositeOperation = 'source-in';
59
+ __personCtx.drawImage(frame['canvas'], 0, 0);
60
+ ctx.globalCompositeOperation = 'copy';
61
+ ctx.drawImage(__sceneCanvas, 0, 0);
62
+ ctx.globalCompositeOperation = 'source-over';
63
+ if(__sceneOptions['drawBack']){
64
+ ctx.save();
65
+ __sceneOptions['drawBack'](ctx, width, height, frame['timestamp'], __sceneData);
66
+ ctx.restore();
67
+ }
68
+ ctx.drawImage(__personCanvas, 0, 0);
69
+ if(__sceneOptions['drawFront']){
70
+ ctx.save();
71
+ __sceneOptions['drawFront'](ctx, width, height, frame['timestamp'], __sceneData);
72
+ ctx.restore();
73
+ }
74
+ };
75
+
76
+ this.destroy = function() {
77
+ __sceneData = null;
78
+ };
79
+
80
+ (function() {
81
+ __options = __options || {};
82
+ __sceneCanvas = __xMediaFilter.createCanvas();
83
+ __sceneCtx = __sceneCanvas.getContext('2d');
84
+ __personCanvas = __xMediaFilter.createCanvas();
85
+ __personCtx = __personCanvas.getContext('2d');
86
+ })();
87
+ };
88
+
89
+ xMediaScene.createRandom = function(seed) {
90
+ var value = seed % 2147483647 || 1;
91
+ return function() {
92
+ value = value * 16807 % 2147483647;
93
+ return (value - 1) / 2147483646;
94
+ };
95
+ };
96
+
97
+ xMediaScene.fillSky = function(ctx, width, height, colorList) {
98
+ var gradient = ctx.createLinearGradient(0, 0, 0, height);
99
+ for(var i = 0; i < colorList.length; i++){
100
+ gradient.addColorStop(i / (colorList.length - 1), colorList[i]);
101
+ }
102
+ ctx.fillStyle = gradient;
103
+ ctx.fillRect(0, 0, width, height);
104
+ };
105
+
106
+ xMediaScene.drawStars = function(ctx, width, height, random, count) {
107
+ for(var i = 0; i < count; i++){
108
+ ctx.fillStyle = 'rgba(255, 255, 255, ' + (0.3 + random() * 0.7) + ')';
109
+ ctx.fillRect(random() * width, random() * height * 0.6, random() < 0.9 ? 1 : 2, 1 + (random() < 0.1 ? 1 : 0));
110
+ }
111
+ };
112
+
113
+ xMediaScene.drawMoon = function(ctx, x, y, radius, color, glowColor) {
114
+ var glow = ctx.createRadialGradient(x, y, radius * 0.8, x, y, radius * 3);
115
+ glow.addColorStop(0, glowColor);
116
+ glow.addColorStop(1, 'rgba(0, 0, 0, 0)');
117
+ ctx.fillStyle = glow;
118
+ ctx.fillRect(x - radius * 3, y - radius * 3, radius * 6, radius * 6);
119
+ var body = ctx.createRadialGradient(x - radius * 0.3, y - radius * 0.3, radius * 0.1, x, y, radius);
120
+ body.addColorStop(0, '#ffffff');
121
+ body.addColorStop(0.35, color);
122
+ body.addColorStop(1, color);
123
+ ctx.fillStyle = body;
124
+ ctx.beginPath();
125
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
126
+ ctx.fill();
127
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.08)';
128
+ var craterList = [[-0.3, -0.2, 0.18], [0.25, 0.1, 0.22], [-0.1, 0.4, 0.12], [0.35, -0.35, 0.1]];
129
+ for(var i = 0; i < craterList.length; i++){
130
+ ctx.beginPath();
131
+ ctx.arc(x + craterList[i][0] * radius, y + craterList[i][1] * radius, craterList[i][2] * radius, 0, Math.PI * 2);
132
+ ctx.fill();
133
+ }
134
+ };
135
+
136
+ xMediaScene.drawTree = function(ctx, x, y, length, angle, width, depth, random) {
137
+ var endX = x + Math.cos(angle) * length;
138
+ var endY = y + Math.sin(angle) * length;
139
+ ctx.lineWidth = width;
140
+ ctx.lineCap = 'round';
141
+ ctx.beginPath();
142
+ ctx.moveTo(x, y);
143
+ ctx.quadraticCurveTo(x + Math.cos(angle + 0.3) * length * 0.5, y + Math.sin(angle + 0.3) * length * 0.5, endX, endY);
144
+ ctx.stroke();
145
+ if(depth <= 0){
146
+ return;
147
+ }
148
+ var branchCount = 2 + Math.floor(random() * 2);
149
+ for(var i = 0; i < branchCount; i++){
150
+ xMediaScene.drawTree(ctx, endX, endY, length * (0.55 + random() * 0.2), angle + (random() - 0.5) * 1.4, width * 0.62, depth - 1, random);
151
+ }
152
+ };
153
+
154
+ xMediaScene.drawBat = function(ctx, x, y, size, flap) {
155
+ ctx.save();
156
+ ctx.translate(x, y);
157
+ ctx.scale(size, size);
158
+ ctx.beginPath();
159
+ for(var side = -1; side <= 1; side += 2){
160
+ ctx.moveTo(0, 0);
161
+ ctx.quadraticCurveTo(side * 0.4, -0.5 * flap - 0.1, side * 1, -0.3 * flap);
162
+ ctx.quadraticCurveTo(side * 0.7, -0.05, side * 0.55, 0.15);
163
+ ctx.quadraticCurveTo(side * 0.35, 0, side * 0.15, 0.15);
164
+ ctx.closePath();
165
+ }
166
+ ctx.ellipse(0, 0.05, 0.12, 0.2, 0, 0, Math.PI * 2);
167
+ ctx.fill();
168
+ ctx.restore();
169
+ };
170
+
171
+ xMediaScene.drawFog = function(ctx, width, height, time, y, color, count, speed) {
172
+ for(var i = 0; i < count; i++){
173
+ var radius = width * (0.18 + (i % 3) * 0.06);
174
+ var x = ((i * 0.37 + time * speed / width * (1 + (i % 2) * 0.5)) % 1.4 - 0.2) * width;
175
+ var fogY = y + Math.sin(time / 2000 + i) * height * 0.02;
176
+ var gradient = ctx.createRadialGradient(x, fogY, 0, x, fogY, radius);
177
+ gradient.addColorStop(0, color);
178
+ gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
179
+ ctx.fillStyle = gradient;
180
+ ctx.fillRect(x - radius, fogY - radius, radius * 2, radius * 2);
181
+ }
182
+ };
183
+
184
+ xMediaScene.createModule = function(name, SceneClass, info) {
185
+ return {
186
+ 'name': 'background/' + (info['category'] ? info['category'] + '/' : '') + name,
187
+ 'filterList': [{'name': name, 'category': 'background', 'title': info['title'], 'icon': info['icon'], 'filterClass': SceneClass}],
188
+ 'dependencyList': []
189
+ };
190
+ };
191
+
192
+ var _drawStatic = function(ctx, width, height, random) {
193
+ xMediaScene.fillSky(ctx, width, height, ['#140003', '#3a0006', '#6e0b0b', '#2a0204']);
194
+ xMediaScene.drawStars(ctx, width, height * 0.6, random, Math.round(width * height / 8000));
195
+ xMediaScene.drawMoon(ctx, width * 0.3, height * 0.34, height * 0.22, '#c8261a', 'rgba(255, 40, 20, 0.35)');
196
+ ctx.strokeStyle = '#080102';
197
+ ctx.fillStyle = '#080102';
198
+ xMediaScene.drawTree(ctx, width * 0.06, height * 1.02, height * 0.3, -Math.PI / 2 + 0.15, height * 0.045, 5, random);
199
+ xMediaScene.drawTree(ctx, width * 0.95, height * 1.02, height * 0.28, -Math.PI / 2 - 0.2, height * 0.04, 5, random);
200
+ ctx.beginPath();
201
+ ctx.moveTo(0, height);
202
+ for(var x = 0; x <= width; x += width / 24){
203
+ ctx.lineTo(x, height * (0.9 + Math.sin(x / width * 11) * 0.02 + random() * 0.015));
204
+ }
205
+ ctx.lineTo(width, height);
206
+ ctx.closePath();
207
+ ctx.fill();
208
+ var crowList = [[0.12, 0.52], [0.86, 0.5], [0.9, 0.62]];
209
+ for(var i = 0; i < crowList.length; i++){
210
+ var crowX = crowList[i][0] * width;
211
+ var crowY = crowList[i][1] * height;
212
+ var size = height * 0.02;
213
+ ctx.beginPath();
214
+ ctx.ellipse(crowX, crowY, size, size * 0.7, -0.3, 0, Math.PI * 2);
215
+ ctx.arc(crowX + size * 0.9, crowY - size * 0.7, size * 0.45, 0, Math.PI * 2);
216
+ ctx.moveTo(crowX + size * 1.3, crowY - size * 0.8);
217
+ ctx.lineTo(crowX + size * 1.8, crowY - size * 0.6);
218
+ ctx.lineTo(crowX + size * 1.3, crowY - size * 0.5);
219
+ ctx.moveTo(crowX - size * 0.8, crowY);
220
+ ctx.lineTo(crowX - size * 1.8, crowY + size * 0.6);
221
+ ctx.lineTo(crowX - size * 0.6, crowY + size * 0.5);
222
+ ctx.fill();
223
+ }
224
+ return {};
225
+ };
226
+
227
+ var _drawBack = function(ctx, width, height, time) {
228
+ for(var i = 0; i < 5; i++){
229
+ var x = ((i * 0.27 + time / 60000 * (1 + i * 0.2)) % 1.5 - 0.25) * width;
230
+ var y = height * (0.12 + i * 0.09);
231
+ var gradient = ctx.createRadialGradient(x, y, 0, x, y, width * 0.22);
232
+ gradient.addColorStop(0, 'rgba(20, 0, 2, 0.75)');
233
+ gradient.addColorStop(1, 'rgba(20, 0, 2, 0)');
234
+ ctx.fillStyle = gradient;
235
+ ctx.save();
236
+ ctx.translate(x, y);
237
+ ctx.scale(1, 0.3);
238
+ ctx.translate(-x, -y);
239
+ ctx.fillRect(x - width * 0.22, y - width * 0.22, width * 0.44, width * 0.44);
240
+ ctx.restore();
241
+ }
242
+ xMediaScene.drawFog(ctx, width, height, time, height * 0.95, 'rgba(160, 10, 10, 0.18)', 5, 0.015);
243
+ };
244
+
245
+ var xMediaBloodMoonScene = function(__xMediaFilter, __options) {
246
+ xMediaScene.call(this, __xMediaFilter, __options, {'seed': 31, 'drawStatic': _drawStatic, 'drawBack': _drawBack});
247
+ };
248
+
249
+ var filterModule = xMediaScene.createModule('bloodMoon', xMediaBloodMoonScene, {'title': 'Blood moon', 'icon': '🌕', 'category': 'halloween'});
250
+
251
+ exports.filterModule = filterModule;
252
+ exports.xMediaBloodMoonScene = xMediaBloodMoonScene;
253
+
254
+ return exports;
255
+
256
+ })({});
257
+ window.xMediaFilter ? window.xMediaFilter.registerModule(xMediaFilterModule.filterModule) : (window.xMediaFilterModuleList = window.xMediaFilterModuleList || []).push(xMediaFilterModule.filterModule);
@@ -0,0 +1 @@
1
+ var xMediaFilterModule=function(e){"use strict";var t=function(e,a,r){var o,i,n,l,d=this,c=null;this.getOrder=function(){return 10},this.getGroup=function(){return"background"},this.isExclusive=function(){return!0},this.getOptions=function(){return a},this.setOptions=function(e){for(var t in e)e.hasOwnProperty(t)&&(a[t]=e[t])},this.load=function(){return e.loadSegmenter().then(function(){return d})},this.process=function(a){var d=e.segmentPerson(a);if(d){var s=a.width,f=a.height,u=a.ctx;o.width===s&&o.height===f&&c||(e.resizeCanvas(o,s,f),c=r.drawStatic(i,s,f,t.createRandom(r.seed||7))||{}),e.resizeCanvas(n,s,f),l.globalCompositeOperation="copy",l.drawImage(d.canvas,0,0,s,f),l.globalCompositeOperation="source-in",l.drawImage(a.canvas,0,0),u.globalCompositeOperation="copy",u.drawImage(o,0,0),u.globalCompositeOperation="source-over",r.drawBack&&(u.save(),r.drawBack(u,s,f,a.timestamp,c),u.restore()),u.drawImage(n,0,0),r.drawFront&&(u.save(),r.drawFront(u,s,f,a.timestamp,c),u.restore())}},this.destroy=function(){c=null},a=a||{},o=e.createCanvas(),i=o.getContext("2d"),n=e.createCanvas(),l=n.getContext("2d")};t.createRandom=function(e){var t=e%2147483647||1;return function(){return((t=16807*t%2147483647)-1)/2147483646}},t.fillSky=function(e,t,a,r){for(var o=e.createLinearGradient(0,0,0,a),i=0;i<r.length;i++)o.addColorStop(i/(r.length-1),r[i]);e.fillStyle=o,e.fillRect(0,0,t,a)},t.drawStars=function(e,t,a,r,o){for(var i=0;i<o;i++)e.fillStyle="rgba(255, 255, 255, "+(.3+.7*r())+")",e.fillRect(r()*t,r()*a*.6,r()<.9?1:2,1+(r()<.1?1:0))},t.drawMoon=function(e,t,a,r,o,i){var n=e.createRadialGradient(t,a,.8*r,t,a,3*r);n.addColorStop(0,i),n.addColorStop(1,"rgba(0, 0, 0, 0)"),e.fillStyle=n,e.fillRect(t-3*r,a-3*r,6*r,6*r);var l=e.createRadialGradient(t-.3*r,a-.3*r,.1*r,t,a,r);l.addColorStop(0,"#ffffff"),l.addColorStop(.35,o),l.addColorStop(1,o),e.fillStyle=l,e.beginPath(),e.arc(t,a,r,0,2*Math.PI),e.fill(),e.fillStyle="rgba(0, 0, 0, 0.08)";for(var d=[[-.3,-.2,.18],[.25,.1,.22],[-.1,.4,.12],[.35,-.35,.1]],c=0;c<d.length;c++)e.beginPath(),e.arc(t+d[c][0]*r,a+d[c][1]*r,d[c][2]*r,0,2*Math.PI),e.fill()},t.drawTree=function(e,a,r,o,i,n,l,d){var c=a+Math.cos(i)*o,s=r+Math.sin(i)*o;if(e.lineWidth=n,e.lineCap="round",e.beginPath(),e.moveTo(a,r),e.quadraticCurveTo(a+Math.cos(i+.3)*o*.5,r+Math.sin(i+.3)*o*.5,c,s),e.stroke(),!(l<=0))for(var f=2+Math.floor(2*d()),u=0;u<f;u++)t.drawTree(e,c,s,o*(.55+.2*d()),i+1.4*(d()-.5),.62*n,l-1,d)},t.drawBat=function(e,t,a,r,o){e.save(),e.translate(t,a),e.scale(r,r),e.beginPath();for(var i=-1;i<=1;i+=2)e.moveTo(0,0),e.quadraticCurveTo(.4*i,-.5*o-.1,1*i,-.3*o),e.quadraticCurveTo(.7*i,-.05,.55*i,.15),e.quadraticCurveTo(.35*i,0,.15*i,.15),e.closePath();e.ellipse(0,.05,.12,.2,0,0,2*Math.PI),e.fill(),e.restore()},t.drawFog=function(e,t,a,r,o,i,n,l){for(var d=0;d<n;d++){var c=t*(.18+d%3*.06),s=((.37*d+r*l/t*(1+d%2*.5))%1.4-.2)*t,f=o+Math.sin(r/2e3+d)*a*.02,u=e.createRadialGradient(s,f,0,s,f,c);u.addColorStop(0,i),u.addColorStop(1,"rgba(0, 0, 0, 0)"),e.fillStyle=u,e.fillRect(s-c,f-c,2*c,2*c)}},t.createModule=function(e,t,a){return{name:"background/"+(a.category?a.category+"/":"")+e,filterList:[{name:e,category:"background",title:a.title,icon:a.icon,filterClass:t}],dependencyList:[]}};var a=function(e,a,r,o){t.fillSky(e,a,r,["#140003","#3a0006","#6e0b0b","#2a0204"]),t.drawStars(e,a,.6*r,o,Math.round(a*r/8e3)),t.drawMoon(e,.3*a,.34*r,.22*r,"#c8261a","rgba(255, 40, 20, 0.35)"),e.strokeStyle="#080102",e.fillStyle="#080102",t.drawTree(e,.06*a,1.02*r,.3*r,-Math.PI/2+.15,.045*r,5,o),t.drawTree(e,.95*a,1.02*r,.28*r,-Math.PI/2-.2,.04*r,5,o),e.beginPath(),e.moveTo(0,r);for(var i=0;i<=a;i+=a/24)e.lineTo(i,r*(.9+.02*Math.sin(i/a*11)+.015*o()));e.lineTo(a,r),e.closePath(),e.fill();for(var n=[[.12,.52],[.86,.5],[.9,.62]],l=0;l<n.length;l++){var d=n[l][0]*a,c=n[l][1]*r,s=.02*r;e.beginPath(),e.ellipse(d,c,s,.7*s,-.3,0,2*Math.PI),e.arc(d+.9*s,c-.7*s,.45*s,0,2*Math.PI),e.moveTo(d+1.3*s,c-.8*s),e.lineTo(d+1.8*s,c-.6*s),e.lineTo(d+1.3*s,c-.5*s),e.moveTo(d-.8*s,c),e.lineTo(d-1.8*s,c+.6*s),e.lineTo(d-.6*s,c+.5*s),e.fill()}return{}},r=function(e,a,r,o){for(var i=0;i<5;i++){var n=((.27*i+o/6e4*(1+.2*i))%1.5-.25)*a,l=r*(.12+.09*i),d=e.createRadialGradient(n,l,0,n,l,.22*a);d.addColorStop(0,"rgba(20, 0, 2, 0.75)"),d.addColorStop(1,"rgba(20, 0, 2, 0)"),e.fillStyle=d,e.save(),e.translate(n,l),e.scale(1,.3),e.translate(-n,-l),e.fillRect(n-.22*a,l-.22*a,.44*a,.44*a),e.restore()}t.drawFog(e,a,r,o,.95*r,"rgba(160, 10, 10, 0.18)",5,.015)},o=function(e,o){t.call(this,e,o,{seed:31,drawStatic:a,drawBack:r})},i=t.createModule("bloodMoon",o,{title:"Blood moon",icon:"\ud83c\udf15",category:"halloween"});return e.filterModule=i,e.xMediaBloodMoonScene=o,e}({});window.xMediaFilter?window.xMediaFilter.registerModule(xMediaFilterModule.filterModule):(window.xMediaFilterModuleList=window.xMediaFilterModuleList||[]).push(xMediaFilterModule.filterModule);
@@ -0,0 +1 @@
1
+ var a=function(t,e,r){var o,n,i,l,d=this,c=null;this.getOrder=function(){return 10},this.getGroup=function(){return"background"},this.isExclusive=function(){return!0},this.getOptions=function(){return e},this.setOptions=function(a){for(var t in a)a.hasOwnProperty(t)&&(e[t]=a[t])},this.load=function(){return t.loadSegmenter().then(function(){return d})},this.process=function(e){var d=t.segmentPerson(e);if(d){var s=e.width,f=e.height,u=e.ctx;o.width===s&&o.height===f&&c||(t.resizeCanvas(o,s,f),c=r.drawStatic(n,s,f,a.createRandom(r.seed||7))||{}),t.resizeCanvas(i,s,f),l.globalCompositeOperation="copy",l.drawImage(d.canvas,0,0,s,f),l.globalCompositeOperation="source-in",l.drawImage(e.canvas,0,0),u.globalCompositeOperation="copy",u.drawImage(o,0,0),u.globalCompositeOperation="source-over",r.drawBack&&(u.save(),r.drawBack(u,s,f,e.timestamp,c),u.restore()),u.drawImage(i,0,0),r.drawFront&&(u.save(),r.drawFront(u,s,f,e.timestamp,c),u.restore())}},this.destroy=function(){c=null},e=e||{},o=t.createCanvas(),n=o.getContext("2d"),i=t.createCanvas(),l=i.getContext("2d")};a.createRandom=function(a){var t=a%2147483647||1;return function(){return((t=16807*t%2147483647)-1)/2147483646}},a.fillSky=function(a,t,e,r){for(var o=a.createLinearGradient(0,0,0,e),n=0;n<r.length;n++)o.addColorStop(n/(r.length-1),r[n]);a.fillStyle=o,a.fillRect(0,0,t,e)},a.drawStars=function(a,t,e,r,o){for(var n=0;n<o;n++)a.fillStyle="rgba(255, 255, 255, "+(.3+.7*r())+")",a.fillRect(r()*t,r()*e*.6,r()<.9?1:2,1+(r()<.1?1:0))},a.drawMoon=function(a,t,e,r,o,n){var i=a.createRadialGradient(t,e,.8*r,t,e,3*r);i.addColorStop(0,n),i.addColorStop(1,"rgba(0, 0, 0, 0)"),a.fillStyle=i,a.fillRect(t-3*r,e-3*r,6*r,6*r);var l=a.createRadialGradient(t-.3*r,e-.3*r,.1*r,t,e,r);l.addColorStop(0,"#ffffff"),l.addColorStop(.35,o),l.addColorStop(1,o),a.fillStyle=l,a.beginPath(),a.arc(t,e,r,0,2*Math.PI),a.fill(),a.fillStyle="rgba(0, 0, 0, 0.08)";for(var d=[[-.3,-.2,.18],[.25,.1,.22],[-.1,.4,.12],[.35,-.35,.1]],c=0;c<d.length;c++)a.beginPath(),a.arc(t+d[c][0]*r,e+d[c][1]*r,d[c][2]*r,0,2*Math.PI),a.fill()},a.drawTree=function(t,e,r,o,n,i,l,d){var c=e+Math.cos(n)*o,s=r+Math.sin(n)*o;if(t.lineWidth=i,t.lineCap="round",t.beginPath(),t.moveTo(e,r),t.quadraticCurveTo(e+Math.cos(n+.3)*o*.5,r+Math.sin(n+.3)*o*.5,c,s),t.stroke(),!(l<=0))for(var f=2+Math.floor(2*d()),u=0;u<f;u++)a.drawTree(t,c,s,o*(.55+.2*d()),n+1.4*(d()-.5),.62*i,l-1,d)},a.drawBat=function(a,t,e,r,o){a.save(),a.translate(t,e),a.scale(r,r),a.beginPath();for(var n=-1;n<=1;n+=2)a.moveTo(0,0),a.quadraticCurveTo(.4*n,-.5*o-.1,1*n,-.3*o),a.quadraticCurveTo(.7*n,-.05,.55*n,.15),a.quadraticCurveTo(.35*n,0,.15*n,.15),a.closePath();a.ellipse(0,.05,.12,.2,0,0,2*Math.PI),a.fill(),a.restore()},a.drawFog=function(a,t,e,r,o,n,i,l){for(var d=0;d<i;d++){var c=t*(.18+d%3*.06),s=((.37*d+r*l/t*(1+d%2*.5))%1.4-.2)*t,f=o+Math.sin(r/2e3+d)*e*.02,u=a.createRadialGradient(s,f,0,s,f,c);u.addColorStop(0,n),u.addColorStop(1,"rgba(0, 0, 0, 0)"),a.fillStyle=u,a.fillRect(s-c,f-c,2*c,2*c)}},a.createModule=function(a,t,e){return{name:"background/"+(e.category?e.category+"/":"")+a,filterList:[{name:a,category:"background",title:e.title,icon:e.icon,filterClass:t}],dependencyList:[]}};var t=function(t,e,r,o){a.fillSky(t,e,r,["#140003","#3a0006","#6e0b0b","#2a0204"]),a.drawStars(t,e,.6*r,o,Math.round(e*r/8e3)),a.drawMoon(t,.3*e,.34*r,.22*r,"#c8261a","rgba(255, 40, 20, 0.35)"),t.strokeStyle="#080102",t.fillStyle="#080102",a.drawTree(t,.06*e,1.02*r,.3*r,-Math.PI/2+.15,.045*r,5,o),a.drawTree(t,.95*e,1.02*r,.28*r,-Math.PI/2-.2,.04*r,5,o),t.beginPath(),t.moveTo(0,r);for(var n=0;n<=e;n+=e/24)t.lineTo(n,r*(.9+.02*Math.sin(n/e*11)+.015*o()));t.lineTo(e,r),t.closePath(),t.fill();for(var i=[[.12,.52],[.86,.5],[.9,.62]],l=0;l<i.length;l++){var d=i[l][0]*e,c=i[l][1]*r,s=.02*r;t.beginPath(),t.ellipse(d,c,s,.7*s,-.3,0,2*Math.PI),t.arc(d+.9*s,c-.7*s,.45*s,0,2*Math.PI),t.moveTo(d+1.3*s,c-.8*s),t.lineTo(d+1.8*s,c-.6*s),t.lineTo(d+1.3*s,c-.5*s),t.moveTo(d-.8*s,c),t.lineTo(d-1.8*s,c+.6*s),t.lineTo(d-.6*s,c+.5*s),t.fill()}return{}},e=function(t,e,r,o){for(var n=0;n<5;n++){var i=((.27*n+o/6e4*(1+.2*n))%1.5-.25)*e,l=r*(.12+.09*n),d=t.createRadialGradient(i,l,0,i,l,.22*e);d.addColorStop(0,"rgba(20, 0, 2, 0.75)"),d.addColorStop(1,"rgba(20, 0, 2, 0)"),t.fillStyle=d,t.save(),t.translate(i,l),t.scale(1,.3),t.translate(-i,-l),t.fillRect(i-.22*e,l-.22*e,.44*e,.44*e),t.restore()}a.drawFog(t,e,r,o,.95*r,"rgba(160, 10, 10, 0.18)",5,.015)},r=function(r,o){a.call(this,r,o,{seed:31,drawStatic:t,drawBack:e})},o=a.createModule("bloodMoon",r,{title:"Blood moon",icon:"\ud83c\udf15",category:"halloween"});export{o as filterModule,r as xMediaBloodMoonScene};
@@ -0,0 +1,248 @@
1
+ var xMediaScene = function(__xMediaFilter, __options, __sceneOptions) {
2
+
3
+ var $this = this;
4
+ var __sceneCanvas;
5
+ var __sceneCtx;
6
+ var __personCanvas;
7
+ var __personCtx;
8
+ var __sceneData = null;
9
+
10
+ this.getOrder = function() {
11
+ return 10;
12
+ };
13
+
14
+ this.getGroup = function() {
15
+ return 'background';
16
+ };
17
+
18
+ this.isExclusive = function() {
19
+ return true;
20
+ };
21
+
22
+ this.getOptions = function() {
23
+ return __options;
24
+ };
25
+
26
+ this.setOptions = function(options) {
27
+ for(var key in options){
28
+ if(options.hasOwnProperty(key)){
29
+ __options[key] = options[key];
30
+ }
31
+ }
32
+ };
33
+
34
+ this.load = function() {
35
+ return __xMediaFilter.loadSegmenter().then(function() {
36
+ return $this;
37
+ });
38
+ };
39
+
40
+ this.process = function(frame) {
41
+ var person = __xMediaFilter.segmentPerson(frame);
42
+ if(!person){
43
+ return;
44
+ }
45
+ var width = frame['width'];
46
+ var height = frame['height'];
47
+ var ctx = frame['ctx'];
48
+ if(__sceneCanvas.width !== width || __sceneCanvas.height !== height || !__sceneData){
49
+ __xMediaFilter.resizeCanvas(__sceneCanvas, width, height);
50
+ __sceneData = __sceneOptions['drawStatic'](__sceneCtx, width, height, xMediaScene.createRandom(__sceneOptions['seed'] || 7)) || {};
51
+ }
52
+ __xMediaFilter.resizeCanvas(__personCanvas, width, height);
53
+ __personCtx.globalCompositeOperation = 'copy';
54
+ __personCtx.drawImage(person['canvas'], 0, 0, width, height);
55
+ __personCtx.globalCompositeOperation = 'source-in';
56
+ __personCtx.drawImage(frame['canvas'], 0, 0);
57
+ ctx.globalCompositeOperation = 'copy';
58
+ ctx.drawImage(__sceneCanvas, 0, 0);
59
+ ctx.globalCompositeOperation = 'source-over';
60
+ if(__sceneOptions['drawBack']){
61
+ ctx.save();
62
+ __sceneOptions['drawBack'](ctx, width, height, frame['timestamp'], __sceneData);
63
+ ctx.restore();
64
+ }
65
+ ctx.drawImage(__personCanvas, 0, 0);
66
+ if(__sceneOptions['drawFront']){
67
+ ctx.save();
68
+ __sceneOptions['drawFront'](ctx, width, height, frame['timestamp'], __sceneData);
69
+ ctx.restore();
70
+ }
71
+ };
72
+
73
+ this.destroy = function() {
74
+ __sceneData = null;
75
+ };
76
+
77
+ (function() {
78
+ __options = __options || {};
79
+ __sceneCanvas = __xMediaFilter.createCanvas();
80
+ __sceneCtx = __sceneCanvas.getContext('2d');
81
+ __personCanvas = __xMediaFilter.createCanvas();
82
+ __personCtx = __personCanvas.getContext('2d');
83
+ })();
84
+ };
85
+
86
+ xMediaScene.createRandom = function(seed) {
87
+ var value = seed % 2147483647 || 1;
88
+ return function() {
89
+ value = value * 16807 % 2147483647;
90
+ return (value - 1) / 2147483646;
91
+ };
92
+ };
93
+
94
+ xMediaScene.fillSky = function(ctx, width, height, colorList) {
95
+ var gradient = ctx.createLinearGradient(0, 0, 0, height);
96
+ for(var i = 0; i < colorList.length; i++){
97
+ gradient.addColorStop(i / (colorList.length - 1), colorList[i]);
98
+ }
99
+ ctx.fillStyle = gradient;
100
+ ctx.fillRect(0, 0, width, height);
101
+ };
102
+
103
+ xMediaScene.drawStars = function(ctx, width, height, random, count) {
104
+ for(var i = 0; i < count; i++){
105
+ ctx.fillStyle = 'rgba(255, 255, 255, ' + (0.3 + random() * 0.7) + ')';
106
+ ctx.fillRect(random() * width, random() * height * 0.6, random() < 0.9 ? 1 : 2, 1 + (random() < 0.1 ? 1 : 0));
107
+ }
108
+ };
109
+
110
+ xMediaScene.drawMoon = function(ctx, x, y, radius, color, glowColor) {
111
+ var glow = ctx.createRadialGradient(x, y, radius * 0.8, x, y, radius * 3);
112
+ glow.addColorStop(0, glowColor);
113
+ glow.addColorStop(1, 'rgba(0, 0, 0, 0)');
114
+ ctx.fillStyle = glow;
115
+ ctx.fillRect(x - radius * 3, y - radius * 3, radius * 6, radius * 6);
116
+ var body = ctx.createRadialGradient(x - radius * 0.3, y - radius * 0.3, radius * 0.1, x, y, radius);
117
+ body.addColorStop(0, '#ffffff');
118
+ body.addColorStop(0.35, color);
119
+ body.addColorStop(1, color);
120
+ ctx.fillStyle = body;
121
+ ctx.beginPath();
122
+ ctx.arc(x, y, radius, 0, Math.PI * 2);
123
+ ctx.fill();
124
+ ctx.fillStyle = 'rgba(0, 0, 0, 0.08)';
125
+ var craterList = [[-0.3, -0.2, 0.18], [0.25, 0.1, 0.22], [-0.1, 0.4, 0.12], [0.35, -0.35, 0.1]];
126
+ for(var i = 0; i < craterList.length; i++){
127
+ ctx.beginPath();
128
+ ctx.arc(x + craterList[i][0] * radius, y + craterList[i][1] * radius, craterList[i][2] * radius, 0, Math.PI * 2);
129
+ ctx.fill();
130
+ }
131
+ };
132
+
133
+ xMediaScene.drawTree = function(ctx, x, y, length, angle, width, depth, random) {
134
+ var endX = x + Math.cos(angle) * length;
135
+ var endY = y + Math.sin(angle) * length;
136
+ ctx.lineWidth = width;
137
+ ctx.lineCap = 'round';
138
+ ctx.beginPath();
139
+ ctx.moveTo(x, y);
140
+ ctx.quadraticCurveTo(x + Math.cos(angle + 0.3) * length * 0.5, y + Math.sin(angle + 0.3) * length * 0.5, endX, endY);
141
+ ctx.stroke();
142
+ if(depth <= 0){
143
+ return;
144
+ }
145
+ var branchCount = 2 + Math.floor(random() * 2);
146
+ for(var i = 0; i < branchCount; i++){
147
+ xMediaScene.drawTree(ctx, endX, endY, length * (0.55 + random() * 0.2), angle + (random() - 0.5) * 1.4, width * 0.62, depth - 1, random);
148
+ }
149
+ };
150
+
151
+ xMediaScene.drawBat = function(ctx, x, y, size, flap) {
152
+ ctx.save();
153
+ ctx.translate(x, y);
154
+ ctx.scale(size, size);
155
+ ctx.beginPath();
156
+ for(var side = -1; side <= 1; side += 2){
157
+ ctx.moveTo(0, 0);
158
+ ctx.quadraticCurveTo(side * 0.4, -0.5 * flap - 0.1, side * 1, -0.3 * flap);
159
+ ctx.quadraticCurveTo(side * 0.7, -0.05, side * 0.55, 0.15);
160
+ ctx.quadraticCurveTo(side * 0.35, 0, side * 0.15, 0.15);
161
+ ctx.closePath();
162
+ }
163
+ ctx.ellipse(0, 0.05, 0.12, 0.2, 0, 0, Math.PI * 2);
164
+ ctx.fill();
165
+ ctx.restore();
166
+ };
167
+
168
+ xMediaScene.drawFog = function(ctx, width, height, time, y, color, count, speed) {
169
+ for(var i = 0; i < count; i++){
170
+ var radius = width * (0.18 + (i % 3) * 0.06);
171
+ var x = ((i * 0.37 + time * speed / width * (1 + (i % 2) * 0.5)) % 1.4 - 0.2) * width;
172
+ var fogY = y + Math.sin(time / 2000 + i) * height * 0.02;
173
+ var gradient = ctx.createRadialGradient(x, fogY, 0, x, fogY, radius);
174
+ gradient.addColorStop(0, color);
175
+ gradient.addColorStop(1, 'rgba(0, 0, 0, 0)');
176
+ ctx.fillStyle = gradient;
177
+ ctx.fillRect(x - radius, fogY - radius, radius * 2, radius * 2);
178
+ }
179
+ };
180
+
181
+ xMediaScene.createModule = function(name, SceneClass, info) {
182
+ return {
183
+ 'name': 'background/' + (info['category'] ? info['category'] + '/' : '') + name,
184
+ 'filterList': [{'name': name, 'category': 'background', 'title': info['title'], 'icon': info['icon'], 'filterClass': SceneClass}],
185
+ 'dependencyList': []
186
+ };
187
+ };
188
+
189
+ var _drawStatic = function(ctx, width, height, random) {
190
+ xMediaScene.fillSky(ctx, width, height, ['#140003', '#3a0006', '#6e0b0b', '#2a0204']);
191
+ xMediaScene.drawStars(ctx, width, height * 0.6, random, Math.round(width * height / 8000));
192
+ xMediaScene.drawMoon(ctx, width * 0.3, height * 0.34, height * 0.22, '#c8261a', 'rgba(255, 40, 20, 0.35)');
193
+ ctx.strokeStyle = '#080102';
194
+ ctx.fillStyle = '#080102';
195
+ xMediaScene.drawTree(ctx, width * 0.06, height * 1.02, height * 0.3, -Math.PI / 2 + 0.15, height * 0.045, 5, random);
196
+ xMediaScene.drawTree(ctx, width * 0.95, height * 1.02, height * 0.28, -Math.PI / 2 - 0.2, height * 0.04, 5, random);
197
+ ctx.beginPath();
198
+ ctx.moveTo(0, height);
199
+ for(var x = 0; x <= width; x += width / 24){
200
+ ctx.lineTo(x, height * (0.9 + Math.sin(x / width * 11) * 0.02 + random() * 0.015));
201
+ }
202
+ ctx.lineTo(width, height);
203
+ ctx.closePath();
204
+ ctx.fill();
205
+ var crowList = [[0.12, 0.52], [0.86, 0.5], [0.9, 0.62]];
206
+ for(var i = 0; i < crowList.length; i++){
207
+ var crowX = crowList[i][0] * width;
208
+ var crowY = crowList[i][1] * height;
209
+ var size = height * 0.02;
210
+ ctx.beginPath();
211
+ ctx.ellipse(crowX, crowY, size, size * 0.7, -0.3, 0, Math.PI * 2);
212
+ ctx.arc(crowX + size * 0.9, crowY - size * 0.7, size * 0.45, 0, Math.PI * 2);
213
+ ctx.moveTo(crowX + size * 1.3, crowY - size * 0.8);
214
+ ctx.lineTo(crowX + size * 1.8, crowY - size * 0.6);
215
+ ctx.lineTo(crowX + size * 1.3, crowY - size * 0.5);
216
+ ctx.moveTo(crowX - size * 0.8, crowY);
217
+ ctx.lineTo(crowX - size * 1.8, crowY + size * 0.6);
218
+ ctx.lineTo(crowX - size * 0.6, crowY + size * 0.5);
219
+ ctx.fill();
220
+ }
221
+ return {};
222
+ };
223
+
224
+ var _drawBack = function(ctx, width, height, time) {
225
+ for(var i = 0; i < 5; i++){
226
+ var x = ((i * 0.27 + time / 60000 * (1 + i * 0.2)) % 1.5 - 0.25) * width;
227
+ var y = height * (0.12 + i * 0.09);
228
+ var gradient = ctx.createRadialGradient(x, y, 0, x, y, width * 0.22);
229
+ gradient.addColorStop(0, 'rgba(20, 0, 2, 0.75)');
230
+ gradient.addColorStop(1, 'rgba(20, 0, 2, 0)');
231
+ ctx.fillStyle = gradient;
232
+ ctx.save();
233
+ ctx.translate(x, y);
234
+ ctx.scale(1, 0.3);
235
+ ctx.translate(-x, -y);
236
+ ctx.fillRect(x - width * 0.22, y - width * 0.22, width * 0.44, width * 0.44);
237
+ ctx.restore();
238
+ }
239
+ xMediaScene.drawFog(ctx, width, height, time, height * 0.95, 'rgba(160, 10, 10, 0.18)', 5, 0.015);
240
+ };
241
+
242
+ var xMediaBloodMoonScene = function(__xMediaFilter, __options) {
243
+ xMediaScene.call(this, __xMediaFilter, __options, {'seed': 31, 'drawStatic': _drawStatic, 'drawBack': _drawBack});
244
+ };
245
+
246
+ var filterModule = xMediaScene.createModule('bloodMoon', xMediaBloodMoonScene, {'title': 'Blood moon', 'icon': '🌕', 'category': 'halloween'});
247
+
248
+ export { filterModule, xMediaBloodMoonScene };