1 | # Danmaku
|
2 |
|
3 | [](https://github.com/weizhenye/Danmaku/actions)
|
4 | [](https://codecov.io/gh/weizhenye/Danmaku)
|
5 | [](https://www.npmjs.com/package/danmaku)
|
6 | [](https://github.com/weizhenye/Danmaku/blob/master/LICENSE)
|
7 | [](https://bundlephobia.com/result?p=danmaku)
|
8 | [](https://www.jsdelivr.com/package/npm/danmaku)
|
9 |
|
10 | [](https://saucelabs.com/u/danmaku)
|
11 |
|
12 | Danmaku is a JavaScript library to display flying comments on HTML media elements (video and audio). It can also display comments to your container in real time without timeline.
|
13 |
|
14 | [Demo](https://danmaku.js.org/)
|
15 |
|
16 | [中文文档](https://github.com/weizhenye/Danmaku/wiki/%E4%B8%AD%E6%96%87%E6%96%87%E6%A1%A3)
|
17 |
|
18 | ## Installation
|
19 |
|
20 | You can install it with npm:
|
21 |
|
22 | ```bash
|
23 | npm install danmaku
|
24 | ```
|
25 |
|
26 | ```js
|
27 | // Full version
|
28 | import Danmaku from 'danmaku';
|
29 | // DOM engine only
|
30 | import Danmaku from 'danmaku/dist/esm/danmaku.dom.js';
|
31 | // Canvas engine only
|
32 | import Danmaku from 'danmaku/dist/esm/danmaku.canvas.js';
|
33 | ```
|
34 |
|
35 | Or use CDN ([jsDelivr](https://www.jsdelivr.com/package/npm/danmaku), [unpkg](https://unpkg.com/danmaku/)):
|
36 |
|
37 | | | Full | DOM engine only | Canvas engine only |
|
38 | | - | - | - | - |
|
39 | | UMD | [](https://cdn.jsdelivr.net/npm/danmaku/dist/danmaku.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/danmaku.dom.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/danmaku.canvas.js) |
|
40 | | UMD minified | [](https://cdn.jsdelivr.net/npm/danmaku/dist/danmaku.min.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/danmaku.dom.min.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/danmaku.canvas.min.js) |
|
41 | | ESM | [](https://cdn.jsdelivr.net/npm/danmaku/dist/esm/danmaku.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/esm/danmaku.dom.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/esm/danmaku.canvas.js) |
|
42 | | ESM minified | [](https://cdn.jsdelivr.net/npm/danmaku/dist/esm/danmaku.min.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/esm/danmaku.dom.min.js) | [](https://cdn.jsdelivr.net/npm/danmaku/dist/esm/danmaku.canvas.min.js) |
|
43 |
|
44 | ## Usage
|
45 |
|
46 | ### Media mode
|
47 |
|
48 | ```html
|
49 | <div id="my-video-container" style="width:640px;height:360px;position:relative;">
|
50 | <video id="my-video" src="./example.mp4" style="position:absolute;"></video>
|
51 | </div>
|
52 |
|
53 | <div id="my-audio-container" style="width:640px;height:360px;position:relative;"></div>
|
54 | <audio id="my-audio" src="./example.mp3"></audio>
|
55 |
|
56 | <script src="path/to/danmaku.min.js"></script>
|
57 | <script>
|
58 | var danmaku1 = new Danmaku({
|
59 | container: document.getElementById('my-video-container'),
|
60 | media: document.getElementById('my-video'),
|
61 | comments: []
|
62 | });
|
63 | var danmaku2 = new Danmaku({
|
64 | container: document.getElementById('my-audio-container'),
|
65 | media: document.getElementById('my-audio'),
|
66 | comments: []
|
67 | });
|
68 | </script>
|
69 | ```
|
70 |
|
71 | ### Live mode
|
72 |
|
73 | To display comments in real time, you need to set up server and use something like [Socket.IO](http://socket.io/). Danmaku is just receiving comments data and display them to container.
|
74 |
|
75 | Here is a simple example using with Socket.IO and Node.js.
|
76 |
|
77 | Server:
|
78 |
|
79 | ```js
|
80 | const app = require('http').createServer(handler);
|
81 | const io = require('socket.io')(app);
|
82 | app.listen(80);
|
83 | function handler(req, res) {
|
84 | // your handler...
|
85 | }
|
86 | io.on('connection', socket => {
|
87 | socket.on('danmaku', comment => {
|
88 | socket.broadcast.emit('danmaku', comment);
|
89 | });
|
90 | });
|
91 | ```
|
92 |
|
93 | Client:
|
94 |
|
95 | ```html
|
96 | <div id="my-container" style="width:640px;height:360px;"></div>
|
97 | <button id="send-button">Send</button>
|
98 |
|
99 | <script src="path/to/socket.io.js"></script>
|
100 | <script src="path/to/danmaku.min.js"></script>
|
101 | <script>
|
102 | var danmaku = new Danmaku({
|
103 | container: document.getElementById('my-container')
|
104 | });
|
105 | var socket = io();
|
106 | socket.on('danmaku', function(comment) {
|
107 | danmaku.emit(comment)
|
108 | });
|
109 | var btn = document.getElementById('send-button');
|
110 | btn.addEventListener('click', function() {
|
111 | var comment = {
|
112 | text: 'bla bla',
|
113 | style: {
|
114 | fontSize: '20px',
|
115 | color: '#ffffff'
|
116 | },
|
117 | };
|
118 | danmaku.emit(comment);
|
119 | socket.emit('danmaku', comment);
|
120 | });
|
121 | </script>
|
122 | ```
|
123 |
|
124 | ## API
|
125 |
|
126 | ### Initialization
|
127 |
|
128 | ```js
|
129 | var danmaku = new Danmaku({
|
130 | // REQUIRED. The stage to display comments will be appended to container.
|
131 | container: document.getElementById('my-container'),
|
132 |
|
133 | // media can be <video> or <audio> element,
|
134 | // if it's not provided, Danmaku will be in live mode
|
135 | media: document.getElementById('my-media'),
|
136 |
|
137 | // Array of comment, used in media mode,
|
138 | // you can find its format in `danmaku.emit` API.
|
139 | comments: [],
|
140 |
|
141 | // You can use DOM engine or canvas engine to render comments.
|
142 | // Canvas engine may more efficient than DOM however it costs more memory.
|
143 | // 'DOM' by default in full version.
|
144 | engine: 'canvas',
|
145 |
|
146 | // You can also set speed by using `danmaku.speed` API.
|
147 | speed: 144
|
148 | });
|
149 | ```
|
150 |
|
151 | ### Emit a comment
|
152 |
|
153 | ```js
|
154 | danmaku.emit({
|
155 | text: 'example',
|
156 |
|
157 | // 'rtl'(right to left) by default, available mode: 'ltr', 'rtl', 'top', 'bottom'.
|
158 | mode: 'rtl',
|
159 |
|
160 | // Specified in seconds, if not provided when using with media,
|
161 | // it will be set to `media.currentTime`. Not required in live mode.
|
162 | time: 233.3,
|
163 |
|
164 | // When using DOM engine, Danmaku will create a <div> node for each comment,
|
165 | // the style object will be set to `node.style` directly, just write with CSS rules.
|
166 | // For example:
|
167 | style: {
|
168 | fontSize: '20px',
|
169 | color: '#ffffff',
|
170 | border: '1px solid #337ab7',
|
171 | textShadow: '-1px -1px #000, -1px 1px #000, 1px -1px #000, 1px 1px #000'
|
172 | },
|
173 |
|
174 | // When using canvas engine, Danmaku will create a <canvas> object for each comment,
|
175 | // you should pass in a CanvasRenderingContext2D object.
|
176 | // For example:
|
177 | style: {
|
178 | font: '10px sans-serif',
|
179 | textAlign: 'start',
|
180 | // Note that 'bottom' is the default
|
181 | textBaseline: 'bottom',
|
182 | direction: 'inherit',
|
183 | fillStyle: '#000',
|
184 | strokeStyle: '#000',
|
185 | lineWidth: 1.0,
|
186 | // ...
|
187 | },
|
188 |
|
189 | // A custom render to draw comment.
|
190 | // when `render` exist, `text` and `style` will be ignored.
|
191 |
|
192 | // When using DOM engine, you should return an HTMLElement.
|
193 | render: function() {
|
194 | var $div = document.createElement('div');
|
195 | var $img = document.createElement('img');
|
196 | $img.src = '/path/to/xxx.png';
|
197 | $div.appendChild($img);
|
198 | return $div;
|
199 | },
|
200 | // When using canvas engine, you should return an HTMLCanvasElement.
|
201 | render: function() {
|
202 | var canvas = document.createElement('canvas');
|
203 | canvas.width = 320;
|
204 | canvas.height = 180;
|
205 | var ctx = canvas.getContext('2d');
|
206 | ctx.beginPath();
|
207 | ctx.arc(75, 75, 50, 0, 2 * Math.PI);
|
208 | ctx.stroke();
|
209 | return canvas;
|
210 | }
|
211 | });
|
212 | ```
|
213 |
|
214 | More details about [CanvasRenderingContext2D](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D).
|
215 |
|
216 | Tips:
|
217 | * With DOM engine, you may want to change line spacing by set `line-height` to each comment, a better way is set `line-height` to the container.
|
218 | * With canvas engine, line height is `1.2` by default, you can set it with `style.font`.
|
219 | * With canvas engine, `style.font` uses the same syntax as the [CSS font](https://developer.mozilla.org/en-US/docs/Web/CSS/font) specifier. However you can only use `px`, `%`, `em`, `rem` units, I'm sure you don't need others.
|
220 | * There is a hitbox for each comment, which height is determined by its line height. With canvas engine, when `style.textBaseline` is `top` or `hanging`, the baseline is set to top of the hitbox; when it's `middle`, baseline is middle of the hitbox; otherwise baseline is bottom of the hitbox. So if you set `style.textBaseline` to `alphabetic` or `hanging`, the comment's head or foot may out of the hitbox and be invisible.
|
221 | * With canvas engine, [`style.filter`](https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/filter) is supported in Chrome 52 and Firefox 49.
|
222 |
|
223 | ### Resize
|
224 |
|
225 | Do it when you resize container.
|
226 |
|
227 | ```js
|
228 | danmaku.resize();
|
229 | ```
|
230 |
|
231 | ### Show
|
232 |
|
233 | ```js
|
234 | danmaku.show();
|
235 | ```
|
236 |
|
237 | ### Hide
|
238 |
|
239 | If you set `display: none;` to the container directly when using DOM engine, you should also do danmaku.hide() otherwise the typesetting will be broken when it's showed.
|
240 |
|
241 | ```js
|
242 | danmaku.hide();
|
243 | ```
|
244 |
|
245 | ### Clear
|
246 |
|
247 | Clear current stage.
|
248 |
|
249 | ```js
|
250 | danmaku.clear();
|
251 | ```
|
252 |
|
253 | ### Speed
|
254 |
|
255 | There is a property `duration` for all comments, which means how long will a comment be shown to the stage. `duration` is calculated by `stage.width / danmaku.speed`, and `danmaku.speed` is a standard for all comments, because the actually speed for each comment is then calculated by `(comment.width + stage.width) / duration`. The default value is 144.
|
256 |
|
257 | ```js
|
258 | danmaku.speed = 144;
|
259 | ```
|
260 |
|
261 | ### Destroy
|
262 |
|
263 | Destroy `danmaku` instance and release memory.
|
264 |
|
265 | ```js
|
266 | danmaku.destroy();
|
267 | ```
|