@xpadev-net/niconicomments 0.2.8 → 0.2.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,10 @@
1
1
  # [niconicomments](https://xpadev.net/niconicomments/)
2
- [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/xpadev-net/niconicomments/blob/master/LICENSE)
3
- ニコニコ動画の公式プレイヤーに多少の互換性を持つコメント描画ライブラリです
4
- This is a comment drawing library that is somewhat compatible with the official Nico Nico Douga player.
2
+ [![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/xpadev-net/niconicomments/blob/master/LICENSE)
3
+ [![Total alerts](https://img.shields.io/lgtm/alerts/g/xpadev-net/niconicomments.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/xpadev-net/niconicomments/alerts/)
4
+ [![Language grade: JavaScript](https://img.shields.io/lgtm/grade/javascript/g/xpadev-net/niconicomments.svg?logo=lgtm&logoWidth=18)](https://lgtm.com/projects/g/xpadev-net/niconicomments/context:javascript)
5
+
6
+ ニコニコ動画の公式プレイヤー互換の高パフォーマンスなコメント描画ライブラリ
7
+ High peformance High compatibility comment drawing library
5
8
  Reference: https://xpadev-net.github.io/niconicomments/
6
9
  Github: https://github.com/xpadev-net/niconicomments
7
10
  npm: https://www.npmjs.com/package/@xpadev-net/niconicomments
@@ -27,6 +30,5 @@ setInterval(() => niconiComments.drawCanvas(Math.floor(video.currentTime * 100))
27
30
  ```
28
31
 
29
32
  ## Sample
30
- [レッツゴー!陰陽師](https://xpadev.net/niconicomments/sample.html)
31
- [レッツゴー!陰陽師(CodePen)](https://codepen.io/xpadev-net/pen/mdBdQmX)
32
- [ニコニコ動画流星群](https://xpadev.net/niconicomments/ryuuseigun.html)
33
+ [サンプル](https://xpadev.net/niconicomments/sample.html)
34
+ [CodePen](https://codepen.io/xpadev-net/pen/mdBdQmX)
package/dist/bundle.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- niconicomments.js v0.2.8
2
+ niconicomments.js v0.2.11
3
3
  (c) 2021 xpadev-net https://xpadev.net
4
4
  Released under the MIT License.
5
5
  */
@@ -9,34 +9,23 @@
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) {
12
+ var _assign = function __assign() {
13
+ _assign = Object.assign || function __assign(t) {
28
14
  for (var s, i = 1, n = arguments.length; i < n; i++) {
29
15
  s = arguments[i];
30
16
 
31
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
17
+ for (var p in s) {
18
+ if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
19
+ }
32
20
  }
33
21
 
34
22
  return t;
35
23
  };
36
24
 
37
- return __assign.apply(this, arguments);
25
+ return _assign.apply(this, arguments);
38
26
  };
39
27
 
28
+ var isDebug = false;
40
29
  var NiconiComments = (function () {
41
30
  function NiconiComments(canvas, data, options) {
42
31
  if (options === void 0) { options = {
@@ -46,11 +35,17 @@
46
35
  showCollision: false,
47
36
  showFPS: false,
48
37
  showCommentCount: false,
49
- drawAllImageOnLoad: false
38
+ drawAllImageOnLoad: false,
39
+ debug: false
50
40
  }; }
51
41
  var _this = this;
42
+ isDebug = options.debug;
43
+ var constructorStart = performance.now();
52
44
  this.canvas = canvas;
53
- this.context = canvas.getContext("2d");
45
+ var context = canvas.getContext("2d");
46
+ if (!context)
47
+ throw new Error("Fail to get CanvasRenderingContext2D");
48
+ this.context = context;
54
49
  this.context.strokeStyle = "rgba(0,0,0,0.7)";
55
50
  this.context.textAlign = "start";
56
51
  this.context.textBaseline = "alphabetic";
@@ -68,17 +63,31 @@
68
63
  },
69
64
  "big": {
70
65
  "default": 111,
71
- "resized": 62
66
+ "resized": 61
67
+ }
68
+ };
69
+ this.lineHeight = {
70
+ "small": {
71
+ "default": 1,
72
+ "resized": 1
73
+ },
74
+ "medium": {
75
+ "default": 1,
76
+ "resized": 1
77
+ },
78
+ "big": {
79
+ "default": 1,
80
+ "resized": 1.01
72
81
  }
73
82
  };
74
83
  this.doubleResizeMaxWidth = {
75
84
  full: {
76
85
  legacy: 3020,
77
- "default": 3220
86
+ default: 3220
78
87
  },
79
88
  normal: {
80
89
  legacy: 2540,
81
- "default": 2740
90
+ default: 2740
82
91
  }
83
92
  };
84
93
  var parsedData = options.formatted ? data : this.parseData(data);
@@ -87,27 +96,33 @@
87
96
  this.showFPS = options.showFPS;
88
97
  this.showCommentCount = options.showCommentCount;
89
98
  this.timeline = {};
90
- this.nicoScripts = { reverse: [], "default": [], replace: [], ban: [] };
99
+ this.nicoScripts = { reverse: [], default: [], replace: [], ban: [] };
91
100
  this.collision_right = {};
92
101
  this.collision_left = {};
93
102
  this.collision_ue = {};
94
103
  this.collision_shita = {};
104
+ this.data = [];
95
105
  this.lastVpos = -1;
96
106
  this.useLegacy = options.useLegacy;
97
107
  this.preRendering(parsedData, options.drawAllImageOnLoad);
98
108
  this.fpsCount = 0;
99
109
  this.fps = 0;
100
- this.fpsClock = window.setInterval(function () {
110
+ window.setInterval(function () {
101
111
  _this.fps = _this.fpsCount * 2;
102
112
  _this.fpsCount = 0;
103
113
  }, 500);
114
+ logger("constructor complete: ".concat(performance.now() - constructorStart, "ms"));
104
115
  }
105
116
  NiconiComments.prototype.parseData = function (data) {
117
+ var parseDataStart = performance.now();
106
118
  var data_ = [];
107
119
  for (var i = 0; i < data.length; i++) {
108
120
  for (var key in data[i]) {
109
- var value = data[i][key];
110
- if (key === "chat" && value["deleted"] !== 1) {
121
+ var val = data[i];
122
+ if (!val)
123
+ continue;
124
+ var value = val[key];
125
+ if (isApiChat(value) && value["deleted"] !== 1) {
111
126
  var tmpParam = {
112
127
  "id": value["no"],
113
128
  "vpos": value["vpos"],
@@ -143,9 +158,11 @@
143
158
  return 1;
144
159
  return 0;
145
160
  });
161
+ logger("parseData complete: ".concat(performance.now() - parseDataStart, "ms"));
146
162
  return data_;
147
163
  };
148
164
  NiconiComments.prototype.preRendering = function (rawData, drawAll) {
165
+ var preRenderingStart = performance.now();
149
166
  var parsedData = this.getCommentPos(this.getCommentSize(this.getFont(rawData)));
150
167
  this.data = this.sortComment(parsedData);
151
168
  if (drawAll) {
@@ -153,16 +170,23 @@
153
170
  this.getTextImage(Number(i));
154
171
  }
155
172
  }
173
+ logger("preRendering complete: ".concat(performance.now() - preRenderingStart, "ms"));
156
174
  };
157
175
  NiconiComments.prototype.getFont = function (parsedData) {
176
+ var getFontStart = performance.now();
158
177
  var result = [];
159
178
  for (var i in parsedData) {
160
- parsedData[i].content = parsedData[i].content.replace(/\t/g, "\u2003\u2003");
161
- result[i] = this.parseCommandAndNicoscript(parsedData[i]);
179
+ var value = parsedData[i];
180
+ if (!value)
181
+ continue;
182
+ value.content = value.content.replace(/\t/g, "\u2003\u2003");
183
+ result[i] = this.parseCommandAndNicoscript(value);
162
184
  }
185
+ logger("getFont complete: ".concat(performance.now() - getFontStart, "ms"));
163
186
  return result;
164
187
  };
165
188
  NiconiComments.prototype.getCommentSize = function (parsedData) {
189
+ var getCommentSizeStart = performance.now();
166
190
  var tmpData = groupBy(parsedData, "font", "fontSize");
167
191
  var result = [];
168
192
  for (var i in tmpData) {
@@ -174,25 +198,29 @@
174
198
  continue;
175
199
  }
176
200
  var measure = this.measureText(comment);
177
- result[comment.index] = parsedData[comment.index];
178
- result[comment.index].height = measure.height;
179
- result[comment.index].width = measure.width;
180
- result[comment.index].width_max = measure.width_max;
181
- result[comment.index].width_min = measure.width_min;
201
+ var size = parsedData[comment.index];
202
+ size.height = measure.height;
203
+ size.width = measure.width;
204
+ size.width_max = measure.width_max;
205
+ size.width_min = measure.width_min;
206
+ size.lineHeight = measure.lineHeight;
182
207
  if (measure.resized) {
183
- result[comment.index].fontSize = measure.fontSize;
208
+ size.fontSize = measure.fontSize;
184
209
  this.context.font = parseFont(i, j, this.useLegacy);
185
210
  }
211
+ result[comment.index] = size;
186
212
  }
187
213
  }
188
214
  }
215
+ logger("getCommentSize complete: ".concat(performance.now() - getCommentSizeStart, "ms"));
189
216
  return result;
190
217
  };
191
218
  NiconiComments.prototype.getCommentPos = function (parsedData) {
219
+ var getCommentPosStart = performance.now();
192
220
  var data = parsedData;
193
221
  for (var i in data) {
194
222
  var comment = data[i];
195
- if (comment.invisible) {
223
+ if (!comment || comment.invisible) {
196
224
  continue;
197
225
  }
198
226
  for (var j = 0; j < 500; j++) {
@@ -250,7 +278,7 @@
250
278
  break;
251
279
  }
252
280
  }
253
- if (left_pos <= 40 && is_break === false) {
281
+ if (left_pos <= 40 && !is_break) {
254
282
  for (var k in this.collision_left[vpos]) {
255
283
  var l = this.collision_left[vpos][k];
256
284
  if ((posY < data[l].posY + data[l].height && posY + comment.height > data[l].posY) && data[l].owner === comment.owner) {
@@ -278,6 +306,9 @@
278
306
  break;
279
307
  }
280
308
  }
309
+ if (is_break) {
310
+ break;
311
+ }
281
312
  }
282
313
  }
283
314
  for (var j = 0; j < 500; j++) {
@@ -343,43 +374,51 @@
343
374
  parsedData[i].posY = posY;
344
375
  }
345
376
  }
377
+ logger("getCommentPos complete: ".concat(performance.now() - getCommentPosStart, "ms"));
346
378
  return parsedData;
347
379
  };
348
380
  NiconiComments.prototype.sortComment = function (parsedData) {
381
+ var sortCommentStart = performance.now();
349
382
  for (var vpos in this.timeline) {
350
- this.timeline[vpos].sort(function (a, b) {
351
- var A = parsedData[a];
352
- var B = parsedData[b];
353
- if (!A.owner && B.owner) {
354
- return -1;
355
- }
356
- else if (A.owner && !B.owner) {
357
- return 1;
383
+ if (!this.timeline[vpos])
384
+ continue;
385
+ var owner = [], user = [];
386
+ for (var _i = 0, _a = this.timeline[vpos]; _i < _a.length; _i++) {
387
+ var i = _a[_i];
388
+ if (parsedData[i].owner) {
389
+ owner.push(i);
358
390
  }
359
391
  else {
360
- return 0;
392
+ user.push(i);
361
393
  }
362
- });
394
+ }
395
+ this.timeline[vpos] = owner.concat(user);
363
396
  }
397
+ logger("parseData complete: ".concat(performance.now() - sortCommentStart, "ms"));
364
398
  return parsedData;
365
399
  };
366
400
  NiconiComments.prototype.measureText = function (comment) {
367
401
  var width, width_max, width_min, height, width_arr = [], lines = comment.content.split("\n");
402
+ if (!comment.lineHeight)
403
+ comment.lineHeight = this.lineHeight[comment.size].default;
368
404
  if (!comment.resized && !comment.ender) {
369
405
  if (comment.size === "big" && lines.length > 2) {
370
406
  comment.fontSize = this.fontSize.big.resized;
407
+ comment.lineHeight = this.lineHeight.big.resized;
371
408
  comment.resized = true;
372
409
  comment.tateresized = true;
373
410
  this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
374
411
  }
375
412
  else if (comment.size === "medium" && lines.length > 4) {
376
413
  comment.fontSize = this.fontSize.medium.resized;
414
+ comment.lineHeight = this.lineHeight.medium.resized;
377
415
  comment.resized = true;
378
416
  comment.tateresized = true;
379
417
  this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
380
418
  }
381
419
  else if (comment.size === "small" && lines.length > 6) {
382
420
  comment.fontSize = this.fontSize.small.resized;
421
+ comment.lineHeight = this.lineHeight.small.resized;
383
422
  comment.resized = true;
384
423
  comment.tateresized = true;
385
424
  this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
@@ -392,7 +431,7 @@
392
431
  width = width_arr.reduce(function (p, c) { return p + c; }, 0) / width_arr.length;
393
432
  width_max = Math.max.apply(Math, width_arr);
394
433
  width_min = Math.min.apply(Math, width_arr);
395
- height = (comment.fontSize * (1 + this.commentYPaddingTop) * lines.length) + (this.commentYMarginBottom * comment.fontSize);
434
+ height = (comment.fontSize * comment.lineHeight * (1 + this.commentYPaddingTop) * lines.length) + (this.commentYMarginBottom * comment.fontSize);
396
435
  if (comment.loc !== "naka" && !comment.tateresized) {
397
436
  if (comment.full && width_max > 1920) {
398
437
  comment.fontSize -= 2;
@@ -409,8 +448,8 @@
409
448
  return this.measureText(comment);
410
449
  }
411
450
  }
412
- else if (comment.loc !== "naka" && comment.tateresized && (comment.full && width_max > 1920 || !comment.full && width_max > 1440) && !comment.yokoResized) {
413
- comment.fontSize = this.fontSize[comment.size]["default"];
451
+ else if (comment.loc !== "naka" && comment.tateresized && (comment.full && width_max > 2120 || !comment.full && width_max > 1440) && !comment.yokoResized) {
452
+ comment.fontSize = this.fontSize[comment.size].default;
414
453
  comment.resized = true;
415
454
  comment.yokoResized = true;
416
455
  this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
@@ -423,7 +462,7 @@
423
462
  return this.measureText(comment);
424
463
  }
425
464
  else if (!comment.full && width_max > this.doubleResizeMaxWidth.normal[this.useLegacy ? "legacy" : "default"]) {
426
- comment.fontSize -= 1.;
465
+ comment.fontSize -= 1;
427
466
  this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
428
467
  return this.measureText(comment);
429
468
  }
@@ -434,7 +473,8 @@
434
473
  "width_min": width_min,
435
474
  "height": height,
436
475
  "resized": comment.resized,
437
- "fontSize": comment.fontSize
476
+ "fontSize": comment.fontSize,
477
+ "lineHeight": comment.lineHeight
438
478
  };
439
479
  };
440
480
  NiconiComments.prototype.drawText = function (comment, vpos) {
@@ -466,17 +506,21 @@
466
506
  else if (comment.loc === "shita") {
467
507
  posY = 1080 - comment.posY - comment.height;
468
508
  }
469
- this.context.drawImage(comment.image, posX, posY);
509
+ if (comment.image && comment.image !== true) {
510
+ this.context.drawImage(comment.image, posX, posY);
511
+ }
470
512
  };
471
513
  NiconiComments.prototype.getTextImage = function (i) {
514
+ var _this = this;
472
515
  var value = this.data[i];
473
- if (value.invisible) {
516
+ if (!value || value.invisible || value.content.match(/^\s*$/))
474
517
  return;
475
- }
476
518
  var image = document.createElement("canvas");
477
519
  image.width = value.width_max;
478
520
  image.height = value.height;
479
521
  var context = image.getContext("2d");
522
+ if (!context)
523
+ throw new Error("Fail to get CanvasRenderingContext2D");
480
524
  context.strokeStyle = "rgba(0,0,0,0.7)";
481
525
  context.textAlign = "start";
482
526
  context.textBaseline = "alphabetic";
@@ -505,12 +549,12 @@
505
549
  var lines = value.content.split("\n");
506
550
  for (var i_1 in lines) {
507
551
  var line = lines[i_1], posY = void 0;
508
- posY = (Number(i_1) + 1) * (value.fontSize) * (1 + this.commentYPaddingTop);
552
+ posY = (Number(i_1) + 1) * (value.fontSize * value.lineHeight) * (1 + this.commentYPaddingTop);
509
553
  context.strokeText(line, 0, posY);
510
554
  context.fillText(line, 0, posY);
511
555
  if (this.showCollision) {
512
556
  context.strokeStyle = "rgba(255,255,0,0.5)";
513
- context.strokeRect(0, posY, value.width_max, value.fontSize * -1);
557
+ context.strokeRect(0, posY, value.width_max, value.fontSize * value.lineHeight * -1);
514
558
  if (value.color === "#000000") {
515
559
  context.strokeStyle = "rgba(255,255,255,0.7)";
516
560
  }
@@ -520,6 +564,10 @@
520
564
  }
521
565
  }
522
566
  this.data[i].image = image;
567
+ setTimeout(function () {
568
+ if (_this.data[i].image)
569
+ delete _this.data[i].image;
570
+ }, 5000);
523
571
  };
524
572
  NiconiComments.prototype.parseCommand = function (comment) {
525
573
  var metadata = comment.mail, loc = null, size = null, fontSize = null, color = null, font = null, full = false, ender = false, _live = false, invisible = false, long = null;
@@ -543,11 +591,11 @@
543
591
  switch (command) {
544
592
  case "big":
545
593
  size = "big";
546
- fontSize = this.fontSize.big["default"];
594
+ fontSize = this.fontSize.big.default;
547
595
  break;
548
596
  case "small":
549
597
  size = "small";
550
- fontSize = this.fontSize.small["default"];
598
+ fontSize = this.fontSize.small.default;
551
599
  break;
552
600
  }
553
601
  }
@@ -660,7 +708,7 @@
660
708
  if (nicoscript) {
661
709
  switch (nicoscript[1]) {
662
710
  case "デフォルト":
663
- this.nicoScripts["default"].push({
711
+ this.nicoScripts.default.push({
664
712
  start: comment.vpos,
665
713
  long: data.long === null ? null : Math.floor(data.long * 100),
666
714
  color: data.color,
@@ -671,6 +719,8 @@
671
719
  break;
672
720
  case "逆":
673
721
  var reverse = comment.content.match(/^@逆 ?(全|コメ|投コメ)?/);
722
+ if (!reverse)
723
+ reverse = [];
674
724
  if (!reverse[1]) {
675
725
  reverse[1] = "全";
676
726
  }
@@ -689,7 +739,7 @@
689
739
  }
690
740
  this.nicoScripts.reverse.push({
691
741
  start: comment.vpos,
692
- end: comment.vpos + (data.long * 100)
742
+ end: comment.vpos + (data.long * 100),
693
743
  });
694
744
  break;
695
745
  case "置換":
@@ -739,27 +789,27 @@
739
789
  data.invisible = true;
740
790
  }
741
791
  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);
792
+ for (var i in this.nicoScripts.default) {
793
+ if (this.nicoScripts.default[i].long !== null && this.nicoScripts.default[i].start + this.nicoScripts.default[i].long < comment.vpos) {
794
+ this.nicoScripts.default = this.nicoScripts.default.splice(Number(i), 1);
745
795
  continue;
746
796
  }
747
- if (this.nicoScripts["default"][i].loc) {
748
- loc = this.nicoScripts["default"][i].loc;
797
+ if (this.nicoScripts.default[i].loc) {
798
+ loc = this.nicoScripts.default[i].loc;
749
799
  }
750
- if (this.nicoScripts["default"][i].color) {
751
- color = this.nicoScripts["default"][i].color;
800
+ if (this.nicoScripts.default[i].color) {
801
+ color = this.nicoScripts.default[i].color;
752
802
  }
753
- if (this.nicoScripts["default"][i].size) {
754
- size = this.nicoScripts["default"][i].size;
803
+ if (this.nicoScripts.default[i].size) {
804
+ size = this.nicoScripts.default[i].size;
755
805
  }
756
- if (this.nicoScripts["default"][i].font) {
757
- font = this.nicoScripts["default"][i].font;
806
+ if (this.nicoScripts.default[i].font) {
807
+ font = this.nicoScripts.default[i].font;
758
808
  }
759
809
  }
760
810
  for (var i in this.nicoScripts.replace) {
761
811
  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);
812
+ this.nicoScripts.default = this.nicoScripts.default.splice(Number(i), 1);
763
813
  continue;
764
814
  }
765
815
  var item = this.nicoScripts.replace[i];
@@ -794,7 +844,7 @@
794
844
  }
795
845
  if (!data.size) {
796
846
  data.size = size;
797
- data.fontSize = this.fontSize[data.size]["default"];
847
+ data.fontSize = this.fontSize[data.size].default;
798
848
  }
799
849
  if (!data.font) {
800
850
  data.font = font;
@@ -807,9 +857,10 @@
807
857
  data.long = Math.floor(data.long * 100);
808
858
  }
809
859
  }
810
- return __assign(__assign({}, comment), data);
860
+ return _assign(_assign({}, comment), data);
811
861
  };
812
862
  NiconiComments.prototype.drawCanvas = function (vpos) {
863
+ var drawCanvasStart = performance.now();
813
864
  if (this.lastVpos === vpos)
814
865
  return;
815
866
  this.lastVpos = vpos;
@@ -828,15 +879,21 @@
828
879
  this.context.drawImage(this.video, offsetX, offsetY, this.video.videoWidth * scale, this.video.videoHeight * scale);
829
880
  }
830
881
  if (this.timeline[vpos]) {
831
- for (var index in this.timeline[vpos]) {
832
- var comment = this.data[this.timeline[vpos][index]];
833
- if (comment.invisible) {
882
+ for (var i in this.timeline[vpos]) {
883
+ var index = this.timeline[vpos][Number(i)];
884
+ var comment = this.data[index];
885
+ if (!comment || comment.invisible || comment.content.match(/^[\u200B-\u200D\uFEFF\u3164\s]*$/)) {
834
886
  continue;
835
887
  }
836
- if (!comment.image) {
837
- this.getTextImage(this.timeline[vpos][index]);
888
+ if (comment.image === undefined) {
889
+ this.getTextImage(index);
890
+ }
891
+ try {
892
+ this.drawText(comment, vpos);
893
+ }
894
+ catch (e) {
895
+ comment.image = false;
838
896
  }
839
- this.drawText(comment, vpos);
840
897
  }
841
898
  }
842
899
  if (this.showFPS) {
@@ -857,6 +914,7 @@
857
914
  this.context.fillText("Count:0", 100, 200);
858
915
  }
859
916
  }
917
+ logger("drawCanvas complete: ".concat(performance.now() - drawCanvasStart, "ms"));
860
918
  };
861
919
  NiconiComments.prototype.clear = function () {
862
920
  this.context.clearRect(0, 0, 1920, 1080);
@@ -918,6 +976,13 @@
918
976
  }
919
977
  return string;
920
978
  };
979
+ var isApiChat = function (item) {
980
+ return !!item.chat;
981
+ };
982
+ var logger = function (msg) {
983
+ if (isDebug)
984
+ console.debug(msg);
985
+ };
921
986
 
922
987
  return NiconiComments;
923
988
 
@@ -0,0 +1,150 @@
1
+ declare type InitOptions = {
2
+ useLegacy: boolean;
3
+ formatted: boolean;
4
+ video: HTMLVideoElement | null;
5
+ showCollision: boolean;
6
+ showFPS: boolean;
7
+ showCommentCount: boolean;
8
+ drawAllImageOnLoad: boolean;
9
+ debug: boolean;
10
+ };
11
+ declare type rawApiResponse = {
12
+ [key: string]: apiPing | apiThread | apiLeaf | apiGlobalNumRes | apiChat;
13
+ };
14
+ declare type apiPing = {
15
+ "content": string;
16
+ };
17
+ declare type apiThread = {
18
+ "resultcode": number;
19
+ "thread": string;
20
+ "server_time": number;
21
+ "ticket": string;
22
+ "revision": number;
23
+ };
24
+ declare type apiLeaf = {
25
+ "thread": string;
26
+ "count": number;
27
+ };
28
+ declare type apiGlobalNumRes = {
29
+ "thread": string;
30
+ "num_res": number;
31
+ };
32
+ declare type apiChat = {
33
+ "thread": string;
34
+ "no": number;
35
+ "vpos": number;
36
+ "date": number;
37
+ "date_usec": number;
38
+ "nicoru": number;
39
+ "premium": number;
40
+ "anonymity": number;
41
+ "user_id": string;
42
+ "mail": string;
43
+ "content": string;
44
+ "deleted": number;
45
+ };
46
+ declare type formattedComment = {
47
+ "id": number;
48
+ "vpos": number;
49
+ "content": string;
50
+ "date": number;
51
+ "date_usec": number;
52
+ "owner": boolean;
53
+ "premium": boolean;
54
+ "mail": string[];
55
+ };
56
+ declare type formattedCommentWithFont = formattedComment & {
57
+ "loc": string;
58
+ "size": string;
59
+ "fontSize": number;
60
+ "font": string;
61
+ "color": string;
62
+ "full": boolean;
63
+ "ender": boolean;
64
+ "_live": boolean;
65
+ "long": number;
66
+ "invisible": boolean;
67
+ };
68
+ declare type formattedCommentWithSize = formattedCommentWithFont & {
69
+ "height": number;
70
+ "width": number;
71
+ "width_max": number;
72
+ "width_min": number;
73
+ "lineHeight": number;
74
+ };
75
+ declare type parsedComment = formattedCommentWithSize & {
76
+ posY: number;
77
+ image?: HTMLCanvasElement | boolean;
78
+ };
79
+ declare type measureTextResult = {
80
+ "width": number;
81
+ "width_max": number;
82
+ "width_min": number;
83
+ "height": number;
84
+ "resized": boolean;
85
+ "fontSize": number;
86
+ "lineHeight": number;
87
+ };
88
+ declare class NiconiComments {
89
+ private canvas;
90
+ private context;
91
+ private readonly commentYPaddingTop;
92
+ private readonly commentYMarginBottom;
93
+ private readonly fontSize;
94
+ private readonly lineHeight;
95
+ private readonly doubleResizeMaxWidth;
96
+ private video;
97
+ private showCollision;
98
+ showFPS: boolean;
99
+ showCommentCount: boolean;
100
+ private data;
101
+ private timeline;
102
+ private nicoScripts;
103
+ private collision_right;
104
+ private collision_left;
105
+ private collision_ue;
106
+ private collision_shita;
107
+ private lastVpos;
108
+ private useLegacy;
109
+ private fpsCount;
110
+ private fps;
111
+ constructor(canvas: HTMLCanvasElement, data: (rawApiResponse | formattedComment)[], options?: InitOptions);
112
+ parseData(data: rawApiResponse[]): formattedComment[];
113
+ preRendering(rawData: formattedComment[], drawAll: boolean): void;
114
+ getFont(parsedData: formattedComment[]): formattedCommentWithFont[];
115
+ getCommentSize(parsedData: formattedCommentWithFont[]): formattedCommentWithSize[];
116
+ getCommentPos(parsedData: parsedComment[]): parsedComment[];
117
+ sortComment(parsedData: parsedComment[]): parsedComment[];
118
+ measureText(comment: {
119
+ content: string;
120
+ resized: boolean;
121
+ ender: any;
122
+ size: string;
123
+ fontSize: number;
124
+ tateresized: boolean;
125
+ font: any;
126
+ loc: string;
127
+ full: any;
128
+ yokoResized: boolean;
129
+ lineHeight: number | undefined;
130
+ }): measureTextResult;
131
+ drawText(comment: parsedComment, vpos: number): void;
132
+ getTextImage(i: number): void;
133
+ parseCommand(comment: any): {
134
+ loc: string | null;
135
+ size: string | null;
136
+ fontSize: number | null;
137
+ color: any;
138
+ font: string | null;
139
+ full: boolean;
140
+ ender: boolean;
141
+ _live: boolean;
142
+ invisible: boolean;
143
+ long: any;
144
+ };
145
+ parseCommandAndNicoscript(comment: formattedComment): formattedCommentWithFont;
146
+ drawCanvas(vpos: number): void;
147
+ clear(): void;
148
+ }
149
+ export default NiconiComments;
150
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,14 +1,16 @@
1
1
  {
2
2
  "name": "@xpadev-net/niconicomments",
3
- "version": "0.2.8",
3
+ "version": "0.2.11",
4
4
  "description": "NiconiComments is a comment drawing library that is somewhat compatible with the official Nico Nico Douga player.",
5
5
  "main": "dist/bundle.js",
6
+ "types": "dist/dts/main.d.ts",
6
7
  "scripts": {
7
8
  "test": "echo \"Error: no test specified\" && exit 1",
8
9
  "build": "rollup -c rollup.config.js",
9
10
  "watch": "rollup -c rollup.config.js -w",
10
11
  "typedoc": "typedoc --options tsdoc.json --out ./docs/type/ ./src/main.ts",
11
- "prepublishOnly": "npm run build"
12
+ "tsc": "tsc --emitDeclarationOnly",
13
+ "prepublishOnly": "npm run tsc&&npm run build"
12
14
  },
13
15
  "repository": {
14
16
  "type": "git",
@@ -22,16 +24,19 @@
22
24
  "url": "https://github.com/xpadev-net/niconicomments/issues"
23
25
  },
24
26
  "files": [
25
- "dist/bundle.js"
27
+ "dist/bundle.js",
28
+ "dist/dts/main.d.ts",
29
+ "dist/dts/main.d.ts.map"
26
30
  ],
27
31
  "homepage": "https://xpadev.net/niconicomments/docs/",
28
32
  "license": "MIT",
29
33
  "devDependencies": {
34
+ "@babel/preset-env": "^7.18.2",
30
35
  "@rollup/plugin-babel": "^5.3.0",
31
- "@rollup/plugin-typescript": "^8.3.1",
32
- "rollup": "~2.66",
33
- "typedoc": "^0.22.13",
36
+ "@rollup/plugin-typescript": "^8.3.2",
37
+ "rollup": "^2.75.6",
38
+ "typedoc": "^0.22.17",
34
39
  "typedoc-plugin-missing-exports": "^0.22.6",
35
- "typescript": "^4.6.3"
40
+ "typescript": "^4.7.3"
36
41
  }
37
42
  }