Commit 452ddd11b5d4a22d81769b5807da0653a72cd005
1 parent
e68703dc
[年会抽奖]修复弹幕重叠问题
Showing
5 changed files
with
735 additions
and
10 deletions
barrage.html
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | <div class="container" id="container"></div> |
17 | 17 | |
18 | 18 | <script src="./js/jquery.min.js"></script> |
19 | - <script src="./js/danmaku.min.js"></script> | |
19 | + <script src="./js/danmaku.js"></script> | |
20 | 20 | <script src="//cdn.bootcss.com/socket.io/2.0.3/socket.io.js"></script> |
21 | 21 | <script> |
22 | 22 | var socketUrl = '//106.54.64.163:3000'; |
... | ... | @@ -26,12 +26,15 @@ |
26 | 26 | container: document.getElementById('container') |
27 | 27 | }); |
28 | 28 | var socket = io(socketUrl); |
29 | + var oldTopNum, topNum; | |
29 | 30 | socket.on('barrage', function(msg) { |
30 | - console.log('socket.on: ', msg); | |
31 | + // console.log('socket.on: ', msg); | |
31 | 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 | 38 | text: msg, |
36 | 39 | style: { |
37 | 40 | fontSize: '35px', |
... | ... | @@ -39,8 +42,8 @@ |
39 | 42 | color: colors[colorIndex], |
40 | 43 | top: topNum * 50 + 'px' |
41 | 44 | } |
42 | - }; | |
43 | - danmaku.emit(comment); | |
45 | + }); | |
46 | + oldTopNum = topNum; | |
44 | 47 | }); |
45 | 48 | </script> |
46 | 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 | 133 | .dialog-reverse-btn {background: url('./img/mobile/dialog_btn_cancel.png') no-repeat;background-size: 100% 100%;color: #CF3727;} |
134 | 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 | 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 | 140 | .clearfix:after {content: " ";display: block;height: 0;visibility: hidden;clear: both;} |
138 | 141 | .hide {display: none;} |
... | ... | @@ -315,6 +318,12 @@ |
315 | 318 | </div> |
316 | 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 | 327 | <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.js"></script> |
319 | 328 | <script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script> |
320 | 329 | <script src="https://cdn.bootcss.com/jquery/1.7.2/jquery.min.js"></script> |
... | ... | @@ -323,8 +332,14 @@ |
323 | 332 | <script src="./js/template.js"></script> |
324 | 333 | <script src="mobile.js?t=2"></script> |
325 | 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 | 343 | </script> |
329 | 344 | |
330 | 345 | <script type="text/html" id="seatListTmpl"> | ... | ... |
server.js