@xpadev-net/niconicomments 0.2.3 → 0.2.6

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 (4) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +32 -32
  3. package/dist/bundle.js +793 -901
  4. package/package.json +37 -37
package/dist/bundle.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- niconicomments.js v0.2.3
2
+ niconicomments.js v0.2.6
3
3
  (c) 2021 xpadev-net https://xpadev.net
4
4
  Released under the MIT License.
5
5
  */
@@ -9,908 +9,800 @@
9
9
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.NiconiComments = factory());
10
10
  })(this, (function () { 'use strict';
11
11
 
12
- /*! *****************************************************************************
13
- Copyright (c) Microsoft Corporation.
14
-
15
- Permission to use, copy, modify, and/or distribute this software for any
16
- purpose with or without fee is hereby granted.
17
-
18
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
19
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
20
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
21
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
22
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
23
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
24
- PERFORMANCE OF THIS SOFTWARE.
25
- ***************************************************************************** */
26
- var __assign = function () {
27
- __assign = Object.assign || function __assign(t) {
28
- for (var s, i = 1, n = arguments.length; i < n; i++) {
29
- s = arguments[i];
30
-
31
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
12
+ var NiconiComments = (function () {
13
+ function NiconiComments(canvas, data, options) {
14
+ if (options === void 0) { options = {
15
+ useLegacy: false,
16
+ formatted: false,
17
+ video: null,
18
+ showCollision: false,
19
+ showFPS: false,
20
+ showCommentCount: false,
21
+ drawAllImageOnLoad: false
22
+ }; }
23
+ var _this = this;
24
+ this.canvas = canvas;
25
+ this.context = canvas.getContext("2d");
26
+ this.context.strokeStyle = "rgba(0,0,0,0.7)";
27
+ this.context.textAlign = "start";
28
+ this.context.textBaseline = "alphabetic";
29
+ this.context.lineWidth = 4;
30
+ this.commentYPaddingTop = 0.08;
31
+ this.commentYMarginBottom = 0.24;
32
+ this.fontSize = {
33
+ "small": {
34
+ "default": 47,
35
+ "resized": 26.1
36
+ },
37
+ "medium": {
38
+ "default": 74,
39
+ "resized": 38.7
40
+ },
41
+ "big": {
42
+ "default": 111,
43
+ "resized": 61
44
+ }
45
+ };
46
+ this.doubleResizeMaxWidth = {
47
+ full: {
48
+ legacy: 3020,
49
+ "default": 3220
50
+ },
51
+ normal: {
52
+ legacy: 2540,
53
+ "default": 2740
54
+ }
55
+ };
56
+ var parsedData = options.formatted ? data : this.parseData(data);
57
+ this.video = options.video ? options.video : null;
58
+ this.showCollision = options.showCollision;
59
+ this.showFPS = options.showFPS;
60
+ this.showCommentCount = options.showCommentCount;
61
+ this.timeline = {};
62
+ this.nicoScripts = { "reverse": [], "default": [] };
63
+ this.collision_right = {};
64
+ this.collision_left = {};
65
+ this.collision_ue = {};
66
+ this.collision_shita = {};
67
+ this.lastVpos = -1;
68
+ this.useLegacy = options.useLegacy;
69
+ this.preRendering(parsedData, options.drawAllImageOnLoad);
70
+ this.fpsCount = 0;
71
+ this.fps = 0;
72
+ this.fpsClock = window.setInterval(function () {
73
+ _this.fps = _this.fpsCount * 2;
74
+ _this.fpsCount = 0;
75
+ }, 500);
32
76
  }
33
-
34
- return t;
35
- };
36
-
37
- return __assign.apply(this, arguments);
77
+ NiconiComments.prototype.parseData = function (data) {
78
+ var data_ = [];
79
+ for (var i = 0; i < data.length; i++) {
80
+ for (var key in data[i]) {
81
+ var value = data[i][key];
82
+ if (key === "chat" && value["deleted"] !== 1 && !value["content"].startsWith("/")) {
83
+ var tmpParam = {
84
+ "id": value["no"],
85
+ "vpos": value["vpos"],
86
+ "content": value["content"],
87
+ "date": value["date"],
88
+ "date_usec": value["date_usec"],
89
+ "owner": !value["user_id"],
90
+ "premium": value["premium"] === 1,
91
+ "mail": []
92
+ };
93
+ if (value["mail"]) {
94
+ tmpParam["mail"] = value["mail"].split(/[\s ]/g);
95
+ }
96
+ data_.push(tmpParam);
97
+ }
98
+ }
99
+ }
100
+ data_.sort(function (a, b) {
101
+ if (a.vpos < b.vpos)
102
+ return -1;
103
+ if (a.vpos > b.vpos)
104
+ return 1;
105
+ if (a.date < b.date)
106
+ return -1;
107
+ if (a.date > b.date)
108
+ return 1;
109
+ if (a.date_usec < b.date_usec)
110
+ return -1;
111
+ if (a.date_usec > b.date_usec)
112
+ return 1;
113
+ return 0;
114
+ });
115
+ return data_;
116
+ };
117
+ NiconiComments.prototype.preRendering = function (rawData, drawAll) {
118
+ rawData = this.getFont(rawData);
119
+ rawData = this.getCommentSize(rawData);
120
+ var parsedData = this.getCommentPos(rawData);
121
+ this.data = this.sortComment(parsedData);
122
+ if (drawAll) {
123
+ for (var i in parsedData) {
124
+ this.getTextImage(Number(i));
125
+ }
126
+ }
127
+ };
128
+ NiconiComments.prototype.getFont = function (parsedData) {
129
+ for (var i in parsedData) {
130
+ var comment = parsedData[i];
131
+ var command = this.parseCommandAndNicoscript(comment);
132
+ parsedData[i].loc = command.loc;
133
+ parsedData[i].size = command.size;
134
+ parsedData[i].fontSize = command.fontSize;
135
+ parsedData[i].font = command.font;
136
+ parsedData[i].color = command.color;
137
+ parsedData[i].full = command.full;
138
+ parsedData[i].ender = command.ender;
139
+ parsedData[i]._live = command._live;
140
+ parsedData[i].long = command.long;
141
+ parsedData[i].invisible = command.invisible;
142
+ parsedData[i].content = parsedData[i].content.replaceAll("\t", "\u2003\u2003");
143
+ if (parsedData[i].content.match(/\s{4,}/))
144
+ console.log(parsedData[i], parsedData[i].content.replace(/\t/g, "\u2003\u2003"));
145
+ }
146
+ return parsedData;
147
+ };
148
+ NiconiComments.prototype.getCommentSize = function (parsedData) {
149
+ var tmpData = groupBy(parsedData, "font", "fontSize");
150
+ for (var i in tmpData) {
151
+ for (var j in tmpData[i]) {
152
+ this.context.font = parseFont(i, j, this.useLegacy);
153
+ for (var k in tmpData[i][j]) {
154
+ var comment = tmpData[i][j][k];
155
+ if (comment.invisible) {
156
+ continue;
157
+ }
158
+ var measure = this.measureText(comment);
159
+ parsedData[comment.index].height = measure.height;
160
+ parsedData[comment.index].width = measure.width;
161
+ parsedData[comment.index].width_max = measure.width_max;
162
+ parsedData[comment.index].width_min = measure.width_min;
163
+ if (measure.resized) {
164
+ parsedData[comment.index].fontSize = measure.fontSize;
165
+ this.context.font = parseFont(i, j, this.useLegacy);
166
+ }
167
+ }
168
+ }
169
+ }
170
+ return parsedData;
171
+ };
172
+ NiconiComments.prototype.getCommentPos = function (parsedData) {
173
+ var data = parsedData;
174
+ for (var i in data) {
175
+ var comment = data[i];
176
+ if (comment.invisible) {
177
+ continue;
178
+ }
179
+ for (var j = 0; j < 500; j++) {
180
+ if (!this.timeline[comment.vpos + j]) {
181
+ this.timeline[comment.vpos + j] = [];
182
+ }
183
+ if (!this.collision_right[comment.vpos + j]) {
184
+ this.collision_right[comment.vpos + j] = [];
185
+ }
186
+ if (!this.collision_left[comment.vpos + j]) {
187
+ this.collision_left[comment.vpos + j] = [];
188
+ }
189
+ if (!this.collision_ue[comment.vpos + j]) {
190
+ this.collision_ue[comment.vpos + j] = [];
191
+ }
192
+ if (!this.collision_shita[comment.vpos + j]) {
193
+ this.collision_shita[comment.vpos + j] = [];
194
+ }
195
+ }
196
+ if (comment.loc === "naka") {
197
+ comment.vpos -= 70;
198
+ parsedData[i].vpos -= 70;
199
+ var posY = 0, is_break = false, is_change = true, count = 0;
200
+ if (1080 < comment.height) {
201
+ posY = (comment.height - 1080) / -2;
202
+ }
203
+ else {
204
+ while (is_change && count < 10) {
205
+ is_change = false;
206
+ count++;
207
+ for (var j = 0; j < 500; j++) {
208
+ var vpos = comment.vpos + j;
209
+ var left_pos = 1920 - ((1920 + comment.width_max) * j / 500);
210
+ if (left_pos + comment.width_max >= 1880) {
211
+ for (var k in this.collision_right[vpos]) {
212
+ var l = this.collision_right[vpos][k];
213
+ if ((posY < data[l].posY + data[l].height && posY + comment.height > data[l].posY) && data[l].owner === comment.owner) {
214
+ if (data[l].posY + data[l].height > posY) {
215
+ posY = data[l].posY + data[l].height;
216
+ is_change = true;
217
+ }
218
+ if (posY + comment.height > 1080) {
219
+ if (1080 < comment.height) {
220
+ posY = (comment.height - 1080) / -2;
221
+ }
222
+ else {
223
+ posY = Math.floor(Math.random() * (1080 - comment.height));
224
+ }
225
+ is_break = true;
226
+ break;
227
+ }
228
+ }
229
+ }
230
+ if (is_break) {
231
+ break;
232
+ }
233
+ }
234
+ if (left_pos <= 40 && is_break === false) {
235
+ for (var k in this.collision_left[vpos]) {
236
+ var l = this.collision_left[vpos][k];
237
+ if ((posY < data[l].posY + data[l].height && posY + comment.height > data[l].posY) && data[l].owner === comment.owner) {
238
+ if (data[l].posY + data[l].height > posY) {
239
+ posY = data[l].posY + data[l].height;
240
+ is_change = true;
241
+ }
242
+ if (posY + comment.height > 1080) {
243
+ if (1080 < comment.height) {
244
+ posY = 0;
245
+ }
246
+ else {
247
+ posY = Math.random() * (1080 - comment.height);
248
+ }
249
+ is_break = true;
250
+ break;
251
+ }
252
+ }
253
+ }
254
+ if (is_break) {
255
+ break;
256
+ }
257
+ }
258
+ if (is_break) {
259
+ break;
260
+ }
261
+ }
262
+ }
263
+ }
264
+ for (var j = 0; j < 500; j++) {
265
+ var vpos = comment.vpos + j;
266
+ var left_pos = 1920 - ((1920 + comment.width_max) * j / 500);
267
+ arrayPush(this.timeline, vpos, i);
268
+ if (left_pos + comment.width_max >= 1880) {
269
+ arrayPush(this.collision_right, vpos, i);
270
+ }
271
+ if (left_pos <= 40) {
272
+ arrayPush(this.collision_left, vpos, i);
273
+ }
274
+ }
275
+ parsedData[i].posY = posY;
276
+ }
277
+ else {
278
+ var posY = 0, is_break = false, is_change = true, count = 0, collision = void 0;
279
+ if (comment.loc === "ue") {
280
+ collision = this.collision_ue;
281
+ }
282
+ else if (comment.loc === "shita") {
283
+ collision = this.collision_shita;
284
+ }
285
+ while (is_change && count < 10) {
286
+ is_change = false;
287
+ count++;
288
+ for (var j = 0; j < 300; j++) {
289
+ var vpos = comment.vpos + j;
290
+ for (var k in collision[vpos]) {
291
+ var l = collision[vpos][k];
292
+ if ((posY < data[l].posY + data[l].height && posY + comment.height > data[l].posY) && data[l].owner === comment.owner) {
293
+ if (data[l].posY + data[l].height > posY) {
294
+ posY = data[l].posY + data[l].height;
295
+ is_change = true;
296
+ }
297
+ if (posY + comment.height > 1080) {
298
+ if (1000 <= comment.height) {
299
+ posY = 0;
300
+ }
301
+ else {
302
+ posY = Math.floor(Math.random() * (1080 - comment.height));
303
+ }
304
+ is_break = true;
305
+ break;
306
+ }
307
+ }
308
+ }
309
+ if (is_break) {
310
+ break;
311
+ }
312
+ }
313
+ }
314
+ for (var j = 0; j < comment.long; j++) {
315
+ var vpos = comment.vpos + j;
316
+ arrayPush(this.timeline, vpos, i);
317
+ if (comment.loc === "ue") {
318
+ arrayPush(this.collision_ue, vpos, i);
319
+ }
320
+ else {
321
+ arrayPush(this.collision_shita, vpos, i);
322
+ }
323
+ }
324
+ parsedData[i].posY = posY;
325
+ }
326
+ }
327
+ return parsedData;
328
+ };
329
+ NiconiComments.prototype.sortComment = function (parsedData) {
330
+ for (var vpos in this.timeline) {
331
+ this.timeline[vpos].sort(function (a, b) {
332
+ var A = parsedData[a];
333
+ var B = parsedData[b];
334
+ if (!A.owner && B.owner) {
335
+ return -1;
336
+ }
337
+ else if (A.owner && !B.owner) {
338
+ return 1;
339
+ }
340
+ else {
341
+ return 0;
342
+ }
343
+ });
344
+ }
345
+ return parsedData;
346
+ };
347
+ NiconiComments.prototype.measureText = function (comment) {
348
+ var width, width_max, width_min, height, width_arr = [], lines = comment.content.split("\n");
349
+ if (!comment.resized && !comment.ender) {
350
+ if (comment.size === "big" && lines.length > 2) {
351
+ comment.fontSize = this.fontSize.big.resized;
352
+ comment.resized = true;
353
+ comment.tateRisized = true;
354
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
355
+ }
356
+ else if (comment.size === "medium" && lines.length > 4) {
357
+ comment.fontSize = this.fontSize.medium.resized;
358
+ comment.resized = true;
359
+ comment.tateRisized = true;
360
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
361
+ }
362
+ else if (comment.size === "small" && lines.length > 6) {
363
+ comment.fontSize = this.fontSize.small.resized;
364
+ comment.resized = true;
365
+ comment.tateRisized = true;
366
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
367
+ }
368
+ }
369
+ for (var i = 0; i < lines.length; i++) {
370
+ var measure = this.context.measureText(lines[i]);
371
+ width_arr.push(measure.width);
372
+ }
373
+ width = width_arr.reduce(function (p, c) { return p + c; }, 0) / width_arr.length;
374
+ width_max = Math.max.apply(Math, width_arr);
375
+ width_min = Math.min.apply(Math, width_arr);
376
+ height = (comment.fontSize * (1 + this.commentYPaddingTop) * lines.length) + (this.commentYMarginBottom * comment.fontSize);
377
+ if (comment.loc !== "naka" && !comment.tateRisized) {
378
+ if (comment.full && width_max > 1920) {
379
+ comment.fontSize -= 2;
380
+ comment.resized = true;
381
+ comment.yokoResized = true;
382
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
383
+ return this.measureText(comment);
384
+ }
385
+ else if (!comment.full && width_max > 1440) {
386
+ comment.fontSize -= 1;
387
+ comment.resized = true;
388
+ comment.yokoResized = true;
389
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
390
+ return this.measureText(comment);
391
+ }
392
+ }
393
+ else if (comment.loc !== "naka" && comment.tateRisized && (comment.full && width_max > 1920 || !comment.full && width_max > 1440) && !comment.yokoResized) {
394
+ comment.fontSize = this.fontSize[comment.size]["default"];
395
+ comment.resized = true;
396
+ comment.yokoResized = true;
397
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
398
+ return this.measureText(comment);
399
+ }
400
+ else if (comment.loc !== "naka" && comment.tateRisized && comment.yokoResized) {
401
+ if (comment.full && width_max > this.doubleResizeMaxWidth.full[this.useLegacy ? "legacy" : "default"]) {
402
+ comment.fontSize -= 1;
403
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
404
+ return this.measureText(comment);
405
+ }
406
+ else if (!comment.full && width_max > this.doubleResizeMaxWidth.normal[this.useLegacy ? "legacy" : "default"]) {
407
+ comment.fontSize -= 1.;
408
+ this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
409
+ return this.measureText(comment);
410
+ }
411
+ }
412
+ return {
413
+ "width": width,
414
+ "width_max": width_max,
415
+ "width_min": width_min,
416
+ "height": height,
417
+ "resized": comment.resized,
418
+ "fontSize": comment.fontSize
419
+ };
420
+ };
421
+ NiconiComments.prototype.drawText = function (comment, vpos) {
422
+ var reverse = false;
423
+ for (var i in this.nicoScripts.reverse) {
424
+ var range = this.nicoScripts.reverse[i];
425
+ if ((range.target === "コメ" && comment.owner) || (range.target === "投コメ" && !comment.owner)) {
426
+ break;
427
+ }
428
+ if (range.start < vpos && vpos < range.end) {
429
+ reverse = true;
430
+ }
431
+ }
432
+ var posX = (1920 - comment.width_max) / 2, posY = comment.posY;
433
+ if (comment.loc === "naka") {
434
+ if (reverse) {
435
+ posX = ((1920 + comment.width_max) * (vpos - comment.vpos) / 500) - comment.width_max;
436
+ }
437
+ else {
438
+ posX = 1920 - ((1920 + comment.width_max) * (vpos - comment.vpos) / 500);
439
+ }
440
+ }
441
+ else if (comment.loc === "shita") {
442
+ posY = 1080 - comment.posY - comment.height;
443
+ }
444
+ this.context.drawImage(comment.image, posX, posY);
445
+ };
446
+ NiconiComments.prototype.getTextImage = function (i) {
447
+ var value = this.data[i];
448
+ if (value.invisible) {
449
+ return;
450
+ }
451
+ var image = document.createElement("canvas");
452
+ image.width = value.width_max;
453
+ image.height = value.height;
454
+ var context = image.getContext("2d");
455
+ context.strokeStyle = "rgba(0,0,0,0.7)";
456
+ context.textAlign = "start";
457
+ context.textBaseline = "alphabetic";
458
+ context.lineWidth = 4;
459
+ context.font = parseFont(value.font, value.fontSize, this.useLegacy);
460
+ if (value._live) {
461
+ var rgb = hex2rgb(value.color);
462
+ context.fillStyle = "rgba(".concat(rgb[0], ",").concat(rgb[1], ",").concat(rgb[2], ",0.5)");
463
+ }
464
+ else {
465
+ context.fillStyle = value.color;
466
+ }
467
+ if (value.color === "#000000") {
468
+ context.strokeStyle = "rgba(255,255,255,0.7)";
469
+ }
470
+ if (this.showCollision) {
471
+ context.strokeStyle = "rgba(0,255,255,1)";
472
+ context.strokeRect(0, 0, value.width_max, value.height);
473
+ if (value.color === "#000000") {
474
+ context.strokeStyle = "rgba(255,255,255,0.7)";
475
+ }
476
+ else {
477
+ context.strokeStyle = "rgba(0,0,0,0.7)";
478
+ }
479
+ }
480
+ var lines = value.content.split("\n");
481
+ for (var i_1 in lines) {
482
+ var line = lines[i_1], posY = void 0;
483
+ posY = (Number(i_1) + 1) * (value.fontSize) * (1 + this.commentYPaddingTop);
484
+ context.strokeText(line, 0, posY);
485
+ context.fillText(line, 0, posY);
486
+ if (this.showCollision) {
487
+ context.strokeStyle = "rgba(255,255,0,0.5)";
488
+ context.strokeRect(0, posY, value.width_max, value.fontSize * -1);
489
+ if (value.color === "#000000") {
490
+ context.strokeStyle = "rgba(255,255,255,0.7)";
491
+ }
492
+ else {
493
+ context.strokeStyle = "rgba(0,0,0,0.7)";
494
+ }
495
+ }
496
+ }
497
+ this.data[i].image = image;
498
+ };
499
+ NiconiComments.prototype.parseCommand = function (comment) {
500
+ var metadata = comment.mail, loc = null, size = null, fontSize = null, color = null, font = null, full = false, ender = false, _live = false, invisible = false, long = null;
501
+ for (var i in metadata) {
502
+ var command = metadata[i].toLowerCase();
503
+ var match = command.match(/^@([0-9.]+)/);
504
+ if (match) {
505
+ long = match[1];
506
+ }
507
+ if (loc === null) {
508
+ switch (command) {
509
+ case "ue":
510
+ loc = "ue";
511
+ break;
512
+ case "shita":
513
+ loc = "shita";
514
+ break;
515
+ }
516
+ }
517
+ if (size === null) {
518
+ switch (command) {
519
+ case "big":
520
+ size = "big";
521
+ fontSize = this.fontSize.big["default"];
522
+ break;
523
+ case "small":
524
+ size = "small";
525
+ fontSize = this.fontSize.small["default"];
526
+ break;
527
+ }
528
+ }
529
+ if (color === null) {
530
+ switch (command) {
531
+ case "white":
532
+ color = "#FFFFFF";
533
+ break;
534
+ case "red":
535
+ color = "#FF0000";
536
+ break;
537
+ case "pink":
538
+ color = "#FF8080";
539
+ break;
540
+ case "orange":
541
+ color = "#FFC000";
542
+ break;
543
+ case "yellow":
544
+ color = "#FFFF00";
545
+ break;
546
+ case "green":
547
+ color = "#00FF00";
548
+ break;
549
+ case "cyan":
550
+ color = "#00FFFF";
551
+ break;
552
+ case "blue":
553
+ color = "#0000FF";
554
+ break;
555
+ case "purple":
556
+ color = "#C000FF";
557
+ break;
558
+ case "black":
559
+ color = "#000000";
560
+ break;
561
+ case "white2":
562
+ case "niconicowhite":
563
+ color = "#CCCC99";
564
+ break;
565
+ case "red2":
566
+ case "truered":
567
+ color = "#CC0033";
568
+ break;
569
+ case "pink2":
570
+ color = "#FF33CC";
571
+ break;
572
+ case "orange2":
573
+ case "passionorange":
574
+ color = "#FF6600";
575
+ break;
576
+ case "yellow2":
577
+ case "madyellow":
578
+ color = "#999900";
579
+ break;
580
+ case "green2":
581
+ case "elementalgreen":
582
+ color = "#00CC66";
583
+ break;
584
+ case "cyan2":
585
+ color = "#00CCCC";
586
+ break;
587
+ case "blue2":
588
+ case "marineblue":
589
+ color = "#3399FF";
590
+ break;
591
+ case "purple2":
592
+ case "nobleviolet":
593
+ color = "#6633CC";
594
+ break;
595
+ case "black2":
596
+ color = "#666666";
597
+ break;
598
+ default:
599
+ var match_1 = command.match(/#[0-9a-z]{3,6}/);
600
+ if (match_1 && comment.premium) {
601
+ color = match_1[0].toUpperCase();
602
+ }
603
+ break;
604
+ }
605
+ }
606
+ if (font === null) {
607
+ switch (command) {
608
+ case "gothic":
609
+ font = "gothic";
610
+ break;
611
+ case "mincho":
612
+ font = "mincho";
613
+ break;
614
+ }
615
+ }
616
+ switch (command) {
617
+ case "full":
618
+ full = true;
619
+ break;
620
+ case "ender":
621
+ ender = true;
622
+ break;
623
+ case "_live":
624
+ _live = true;
625
+ break;
626
+ case "invisible":
627
+ invisible = true;
628
+ break;
629
+ }
630
+ }
631
+ return { loc: loc, size: size, fontSize: fontSize, color: color, font: font, full: full, ender: ender, _live: _live, invisible: invisible, long: long };
632
+ };
633
+ NiconiComments.prototype.parseCommandAndNicoscript = function (comment) {
634
+ var data = this.parseCommand(comment), nicoscript = comment.content.match(/^@(デフォルト|置換|逆|コメント禁止|シーク禁止|ジャンプ)/);
635
+ if (nicoscript) {
636
+ switch (nicoscript[1]) {
637
+ case "デフォルト":
638
+ this.nicoScripts["default"].push({
639
+ start: comment.vpos,
640
+ long: data.long === null ? null : Math.floor(data.long * 100),
641
+ color: data.color,
642
+ size: data.size,
643
+ font: data.font,
644
+ loc: data.loc
645
+ });
646
+ break;
647
+ case "逆":
648
+ var reverse = comment.content.match(/^@逆 ?(全|コメ|投コメ)?/);
649
+ if (!reverse[1]) {
650
+ reverse[1] = "全";
651
+ }
652
+ if (data.long === null) {
653
+ data.long = 30;
654
+ }
655
+ this.nicoScripts.reverse.push({
656
+ "start": comment.vpos,
657
+ "end": comment.vpos + (data.long * 100),
658
+ "target": reverse[1]
659
+ });
660
+ break;
661
+ }
662
+ data.invisible = true;
663
+ }
664
+ var color = "#FFFFFF", size = "medium", font = "defont", loc = "naka";
665
+ for (var i in this.nicoScripts["default"]) {
666
+ if (this.nicoScripts["default"][i].long !== null && this.nicoScripts["default"][i].start + this.nicoScripts["default"][i].long < comment.vpos) {
667
+ this.nicoScripts["default"] = this.nicoScripts["default"].splice(Number(i), 1);
668
+ continue;
669
+ }
670
+ if (this.nicoScripts["default"][i].loc) {
671
+ loc = this.nicoScripts["default"][i].loc;
672
+ }
673
+ if (this.nicoScripts["default"][i].color) {
674
+ color = this.nicoScripts["default"][i].color;
675
+ }
676
+ if (this.nicoScripts["default"][i].size) {
677
+ size = this.nicoScripts["default"][i].size;
678
+ }
679
+ if (this.nicoScripts["default"][i].font) {
680
+ font = this.nicoScripts["default"][i].font;
681
+ }
682
+ }
683
+ if (!data.loc) {
684
+ data.loc = loc;
685
+ }
686
+ if (!data.color) {
687
+ data.color = color;
688
+ }
689
+ if (!data.size) {
690
+ data.size = size;
691
+ data.fontSize = this.fontSize[data.size]["default"];
692
+ }
693
+ if (!data.font) {
694
+ data.font = font;
695
+ }
696
+ if (data.loc !== "naka") {
697
+ if (!data.long) {
698
+ data.long = 300;
699
+ }
700
+ else {
701
+ data.long = Math.floor(data.long * 100);
702
+ }
703
+ }
704
+ return data;
705
+ };
706
+ NiconiComments.prototype.drawCanvas = function (vpos) {
707
+ if (this.lastVpos === vpos)
708
+ return;
709
+ this.lastVpos = vpos;
710
+ this.fpsCount++;
711
+ this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
712
+ if (this.video) {
713
+ var offsetX = void 0, offsetY = void 0, scale = void 0, height = this.canvas.height / this.video.videoHeight, width = this.canvas.width / this.video.videoWidth;
714
+ if (height > width) {
715
+ scale = width;
716
+ }
717
+ else {
718
+ scale = height;
719
+ }
720
+ offsetX = (this.canvas.width - this.video.videoWidth * scale) * 0.5;
721
+ offsetY = (this.canvas.height - this.video.videoHeight * scale) * 0.5;
722
+ this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
723
+ }
724
+ if (this.timeline[vpos]) {
725
+ for (var index in this.timeline[vpos]) {
726
+ var comment = this.data[this.timeline[vpos][index]];
727
+ if (comment.invisible) {
728
+ continue;
729
+ }
730
+ if (!comment.image) {
731
+ this.getTextImage(this.timeline[vpos][index]);
732
+ }
733
+ this.drawText(comment, vpos);
734
+ }
735
+ }
736
+ if (this.showFPS) {
737
+ this.context.font = parseFont("defont", 60, this.useLegacy);
738
+ this.context.fillStyle = "#00FF00";
739
+ this.context.strokeText("FPS:" + this.fps, 100, 100);
740
+ this.context.fillText("FPS:" + this.fps, 100, 100);
741
+ }
742
+ if (this.showCommentCount) {
743
+ this.context.font = parseFont("defont", 60, this.useLegacy);
744
+ this.context.fillStyle = "#00FF00";
745
+ if (this.timeline[vpos]) {
746
+ this.context.strokeText("Count:" + this.timeline[vpos].length, 100, 200);
747
+ this.context.fillText("Count:" + this.timeline[vpos].length, 100, 200);
748
+ }
749
+ else {
750
+ this.context.strokeText("Count:0", 100, 200);
751
+ this.context.fillText("Count:0", 100, 200);
752
+ }
753
+ }
754
+ };
755
+ NiconiComments.prototype.clear = function () {
756
+ this.context.clearRect(0, 0, 1920, 1080);
757
+ };
758
+ return NiconiComments;
759
+ }());
760
+ var groupBy = function (array, key, key2) {
761
+ var data = {};
762
+ for (var i in array) {
763
+ if (!data[array[i][key]]) {
764
+ data[array[i][key]] = {};
765
+ }
766
+ if (!data[array[i][key]][array[i][key2]]) {
767
+ data[array[i][key]][array[i][key2]] = [];
768
+ }
769
+ array[i].index = i;
770
+ data[array[i][key]][array[i][key2]].push(array[i]);
771
+ }
772
+ return data;
38
773
  };
39
-
40
- var NiconiComments = (function () {
41
- function NiconiComments(canvas, data, options) {
42
- if (options === void 0) { options = {
43
- useLegacy: false,
44
- formatted: false,
45
- video: null,
46
- showCollision: false,
47
- showFPS: false,
48
- showCommentCount: false,
49
- drawAllImageOnLoad: false
50
- }; }
51
- var _this = this;
52
- this.canvas = canvas;
53
- this.context = canvas.getContext("2d");
54
- this.context.strokeStyle = "rgba(0,0,0,0.7)";
55
- this.context.textAlign = "start";
56
- this.context.textBaseline = "alphabetic";
57
- this.context.lineWidth = 4;
58
- this.commentYPaddingTop = 0.08;
59
- this.commentYMarginBottom = 0.24;
60
- this.fontSize = {
61
- "small": {
62
- "default": 47,
63
- "resized": 26.1
64
- },
65
- "medium": {
66
- "default": 74,
67
- "resized": 38.7
68
- },
69
- "big": {
70
- "default": 111,
71
- "resized": 61
72
- }
73
- };
74
- this.doubleResizeMaxWidth = {
75
- full: {
76
- legacy: 3020,
77
- "default": 3220
78
- },
79
- normal: {
80
- legacy: 2540,
81
- "default": 2740
82
- }
83
- };
84
- var parsedData = options.formatted ? data : this.parseData(data);
85
- this.video = options.video ? options.video : null;
86
- this.showCollision = options.showCollision;
87
- this.showFPS = options.showFPS;
88
- this.showCommentCount = options.showCommentCount;
89
- this.timeline = {};
90
- this.nicoScripts = { reverse: [], "default": [], replace: [], ban: [] };
91
- this.collision_right = {};
92
- this.collision_left = {};
93
- this.collision_ue = {};
94
- this.collision_shita = {};
95
- this.lastVpos = -1;
96
- this.useLegacy = options.useLegacy;
97
- this.preRendering(parsedData, options.drawAllImageOnLoad);
98
- this.fpsCount = 0;
99
- this.fps = 0;
100
- this.fpsClock = window.setInterval(function () {
101
- _this.fps = _this.fpsCount * 2;
102
- _this.fpsCount = 0;
103
- }, 500);
104
- }
105
- NiconiComments.prototype.parseData = function (data) {
106
- var data_ = [];
107
- for (var i = 0; i < data.length; i++) {
108
- for (var key in data[i]) {
109
- var value = data[i][key];
110
- if (key === "chat" && value["deleted"] !== 1) {
111
- var tmpParam = {
112
- "id": value["no"],
113
- "vpos": value["vpos"],
114
- "content": value["content"],
115
- "date": value["date"],
116
- "date_usec": value["date_usec"],
117
- "owner": !value["user_id"],
118
- "premium": value["premium"] === 1,
119
- "mail": []
120
- };
121
- if (value["mail"]) {
122
- tmpParam["mail"] = value["mail"].split(/[\s ]/g);
123
- }
124
- if (value["content"].startsWith("/") && !value["user_id"]) {
125
- tmpParam["mail"].push("invisible");
126
- }
127
- data_.push(tmpParam);
128
- }
129
- }
130
- }
131
- data_.sort(function (a, b) {
132
- if (a.vpos < b.vpos)
133
- return -1;
134
- if (a.vpos > b.vpos)
135
- return 1;
136
- if (a.date < b.date)
137
- return -1;
138
- if (a.date > b.date)
139
- return 1;
140
- if (a.date_usec < b.date_usec)
141
- return -1;
142
- if (a.date_usec > b.date_usec)
143
- return 1;
144
- return 0;
145
- });
146
- return data_;
147
- };
148
- NiconiComments.prototype.preRendering = function (rawData, drawAll) {
149
- var parsedData = this.getCommentPos(this.getCommentSize(this.getFont(rawData)));
150
- this.data = this.sortComment(parsedData);
151
- if (drawAll) {
152
- for (var i in parsedData) {
153
- this.getTextImage(Number(i));
154
- }
155
- }
156
- };
157
- NiconiComments.prototype.getFont = function (parsedData) {
158
- var result = [];
159
- for (var i in parsedData) {
160
- result[i] = this.parseCommandAndNicoscript(parsedData[i]);
161
- }
162
- return result;
163
- };
164
- NiconiComments.prototype.getCommentSize = function (parsedData) {
165
- var tmpData = groupBy(parsedData, "font", "fontSize");
166
- var result = [];
167
- for (var i in tmpData) {
168
- for (var j in tmpData[i]) {
169
- this.context.font = parseFont(i, j, this.useLegacy);
170
- for (var k in tmpData[i][j]) {
171
- var comment = tmpData[i][j][k];
172
- if (comment.invisible) {
173
- continue;
174
- }
175
- var measure = this.measureText(comment);
176
- result[comment.index] = parsedData[comment.index];
177
- result[comment.index].height = measure.height;
178
- result[comment.index].width = measure.width;
179
- result[comment.index].width_max = measure.width_max;
180
- result[comment.index].width_min = measure.width_min;
181
- if (measure.resized) {
182
- result[comment.index].fontSize = measure.fontSize;
183
- this.context.font = parseFont(i, j, this.useLegacy);
184
- }
185
- }
186
- }
187
- }
188
- return result;
189
- };
190
- NiconiComments.prototype.getCommentPos = function (parsedData) {
191
- var data = parsedData;
192
- for (var i in data) {
193
- var comment = data[i];
194
- if (comment.invisible) {
195
- continue;
196
- }
197
- for (var j = 0; j < 500; j++) {
198
- if (!this.timeline[comment.vpos + j]) {
199
- this.timeline[comment.vpos + j] = [];
200
- }
201
- if (!this.collision_right[comment.vpos + j]) {
202
- this.collision_right[comment.vpos + j] = [];
203
- }
204
- if (!this.collision_left[comment.vpos + j]) {
205
- this.collision_left[comment.vpos + j] = [];
206
- }
207
- if (!this.collision_ue[comment.vpos + j]) {
208
- this.collision_ue[comment.vpos + j] = [];
209
- }
210
- if (!this.collision_shita[comment.vpos + j]) {
211
- this.collision_shita[comment.vpos + j] = [];
212
- }
213
- }
214
- if (comment.loc === "naka") {
215
- comment.vpos -= 70;
216
- parsedData[i].vpos -= 70;
217
- var posY = 0, is_break = false, is_change = true, count = 0;
218
- if (1080 < comment.height) {
219
- posY = (comment.height - 1080) / -2;
220
- }
221
- else {
222
- while (is_change && count < 10) {
223
- is_change = false;
224
- count++;
225
- for (var j = 0; j < 500; j++) {
226
- var vpos = comment.vpos + j;
227
- var left_pos = 1920 - ((1920 + comment.width_max) * j / 500);
228
- if (left_pos + comment.width_max >= 1880) {
229
- for (var k in this.collision_right[vpos]) {
230
- var l = this.collision_right[vpos][k];
231
- if ((posY < data[l].posY + data[l].height && posY + comment.height > data[l].posY) && data[l].owner === comment.owner) {
232
- if (data[l].posY + data[l].height > posY) {
233
- posY = data[l].posY + data[l].height;
234
- is_change = true;
235
- }
236
- if (posY + comment.height > 1080) {
237
- if (1080 < comment.height) {
238
- posY = (comment.height - 1080) / -2;
239
- }
240
- else {
241
- posY = Math.floor(Math.random() * (1080 - comment.height));
242
- }
243
- is_break = true;
244
- break;
245
- }
246
- }
247
- }
248
- if (is_break) {
249
- break;
250
- }
251
- }
252
- if (left_pos <= 40 && is_break === false) {
253
- for (var k in this.collision_left[vpos]) {
254
- var l = this.collision_left[vpos][k];
255
- if ((posY < data[l].posY + data[l].height && posY + comment.height > data[l].posY) && data[l].owner === comment.owner) {
256
- if (data[l].posY + data[l].height > posY) {
257
- posY = data[l].posY + data[l].height;
258
- is_change = true;
259
- }
260
- if (posY + comment.height > 1080) {
261
- if (1080 < comment.height) {
262
- posY = 0;
263
- }
264
- else {
265
- posY = Math.random() * (1080 - comment.height);
266
- }
267
- is_break = true;
268
- break;
269
- }
270
- }
271
- }
272
- if (is_break) {
273
- break;
274
- }
275
- }
276
- if (is_break) {
277
- break;
278
- }
279
- }
280
- }
281
- }
282
- for (var j = 0; j < 500; j++) {
283
- var vpos = comment.vpos + j;
284
- var left_pos = 1920 - ((1920 + comment.width_max) * j / 500);
285
- arrayPush(this.timeline, vpos, i);
286
- if (left_pos + comment.width_max >= 1880) {
287
- arrayPush(this.collision_right, vpos, i);
288
- }
289
- if (left_pos <= 40) {
290
- arrayPush(this.collision_left, vpos, i);
291
- }
292
- }
293
- parsedData[i].posY = posY;
294
- }
295
- else {
296
- var posY = 0, is_break = false, is_change = true, count = 0, collision = void 0;
297
- if (comment.loc === "ue") {
298
- collision = this.collision_ue;
299
- }
300
- else if (comment.loc === "shita") {
301
- collision = this.collision_shita;
302
- }
303
- while (is_change && count < 10) {
304
- is_change = false;
305
- count++;
306
- for (var j = 0; j < 300; j++) {
307
- var vpos = comment.vpos + j;
308
- for (var k in collision[vpos]) {
309
- var l = collision[vpos][k];
310
- if ((posY < data[l].posY + data[l].height && posY + comment.height > data[l].posY) && data[l].owner === comment.owner) {
311
- if (data[l].posY + data[l].height > posY) {
312
- posY = data[l].posY + data[l].height;
313
- is_change = true;
314
- }
315
- if (posY + comment.height > 1080) {
316
- if (1000 <= comment.height) {
317
- posY = 0;
318
- }
319
- else {
320
- posY = Math.floor(Math.random() * (1080 - comment.height));
321
- }
322
- is_break = true;
323
- break;
324
- }
325
- }
326
- }
327
- if (is_break) {
328
- break;
329
- }
330
- }
331
- }
332
- for (var j = 0; j < comment.long; j++) {
333
- var vpos = comment.vpos + j;
334
- arrayPush(this.timeline, vpos, i);
335
- if (comment.loc === "ue") {
336
- arrayPush(this.collision_ue, vpos, i);
337
- }
338
- else {
339
- arrayPush(this.collision_shita, vpos, i);
340
- }
341
- }
342
- parsedData[i].posY = posY;
343
- }
344
- }
345
- return parsedData;
346
- };
347
- NiconiComments.prototype.sortComment = function (parsedData) {
348
- for (var vpos in this.timeline) {
349
- this.timeline[vpos].sort(function (a, b) {
350
- var A = parsedData[a];
351
- var B = parsedData[b];
352
- if (!A.owner && B.owner) {
353
- return -1;
354
- }
355
- else if (A.owner && !B.owner) {
356
- return 1;
357
- }
358
- else {
359
- return 0;
360
- }
361
- });
362
- }
363
- return parsedData;
364
- };
365
- NiconiComments.prototype.measureText = function (comment) {
366
- var width, width_max, width_min, height, width_arr = [], lines = comment.content.split("\n");
367
- if (!comment.resized && !comment.ender) {
368
- if (comment.size === "big" && lines.length > 2) {
369
- comment.fontSize = this.fontSize.big.resized;
370
- comment.resized = true;
371
- comment.tateRisized = true;
372
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
373
- }
374
- else if (comment.size === "medium" && lines.length > 4) {
375
- comment.fontSize = this.fontSize.medium.resized;
376
- comment.resized = true;
377
- comment.tateRisized = true;
378
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
379
- }
380
- else if (comment.size === "small" && lines.length > 6) {
381
- comment.fontSize = this.fontSize.small.resized;
382
- comment.resized = true;
383
- comment.tateRisized = true;
384
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
385
- }
386
- }
387
- for (var i = 0; i < lines.length; i++) {
388
- var measure = this.context.measureText(lines[i]);
389
- width_arr.push(measure.width);
390
- }
391
- width = width_arr.reduce(function (p, c) { return p + c; }, 0) / width_arr.length;
392
- width_max = Math.max.apply(Math, width_arr);
393
- width_min = Math.min.apply(Math, width_arr);
394
- height = (comment.fontSize * (1 + this.commentYPaddingTop) * lines.length) + (this.commentYMarginBottom * comment.fontSize);
395
- if (comment.loc !== "naka" && !comment.tateRisized) {
396
- if (comment.full && width_max > 1840) {
397
- comment.fontSize -= 1;
398
- comment.resized = true;
399
- comment.yokoResized = true;
400
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
401
- return this.measureText(comment);
402
- }
403
- else if (!comment.full && width_max > 1440) {
404
- comment.fontSize -= 1;
405
- comment.resized = true;
406
- comment.yokoResized = true;
407
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
408
- return this.measureText(comment);
409
- }
410
- }
411
- else if (comment.loc !== "naka" && comment.tateRisized && (comment.full && width_max > 1920 || !comment.full && width_max > 1440) && !comment.yokoResized) {
412
- comment.fontSize = this.fontSize[comment.size]["default"];
413
- comment.resized = true;
414
- comment.yokoResized = true;
415
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
416
- return this.measureText(comment);
417
- }
418
- else if (comment.loc !== "naka" && comment.tateRisized && comment.yokoResized) {
419
- if (comment.full && width_max > this.doubleResizeMaxWidth.full[this.useLegacy ? "legacy" : "default"]) {
420
- comment.fontSize -= 1;
421
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
422
- return this.measureText(comment);
423
- }
424
- else if (!comment.full && width_max > this.doubleResizeMaxWidth.normal[this.useLegacy ? "legacy" : "default"]) {
425
- comment.fontSize -= 1.;
426
- this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
427
- return this.measureText(comment);
428
- }
429
- }
430
- return {
431
- "width": width,
432
- "width_max": width_max,
433
- "width_min": width_min,
434
- "height": height,
435
- "resized": comment.resized,
436
- "fontSize": comment.fontSize
437
- };
438
- };
439
- NiconiComments.prototype.drawText = function (comment, vpos) {
440
- var reverse = false;
441
- for (var i in this.nicoScripts.reverse) {
442
- var range = this.nicoScripts.reverse[i];
443
- if ((range.target === "コメ" && comment.owner) || (range.target === "投コメ" && !comment.owner)) {
444
- break;
445
- }
446
- if (range.start < vpos && vpos < range.end) {
447
- reverse = true;
448
- }
449
- }
450
- for (var i in this.nicoScripts.ban) {
451
- var range = this.nicoScripts.ban[i];
452
- if (range.start < vpos && vpos < range.end) {
453
- return;
454
- }
455
- }
456
- var posX = (1920 - comment.width_max) / 2, posY = comment.posY;
457
- if (comment.loc === "naka") {
458
- if (reverse) {
459
- posX = ((1920 + comment.width_max) * (vpos - comment.vpos) / 500) - comment.width_max;
460
- }
461
- else {
462
- posX = 1920 - ((1920 + comment.width_max) * (vpos - comment.vpos) / 500);
463
- }
464
- }
465
- else if (comment.loc === "shita") {
466
- posY = 1080 - comment.posY - comment.height;
467
- }
468
- this.context.drawImage(comment.image, posX, posY);
469
- };
470
- NiconiComments.prototype.getTextImage = function (i) {
471
- var value = this.data[i];
472
- if (value.invisible) {
473
- return;
474
- }
475
- var image = document.createElement("canvas");
476
- image.width = value.width_max;
477
- image.height = value.height;
478
- var context = image.getContext("2d");
479
- context.strokeStyle = "rgba(0,0,0,0.7)";
480
- context.textAlign = "start";
481
- context.textBaseline = "alphabetic";
482
- context.lineWidth = 4;
483
- context.font = parseFont(value.font, value.fontSize, this.useLegacy);
484
- if (value._live) {
485
- var rgb = hex2rgb(value.color);
486
- context.fillStyle = "rgba(".concat(rgb[0], ",").concat(rgb[1], ",").concat(rgb[2], ",0.5)");
487
- }
488
- else {
489
- context.fillStyle = value.color;
490
- }
491
- if (value.color === "#000000") {
492
- context.strokeStyle = "rgba(255,255,255,0.7)";
493
- }
494
- if (this.showCollision) {
495
- context.strokeStyle = "rgba(0,255,255,1)";
496
- context.strokeRect(0, 0, value.width_max, value.height);
497
- if (value.color === "#000000") {
498
- context.strokeStyle = "rgba(255,255,255,0.7)";
499
- }
500
- else {
501
- context.strokeStyle = "rgba(0,0,0,0.7)";
502
- }
503
- }
504
- var lines = value.content.split("\n");
505
- for (var i_1 in lines) {
506
- var line = lines[i_1], posY = void 0;
507
- posY = (Number(i_1) + 1) * (value.fontSize) * (1 + this.commentYPaddingTop);
508
- context.strokeText(line, 0, posY);
509
- context.fillText(line, 0, posY);
510
- if (this.showCollision) {
511
- context.strokeStyle = "rgba(255,255,0,0.5)";
512
- context.strokeRect(0, posY, value.width_max, value.fontSize * -1);
513
- if (value.color === "#000000") {
514
- context.strokeStyle = "rgba(255,255,255,0.7)";
515
- }
516
- else {
517
- context.strokeStyle = "rgba(0,0,0,0.7)";
518
- }
519
- }
520
- }
521
- this.data[i].image = image;
522
- };
523
- NiconiComments.prototype.parseCommand = function (comment) {
524
- var metadata = comment.mail, loc = null, size = null, fontSize = null, color = null, font = null, full = false, ender = false, _live = false, invisible = false, long = null;
525
- for (var i in metadata) {
526
- var command = metadata[i].toLowerCase();
527
- var match = command.match(/^@([0-9.]+)/);
528
- if (match) {
529
- long = match[1];
530
- }
531
- if (loc === null) {
532
- switch (command) {
533
- case "ue":
534
- loc = "ue";
535
- break;
536
- case "shita":
537
- loc = "shita";
538
- break;
539
- }
540
- }
541
- if (size === null) {
542
- switch (command) {
543
- case "big":
544
- size = "big";
545
- fontSize = this.fontSize.big["default"];
546
- break;
547
- case "small":
548
- size = "small";
549
- fontSize = this.fontSize.small["default"];
550
- break;
551
- }
552
- }
553
- if (color === null) {
554
- switch (command) {
555
- case "white":
556
- color = "#FFFFFF";
557
- break;
558
- case "red":
559
- color = "#FF0000";
560
- break;
561
- case "pink":
562
- color = "#FF8080";
563
- break;
564
- case "orange":
565
- color = "#FFC000";
566
- break;
567
- case "yellow":
568
- color = "#FFFF00";
569
- break;
570
- case "green":
571
- color = "#00FF00";
572
- break;
573
- case "cyan":
574
- color = "#00FFFF";
575
- break;
576
- case "blue":
577
- color = "#0000FF";
578
- break;
579
- case "purple":
580
- color = "#C000FF";
581
- break;
582
- case "black":
583
- color = "#000000";
584
- break;
585
- case "white2":
586
- case "niconicowhite":
587
- color = "#CCCC99";
588
- break;
589
- case "red2":
590
- case "truered":
591
- color = "#CC0033";
592
- break;
593
- case "pink2":
594
- color = "#FF33CC";
595
- break;
596
- case "orange2":
597
- case "passionorange":
598
- color = "#FF6600";
599
- break;
600
- case "yellow2":
601
- case "madyellow":
602
- color = "#999900";
603
- break;
604
- case "green2":
605
- case "elementalgreen":
606
- color = "#00CC66";
607
- break;
608
- case "cyan2":
609
- color = "#00CCCC";
610
- break;
611
- case "blue2":
612
- case "marineblue":
613
- color = "#3399FF";
614
- break;
615
- case "purple2":
616
- case "nobleviolet":
617
- color = "#6633CC";
618
- break;
619
- case "black2":
620
- color = "#666666";
621
- break;
622
- default:
623
- var match_1 = command.match(/#[0-9a-z]{3,6}/);
624
- if (match_1 && comment.premium) {
625
- color = match_1[0].toUpperCase();
626
- }
627
- break;
628
- }
629
- }
630
- if (font === null) {
631
- switch (command) {
632
- case "gothic":
633
- font = "gothic";
634
- break;
635
- case "mincho":
636
- font = "mincho";
637
- break;
638
- }
639
- }
640
- switch (command) {
641
- case "full":
642
- full = true;
643
- break;
644
- case "ender":
645
- ender = true;
646
- break;
647
- case "_live":
648
- _live = true;
649
- break;
650
- case "invisible":
651
- invisible = true;
652
- break;
653
- }
654
- }
655
- return { loc: loc, size: size, fontSize: fontSize, color: color, font: font, full: full, ender: ender, _live: _live, invisible: invisible, long: long };
656
- };
657
- NiconiComments.prototype.parseCommandAndNicoscript = function (comment) {
658
- comment.content = comment.content.replace("/\t/g", "  ");
659
- var data = this.parseCommand(comment), nicoscript = comment.content.match(/^@(デフォルト|置換|逆|コメント禁止|シーク禁止|ジャンプ)/);
660
- if (nicoscript) {
661
- switch (nicoscript[1]) {
662
- case "デフォルト":
663
- this.nicoScripts["default"].push({
664
- start: comment.vpos,
665
- long: data.long === null ? null : Math.floor(data.long * 100),
666
- color: data.color,
667
- size: data.size,
668
- font: data.font,
669
- loc: data.loc
670
- });
671
- break;
672
- case "逆":
673
- var reverse = comment.content.match(/^@逆 ?(全|コメ|投コメ)?/);
674
- if (!reverse[1]) {
675
- reverse[1] = "全";
676
- }
677
- if (data.long === null) {
678
- data.long = 30;
679
- }
680
- this.nicoScripts.reverse.push({
681
- start: comment.vpos,
682
- end: comment.vpos + (data.long * 100),
683
- target: reverse[1]
684
- });
685
- break;
686
- case "コメント禁止":
687
- if (data.long === null) {
688
- data.long = 30;
689
- }
690
- this.nicoScripts.reverse.push({
691
- start: comment.vpos,
692
- end: comment.vpos + (data.long * 100)
693
- });
694
- break;
695
- case "置換":
696
- var content = comment.content.split(""), quote = "", last_i = "", string = "", result = [];
697
- for (var _i = 0, _a = content.slice(4); _i < _a.length; _i++) {
698
- var i = _a[_i];
699
- if (i.match(/["'「]/) && quote === "") {
700
- quote = i;
701
- }
702
- else if (i.match(/["']/) && quote === i && last_i !== "\\") {
703
- result.push(string.replace("\\n", "\n"));
704
- quote = "";
705
- string = "";
706
- }
707
- else if (i.match(/」/) && quote === "「") {
708
- result.push(string);
709
- quote = "";
710
- string = "";
711
- }
712
- else if (quote === "" && i.match(/[\s ]/)) {
713
- if (string) {
714
- result.push(string);
715
- string = "";
716
- }
717
- }
718
- else {
719
- string += i;
720
- }
721
- last_i = i;
722
- }
723
- result.push(string);
724
- this.nicoScripts.replace.push({
725
- start: comment.vpos,
726
- long: data.long === null ? null : Math.floor(data.long * 100),
727
- keyword: result[0],
728
- replace: result[1] || "",
729
- range: result[2] || "単",
730
- target: result[3] || "コメ",
731
- condition: result[4] || "部分一致",
732
- color: data.color,
733
- size: data.size,
734
- font: data.font,
735
- loc: data.loc
736
- });
737
- break;
738
- }
739
- data.invisible = true;
740
- }
741
- var color = "#FFFFFF", size = "medium", font = "defont", loc = "naka";
742
- for (var i in this.nicoScripts["default"]) {
743
- if (this.nicoScripts["default"][i].long !== null && this.nicoScripts["default"][i].start + this.nicoScripts["default"][i].long < comment.vpos) {
744
- this.nicoScripts["default"] = this.nicoScripts["default"].splice(Number(i), 1);
745
- continue;
746
- }
747
- if (this.nicoScripts["default"][i].loc) {
748
- loc = this.nicoScripts["default"][i].loc;
749
- }
750
- if (this.nicoScripts["default"][i].color) {
751
- color = this.nicoScripts["default"][i].color;
752
- }
753
- if (this.nicoScripts["default"][i].size) {
754
- size = this.nicoScripts["default"][i].size;
755
- }
756
- if (this.nicoScripts["default"][i].font) {
757
- font = this.nicoScripts["default"][i].font;
758
- }
759
- }
760
- for (var i in this.nicoScripts.replace) {
761
- if (this.nicoScripts.replace[i].long !== null && this.nicoScripts.replace[i].start + this.nicoScripts.replace[i].long < comment.vpos) {
762
- this.nicoScripts["default"] = this.nicoScripts["default"].splice(Number(i), 1);
763
- continue;
764
- }
765
- var item = this.nicoScripts.replace[i];
766
- if ((item.target === "コメ" && comment.owner) || (item.target === "投コメ" && !comment.owner) || (item.target === "含まない" && comment.owner))
767
- continue;
768
- if ((item.condition === "完全一致" && comment.content === item.keyword) || (item.condition === "部分一致" && comment.content.indexOf(item.keyword) !== -1)) {
769
- console.log(item, comment);
770
- if (item.range === "単") {
771
- comment.content = comment.content.replace(new RegExp(item.keyword, "g"), item.replace);
772
- }
773
- else {
774
- comment.content = item.replace;
775
- }
776
- console.log(comment);
777
- if (item.loc) {
778
- loc = item.loc;
779
- }
780
- if (item.color) {
781
- color = item.color;
782
- }
783
- if (item.size) {
784
- size = item.size;
785
- }
786
- if (item.font) {
787
- font = item.font;
788
- }
789
- }
790
- }
791
- if (!data.loc) {
792
- data.loc = loc;
793
- }
794
- if (!data.color) {
795
- data.color = color;
796
- }
797
- if (!data.size) {
798
- data.size = size;
799
- data.fontSize = this.fontSize[data.size]["default"];
800
- }
801
- if (!data.font) {
802
- data.font = font;
803
- }
804
- if (data.loc !== "naka") {
805
- if (!data.long) {
806
- data.long = 300;
807
- }
808
- else {
809
- data.long = Math.floor(data.long * 100);
810
- }
811
- }
812
- return __assign(__assign({}, comment), data);
813
- };
814
- NiconiComments.prototype.drawCanvas = function (vpos) {
815
- if (this.lastVpos === vpos)
816
- return;
817
- this.lastVpos = vpos;
818
- this.fpsCount++;
819
- this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
820
- if (this.video) {
821
- var offsetX = void 0, offsetY = void 0, scale = void 0, height = this.canvas.height / this.video.videoHeight, width = this.canvas.width / this.video.videoWidth;
822
- if (height > width) {
823
- scale = width;
824
- }
825
- else {
826
- scale = height;
827
- }
828
- offsetX = (this.canvas.width - this.video.videoWidth * scale) * 0.5;
829
- offsetY = (this.canvas.height - this.video.videoHeight * scale) * 0.5;
830
- this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
831
- }
832
- if (this.timeline[vpos]) {
833
- for (var index in this.timeline[vpos]) {
834
- var comment = this.data[this.timeline[vpos][index]];
835
- if (comment.invisible) {
836
- continue;
837
- }
838
- if (!comment.image) {
839
- this.getTextImage(this.timeline[vpos][index]);
840
- }
841
- this.drawText(comment, vpos);
842
- }
843
- }
844
- if (this.showFPS) {
845
- this.context.font = parseFont("defont", 60, this.useLegacy);
846
- this.context.fillStyle = "#00FF00";
847
- this.context.strokeText("FPS:" + this.fps, 100, 100);
848
- this.context.fillText("FPS:" + this.fps, 100, 100);
849
- }
850
- if (this.showCommentCount) {
851
- this.context.font = parseFont("defont", 60, this.useLegacy);
852
- this.context.fillStyle = "#00FF00";
853
- if (this.timeline[vpos]) {
854
- this.context.strokeText("Count:" + this.timeline[vpos].length, 100, 200);
855
- this.context.fillText("Count:" + this.timeline[vpos].length, 100, 200);
856
- }
857
- else {
858
- this.context.strokeText("Count:0", 100, 200);
859
- this.context.fillText("Count:0", 100, 200);
860
- }
861
- }
862
- };
863
- NiconiComments.prototype.clear = function () {
864
- this.context.clearRect(0, 0, 1920, 1080);
865
- };
866
- return NiconiComments;
867
- }());
868
- var groupBy = function (array, key, key2) {
869
- var data = {};
870
- for (var i in array) {
871
- if (!data[array[i][key]]) {
872
- data[array[i][key]] = {};
873
- }
874
- if (!data[array[i][key]][array[i][key2]]) {
875
- data[array[i][key]][array[i][key2]] = [];
876
- }
877
- array[i].index = i;
878
- data[array[i][key]][array[i][key2]].push(array[i]);
879
- }
880
- return data;
881
- };
882
- var parseFont = function (font, size, useLegacy) {
883
- switch (font) {
884
- case "gothic":
885
- return "normal 400 ".concat(size, "px \"\u6E38\u30B4\u30B7\u30C3\u30AF\u4F53\", \"\u6E38\u30B4\u30B7\u30C3\u30AF\", \"Yu Gothic\", YuGothic, yugothic, YuGo-Medium");
886
- case "mincho":
887
- return "normal 400 ".concat(size, "px \"\u6E38\u660E\u671D\u4F53\", \"\u6E38\u660E\u671D\", \"Yu Mincho\", YuMincho, yumincho, YuMin-Medium");
888
- default:
889
- if (useLegacy) {
890
- return "normal 600 ".concat(size, "px Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
891
- }
892
- else {
893
- return "normal 600 ".concat(size, "px sans-serif, Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
894
- }
895
- }
896
- };
897
- var arrayPush = function (array, key, push) {
898
- if (!array) {
899
- array = {};
900
- }
901
- if (!array[key]) {
902
- array[key] = [];
903
- }
904
- array[key].push(push);
905
- };
906
- var hex2rgb = function (hex) {
907
- if (hex.slice(0, 1) === "#")
908
- hex = hex.slice(1);
909
- if (hex.length === 3)
910
- hex = hex.slice(0, 1) + hex.slice(0, 1) + hex.slice(1, 2) + hex.slice(1, 2) + hex.slice(2, 3) + hex.slice(2, 3);
911
- return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map(function (str) {
912
- return parseInt(str, 16);
913
- });
774
+ var parseFont = function (font, size, useLegacy) {
775
+ switch (font) {
776
+ case "gothic":
777
+ return "normal 400 ".concat(size, "px \"\u6E38\u30B4\u30B7\u30C3\u30AF\u4F53\", \"\u6E38\u30B4\u30B7\u30C3\u30AF\", \"Yu Gothic\", YuGothic, yugothic, YuGo-Medium");
778
+ case "mincho":
779
+ return "normal 400 ".concat(size, "px \"\u6E38\u660E\u671D\u4F53\", \"\u6E38\u660E\u671D\", \"Yu Mincho\", YuMincho, yumincho, YuMin-Medium");
780
+ default:
781
+ if (useLegacy) {
782
+ return "normal 600 ".concat(size, "px Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
783
+ }
784
+ else {
785
+ return "normal 600 ".concat(size, "px sans-serif, Arial, \"\uFF2D\uFF33 \uFF30\u30B4\u30B7\u30C3\u30AF\", \"MS PGothic\", MSPGothic, MS-PGothic");
786
+ }
787
+ }
788
+ };
789
+ var arrayPush = function (array, key, push) {
790
+ if (!array) {
791
+ array = {};
792
+ }
793
+ if (!array[key]) {
794
+ array[key] = [];
795
+ }
796
+ array[key].push(push);
797
+ };
798
+ var hex2rgb = function (hex) {
799
+ if (hex.slice(0, 1) === "#")
800
+ hex = hex.slice(1);
801
+ if (hex.length === 3)
802
+ hex = hex.slice(0, 1) + hex.slice(0, 1) + hex.slice(1, 2) + hex.slice(1, 2) + hex.slice(2, 3) + hex.slice(2, 3);
803
+ return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map(function (str) {
804
+ return parseInt(str, 16);
805
+ });
914
806
  };
915
807
 
916
808
  return NiconiComments;