UNPKG

rc-danmuku

Version:
197 lines (159 loc) 6.84 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = void 0; 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 _react = _interopRequireDefault(require("react")); var _reactDom = _interopRequireDefault(require("react-dom")); var BulletStatus; (function (BulletStatus) { BulletStatus["PENDING"] = "pending"; BulletStatus["RUNNING"] = "running"; BulletStatus["PAUSED"] = "paused"; BulletStatus["FINISHED"] = "finished"; })(BulletStatus || (BulletStatus = {})); var Bullet = /*#__PURE__*/function () { // 当前状态 // 弹幕DOM元素 // 速度 // 目标挂载容器 // 目标轨道 // 弹幕行高 // 弹幕完全显示的回调 // 是否全部出现 // 暂停时距离右边的距离 // 弹幕全部出现的计时器 function Bullet(node, options) { var _this = this; (0, _classCallCheck2["default"])(this, Bullet); (0, _defineProperty2["default"])(this, "status", BulletStatus.PENDING); (0, _defineProperty2["default"])(this, "element", void 0); (0, _defineProperty2["default"])(this, "speed", void 0); (0, _defineProperty2["default"])(this, "targetContainer", void 0); (0, _defineProperty2["default"])(this, "trackIndex", void 0); (0, _defineProperty2["default"])(this, "rowHeight", void 0); (0, _defineProperty2["default"])(this, "onTotalOut", void 0); (0, _defineProperty2["default"])(this, "isTotalOut", false); (0, _defineProperty2["default"])(this, "rightDistance", 0); (0, _defineProperty2["default"])(this, "totalOutTimer", 0); this.speed = options.speed; this.targetContainer = options.targetContainer; this.trackIndex = options.trackIndex; this.rowHeight = options.rowHeight; this.onTotalOut = options.onTotalOut; var div = document.createElement('div'); div.className = 'bullet-item'; div.setAttribute('style', "position: absolute;\n line-height: 1.125;\n user-select: none;\n white-space: pre;\n perspective: 500px;\n will-change: transform;\n pointer-events: none;"); div.style.opacity = String(options.opacity); var reactNode = typeof node === 'string' ? /*#__PURE__*/_react["default"].createElement("span", { className: "bullet-item-text", style: { textShadow: '#000 1px 0px 1px, #000 0px 1px 1px, #000 0px -1px 1px,#000 -1px 0px 1px', color: options.color || '#fff', fontSize: "".concat(options.fontSize, "px") } }, node) : node; _reactDom["default"].render(reactNode, div); this.element = div; options.targetContainer.appendChild(this.element); var _this$targetContainer = this.targetContainer.getBoundingClientRect(), width = _this$targetContainer.width; div.style.left = "".concat(width, "px"); div.style.top = "".concat(this.trackIndex * this.rowHeight, "px"); if (options.minGapWidth && options.minGapWidth > 0) { div.style.paddingRight = "".concat(options.minGapWidth, "px"); } this.element.addEventListener('transitionend', function () { // console.log('====transition end===='); _this.destroy(); _this.status = BulletStatus.FINISHED; _this.isTotalOut = false; options.onDestroy(options.trackIndex); }); } // 根据弹幕当前位置计算出弹幕完全显示需要的时间,并在改时间后将弹幕状态设置为完全可见状态 (0, _createClass2["default"])(Bullet, [{ key: "startTotalOutTimer", value: function startTotalOutTimer() { var _this2 = this; if (this.totalOutTimer) { return; } var _this$targetContainer2 = this.targetContainer.getBoundingClientRect(), left = _this$targetContainer2.left, width = _this$targetContainer2.width; var _this$element$getBoun = this.element.getBoundingClientRect(), bulletLeft = _this$element$getBoun.left; var notOutWidth = this.element.offsetWidth - (left + width - bulletLeft); if (notOutWidth <= 0) { return; } // 该条弹幕完全展示出所需的时间 var totalOutTime = notOutWidth / this.speed; this.totalOutTimer = setTimeout(function () { // console.log('====set is total out===='); _this2.isTotalOut = true; _this2.totalOutTimer = 0; if (_this2.onTotalOut) { _this2.onTotalOut(_this2.trackIndex); } }, totalOutTime * 1000); } // 清楚弹幕完全显示状态的计时器 }, { key: "clearTotalOutTimer", value: function clearTotalOutTimer() { if (this.totalOutTimer) { clearTimeout(this.totalOutTimer); this.totalOutTimer = 0; } } // 弹幕运行 }, { key: "run", value: function run() { var _this$targetContainer3 = this.targetContainer.getBoundingClientRect(), width = _this$targetContainer3.width; this.element.style.transition = "transform ".concat(((width + this.element.scrollWidth - this.rightDistance) / this.speed).toFixed(2), "s linear"); this.element.style.transform = "translate3d(-".concat(width + this.element.scrollWidth, "px, 0, 0)"); this.status = BulletStatus.RUNNING; this.startTotalOutTimer(); } // 弹幕暂停 }, { key: "pause", value: function pause() { var _this$targetContainer4 = this.targetContainer.getBoundingClientRect(), containerLeft = _this$targetContainer4.left, containeWidth = _this$targetContainer4.width; var _this$element$getBoun2 = this.element.getBoundingClientRect(), bulletLeft = _this$element$getBoun2.left; this.rightDistance = containeWidth - (bulletLeft - containerLeft); this.element.style.transform = "translate3d(-".concat(this.rightDistance, "px, 0, 0)"); this.element.style.transition = 'transform 0s linear 0s'; this.status = BulletStatus.PAUSED; this.clearTotalOutTimer(); } // 销毁弹幕 }, { key: "destroy", value: function destroy() { if (this.totalOutTimer) { clearTimeout(this.totalOutTimer); } _reactDom["default"].unmountComponentAtNode(this.element); this.element.remove(); } }, { key: "isRunning", get: function get() { return this.status === BulletStatus.RUNNING; } }, { key: "isFinished", get: function get() { return this.status === BulletStatus.FINISHED; } }]); return Bullet; }(); var _default = Bullet; exports["default"] = _default;