Commit 452ddd11b5d4a22d81769b5807da0653a72cd005
1 parent
e68703dc
[年会抽奖]修复弹幕重叠问题
Showing
5 changed files
with
735 additions
and
10 deletions
barrage.html
@@ -16,7 +16,7 @@ | @@ -16,7 +16,7 @@ | ||
16 | <div class="container" id="container"></div> | 16 | <div class="container" id="container"></div> |
17 | 17 | ||
18 | <script src="./js/jquery.min.js"></script> | 18 | <script src="./js/jquery.min.js"></script> |
19 | - <script src="./js/danmaku.min.js"></script> | 19 | + <script src="./js/danmaku.js"></script> |
20 | <script src="//cdn.bootcss.com/socket.io/2.0.3/socket.io.js"></script> | 20 | <script src="//cdn.bootcss.com/socket.io/2.0.3/socket.io.js"></script> |
21 | <script> | 21 | <script> |
22 | var socketUrl = '//106.54.64.163:3000'; | 22 | var socketUrl = '//106.54.64.163:3000'; |
@@ -26,12 +26,15 @@ | @@ -26,12 +26,15 @@ | ||
26 | container: document.getElementById('container') | 26 | container: document.getElementById('container') |
27 | }); | 27 | }); |
28 | var socket = io(socketUrl); | 28 | var socket = io(socketUrl); |
29 | + var oldTopNum, topNum; | ||
29 | socket.on('barrage', function(msg) { | 30 | socket.on('barrage', function(msg) { |
30 | - console.log('socket.on: ', msg); | 31 | + // console.log('socket.on: ', msg); |
31 | var colorIndex = Math.floor(Math.random() * (2 - 0 + 1)); // 生成 0-2 随机数 | 32 | var colorIndex = Math.floor(Math.random() * (2 - 0 + 1)); // 生成 0-2 随机数 |
32 | - var topNum = Math.floor(Math.random() * (10 - 1 + 1) + 1); // 生成 1-10 随机数 | ||
33 | - | ||
34 | - var comment = { | 33 | + topNum = Math.floor(Math.random() * (10 - 1 + 1) + 1); // 生成 1-10 随机数 |
34 | + while (topNum === oldTopNum) { | ||
35 | + topNum = Math.floor(Math.random() * (10 - 1 + 1) + 1); | ||
36 | + } | ||
37 | + danmaku.emit({ | ||
35 | text: msg, | 38 | text: msg, |
36 | style: { | 39 | style: { |
37 | fontSize: '35px', | 40 | fontSize: '35px', |
@@ -39,8 +42,8 @@ | @@ -39,8 +42,8 @@ | ||
39 | color: colors[colorIndex], | 42 | color: colors[colorIndex], |
40 | top: topNum * 50 + 'px' | 43 | top: topNum * 50 + 'px' |
41 | } | 44 | } |
42 | - }; | ||
43 | - danmaku.emit(comment); | 45 | + }); |
46 | + oldTopNum = topNum; | ||
44 | }); | 47 | }); |
45 | </script> | 48 | </script> |
46 | </body> | 49 | </body> |
img/mobile/no_auth.png
0 → 100644
1.15 MB
js/danmaku.js
0 → 100644
1 | +(function (global, factory) { | ||
2 | + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : | ||
3 | + typeof define === 'function' && define.amd ? define(factory) : | ||
4 | + (global = global || self, global.Danmaku = factory()); | ||
5 | +}(this, (function () { 'use strict'; | ||
6 | + | ||
7 | + /* eslint no-invalid-this: 0 */ | ||
8 | + function allocate(cmt) { | ||
9 | + var that = this; | ||
10 | + var ct = this._hasMedia ? this.media.currentTime : Date.now() / 1000; | ||
11 | + var pbr = this._hasMedia ? this.media.playbackRate : 1; | ||
12 | + function willCollide(cr, cmt) { | ||
13 | + if (cmt.mode === 'top' || cmt.mode === 'bottom') { | ||
14 | + return ct - cr.time < that.duration; | ||
15 | + } | ||
16 | + var crTotalWidth = that.width + cr.width; | ||
17 | + var crElapsed = crTotalWidth * (ct - cr.time) * pbr / that.duration; | ||
18 | + if (cr.width > crElapsed) { | ||
19 | + return true; | ||
20 | + } | ||
21 | + // (rtl mode) the right end of `cr` move out of left side of stage | ||
22 | + var crLeftTime = that.duration + cr.time - ct; | ||
23 | + var cmtTotalWidth = that.width + cmt.width; | ||
24 | + var cmtTime = that._hasMedia ? cmt.time : cmt._utc; | ||
25 | + var cmtElapsed = cmtTotalWidth * (ct - cmtTime) * pbr / that.duration; | ||
26 | + var cmtArrival = that.width - cmtElapsed; | ||
27 | + // (rtl mode) the left end of `cmt` reach the left side of stage | ||
28 | + var cmtArrivalTime = that.duration * cmtArrival / (that.width + cmt.width); | ||
29 | + return crLeftTime > cmtArrivalTime; | ||
30 | + } | ||
31 | + var crs = this._space[cmt.mode]; | ||
32 | + var last = 0; | ||
33 | + var curr = 0; | ||
34 | + for (var i = 1; i < crs.length; i++) { | ||
35 | + var cr = crs[i]; | ||
36 | + var requiredRange = cmt.height; | ||
37 | + if (cmt.mode === 'top' || cmt.mode === 'bottom') { | ||
38 | + requiredRange += cr.height; | ||
39 | + } | ||
40 | + if (cr.range - cr.height - crs[last].range >= requiredRange) { | ||
41 | + curr = i; | ||
42 | + break; | ||
43 | + } | ||
44 | + if (willCollide(cr, cmt)) { | ||
45 | + last = i; | ||
46 | + } | ||
47 | + } | ||
48 | + var channel = crs[last].range; | ||
49 | + var crObj = { | ||
50 | + range: channel + cmt.height, | ||
51 | + time: this._hasMedia ? cmt.time : cmt._utc, | ||
52 | + width: cmt.width, | ||
53 | + height: cmt.height | ||
54 | + }; | ||
55 | + crs.splice(last + 1, curr - last - 1, crObj); | ||
56 | + | ||
57 | + if (cmt.mode === 'bottom') { | ||
58 | + return this.height - cmt.height - channel % this.height; | ||
59 | + } | ||
60 | + return channel % (this.height - cmt.height); | ||
61 | + } | ||
62 | + | ||
63 | + function createCommentNode(cmt) { | ||
64 | + var node = document.createElement('div'); | ||
65 | + node.style.cssText = 'position:absolute;'; | ||
66 | + if (typeof cmt.render === 'function') { | ||
67 | + var $el = cmt.render(); | ||
68 | + if ($el instanceof HTMLElement) { | ||
69 | + node.appendChild($el); | ||
70 | + return node; | ||
71 | + } | ||
72 | + } | ||
73 | + if (cmt.html === true) { | ||
74 | + node.innerHTML = cmt.text; | ||
75 | + } else { | ||
76 | + node.textContent = cmt.text; | ||
77 | + } | ||
78 | + if (cmt.style) { | ||
79 | + for (var key in cmt.style) { | ||
80 | + node.style[key] = cmt.style[key]; | ||
81 | + } | ||
82 | + } | ||
83 | + return node; | ||
84 | + } | ||
85 | + | ||
86 | + var transform = (function() { | ||
87 | + var properties = [ | ||
88 | + 'oTransform', // Opera 11.5 | ||
89 | + 'msTransform', // IE 9 | ||
90 | + 'mozTransform', | ||
91 | + 'webkitTransform', | ||
92 | + 'transform' | ||
93 | + ]; | ||
94 | + var style = document.createElement('div').style; | ||
95 | + for (var i = 0; i < properties.length; i++) { | ||
96 | + /* istanbul ignore else */ | ||
97 | + if (properties[i] in style) { | ||
98 | + return properties[i]; | ||
99 | + } | ||
100 | + } | ||
101 | + /* istanbul ignore next */ | ||
102 | + return 'transform'; | ||
103 | + }()); | ||
104 | + | ||
105 | + /* eslint no-invalid-this: 0 */ | ||
106 | + function domEngine() { | ||
107 | + var dn = Date.now() / 1000; | ||
108 | + var ct = this._hasMedia ? this.media.currentTime : dn; | ||
109 | + var pbr = this._hasMedia ? this.media.playbackRate : 1; | ||
110 | + var cmt = null; | ||
111 | + var cmtt = 0; | ||
112 | + var i = 0; | ||
113 | + for (i = this.runningList.length - 1; i >= 0; i--) { | ||
114 | + cmt = this.runningList[i]; | ||
115 | + cmtt = this._hasMedia ? cmt.time : cmt._utc; | ||
116 | + if (ct - cmtt > this.duration) { | ||
117 | + this.stage.removeChild(cmt.node); | ||
118 | + /* istanbul ignore else */ | ||
119 | + if (!this._hasMedia) { | ||
120 | + cmt.node = null; | ||
121 | + } | ||
122 | + this.runningList.splice(i, 1); | ||
123 | + } | ||
124 | + } | ||
125 | + var pendingList = []; | ||
126 | + var df = document.createDocumentFragment(); | ||
127 | + while (this.position < this.comments.length) { | ||
128 | + cmt = this.comments[this.position]; | ||
129 | + cmtt = this._hasMedia ? cmt.time : cmt._utc; | ||
130 | + if (cmtt >= ct) { | ||
131 | + break; | ||
132 | + } | ||
133 | + if (ct - cmtt > this.duration) { | ||
134 | + ++this.position; | ||
135 | + continue; | ||
136 | + } | ||
137 | + if (this._hasMedia) { | ||
138 | + cmt._utc = dn - (this.media.currentTime - cmt.time); | ||
139 | + } | ||
140 | + cmt.node = cmt.node || createCommentNode(cmt); | ||
141 | + this.runningList.push(cmt); | ||
142 | + pendingList.push(cmt); | ||
143 | + df.appendChild(cmt.node); | ||
144 | + ++this.position; | ||
145 | + } | ||
146 | + if (pendingList.length) { | ||
147 | + this.stage.appendChild(df); | ||
148 | + } | ||
149 | + for (i = 0; i < pendingList.length; i++) { | ||
150 | + cmt = pendingList[i]; | ||
151 | + cmt.width = cmt.width || cmt.node.offsetWidth; | ||
152 | + cmt.height = cmt.height || cmt.node.offsetHeight; | ||
153 | + } | ||
154 | + for (i = 0; i < pendingList.length; i++) { | ||
155 | + cmt = pendingList[i]; | ||
156 | + cmt.y = allocate.call(this, cmt); | ||
157 | + if (cmt.mode === 'top' || cmt.mode === 'bottom') { | ||
158 | + cmt.x = (this.width - cmt.width) >> 1; | ||
159 | + cmt.node.style[transform] = 'translateX(' + cmt.x + 'px)'; | ||
160 | + } | ||
161 | + } | ||
162 | + for (i = 0; i < this.runningList.length; i++) { | ||
163 | + cmt = this.runningList[i]; | ||
164 | + if (cmt.mode === 'top' || cmt.mode === 'bottom') { | ||
165 | + continue; | ||
166 | + } | ||
167 | + var totalWidth = this.width + cmt.width; | ||
168 | + var elapsed = totalWidth * (dn - cmt._utc) * pbr / this.duration; | ||
169 | + elapsed |= 0; | ||
170 | + if (cmt.mode === 'ltr') cmt.x = elapsed - cmt.width; | ||
171 | + if (cmt.mode === 'rtl') cmt.x = this.width - elapsed; | ||
172 | + cmt.node.style[transform] = 'translateX(' + cmt.x + 'px)'; | ||
173 | + } | ||
174 | + } | ||
175 | + | ||
176 | + var canvasHeightCache = Object.create(null); | ||
177 | + | ||
178 | + function canvasHeight(font, fontSize) { | ||
179 | + if (canvasHeightCache[font]) { | ||
180 | + return canvasHeightCache[font]; | ||
181 | + } | ||
182 | + var height = 12; | ||
183 | + // eslint-disable-next-line max-len | ||
184 | + var regex = /(\d+(?:\.\d+)?)(px|%|em|rem)(?:\s*\/\s*(\d+(?:\.\d+)?)(px|%|em|rem)?)?/; | ||
185 | + var p = font.match(regex); | ||
186 | + if (p) { | ||
187 | + var fs = p[1] * 1 || 10; | ||
188 | + var fsu = p[2]; | ||
189 | + var lh = p[3] * 1 || 1.2; | ||
190 | + var lhu = p[4]; | ||
191 | + if (fsu === '%') fs *= fontSize.container / 100; | ||
192 | + if (fsu === 'em') fs *= fontSize.container; | ||
193 | + if (fsu === 'rem') fs *= fontSize.root; | ||
194 | + if (lhu === 'px') height = lh; | ||
195 | + if (lhu === '%') height = fs * lh / 100; | ||
196 | + if (lhu === 'em') height = fs * lh; | ||
197 | + if (lhu === 'rem') height = fontSize.root * lh; | ||
198 | + if (lhu === undefined) height = fs * lh; | ||
199 | + } | ||
200 | + canvasHeightCache[font] = height; | ||
201 | + return height; | ||
202 | + } | ||
203 | + | ||
204 | + function createCommentCanvas(cmt, fontSize) { | ||
205 | + if (typeof cmt.render === 'function') { | ||
206 | + var cvs = cmt.render(); | ||
207 | + if (cvs instanceof HTMLCanvasElement) { | ||
208 | + cmt.width = cvs.width; | ||
209 | + cmt.height = cvs.height; | ||
210 | + return cvs; | ||
211 | + } | ||
212 | + } | ||
213 | + var canvas = document.createElement('canvas'); | ||
214 | + var ctx = canvas.getContext('2d'); | ||
215 | + var style = cmt.canvasStyle || {}; | ||
216 | + style.font = style.font || '10px sans-serif'; | ||
217 | + style.textBaseline = style.textBaseline || 'bottom'; | ||
218 | + var strokeWidth = style.lineWidth * 1; | ||
219 | + strokeWidth = (strokeWidth > 0 && strokeWidth !== Infinity) | ||
220 | + ? Math.ceil(strokeWidth) | ||
221 | + : !!style.strokeStyle * 1; | ||
222 | + ctx.font = style.font; | ||
223 | + cmt.width = cmt.width || | ||
224 | + Math.max(1, Math.ceil(ctx.measureText(cmt.text).width) + strokeWidth * 2); | ||
225 | + cmt.height = cmt.height || | ||
226 | + Math.ceil(canvasHeight(style.font, fontSize)) + strokeWidth * 2; | ||
227 | + canvas.width = cmt.width; | ||
228 | + canvas.height = cmt.height; | ||
229 | + for (var key in style) { | ||
230 | + ctx[key] = style[key]; | ||
231 | + } | ||
232 | + var baseline = 0; | ||
233 | + switch (style.textBaseline) { | ||
234 | + case 'top': | ||
235 | + case 'hanging': | ||
236 | + baseline = strokeWidth; | ||
237 | + break; | ||
238 | + case 'middle': | ||
239 | + baseline = cmt.height >> 1; | ||
240 | + break; | ||
241 | + default: | ||
242 | + baseline = cmt.height - strokeWidth; | ||
243 | + } | ||
244 | + if (style.strokeStyle) { | ||
245 | + ctx.strokeText(cmt.text, strokeWidth, baseline); | ||
246 | + } | ||
247 | + ctx.fillText(cmt.text, strokeWidth, baseline); | ||
248 | + return canvas; | ||
249 | + } | ||
250 | + | ||
251 | + /* eslint no-invalid-this: 0 */ | ||
252 | + function canvasEngine() { | ||
253 | + this.stage.context.clearRect(0, 0, this.width, this.height); | ||
254 | + var dn = Date.now() / 1000; | ||
255 | + var ct = this._hasMedia ? this.media.currentTime : dn; | ||
256 | + var pbr = this._hasMedia ? this.media.playbackRate : 1; | ||
257 | + var cmt = null; | ||
258 | + var cmtt = 0; | ||
259 | + var i = 0; | ||
260 | + for (i = this.runningList.length - 1; i >= 0; i--) { | ||
261 | + cmt = this.runningList[i]; | ||
262 | + cmtt = this._hasMedia ? cmt.time : cmt._utc; | ||
263 | + if (ct - cmtt > this.duration) { | ||
264 | + // avoid caching canvas to reduce memory usage | ||
265 | + cmt.canvas = null; | ||
266 | + this.runningList.splice(i, 1); | ||
267 | + } | ||
268 | + } | ||
269 | + while (this.position < this.comments.length) { | ||
270 | + cmt = this.comments[this.position]; | ||
271 | + cmtt = this._hasMedia ? cmt.time : cmt._utc; | ||
272 | + if (cmtt >= ct) { | ||
273 | + break; | ||
274 | + } | ||
275 | + if (ct - cmtt > this.duration) { | ||
276 | + ++this.position; | ||
277 | + continue; | ||
278 | + } | ||
279 | + if (this._hasMedia) { | ||
280 | + cmt._utc = dn - (this.media.currentTime - cmt.time); | ||
281 | + } | ||
282 | + cmt.canvas = createCommentCanvas(cmt, this._fontSize); | ||
283 | + cmt.y = allocate.call(this, cmt); | ||
284 | + if (cmt.mode === 'top' || cmt.mode === 'bottom') { | ||
285 | + cmt.x = (this.width - cmt.width) >> 1; | ||
286 | + } | ||
287 | + this.runningList.push(cmt); | ||
288 | + ++this.position; | ||
289 | + } | ||
290 | + for (i = 0; i < this.runningList.length; i++) { | ||
291 | + cmt = this.runningList[i]; | ||
292 | + var totalWidth = this.width + cmt.width; | ||
293 | + var elapsed = totalWidth * (dn - cmt._utc) * pbr / this.duration; | ||
294 | + if (cmt.mode === 'ltr') cmt.x = (elapsed - cmt.width + .5) | 0; | ||
295 | + if (cmt.mode === 'rtl') cmt.x = (this.width - elapsed + .5) | 0; | ||
296 | + this.stage.context.drawImage(cmt.canvas, cmt.x, cmt.y); | ||
297 | + } | ||
298 | + } | ||
299 | + | ||
300 | + var raf = | ||
301 | + window.requestAnimationFrame || | ||
302 | + window.mozRequestAnimationFrame || | ||
303 | + window.webkitRequestAnimationFrame || | ||
304 | + function(cb) { | ||
305 | + return setTimeout(cb, 50 / 3); | ||
306 | + }; | ||
307 | + | ||
308 | + var caf = | ||
309 | + window.cancelAnimationFrame || | ||
310 | + window.mozCancelAnimationFrame || | ||
311 | + window.webkitCancelAnimationFrame || | ||
312 | + clearTimeout; | ||
313 | + | ||
314 | + /* eslint no-invalid-this: 0 */ | ||
315 | + function play() { | ||
316 | + if (!this.visible || !this.paused) { | ||
317 | + return this; | ||
318 | + } | ||
319 | + this.paused = false; | ||
320 | + if (this._hasMedia) { | ||
321 | + for (var i = 0; i < this.runningList.length; i++) { | ||
322 | + var cmt = this.runningList[i]; | ||
323 | + cmt._utc = Date.now() / 1000 - (this.media.currentTime - cmt.time); | ||
324 | + } | ||
325 | + } | ||
326 | + var that = this; | ||
327 | + var engine = this._useCanvas ? canvasEngine : domEngine; | ||
328 | + function frame() { | ||
329 | + engine.call(that); | ||
330 | + that._requestID = raf(frame); | ||
331 | + } | ||
332 | + this._requestID = raf(frame); | ||
333 | + return this; | ||
334 | + } | ||
335 | + | ||
336 | + /* eslint no-invalid-this: 0 */ | ||
337 | + function pause() { | ||
338 | + if (!this.visible || this.paused) { | ||
339 | + return this; | ||
340 | + } | ||
341 | + this.paused = true; | ||
342 | + caf(this._requestID); | ||
343 | + this._requestID = 0; | ||
344 | + return this; | ||
345 | + } | ||
346 | + | ||
347 | + function binsearch(arr, prop, key) { | ||
348 | + var mid = 0; | ||
349 | + var left = 0; | ||
350 | + var right = arr.length; | ||
351 | + while (left < right - 1) { | ||
352 | + mid = (left + right) >> 1; | ||
353 | + if (key >= arr[mid][prop]) { | ||
354 | + left = mid; | ||
355 | + } else { | ||
356 | + right = mid; | ||
357 | + } | ||
358 | + } | ||
359 | + if (arr[left] && key < arr[left][prop]) { | ||
360 | + return left; | ||
361 | + } | ||
362 | + return right; | ||
363 | + } | ||
364 | + | ||
365 | + function collidableRange() { | ||
366 | + var max = 9007199254740991; | ||
367 | + return [{ | ||
368 | + range: 0, | ||
369 | + time: -max, | ||
370 | + width: max, | ||
371 | + height: 0 | ||
372 | + }, { | ||
373 | + range: max, | ||
374 | + time: max, | ||
375 | + width: 0, | ||
376 | + height: 0 | ||
377 | + }]; | ||
378 | + } | ||
379 | + | ||
380 | + function resetSpace(space) { | ||
381 | + space.ltr = collidableRange(); | ||
382 | + space.rtl = collidableRange(); | ||
383 | + space.top = collidableRange(); | ||
384 | + space.bottom = collidableRange(); | ||
385 | + } | ||
386 | + | ||
387 | + /* eslint no-invalid-this: 0 */ | ||
388 | + function seek() { | ||
389 | + if (!this._hasMedia) { | ||
390 | + return this; | ||
391 | + } | ||
392 | + this.clear(); | ||
393 | + resetSpace(this._space); | ||
394 | + var position = binsearch(this.comments, 'time', this.media.currentTime); | ||
395 | + this.position = Math.max(0, position - 1); | ||
396 | + return this; | ||
397 | + } | ||
398 | + | ||
399 | + /* eslint no-invalid-this: 0 */ | ||
400 | + function bindEvents(_) { | ||
401 | + _.play = play.bind(this); | ||
402 | + _.pause = pause.bind(this); | ||
403 | + _.seeking = seek.bind(this); | ||
404 | + this.media.addEventListener('play', _.play); | ||
405 | + this.media.addEventListener('pause', _.pause); | ||
406 | + this.media.addEventListener('seeking', _.seeking); | ||
407 | + } | ||
408 | + | ||
409 | + /* eslint no-invalid-this: 0 */ | ||
410 | + function unbindEvents(_) { | ||
411 | + this.media.removeEventListener('play', _.play); | ||
412 | + this.media.removeEventListener('pause', _.pause); | ||
413 | + this.media.removeEventListener('seeking', _.seeking); | ||
414 | + _.play = null; | ||
415 | + _.pause = null; | ||
416 | + _.seeking = null; | ||
417 | + } | ||
418 | + | ||
419 | + function computeFontSize(el, fontSize) { | ||
420 | + var fs = window | ||
421 | + .getComputedStyle(el, null) | ||
422 | + .getPropertyValue('font-size') | ||
423 | + .match(/(.+)px/)[1] * 1; | ||
424 | + if (el.tagName === 'HTML') { | ||
425 | + fontSize.root = fs; | ||
426 | + } else { | ||
427 | + fontSize.container = fs; | ||
428 | + } | ||
429 | + } | ||
430 | + | ||
431 | + function formatMode(mode) { | ||
432 | + if (!/^(ltr|top|bottom)$/i.test(mode)) { | ||
433 | + return 'rtl'; | ||
434 | + } | ||
435 | + return mode.toLowerCase(); | ||
436 | + } | ||
437 | + | ||
438 | + function initMixin(Danmaku) { | ||
439 | + Danmaku.prototype.init = function(opt) { | ||
440 | + if (this._isInited) { | ||
441 | + return this; | ||
442 | + } | ||
443 | + | ||
444 | + if ( | ||
445 | + !opt || ( | ||
446 | + !opt.container && | ||
447 | + (!opt.video || (opt.video && !opt.video.parentNode)) | ||
448 | + ) | ||
449 | + ) { | ||
450 | + throw new Error('Danmaku requires container when initializing.'); | ||
451 | + } | ||
452 | + this._hasInitContainer = !!opt.container; | ||
453 | + this.container = opt.container; | ||
454 | + this.visible = true; | ||
455 | + | ||
456 | + this.engine = (opt.engine || 'DOM').toLowerCase(); | ||
457 | + this._useCanvas = (this.engine === 'canvas'); | ||
458 | + this._requestID = 0; | ||
459 | + | ||
460 | + this._speed = Math.max(0, opt.speed) || 144; | ||
461 | + this.duration = 4; | ||
462 | + | ||
463 | + this.comments = opt.comments || []; | ||
464 | + this.comments.sort(function(a, b) { | ||
465 | + return a.time - b.time; | ||
466 | + }); | ||
467 | + for (var i = 0; i < this.comments.length; i++) { | ||
468 | + this.comments[i].mode = formatMode(this.comments[i].mode); | ||
469 | + } | ||
470 | + this.runningList = []; | ||
471 | + this.position = 0; | ||
472 | + | ||
473 | + this.paused = true; | ||
474 | + this.media = opt.video || opt.audio; | ||
475 | + this._hasMedia = !!this.media; | ||
476 | + this._hasVideo = !!opt.video; | ||
477 | + if (this._hasVideo && !this._hasInitContainer) { | ||
478 | + var isPlay = !this.media.paused; | ||
479 | + this.container = document.createElement('div'); | ||
480 | + this.container.style.position = this.media.style.position; | ||
481 | + this.media.style.position = 'absolute'; | ||
482 | + this.media.parentNode.insertBefore(this.container, this.media); | ||
483 | + this.container.appendChild(this.media); | ||
484 | + // In Webkit/Blink, making a change to video element will pause the video. | ||
485 | + if (isPlay && this.media.paused) { | ||
486 | + this.media.play(); | ||
487 | + } | ||
488 | + } | ||
489 | + if (this._hasMedia) { | ||
490 | + this._listener = {}; | ||
491 | + bindEvents.call(this, this._listener); | ||
492 | + } | ||
493 | + | ||
494 | + if (this._useCanvas) { | ||
495 | + this.stage = document.createElement('canvas'); | ||
496 | + this.stage.context = this.stage.getContext('2d'); | ||
497 | + } else { | ||
498 | + this.stage = document.createElement('div'); | ||
499 | + this.stage.style.cssText = | ||
500 | + 'overflow:hidden;white-space:nowrap;transform:translateZ(0);'; | ||
501 | + } | ||
502 | + this.stage.style.cssText += 'position:relative;pointer-events:none;'; | ||
503 | + | ||
504 | + this.resize(); | ||
505 | + this.container.appendChild(this.stage); | ||
506 | + | ||
507 | + this._space = {}; | ||
508 | + resetSpace(this._space); | ||
509 | + this._fontSize = { | ||
510 | + root: 16, | ||
511 | + container: 16 | ||
512 | + }; | ||
513 | + computeFontSize(document.getElementsByTagName('html')[0], this._fontSize); | ||
514 | + computeFontSize(this.container, this._fontSize); | ||
515 | + | ||
516 | + if (!this._hasMedia || !this.media.paused) { | ||
517 | + seek.call(this); | ||
518 | + play.call(this); | ||
519 | + } | ||
520 | + this._isInited = true; | ||
521 | + return this; | ||
522 | + }; | ||
523 | + } | ||
524 | + | ||
525 | + var properties = [ | ||
526 | + // meta | ||
527 | + 'mode', 'time', | ||
528 | + // both engine | ||
529 | + 'text', 'render', | ||
530 | + // DOM engine | ||
531 | + 'html', 'style', | ||
532 | + // canvas engine | ||
533 | + 'canvasStyle' | ||
534 | + ]; | ||
535 | + | ||
536 | + function emitMixin(Danmaku) { | ||
537 | + Danmaku.prototype.emit = function(obj) { | ||
538 | + if (!obj || Object.prototype.toString.call(obj) !== '[object Object]') { | ||
539 | + return this; | ||
540 | + } | ||
541 | + var cmt = {}; | ||
542 | + for (var i = 0; i < properties.length; i++) { | ||
543 | + if (obj[properties[i]] !== undefined) { | ||
544 | + cmt[properties[i]] = obj[properties[i]]; | ||
545 | + } | ||
546 | + } | ||
547 | + cmt.text = (cmt.text || '').toString(); | ||
548 | + cmt.mode = formatMode(cmt.mode); | ||
549 | + cmt._utc = Date.now() / 1000; | ||
550 | + if (this._hasMedia) { | ||
551 | + var position = 0; | ||
552 | + if (cmt.time === undefined) { | ||
553 | + cmt.time = this.media.currentTime; | ||
554 | + position = this.position; | ||
555 | + } else { | ||
556 | + position = binsearch(this.comments, 'time', cmt.time); | ||
557 | + if (position < this.position) { | ||
558 | + this.position += 1; | ||
559 | + } | ||
560 | + } | ||
561 | + this.comments.splice(position, 0, cmt); | ||
562 | + } else { | ||
563 | + this.comments.push(cmt); | ||
564 | + } | ||
565 | + return this; | ||
566 | + }; | ||
567 | + } | ||
568 | + | ||
569 | + function clearMixin(Danmaku) { | ||
570 | + Danmaku.prototype.clear = function() { | ||
571 | + if (this._useCanvas) { | ||
572 | + this.stage.context.clearRect(0, 0, this.width, this.height); | ||
573 | + // avoid caching canvas to reduce memory usage | ||
574 | + for (var i = 0; i < this.runningList.length; i++) { | ||
575 | + this.runningList[i].canvas = null; | ||
576 | + } | ||
577 | + } else { | ||
578 | + var lc = this.stage.lastChild; | ||
579 | + while (lc) { | ||
580 | + this.stage.removeChild(lc); | ||
581 | + lc = this.stage.lastChild; | ||
582 | + } | ||
583 | + } | ||
584 | + this.runningList = []; | ||
585 | + return this; | ||
586 | + }; | ||
587 | + } | ||
588 | + | ||
589 | + function destroyMixin(Danmaku) { | ||
590 | + Danmaku.prototype.destroy = function() { | ||
591 | + if (!this._isInited) { | ||
592 | + return this; | ||
593 | + } | ||
594 | + | ||
595 | + pause.call(this); | ||
596 | + this.clear(); | ||
597 | + if (this._hasMedia) { | ||
598 | + unbindEvents.call(this, this._listener); | ||
599 | + } | ||
600 | + if (this._hasVideo && !this._hasInitContainer) { | ||
601 | + var isPlay = !this.media.paused; | ||
602 | + this.media.style.position = this.container.style.position; | ||
603 | + this.container.parentNode.insertBefore(this.media, this.container); | ||
604 | + this.container.parentNode.removeChild(this.container); | ||
605 | + /* istanbul ignore next */ | ||
606 | + if (isPlay && this.media.paused) { | ||
607 | + this.media.play(); | ||
608 | + } | ||
609 | + } | ||
610 | + for (var key in this) { | ||
611 | + /* istanbul ignore else */ | ||
612 | + if (Object.prototype.hasOwnProperty.call(this, key)) { | ||
613 | + this[key] = null; | ||
614 | + } | ||
615 | + } | ||
616 | + return this; | ||
617 | + }; | ||
618 | + } | ||
619 | + | ||
620 | + function showMixin(Danmaku) { | ||
621 | + Danmaku.prototype.show = function() { | ||
622 | + if (this.visible) { | ||
623 | + return this; | ||
624 | + } | ||
625 | + this.visible = true; | ||
626 | + if (this._hasMedia && this.media.paused) { | ||
627 | + return this; | ||
628 | + } | ||
629 | + seek.call(this); | ||
630 | + play.call(this); | ||
631 | + return this; | ||
632 | + }; | ||
633 | + } | ||
634 | + | ||
635 | + function hideMixin(Danmaku) { | ||
636 | + Danmaku.prototype.hide = function() { | ||
637 | + if (!this.visible) { | ||
638 | + return this; | ||
639 | + } | ||
640 | + pause.call(this); | ||
641 | + this.clear(); | ||
642 | + this.visible = false; | ||
643 | + return this; | ||
644 | + }; | ||
645 | + } | ||
646 | + | ||
647 | + function resizeMixin(Danmaku) { | ||
648 | + Danmaku.prototype.resize = function() { | ||
649 | + if (this._hasInitContainer) { | ||
650 | + this.width = this.container.offsetWidth; | ||
651 | + this.height = this.container.offsetHeight; | ||
652 | + } | ||
653 | + if (this._hasVideo && | ||
654 | + (!this._hasInitContainer || !this.width || !this.height)) { | ||
655 | + this.width = this.media.clientWidth; | ||
656 | + this.height = this.media.clientHeight; | ||
657 | + } | ||
658 | + if (this._useCanvas) { | ||
659 | + this.stage.width = this.width; | ||
660 | + this.stage.height = this.height; | ||
661 | + } else { | ||
662 | + this.stage.style.width = this.width + 'px'; | ||
663 | + this.stage.style.height = this.height + 'px'; | ||
664 | + } | ||
665 | + this.duration = this.width / this._speed; | ||
666 | + return this; | ||
667 | + }; | ||
668 | + } | ||
669 | + | ||
670 | + function speedMixin(Danmaku) { | ||
671 | + Object.defineProperty(Danmaku.prototype, 'speed', { | ||
672 | + get: function() { | ||
673 | + return this._speed; | ||
674 | + }, | ||
675 | + set: function(s) { | ||
676 | + if (typeof s !== 'number' || | ||
677 | + isNaN(s) || | ||
678 | + !isFinite(s) || | ||
679 | + s <= 0) { | ||
680 | + return this._speed; | ||
681 | + } | ||
682 | + this._speed = s; | ||
683 | + if (this.width) { | ||
684 | + this.duration = this.width / s; | ||
685 | + } | ||
686 | + return s; | ||
687 | + } | ||
688 | + }); | ||
689 | + } | ||
690 | + | ||
691 | + function Danmaku(opt) { | ||
692 | + this._isInited = false; | ||
693 | + opt && this.init(opt); | ||
694 | + } | ||
695 | + | ||
696 | + initMixin(Danmaku); | ||
697 | + emitMixin(Danmaku); | ||
698 | + clearMixin(Danmaku); | ||
699 | + destroyMixin(Danmaku); | ||
700 | + showMixin(Danmaku); | ||
701 | + hideMixin(Danmaku); | ||
702 | + resizeMixin(Danmaku); | ||
703 | + speedMixin(Danmaku); | ||
704 | + | ||
705 | + return Danmaku; | ||
706 | + | ||
707 | +}))); |
mobile.html
@@ -133,6 +133,9 @@ | @@ -133,6 +133,9 @@ | ||
133 | .dialog-reverse-btn {background: url('./img/mobile/dialog_btn_cancel.png') no-repeat;background-size: 100% 100%;color: #CF3727;} | 133 | .dialog-reverse-btn {background: url('./img/mobile/dialog_btn_cancel.png') no-repeat;background-size: 100% 100%;color: #CF3727;} |
134 | .dialog-close {position: absolute;top: -.6rem;right: .26rem;width: .76rem;height: .76rem;background: url('./img/mobile/dialog_close.png') no-repeat;background-size: 100% 100%;} | 134 | .dialog-close {position: absolute;top: -.6rem;right: .26rem;width: .76rem;height: .76rem;background: url('./img/mobile/dialog_close.png') no-repeat;background-size: 100% 100%;} |
135 | 135 | ||
136 | + .no-auth {width: 100%;height: 100vh;display: flex;flex-direction: column;justify-content: center;align-items: center;font-size: .32rem;color: #000;} | ||
137 | + .no-auth-icon {width: 3rem;margin-bottom: .3rem;} | ||
138 | + .no-auth-text {padding-bottom: 2rem;} | ||
136 | .toast-tip {display: none;position: fixed;bottom: 50%;left: 50%;transform: translateX(-50%);z-index: 11;opacity: 0;padding: 0 .5rem;height: .84rem;background: rgba(0, 0, 0, .8);border-radius: .06rem;transition: opacity 1s ease-out;line-height: .84rem;text-align: center;font-size: .28rem;color: #fff;} | 139 | .toast-tip {display: none;position: fixed;bottom: 50%;left: 50%;transform: translateX(-50%);z-index: 11;opacity: 0;padding: 0 .5rem;height: .84rem;background: rgba(0, 0, 0, .8);border-radius: .06rem;transition: opacity 1s ease-out;line-height: .84rem;text-align: center;font-size: .28rem;color: #fff;} |
137 | .clearfix:after {content: " ";display: block;height: 0;visibility: hidden;clear: both;} | 140 | .clearfix:after {content: " ";display: block;height: 0;visibility: hidden;clear: both;} |
138 | .hide {display: none;} | 141 | .hide {display: none;} |
@@ -315,6 +318,12 @@ | @@ -315,6 +318,12 @@ | ||
315 | </div> | 318 | </div> |
316 | </div> | 319 | </div> |
317 | 320 | ||
321 | + <!-- 非微信浏览器打开 --> | ||
322 | + <div class="no-auth hide"> | ||
323 | + <img class="no-auth-icon" src="./img/mobile/no_auth.png"> | ||
324 | + <span class="no-auth-text">请在微信中使用</span> | ||
325 | + </div> | ||
326 | + | ||
318 | <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.js"></script> | 327 | <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.js"></script> |
319 | <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> | 328 | <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> |
320 | <script src="https://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script> | 329 | <script src="https://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script> |
@@ -323,8 +332,14 @@ | @@ -323,8 +332,14 @@ | ||
323 | <script src="./js/template.js"></script> | 332 | <script src="./js/template.js"></script> |
324 | <script src="mobile.js?t=2"></script> | 333 | <script src="mobile.js?t=2"></script> |
325 | <script> | 334 | <script> |
326 | - var vConsole = new VConsole(); | ||
327 | - action.init(); | 335 | + var ua = window.navigator.userAgent.toLowerCase(); |
336 | + if (ua.match(/MicroMessenger/i) == 'micromessenger') { | ||
337 | + var vConsole = new VConsole(); | ||
338 | + action.init(); | ||
339 | + } else { | ||
340 | + $('.wrap, .dialog-wrap').hide(); | ||
341 | + $('.no-auth').css('display', 'flex'); | ||
342 | + } | ||
328 | </script> | 343 | </script> |
329 | 344 | ||
330 | <script type="text/html" id="seatListTmpl"> | 345 | <script type="text/html" id="seatListTmpl"> |
server.js
@@ -55,7 +55,7 @@ io.on('connection', function(socket) { | @@ -55,7 +55,7 @@ io.on('connection', function(socket) { | ||
55 | timer = setInterval(function() { | 55 | timer = setInterval(function() { |
56 | var msg = defaultMsgs[Math.floor(Math.random() * (19 - 0 + 1))]; | 56 | var msg = defaultMsgs[Math.floor(Math.random() * (19 - 0 + 1))]; |
57 | io.emit('barrage', msg); | 57 | io.emit('barrage', msg); |
58 | - }, 24000); | 58 | + }, 25000); |
59 | }); | 59 | }); |
60 | 60 | ||
61 | // 断开连接 | 61 | // 断开连接 |