rc-danmuku
Version:
352 lines (302 loc) • 11.6 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _Bullet = _interopRequireDefault(require("./Bullet"));
var Danmaku = /*#__PURE__*/function () {
// 弹幕容器
// 容器宽度
// 容器高度
// 弹幕轨道高度
// 弹幕轨道数量
// 弹幕速度
// 弹幕透明度 0-1
// 弹幕之前的最小间隔宽度
// 是否处于暂停中
// 是否已被销毁
// 当前展示的弹幕数组
// 待发送的弹幕队列
function Danmaku(ele) {
var _this = this,
_options$rowHeight,
_options$speed,
_options$fontSize,
_options$opacity,
_options$minGapWidth;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
(0, _classCallCheck2["default"])(this, Danmaku);
(0, _defineProperty2["default"])(this, "container", null);
(0, _defineProperty2["default"])(this, "width", 0);
(0, _defineProperty2["default"])(this, "height", 0);
(0, _defineProperty2["default"])(this, "rowHeight", 40);
(0, _defineProperty2["default"])(this, "trackCount", 0);
(0, _defineProperty2["default"])(this, "speed", 100);
(0, _defineProperty2["default"])(this, "fontSize", 18);
(0, _defineProperty2["default"])(this, "opacity", 1);
(0, _defineProperty2["default"])(this, "minGapWidth", 0);
(0, _defineProperty2["default"])(this, "allPaused", false);
(0, _defineProperty2["default"])(this, "isDestroyed", false);
(0, _defineProperty2["default"])(this, "options", {});
(0, _defineProperty2["default"])(this, "trackList", []);
(0, _defineProperty2["default"])(this, "queue", []);
(0, _defineProperty2["default"])(this, "isRunningWhenPageHide", true);
(0, _defineProperty2["default"])(this, "visibilityChangeEventHandle", function () {
if (document.visibilityState === 'hidden') {
_this.isRunningWhenPageHide = !_this.allPaused;
if (!_this.allPaused) {
_this.pause();
}
} else if (_this.isRunningWhenPageHide && _this.allPaused) {
_this.resume();
}
});
Danmaku.optionsParamsCheck(options);
if (typeof ele === 'string') {
this.container = document.querySelector(ele);
if (!this.container) {
throw new Error('container not found');
}
} else {
this.container = ele;
}
this.options = options;
this.rowHeight = (_options$rowHeight = options.rowHeight) !== null && _options$rowHeight !== void 0 ? _options$rowHeight : Danmaku.DEFAULT_ROW_HEIGHT;
this.speed = (_options$speed = options.speed) !== null && _options$speed !== void 0 ? _options$speed : Danmaku.DEFAULT_SPEED;
this.fontSize = (_options$fontSize = options.fontSize) !== null && _options$fontSize !== void 0 ? _options$fontSize : Danmaku.DEFAULT_FONTSIZE;
this.opacity = (_options$opacity = options.opacity) !== null && _options$opacity !== void 0 ? _options$opacity : Danmaku.DEFAULT_OPACITY;
this.minGapWidth = (_options$minGapWidth = options.minGapWidth) !== null && _options$minGapWidth !== void 0 ? _options$minGapWidth : Danmaku.DEFAULT_GAP_WIDTH;
this.container.classList.add(Danmaku.containerClassName);
this.container.style.position = 'relative';
this.container.style.overflow = 'hidden';
var _this$container$getBo = this.container.getBoundingClientRect(),
width = _this$container$getBo.width,
height = _this$container$getBo.height;
this.width = width;
this.height = height;
this.trackCount = Math.floor(height / this.rowHeight);
if (options.maxRow && options.maxRow > 0) {
this.trackCount = Math.min(options.maxRow, this.trackCount);
}
this.trackList = Array(this.trackCount).fill(null).map(function () {
return [];
});
document.addEventListener('visibilitychange', this.visibilityChangeEventHandle);
} // 工具方法,数字是否大于0
(0, _createClass2["default"])(Danmaku, [{
key: "getTrackIndex",
// 获取相对最空闲的弹幕轨道
value: function getTrackIndex() {
if (!this.trackList.length) {
return 0;
}
var result = 0;
var minCount = this.trackList[0].length;
this.trackList.forEach(function (list, index) {
var _list$filter = list.filter(function (bullet) {
return !bullet.isTotalOut;
}),
length = _list$filter.length;
if (length < minCount) {
minCount = length;
result = index;
}
});
return result;
}
/**
* 立即发送弹幕到屏幕上,自动寻找最空闲的轨道,若没有空闲轨道则可能有重叠弹幕
* @param node 要发送的React组件或者文本
*/
}, {
key: "emit",
value: function emit(node) {
var _this2 = this;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (!this.container || this.isDestroyed) {
return;
}
var trackIndex = this.getTrackIndex();
var bulletItem = new _Bullet["default"](node, {
color: options.color,
speed: this.speed,
opacity: this.opacity,
fontSize: this.fontSize,
targetContainer: this.container,
trackIndex: trackIndex,
rowHeight: this.rowHeight,
minGapWidth: this.minGapWidth,
onTotalOut: function onTotalOut() {
_this2.popBulletToFreeTrack();
},
onDestroy: function onDestroy(targetTrackIndex) {
var _this2$options$onBull, _this2$options;
_this2.trackList[targetTrackIndex] = _this2.trackList[targetTrackIndex].filter(function (item) {
return !item.isFinished;
});
(_this2$options$onBull = (_this2$options = _this2.options).onBulletOut) === null || _this2$options$onBull === void 0 ? void 0 : _this2$options$onBull.call(_this2$options);
}
});
this.trackList[trackIndex].push(bulletItem);
if (!this.allPaused) {
var _this$options$onBulle, _this$options;
bulletItem.run();
(_this$options$onBulle = (_this$options = this.options).onBulletIn) === null || _this$options$onBulle === void 0 ? void 0 : _this$options$onBulle.call(_this$options);
}
if (this.getRestAmount() === 0) {
var _this$options$onQueue, _this$options2;
(_this$options$onQueue = (_this$options2 = this.options).onQueueRunOut) === null || _this$options$onQueue === void 0 ? void 0 : _this$options$onQueue.call(_this$options2);
}
} // 是否有空闲轨道(该轨道发送弹幕时不会和上一条弹幕重叠)
}, {
key: "hasFreeTrack",
value: function hasFreeTrack() {
return this.trackList.some(function (bullets) {
return !bullets || !bullets.length || bullets[bullets.length - 1].isTotalOut;
});
} // 如果队列中还有弹幕并且有空闲的轨道,则弹出
}, {
key: "popBulletToFreeTrack",
value: function popBulletToFreeTrack() {
if (this.queue.length > 0 && this.hasFreeTrack()) {
var item = this.queue.shift();
if (item) {
this.emit(item.node, item.options);
this.popBulletToFreeTrack();
}
}
}
/**
* 当有空闲弹幕轨道时,直接发送弹幕,效果通emit方法一样,
* 若全部轨道都占用,则将弹幕暂存到队列中,待空闲后再依次放出
* @param node
*/
}, {
key: "push",
value: function push(node) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (this.isDestroyed) {
return;
}
if (this.hasFreeTrack()) {
this.emit(node, options);
} else {
this.queue.push({
node: node,
options: options
});
}
} // 推送一个弹幕数组
}, {
key: "pushAll",
value: function pushAll(nodeArr) {
var _this$queue;
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
if (this.isDestroyed) {
return;
}
(_this$queue = this.queue).push.apply(_this$queue, (0, _toConsumableArray2["default"])(nodeArr.map(function (item) {
return {
node: item,
options: options
};
})));
this.popBulletToFreeTrack();
}
/**
* pause
*/
}, {
key: "pause",
value: function pause() {
if (this.allPaused) {
return;
}
this.allPaused = true;
this.trackList.forEach(function (list) {
return list.forEach(function (item) {
item.pause();
});
});
}
/**
* resume
*/
}, {
key: "resume",
value: function resume() {
if (!this.allPaused || this.isDestroyed) {
return;
}
this.allPaused = false;
this.trackList.forEach(function (list) {
return list.forEach(function (item) {
item.run();
});
});
}
/**
* destroy
*/
}, {
key: "destroy",
value: function destroy() {
if (this.container) {
this.trackList.forEach(function (list) {
return list.forEach(function (item) {
item.destroy();
});
});
this.trackList = [];
document.removeEventListener('visibilitychange', this.visibilityChangeEventHandle);
this.container.classList.remove(Danmaku.containerClassName);
this.container = null;
this.isDestroyed = true;
}
}
/**
* 获取剩余还没发出的弹幕数量
*/
}, {
key: "getRestAmount",
value: function getRestAmount() {
return this.queue.length;
}
/**
* 清空弹幕队列(只能清空排队中还未发出的弹幕)
*/
}, {
key: "clearQueue",
value: function clearQueue() {
this.queue = [];
}
}], [{
key: "optionsParamsCheck",
// 检查参数是否合法
value: function optionsParamsCheck() {
var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
['rowHeight', 'speed', 'opacity', 'fontSize', 'maxRow', 'minGapWidth'].forEach(function (item) {
if (typeof options[item] === 'number' && !Danmaku.numberIsGreaterThanZero(options[item])) {
throw new Error("rc-danmaku: ".concat(item, " \u5FC5\u987B\u5927\u4E8E\u7B49\u4E8E0"));
}
});
} // 页面不可见时暂停弹幕滚动
}]);
return Danmaku;
}();
(0, _defineProperty2["default"])(Danmaku, "DEFAULT_ROW_HEIGHT", 40);
(0, _defineProperty2["default"])(Danmaku, "DEFAULT_SPEED", 100);
(0, _defineProperty2["default"])(Danmaku, "DEFAULT_FONTSIZE", 18);
(0, _defineProperty2["default"])(Danmaku, "DEFAULT_OPACITY", 1);
(0, _defineProperty2["default"])(Danmaku, "DEFAULT_GAP_WIDTH", 20);
(0, _defineProperty2["default"])(Danmaku, "containerClassName", 'danmaku-container');
(0, _defineProperty2["default"])(Danmaku, "numberIsGreaterThanZero", function (number) {
return number !== undefined && number >= 0;
});
var _default = Danmaku;
exports["default"] = _default;