Commit 452ddd11b5d4a22d81769b5807da0653a72cd005

Authored by zouyang0921
1 parent e68703dc

[年会抽奖]修复弹幕重叠问题

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(&#39;connection&#39;, function(socket) { @@ -55,7 +55,7 @@ io.on(&#39;connection&#39;, 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 // 断开连接