fca-nayan-r 1.4.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of fca-nayan-r might be problematic. Click here for more details.

Files changed (120) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -0
  2. package/.cache/replit/nix/env.json +1 -0
  3. package/.config/configstore/update-notifier-npm.json +4 -0
  4. package/.config/configstore/update-notifier-npm.json.1735545094 +4 -0
  5. package/.gitattributes +2 -0
  6. package/.replit +80 -0
  7. package/.upm/store.json +1 -0
  8. package/Extra/Database/index.js +469 -0
  9. package/Extra/ExtraAddons.js +82 -0
  10. package/Extra/ExtraFindUID.js +62 -0
  11. package/Extra/ExtraGetThread.js +340 -0
  12. package/Extra/ExtraScreenShot.js +430 -0
  13. package/Extra/ExtraUptimeRobot.js +38 -0
  14. package/Extra/Html/Classic/script.js +119 -0
  15. package/Extra/Html/Classic/style.css +8 -0
  16. package/Extra/Security/Index.js +146 -0
  17. package/Extra/Security/Step_1.js +6 -0
  18. package/Extra/Security/Step_2.js +22 -0
  19. package/Extra/Security/Step_3.js +22 -0
  20. package/Extra/Src/Change_Environment.js +24 -0
  21. package/Extra/Src/Check_Update.js +67 -0
  22. package/Extra/Src/History.js +115 -0
  23. package/Extra/Src/Instant_Update.js +65 -0
  24. package/Extra/Src/Last-Run.js +65 -0
  25. package/Extra/Src/Premium.js +81 -0
  26. package/Extra/Src/Release_Memory.js +41 -0
  27. package/Extra/Src/uuid.js +137 -0
  28. package/Func/AcceptAgreement.js +32 -0
  29. package/Func/ClearCache.js +64 -0
  30. package/Func/ReportV1.js +54 -0
  31. package/LICENSE +21 -0
  32. package/Language/index.json +207 -0
  33. package/Main.js +1095 -0
  34. package/README.md +140 -0
  35. package/SECURITY.md +17 -0
  36. package/broadcast.js +40 -0
  37. package/index.js +351 -0
  38. package/logger.js +66 -0
  39. package/package.json +94 -0
  40. package/replit.nix +8 -0
  41. package/src/Dev_Horizon_Data.js +125 -0
  42. package/src/Premium.js +30 -0
  43. package/src/Screenshot.js +83 -0
  44. package/src/addExternalModule.js +16 -0
  45. package/src/addUserToGroup.js +79 -0
  46. package/src/changeAdminStatus.js +79 -0
  47. package/src/changeArchivedStatus.js +41 -0
  48. package/src/changeAvt.js +85 -0
  49. package/src/changeBio.js +65 -0
  50. package/src/changeBlockedStatus.js +36 -0
  51. package/src/changeGroupImage.js +106 -0
  52. package/src/changeNickname.js +45 -0
  53. package/src/changeThreadColor.js +62 -0
  54. package/src/changeThreadEmoji.js +42 -0
  55. package/src/createNewGroup.js +70 -0
  56. package/src/createPoll.js +60 -0
  57. package/src/deleteMessage.js +45 -0
  58. package/src/deleteThread.js +43 -0
  59. package/src/forwardAttachment.js +48 -0
  60. package/src/getAccessToken.js +28 -0
  61. package/src/getCurrentUserID.js +7 -0
  62. package/src/getEmojiUrl.js +27 -0
  63. package/src/getFriendsList.js +73 -0
  64. package/src/getMessage.js +80 -0
  65. package/src/getThreadHistory.js +537 -0
  66. package/src/getThreadInfo.js +440 -0
  67. package/src/getThreadList.js +213 -0
  68. package/src/getThreadMain.js +220 -0
  69. package/src/getThreadPictures.js +59 -0
  70. package/src/getUID.js +59 -0
  71. package/src/getUserID.js +62 -0
  72. package/src/getUserInfo.js +113 -0
  73. package/src/getUserInfoMain.js +65 -0
  74. package/src/getUserInfoV2.js +32 -0
  75. package/src/getUserInfoV3.js +63 -0
  76. package/src/getUserInfoV4.js +55 -0
  77. package/src/getUserInfoV5.js +61 -0
  78. package/src/handleFriendRequest.js +46 -0
  79. package/src/handleMessageRequest.js +49 -0
  80. package/src/httpGet.js +49 -0
  81. package/src/httpPost.js +48 -0
  82. package/src/httpPostFormData.js +41 -0
  83. package/src/listenMqtt.js +790 -0
  84. package/src/logout.js +68 -0
  85. package/src/markAsDelivered.js +48 -0
  86. package/src/markAsRead.js +70 -0
  87. package/src/markAsReadAll.js +43 -0
  88. package/src/markAsSeen.js +51 -0
  89. package/src/muteThread.js +47 -0
  90. package/src/removeUserFromGroup.js +49 -0
  91. package/src/resolvePhotoUrl.js +37 -0
  92. package/src/searchForThread.js +43 -0
  93. package/src/sendMessage.js +334 -0
  94. package/src/sendTypingIndicator.js +80 -0
  95. package/src/setMessageReaction.js +109 -0
  96. package/src/setPostReaction.js +102 -0
  97. package/src/setTitle.js +74 -0
  98. package/src/threadColors.js +39 -0
  99. package/src/unfriend.js +43 -0
  100. package/src/unsendMessage.js +40 -0
  101. package/test/Database_Test.js +4 -0
  102. package/test/Db2.js +530 -0
  103. package/test/Horizon_Database/A_README.md +1 -0
  104. package/test/Horizon_Database/Database.db +0 -0
  105. package/test/Nayan_Database/A_README.md +1 -0
  106. package/test/Nayan_Database/Database.db +0 -0
  107. package/test/Nayan_Database/N +1 -0
  108. package/test/data/shareAttach.js +146 -0
  109. package/test/data/something.mov +0 -0
  110. package/test/data/test.png +0 -0
  111. package/test/data/test.txt +7 -0
  112. package/test/env/.env +0 -0
  113. package/test/env.env +0 -0
  114. package/test/example-config.json +18 -0
  115. package/test/example-db.db +0 -0
  116. package/test/memoryleak.js +18 -0
  117. package/test/test-page.js +140 -0
  118. package/test/test.js +385 -0
  119. package/test/testv2.js +18 -0
  120. package/utils.js +1639 -0
@@ -0,0 +1,430 @@
1
+ /* global document */
2
+ 'use strict';
3
+ const {promisify} = require('util');
4
+ const fs = require('fs');
5
+ const fileUrl = require('file-url');
6
+ const puppeteer = require('puppeteer');
7
+ const toughCookie = require('tough-cookie');
8
+
9
+ const writeFile = promisify(fs.writeFile);
10
+
11
+ const isUrl = string => /^(https?|file):\/\/|^data:/.test(string);
12
+
13
+ const scrollToElement = (element, options) => {
14
+ const isOverflown = element => {
15
+ return (
16
+ element.scrollHeight > element.clientHeight ||
17
+ element.scrollWidth > element.clientWidth
18
+ );
19
+ };
20
+
21
+ const findScrollParent = element => {
22
+ if (element === undefined) {
23
+ return;
24
+ }
25
+
26
+ if (isOverflown(element)) {
27
+ return element;
28
+ }
29
+
30
+ return findScrollParent(element.parentElement);
31
+ };
32
+
33
+ const calculateOffset = (rect, options) => {
34
+ if (options === undefined) {
35
+ return {
36
+ x: rect.left,
37
+ y: rect.top
38
+ };
39
+ }
40
+
41
+ const offset = options.offset || 0;
42
+
43
+ switch (options.offsetFrom) {
44
+ case 'top':
45
+ return {
46
+ x: rect.left,
47
+ y: rect.top + offset
48
+ };
49
+ case 'right':
50
+ return {
51
+ x: rect.left - offset,
52
+ y: rect.top
53
+ };
54
+ case 'bottom':
55
+ return {
56
+ x: rect.left,
57
+ y: rect.top - offset
58
+ };
59
+ case 'left':
60
+ return {
61
+ x: rect.left + offset,
62
+ y: rect.top
63
+ };
64
+ default:
65
+ throw new Error('Invalid `scrollToElement.offsetFrom` value');
66
+ }
67
+ };
68
+
69
+ const rect = element.getBoundingClientRect();
70
+ const offset = calculateOffset(rect, options);
71
+ const parent = findScrollParent(element);
72
+
73
+ if (parent !== undefined) {
74
+ parent.scrollIntoView(true);
75
+ parent.scrollTo(offset.x, offset.y);
76
+ }
77
+ };
78
+
79
+ const disableAnimations = () => {
80
+ const rule = `
81
+ *,
82
+ ::before,
83
+ ::after {
84
+ animation: initial !important;
85
+ transition: initial !important;
86
+ }
87
+ `;
88
+
89
+ const style = document.createElement('style');
90
+ document.body.append(style);
91
+
92
+ style.sheet.insertRule(rule);
93
+ };
94
+
95
+ const getBoundingClientRect = element => {
96
+ const {top, left, height, width, x, y} = element.getBoundingClientRect();
97
+ return {top, left, height, width, x, y};
98
+ };
99
+
100
+ const parseCookie = (url, cookie) => {
101
+ if (typeof cookie === 'object') {
102
+ return cookie;
103
+ }
104
+
105
+ const jar = new toughCookie.CookieJar(undefined, {rejectPublicSuffixes: false});
106
+ jar.setCookieSync(cookie, url);
107
+ const returnValue = jar.serializeSync().cookies[0];
108
+
109
+ // Use this instead of the above when the following issue is fixed:
110
+ // https://github.com/salesforce/tough-cookie/issues/149
111
+ // const ret = toughCookie.parse(cookie).serializeSync();
112
+
113
+ returnValue.name = returnValue.key;
114
+ delete returnValue.key;
115
+
116
+ if (returnValue.expires) {
117
+ returnValue.expires = Math.floor(new Date(returnValue.expires) / 1000);
118
+ }
119
+
120
+ return returnValue;
121
+ };
122
+
123
+ const imagesHaveLoaded = () => [...document.images].map(element => element.complete);
124
+
125
+ const captureWebsite = async (input, options) => {
126
+ options = {
127
+ inputType: 'url',
128
+ width: 1920,
129
+ height: 1080,
130
+ scaleFactor: 2,
131
+ fullPage: false,
132
+ defaultBackground: true,
133
+ timeout: 60, // The Puppeteer default of 30 is too short
134
+ delay: 0,
135
+ debug: false,
136
+ darkMode: true,
137
+ launchOptions: { devtools:true },
138
+ _keepAlive: true,
139
+ isJavaScriptEnabled: true,
140
+ inset: 0,
141
+ args: ["--webview-disable-safebrowsing-support",
142
+ "--disable-web-security"],
143
+ ignoreHTTPSErrors: true,
144
+ ...options
145
+ };
146
+
147
+ const isHTMLContent = options.inputType === 'html';
148
+
149
+ input = isHTMLContent || isUrl(input) ? input : fileUrl(input);
150
+
151
+ const timeoutInSeconds = options.timeout * 1000;
152
+
153
+ const viewportOptions = {
154
+ width: options.width,
155
+ height: options.height,
156
+ deviceScaleFactor: options.scaleFactor
157
+ };
158
+
159
+ const screenshotOptions = {};
160
+
161
+ if (options.type) {
162
+ screenshotOptions.type = options.type;
163
+ }
164
+
165
+ if (options.quality) {
166
+ screenshotOptions.quality = options.quality * 100;
167
+ }
168
+
169
+ if (options.fullPage) {
170
+ screenshotOptions.fullPage = options.fullPage;
171
+ }
172
+
173
+ if (typeof options.defaultBackground === 'boolean') {
174
+ screenshotOptions.omitBackground = !options.defaultBackground;
175
+ }
176
+
177
+ const launchOptions = {...options.launchOptions};
178
+
179
+ if (options.debug) {
180
+ launchOptions.headless = false;
181
+ launchOptions.slowMo = 100;
182
+ }
183
+
184
+ const browser = options._browser || await puppeteer.launch(launchOptions);
185
+ const page = await browser.newPage();
186
+
187
+ if (options.preloadFunction) {
188
+ await page.evaluateOnNewDocument(options.preloadFunction);
189
+ }
190
+
191
+ await page.setJavaScriptEnabled(options.isJavaScriptEnabled);
192
+
193
+ if (options.debug) {
194
+ page.on('console', message => {
195
+ let {url, lineNumber, columnNumber} = message.location();
196
+ lineNumber = lineNumber ? `:${lineNumber}` : '';
197
+ columnNumber = columnNumber ? `:${columnNumber}` : '';
198
+ const location = url ? ` (${url}${lineNumber}${columnNumber})` : '';
199
+ console.log(`\nPage log:${location}\n${message.text()}\n`);
200
+ });
201
+
202
+ page.on('pageerror', error => {
203
+ console.log('\nPage error:', error, '\n');
204
+ });
205
+
206
+ // TODO: Add more events from https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#event-requestfailed
207
+ }
208
+
209
+ if (options.authentication) {
210
+ await page.authenticate(options.authentication);
211
+ }
212
+
213
+ if (options.cookies) {
214
+ const cookies = options.cookies.map(cookie => parseCookie(isHTMLContent ? 'about:blank' : input, cookie));
215
+ await page.setCookie(...cookies);
216
+ }
217
+
218
+ if (options.headers) {
219
+ await page.setExtraHTTPHeaders(options.headers);
220
+ }
221
+
222
+ if (options.userAgent) {
223
+ await page.setUserAgent(options.userAgent);
224
+ }
225
+
226
+ await page.setViewport(viewportOptions);
227
+
228
+ if (options.emulateDevice) {
229
+ if (!(options.emulateDevice in puppeteer.devices)) {
230
+ throw new Error(`The device name \`${options.emulateDevice}\` is not supported`);
231
+ }
232
+
233
+ await page.emulate(puppeteer.devices[options.emulateDevice]);
234
+ }
235
+
236
+ await page.emulateMediaFeatures([{
237
+ name: 'prefers-color-scheme',
238
+ value: options.darkMode ? 'dark' : 'light'
239
+ }]);
240
+
241
+ await page[isHTMLContent ? 'setContent' : 'goto'](input, {
242
+ timeout: timeoutInSeconds,
243
+ waitUntil: 'networkidle2'
244
+ });
245
+ if (options.disableAnimations) {
246
+ await page.evaluate(disableAnimations, options.disableAnimations);
247
+ }
248
+
249
+ if (options.hideElements) {
250
+ await page.addStyleTag({
251
+ content: `${options.hideElements.join(', ')} { visibility: hidden !important; }`
252
+ });
253
+ }
254
+
255
+ if (options.removeElements) {
256
+ await page.addStyleTag({
257
+ content: `${options.removeElements.join(', ')} { display: none !important; }`
258
+ });
259
+ }
260
+
261
+ if (options.clickElement) {
262
+ await page.click(options.clickElement);
263
+ }
264
+
265
+ const getInjectKey = (ext, value) => isUrl(value) ? 'url' : (value.endsWith(`.${ext}`) ? 'path' : 'content');
266
+
267
+ if (!options.isJavaScriptEnabled) {
268
+ // Enable JavaScript again for `modules` and `scripts`.
269
+ await page.setJavaScriptEnabled(true);
270
+ }
271
+
272
+ if (options.modules) {
273
+ await Promise.all(options.modules.map(module_ => {
274
+ return page.addScriptTag({
275
+ [getInjectKey('js', module_)]: module_,
276
+ type: 'module'
277
+ });
278
+ }));
279
+ }
280
+
281
+ if (options.scripts) {
282
+ await Promise.all(options.scripts.map(script => {
283
+ return page.addScriptTag({
284
+ [getInjectKey('js', script)]: script
285
+ });
286
+ }));
287
+ }
288
+
289
+ if (options.styles) {
290
+ await Promise.all(options.styles.map(style => {
291
+ return page.addStyleTag({
292
+ [getInjectKey('css', style)]: style
293
+ });
294
+ }));
295
+ }
296
+
297
+ if (options.waitForElement) {
298
+ await page.waitForSelector(options.waitForElement, {
299
+ visible: true,
300
+ timeout: timeoutInSeconds
301
+ });
302
+ }
303
+
304
+ if (options.beforeScreenshot) {
305
+ await options.beforeScreenshot(page, browser);
306
+ }
307
+
308
+ if (options.element) {
309
+ await page.waitForSelector(options.element, {
310
+ visible: true,
311
+ timeout: timeoutInSeconds
312
+ });
313
+ screenshotOptions.clip = await page.$eval(options.element, getBoundingClientRect);
314
+ screenshotOptions.fullPage = false;
315
+ }
316
+
317
+ if (options.delay) {
318
+ await page.waitForTimeout(options.delay * 1000);
319
+ }
320
+
321
+ if (options.scrollToElement) {
322
+ // eslint-disable-next-line unicorn/prefer-ternary
323
+ if (typeof options.scrollToElement === 'object') {
324
+ await page.$eval(options.scrollToElement.element, scrollToElement, options.scrollToElement);
325
+ } else {
326
+ await page.$eval(options.scrollToElement, scrollToElement);
327
+ }
328
+ }
329
+
330
+ if (screenshotOptions.fullPage) {
331
+ // Get the height of the rendered page
332
+ const bodyHandle = await page.$('body');
333
+ const bodyBoundingHeight = await bodyHandle.boundingBox();
334
+ await bodyHandle.dispose();
335
+
336
+ // Scroll one viewport at a time, pausing to let content load
337
+ const viewportHeight = viewportOptions.height;
338
+ let viewportIncrement = 0;
339
+ while (viewportIncrement + viewportHeight < bodyBoundingHeight) {
340
+ const navigationPromise = page.waitForNavigation({waitUntil: 'networkidle0'});
341
+ /* eslint-disable no-await-in-loop */
342
+ await page.evaluate(_viewportHeight => {
343
+ /* eslint-disable no-undef */
344
+ window.scrollBy(0, _viewportHeight);
345
+ /* eslint-enable no-undef */
346
+ }, viewportHeight);
347
+ await navigationPromise;
348
+ /* eslint-enable no-await-in-loop */
349
+ viewportIncrement += viewportHeight;
350
+ }
351
+
352
+ // Scroll back to top
353
+ await page.evaluate(_ => {
354
+ /* eslint-disable no-undef */
355
+ window.scrollTo(0, 0);
356
+ /* eslint-enable no-undef */
357
+ });
358
+
359
+ // Some extra delay to let images load
360
+ await page.waitForFunction(imagesHaveLoaded, {timeout: timeoutInSeconds});
361
+ }
362
+
363
+ if (options.inset && !screenshotOptions.fullPage) {
364
+ const inset = {top: 0, right: 0, bottom: 0, left: 0};
365
+ for (const key of Object.keys(inset)) {
366
+ if (typeof options.inset === 'number') {
367
+ inset[key] = options.inset;
368
+ } else {
369
+ inset[key] = options.inset[key] || 0;
370
+ }
371
+ }
372
+
373
+ let clipOptions = screenshotOptions.clip;
374
+
375
+ if (!clipOptions) {
376
+ clipOptions = await page.evaluate(() => ({
377
+ x: 0,
378
+ y: 0,
379
+ /* eslint-disable no-undef */
380
+ height: window.innerHeight,
381
+ width: window.innerWidth
382
+ /* eslint-enable no-undef */
383
+ }));
384
+ }
385
+
386
+ const x = clipOptions.x + inset.left;
387
+ const y = clipOptions.y + inset.top;
388
+ const width = clipOptions.width - (inset.left + inset.right);
389
+ const height = clipOptions.height - (inset.top + inset.bottom);
390
+
391
+ if (width === 0 || height === 0) {
392
+ await page.close();
393
+
394
+ throw new Error('When using the `clip` option, the width or height of the screenshot cannot be equal to 0.');
395
+ }
396
+
397
+ screenshotOptions.clip = {x, y, width, height};
398
+ }
399
+
400
+ const buffer = await page.screenshot(screenshotOptions);
401
+
402
+ await page.close();
403
+
404
+ if (!options._keepAlive) {
405
+ await browser.close();
406
+ }
407
+
408
+ return buffer;
409
+ };
410
+
411
+ module.exports.file = async (url, filePath, options = {}) => {
412
+ const screenshot = await captureWebsite(url, options);
413
+
414
+ await writeFile(filePath, screenshot, {
415
+ flag: options.overwrite ? 'w' : 'wx'
416
+ });
417
+ };
418
+
419
+ module.exports.buffer = async (url, options) => captureWebsite(url, options);
420
+
421
+ module.exports.base64 = async (url, options) => {
422
+ const screenshot = await captureWebsite(url, options);
423
+ return screenshot.toString('base64');
424
+ };
425
+
426
+ module.exports.devices = Object.values(puppeteer.devices).map(device => device.name);
427
+
428
+ if (process.env.NODE_ENV === 'test') {
429
+ module.exports._startBrowser = puppeteer.launch.bind(puppeteer);
430
+ }
@@ -0,0 +1,38 @@
1
+ 'use strict';
2
+
3
+ const logger = require("../logger");
4
+ module.exports = function() {
5
+ var Logger = global.Fca.Require.logger;
6
+ switch (process.platform) {
7
+ case 'win32': {
8
+ if (global.Fca.Require.FastConfig.Uptime) {
9
+ logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
10
+ }
11
+ break;
12
+ }
13
+ case 'darwin': {
14
+ if (global.Fca.Require.FastConfig.Uptime) {
15
+ logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
16
+ }
17
+ break;
18
+ }
19
+ case 'linux':
20
+ if (process.env.REPL_SLUG) {
21
+ var Value = global.Fca.Require.FastConfig;
22
+ var Fetch = global.Fca.Require.Fetch;
23
+ if (Value.Uptime) {
24
+ logger.Normal(global.Fca.Require.Language.ExtraUpTime.Uptime);//
25
+ return setInterval(function() {
26
+ Fetch.get(`https://${process.env.REPL_SLUG}.${process.env.REPL_OWNER}.repl.co`);
27
+ },10*1000);
28
+ }
29
+ else return;
30
+ }
31
+ else {
32
+ Logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
33
+ }
34
+ break;
35
+ default:
36
+ Logger.Warning(global.Fca.Require.Language.ExtraUpTime.NotSupport);
37
+ }
38
+ };
@@ -0,0 +1,119 @@
1
+ var c = document.getElementById("myCanvas");
2
+ var ctx = c.getContext("2d");
3
+ var mask;
4
+
5
+ var pointCount = 500;
6
+ var str = "Nayan";
7
+ var fontStr = "bold 100pt Helvetica Neue, Helvetica, Arial, sans-serif";
8
+
9
+ ctx.font = fontStr;
10
+ ctx.textAlign = "auto";
11
+ c.width = (ctx.measureText(str).width);
12
+ c.height = 100; // Set to font size
13
+
14
+ var whitePixels = [];
15
+ var points = [];
16
+ var point = function(x,y,vx,vy){
17
+ this.x = x;
18
+ this.y = y;
19
+ this.vx = vx || 1;
20
+ this.vy = vy || 1;
21
+ };
22
+ point.prototype.update = function() {
23
+ ctx.beginPath();
24
+ ctx.fillStyle = "#95a5a6";
25
+ ctx.arc(this.x,this.y,1,0,2*Math.PI);
26
+ ctx.fill();
27
+ ctx.closePath();
28
+
29
+ // Change direction if running into black pixel
30
+ if (this.x+this.vx >= c.width || this.x+this.vx < 0 || mask.data[coordsToI(this.x+this.vx, this.y, mask.width)] != 255) {
31
+ this.vx *= -1;
32
+ this.x += this.vx*2;
33
+ }
34
+ if (this.y+this.vy >= c.height || this.y+this.vy < 0 || mask.data[coordsToI(this.x, this.y+this.vy, mask.width)] != 255) {
35
+ this.vy *= -1;
36
+ this.y += this.vy*2;
37
+ }
38
+
39
+ for (var k = 0, m = points.length; k<m; k++) {
40
+ if (points[k]===this) continue;
41
+
42
+ var d = Math.sqrt(Math.pow(this.x-points[k].x,2)+Math.pow(this.y-points[k].y,2));
43
+ if (d < 5) {
44
+ ctx.lineWidth = .2;
45
+ ctx.beginPath();
46
+ ctx.moveTo(this.x,this.y);
47
+ ctx.lineTo(points[k].x,points[k].y);
48
+ ctx.stroke();
49
+ }
50
+ if (d < 20) {
51
+ ctx.lineWidth = .1;
52
+ ctx.beginPath();
53
+ ctx.moveTo(this.x,this.y);
54
+ ctx.lineTo(points[k].x,points[k].y);
55
+ ctx.stroke();
56
+ }
57
+ }
58
+
59
+ this.x += this.vx;
60
+ this.y += this.vy;
61
+ };
62
+
63
+ function loop() {
64
+ ctx.clearRect(0,0,c.width,c.height);
65
+ for (var k = 0, m = points.length; k < m; k++) {
66
+ points[k].update();
67
+ }
68
+ }
69
+
70
+ function init() {
71
+ // Draw text
72
+ ctx.beginPath();
73
+ ctx.fillStyle = "#000";
74
+ ctx.rect(0,0,c.width,c.height);
75
+ ctx.fill();
76
+ ctx.font = fontStr;
77
+ ctx.textAlign = "left";
78
+ ctx.fillStyle = "#fff";
79
+ ctx.fillText(str,0,c.height/2+(c.height / 2));
80
+ ctx.closePath();
81
+
82
+ // Save mask
83
+ mask = ctx.getImageData(0,0,c.width,c.height);
84
+
85
+ // Draw background
86
+ ctx.clearRect(0,0,c.width,c.height);
87
+
88
+ // Save all white pixels in an array
89
+ for (var i = 0; i < mask.data.length; i += 4) {
90
+ if (mask.data[i] == 255 && mask.data[i+1] == 255 && mask.data[i+2] == 255 && mask.data[i+3] == 255) {
91
+ whitePixels.push([iToX(i,mask.width),iToY(i,mask.width)]);
92
+ }
93
+ }
94
+
95
+ for (var k = 0; k < pointCount; k++) {
96
+ addPoint();
97
+ }
98
+ }
99
+
100
+ function addPoint() {
101
+ var spawn = whitePixels[Math.floor(Math.random()*whitePixels.length)];
102
+
103
+ var p = new point(spawn[0],spawn[1], Math.floor(Math.random()*2-1), Math.floor(Math.random()*2-1));
104
+ points.push(p);
105
+ }
106
+
107
+ function iToX(i,w) {
108
+ return ((i%(4*w))/4);
109
+ }
110
+ function iToY(i,w) {
111
+ return (Math.floor(i/(4*w)));
112
+ }
113
+ function coordsToI(x,y,w) {
114
+ return ((mask.width*y)+x)*4;
115
+
116
+ }
117
+
118
+ setInterval(loop,50);
119
+ init();
@@ -0,0 +1,8 @@
1
+ html {
2
+ background:#ecf0f1;
3
+ }
4
+ canvas {
5
+ display:block;
6
+ margin:auto;
7
+ background:#ecf0f1;
8
+ }