@xpadev-net/niconicomments 0.0.8 → 0.1.0
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/LICENSE +3 -7
- package/README.md +6 -2
- package/dist/bundle.js +126 -48
- package/package.json +6 -5
package/LICENSE
CHANGED
|
@@ -1,11 +1,7 @@
|
|
|
1
|
-
The MIT License
|
|
2
|
-
===============
|
|
3
|
-
|
|
4
1
|
Copyright (c) 2021 xpadev https://xpadev.net
|
|
5
2
|
|
|
6
|
-
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
7
4
|
|
|
8
|
-
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
作者または著作権者は、契約行為、不法行為、またはそれ以外であろうと、ソフトウェアに起因または関連し、あるいはソフトウェアの使用またはその他の扱いによって生じる一切の請求、損害、その他の義務について何らの責任も負わないものとします。
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# [niconicomments](https://xpadev.net/niconicomments/)
|
|
2
|
-
[](https://github.com/
|
|
2
|
+
[](https://github.com/xpadev-net/niconicomments/blob/master/LICENSE)
|
|
3
3
|
ニコニコ動画の公式プレイヤーに多少の互換性を持つコメント描画ライブラリです
|
|
4
4
|
This is a comment drawing library that is somewhat compatible with the official Nico Nico Douga player.
|
|
5
5
|
Reference: https://xpadev.net/niconicomments/docs/
|
|
@@ -7,7 +7,11 @@ Github: https://github.com/xpadev-net/niconicomments
|
|
|
7
7
|
|
|
8
8
|
## Installation
|
|
9
9
|
```html
|
|
10
|
-
<script src="https://cdn.jsdelivr.net/npm/niconicomments@latest/
|
|
10
|
+
<script src="https://cdn.jsdelivr.net/npm/@xpadev-net/niconicomments@latest/dist/bundle.min.js"></script>
|
|
11
|
+
```
|
|
12
|
+
or
|
|
13
|
+
```
|
|
14
|
+
npm i @xpadev-net/niconicomments
|
|
11
15
|
```
|
|
12
16
|
|
|
13
17
|
## Examples
|
package/dist/bundle.js
CHANGED
|
@@ -20,7 +20,21 @@
|
|
|
20
20
|
this.context.textBaseline = "top";
|
|
21
21
|
this.context.lineWidth = "6";
|
|
22
22
|
this.commentYOffset = 0.25;
|
|
23
|
-
this.commentYMarginTop =
|
|
23
|
+
this.commentYMarginTop = 10;
|
|
24
|
+
this.fontSize = {
|
|
25
|
+
"small": {
|
|
26
|
+
"default": 45,
|
|
27
|
+
"resized": 20
|
|
28
|
+
},
|
|
29
|
+
"medium": {
|
|
30
|
+
"default": 70,
|
|
31
|
+
"resized": 35
|
|
32
|
+
},
|
|
33
|
+
"big": {
|
|
34
|
+
"default": 120,
|
|
35
|
+
"resized": 57.5
|
|
36
|
+
}
|
|
37
|
+
};
|
|
24
38
|
|
|
25
39
|
if (formatted) {
|
|
26
40
|
this.data = data;
|
|
@@ -30,6 +44,7 @@
|
|
|
30
44
|
|
|
31
45
|
this.showCollision = false;
|
|
32
46
|
this.showFPS = false;
|
|
47
|
+
this.showCommentCount = false;
|
|
33
48
|
this.timeline = {};
|
|
34
49
|
this.nicoScripts = {
|
|
35
50
|
"reverse": []
|
|
@@ -61,18 +76,19 @@
|
|
|
61
76
|
for (let key in data[i]) {
|
|
62
77
|
let value = data[i][key];
|
|
63
78
|
|
|
64
|
-
if (key === "chat") {
|
|
79
|
+
if (key === "chat" && value["deleted"] !== 1) {
|
|
65
80
|
let tmpParam = {
|
|
66
81
|
"id": value["no"],
|
|
67
82
|
"vpos": value["vpos"],
|
|
68
83
|
"content": value["content"],
|
|
69
84
|
"date": value["date"],
|
|
70
85
|
"date_usec": value["date_usec"],
|
|
71
|
-
"owner": !value["user_id"]
|
|
86
|
+
"owner": !value["user_id"],
|
|
87
|
+
"premium": value["premium"] === 1
|
|
72
88
|
};
|
|
73
89
|
|
|
74
90
|
if (value["mail"]) {
|
|
75
|
-
tmpParam["mail"] = value["mail"].split(
|
|
91
|
+
tmpParam["mail"] = value["mail"].split(/[\s ]/g);
|
|
76
92
|
} else {
|
|
77
93
|
tmpParam["mail"] = [];
|
|
78
94
|
}
|
|
@@ -119,7 +135,8 @@
|
|
|
119
135
|
this.data[i].color = command.color;
|
|
120
136
|
this.data[i].full = command.full;
|
|
121
137
|
this.data[i].ender = command.ender;
|
|
122
|
-
this.data[i].
|
|
138
|
+
this.data[i]._live = command._live;
|
|
139
|
+
this.data[i].content = this.data[i].content.replaceAll("\t", " ");
|
|
123
140
|
}
|
|
124
141
|
}
|
|
125
142
|
/**
|
|
@@ -348,20 +365,31 @@
|
|
|
348
365
|
|
|
349
366
|
|
|
350
367
|
measureText(comment) {
|
|
351
|
-
let msg = comment.content;
|
|
352
|
-
|
|
353
|
-
if (!comment.defaultFontSize) {
|
|
354
|
-
comment.defaultFontSize = comment.fontSize;
|
|
355
|
-
} else {
|
|
356
|
-
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
368
|
let width,
|
|
360
369
|
width_max,
|
|
361
370
|
width_min,
|
|
362
371
|
height,
|
|
363
372
|
width_arr = [],
|
|
364
|
-
lines =
|
|
373
|
+
lines = comment.content.split("\n");
|
|
374
|
+
|
|
375
|
+
if (!comment.resized && !comment.ender) {
|
|
376
|
+
if (comment.size === "big" && lines.length > 2) {
|
|
377
|
+
comment.fontSize = this.fontSize.big.resized;
|
|
378
|
+
comment.resized = true;
|
|
379
|
+
comment.tateRisized = true;
|
|
380
|
+
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
381
|
+
} else if (comment.size === "medium" && lines.length > 4) {
|
|
382
|
+
comment.fontSize = this.fontSize.medium.resized;
|
|
383
|
+
comment.resized = true;
|
|
384
|
+
comment.tateRisized = true;
|
|
385
|
+
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
386
|
+
} else if (comment.size === "small" && lines.length > 6) {
|
|
387
|
+
comment.fontSize = this.fontSize.small.resized;
|
|
388
|
+
comment.resized = true;
|
|
389
|
+
comment.tateRisized = true;
|
|
390
|
+
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
365
393
|
|
|
366
394
|
for (let i = 0; i < lines.length; i++) {
|
|
367
395
|
let measure = this.context.measureText(lines[i]);
|
|
@@ -371,22 +399,39 @@
|
|
|
371
399
|
width = width_arr.reduce((p, c) => p + c, 0) / width_arr.length;
|
|
372
400
|
width_max = Math.max(...width_arr);
|
|
373
401
|
width_min = Math.min(...width_arr);
|
|
374
|
-
height = comment.fontSize
|
|
402
|
+
height = (comment.fontSize + this.commentYMarginTop) * lines.length;
|
|
375
403
|
|
|
376
|
-
if (
|
|
377
|
-
comment.
|
|
404
|
+
if (comment.loc !== "naka" && !comment.tateRisized) {
|
|
405
|
+
if (comment.full && width_max > 1920) {
|
|
406
|
+
comment.fontSize -= 1;
|
|
407
|
+
comment.resized = true;
|
|
408
|
+
comment.yokoResized = true;
|
|
409
|
+
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
410
|
+
return this.measureText(comment);
|
|
411
|
+
} else if (!comment.full && width_max > 1440) {
|
|
412
|
+
comment.fontSize -= 1;
|
|
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.tateRisized && (comment.full && width_max > 1920 || !comment.full && width_max > 1440) && !comment.yokoResized) {
|
|
419
|
+
comment.fontSize = this.fontSize[comment.size].default;
|
|
378
420
|
comment.resized = true;
|
|
421
|
+
comment.yokoResized = true;
|
|
379
422
|
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
380
423
|
return this.measureText(comment);
|
|
381
|
-
} else if (comment.
|
|
382
|
-
if (comment.full &&
|
|
424
|
+
} else if (comment.tateRisized && comment.yokoResized) {
|
|
425
|
+
if (comment.full && width_max > 3420) {
|
|
383
426
|
comment.fontSize -= 1;
|
|
384
427
|
comment.resized = true;
|
|
428
|
+
comment.yokoResized = true;
|
|
385
429
|
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
386
430
|
return this.measureText(comment);
|
|
387
|
-
} else if (!comment.full &&
|
|
431
|
+
} else if (!comment.full && width_max > 2940) {
|
|
388
432
|
comment.fontSize -= 1;
|
|
389
433
|
comment.resized = true;
|
|
434
|
+
comment.yokoResized = true;
|
|
390
435
|
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
391
436
|
return this.measureText(comment);
|
|
392
437
|
}
|
|
@@ -426,29 +471,25 @@
|
|
|
426
471
|
let lines = comment.content.split("\n"),
|
|
427
472
|
posX = (1920 - comment.width_max) / 2;
|
|
428
473
|
|
|
429
|
-
if (comment.loc === "
|
|
430
|
-
if (reverse) {
|
|
431
|
-
posX = (1920 + comment.width_max) * (vpos - comment.vpos) / 500;
|
|
432
|
-
} else {
|
|
433
|
-
posX = 1920 - (1920 + comment.width_max) * (vpos - comment.vpos) / 500;
|
|
434
|
-
}
|
|
435
|
-
|
|
474
|
+
if (comment.loc === "shita") {
|
|
436
475
|
for (let i in lines) {
|
|
437
476
|
let line = lines[i];
|
|
438
|
-
let posY = comment.posY + i * comment.fontSize
|
|
477
|
+
let posY = 1080 - comment.posY + i * (comment.fontSize + this.commentYMarginTop) - comment.height + this.commentYOffset * comment.fontSize;
|
|
439
478
|
this.context.strokeText(line, posX, posY);
|
|
440
479
|
this.context.fillText(line, posX, posY);
|
|
441
480
|
}
|
|
442
|
-
} else
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
481
|
+
} else {
|
|
482
|
+
if (comment.loc === "naka") {
|
|
483
|
+
if (reverse) {
|
|
484
|
+
posX = (1920 + comment.width_max) * (vpos - comment.vpos) / 500 - comment.width_max;
|
|
485
|
+
} else {
|
|
486
|
+
posX = 1920 - (1920 + comment.width_max) * (vpos - comment.vpos) / 500;
|
|
487
|
+
}
|
|
447
488
|
}
|
|
448
|
-
|
|
489
|
+
|
|
449
490
|
for (let i in lines) {
|
|
450
491
|
let line = lines[i];
|
|
451
|
-
let posY =
|
|
492
|
+
let posY = comment.posY + i * (comment.fontSize + this.commentYMarginTop) + this.commentYOffset * comment.fontSize;
|
|
452
493
|
this.context.strokeText(line, posX, posY);
|
|
453
494
|
this.context.fillText(line, posX, posY);
|
|
454
495
|
}
|
|
@@ -469,7 +510,7 @@
|
|
|
469
510
|
/**
|
|
470
511
|
* コメントに含まれるコマンドを解釈する
|
|
471
512
|
* @param comment- 独自フォーマットのコメントデータ
|
|
472
|
-
* @returns {{loc: string, size: string, color: string, fontSize: number, ender: boolean, font: string, full: boolean}}
|
|
513
|
+
* @returns {{loc: string, size: string, color: string, fontSize: number, ender: boolean, font: string, full: boolean, _live: boolean}}
|
|
473
514
|
*/
|
|
474
515
|
|
|
475
516
|
|
|
@@ -477,12 +518,13 @@
|
|
|
477
518
|
let metadata = comment.mail,
|
|
478
519
|
loc = "naka",
|
|
479
520
|
size = "medium",
|
|
480
|
-
fontSize =
|
|
481
|
-
color = "#
|
|
521
|
+
fontSize = this.fontSize.medium.default,
|
|
522
|
+
color = "#ffffff",
|
|
482
523
|
font = 'defont',
|
|
483
524
|
full = false,
|
|
484
525
|
ender = false,
|
|
485
|
-
reverse = comment.content.match(/@逆 ?(全|コメ|投コメ)?/)
|
|
526
|
+
reverse = comment.content.match(/@逆 ?(全|コメ|投コメ)?/),
|
|
527
|
+
_live = false;
|
|
486
528
|
|
|
487
529
|
if (reverse) {
|
|
488
530
|
if (!reverse[1]) {
|
|
@@ -513,7 +555,7 @@
|
|
|
513
555
|
}
|
|
514
556
|
|
|
515
557
|
for (let i in metadata) {
|
|
516
|
-
let command = metadata[i];
|
|
558
|
+
let command = metadata[i].toLowerCase();
|
|
517
559
|
|
|
518
560
|
if (loc === "naka") {
|
|
519
561
|
switch (command) {
|
|
@@ -531,18 +573,22 @@
|
|
|
531
573
|
switch (command) {
|
|
532
574
|
case "big":
|
|
533
575
|
size = "big";
|
|
534
|
-
fontSize =
|
|
576
|
+
fontSize = this.fontSize.big.default;
|
|
535
577
|
break;
|
|
536
578
|
|
|
537
579
|
case "small":
|
|
538
580
|
size = "small";
|
|
539
|
-
fontSize =
|
|
581
|
+
fontSize = this.fontSize.small.default;
|
|
540
582
|
break;
|
|
541
583
|
}
|
|
542
584
|
}
|
|
543
585
|
|
|
544
|
-
if (color === "#
|
|
586
|
+
if (color === "#ffffff") {
|
|
545
587
|
switch (command) {
|
|
588
|
+
case "white":
|
|
589
|
+
color = "#FFFFFF";
|
|
590
|
+
break;
|
|
591
|
+
|
|
546
592
|
case "red":
|
|
547
593
|
color = "#FF0000";
|
|
548
594
|
break;
|
|
@@ -627,12 +673,13 @@
|
|
|
627
673
|
break;
|
|
628
674
|
|
|
629
675
|
default:
|
|
630
|
-
const match = command.match(/#[0-9a-
|
|
676
|
+
const match = command.match(/#[0-9a-z]{3,6}/);
|
|
631
677
|
|
|
632
|
-
if (match) {
|
|
633
|
-
color = match[0];
|
|
678
|
+
if (match && comment.premium) {
|
|
679
|
+
color = match[0].toUpperCase();
|
|
634
680
|
}
|
|
635
681
|
|
|
682
|
+
break;
|
|
636
683
|
}
|
|
637
684
|
}
|
|
638
685
|
|
|
@@ -656,6 +703,9 @@
|
|
|
656
703
|
case "ender":
|
|
657
704
|
ender = true;
|
|
658
705
|
break;
|
|
706
|
+
|
|
707
|
+
case "_live":
|
|
708
|
+
_live = true;
|
|
659
709
|
}
|
|
660
710
|
}
|
|
661
711
|
|
|
@@ -666,7 +716,8 @@
|
|
|
666
716
|
color,
|
|
667
717
|
font,
|
|
668
718
|
full,
|
|
669
|
-
ender
|
|
719
|
+
ender,
|
|
720
|
+
_live
|
|
670
721
|
};
|
|
671
722
|
}
|
|
672
723
|
/**
|
|
@@ -682,7 +733,13 @@
|
|
|
682
733
|
for (let index in this.timeline[vpos]) {
|
|
683
734
|
let comment = this.data[this.timeline[vpos][index]];
|
|
684
735
|
this.context.font = parseFont(comment.font, comment.fontSize, this.useLegacy);
|
|
685
|
-
|
|
736
|
+
|
|
737
|
+
if (comment._live) {
|
|
738
|
+
let rgb = hex2rgb(comment.color);
|
|
739
|
+
this.context.fillStyle = `rgba(${rgb[0]},${rgb[1]},${rgb[2]},0.5)`;
|
|
740
|
+
} else {
|
|
741
|
+
this.context.fillStyle = comment.color;
|
|
742
|
+
}
|
|
686
743
|
|
|
687
744
|
if (comment.color === "#000000") {
|
|
688
745
|
this.context.strokeStyle = "rgba(255,255,255,0.7)";
|
|
@@ -701,6 +758,13 @@
|
|
|
701
758
|
this.context.strokeText("FPS:" + this.fps, 100, 100);
|
|
702
759
|
this.context.fillText("FPS:" + this.fps, 100, 100);
|
|
703
760
|
}
|
|
761
|
+
|
|
762
|
+
if (this.showCommentCount) {
|
|
763
|
+
this.context.font = parseFont("defont", 60, this.useLegacy);
|
|
764
|
+
this.context.fillStyle = "#00FF00";
|
|
765
|
+
this.context.strokeText("Count:" + this.timeline[vpos].length, 100, 200);
|
|
766
|
+
this.context.fillText("Count:" + this.timeline[vpos].length, 100, 200);
|
|
767
|
+
}
|
|
704
768
|
}
|
|
705
769
|
/**
|
|
706
770
|
* キャンバスを消去する
|
|
@@ -784,6 +848,20 @@
|
|
|
784
848
|
|
|
785
849
|
array[key].push(push);
|
|
786
850
|
};
|
|
851
|
+
/**
|
|
852
|
+
* Hexからrgbに変換する(_live用)
|
|
853
|
+
* @param {string} hex
|
|
854
|
+
* @return {array} RGB
|
|
855
|
+
*/
|
|
856
|
+
|
|
857
|
+
|
|
858
|
+
const hex2rgb = hex => {
|
|
859
|
+
if (hex.slice(0, 1) === "#") hex = hex.slice(1);
|
|
860
|
+
if (hex.length === 3) 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);
|
|
861
|
+
return [hex.slice(0, 2), hex.slice(2, 4), hex.slice(4, 6)].map(function (str) {
|
|
862
|
+
return parseInt(str, 16);
|
|
863
|
+
});
|
|
864
|
+
};
|
|
787
865
|
|
|
788
866
|
return NiconiComments;
|
|
789
867
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xpadev-net/niconicomments",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
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
6
|
"scripts": {
|
|
@@ -22,11 +22,12 @@
|
|
|
22
22
|
"files": [
|
|
23
23
|
"dist/bundle.js"
|
|
24
24
|
],
|
|
25
|
-
"homepage": "https://xpadev.net/",
|
|
25
|
+
"homepage": "https://xpadev.net/niconicomments/docs/",
|
|
26
26
|
"license": "MIT",
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
"rollup": "^2.61.1"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@rollup/plugin-babel": "^5.3.0"
|
|
31
32
|
}
|
|
32
33
|
}
|