UNPKG

@qier-player/danmaku

Version:

Powerful danmaku, support many features.

156 lines 6.17 kB
var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { if (typeof b !== "function" && b !== null) throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; import BaseRolling from './base-rolling'; import { createDanmu } from '../helper'; import { isEmptyArray } from '../utils/is'; import { TIME_PER_FRAME } from '../constants'; import { getArrayLast } from '../utils/get'; var RollingCommander = /** @class */ (function (_super) { __extends(RollingCommander, _super); function RollingCommander() { return _super !== null && _super.apply(this, arguments) || this; } Object.defineProperty(RollingCommander.prototype, "defaultSpeed", { get: function () { return (this.trackWidth / this.duration) * TIME_PER_FRAME; }, enumerable: false, configurable: true }); Object.defineProperty(RollingCommander.prototype, "randomSpeed", { get: function () { return 0.8 + Math.random() * 1.2; }, enumerable: false, configurable: true }); RollingCommander.prototype.add = function (danmu) { var trackId = this.findTrack(); if (trackId === -1) { return false; } var text = danmu.text, color = danmu.color, size = danmu.size, offset = danmu.offset; var danmuDom = createDanmu(text, color, size, this.trackHeight, offset); this.el.appendChild(danmuDom); var width = danmuDom.offsetWidth; // 根据追及问题,计算弹幕的速度 var track = this.tracks[trackId]; var trackOffset = track.offset; var trackWidth = this.trackWidth; var speed; if (isEmptyArray(track.danmus)) { speed = this.defaultSpeed * this.randomSpeed; } else { var preSpeed = getArrayLast(track.danmus).speed; speed = (trackWidth * preSpeed) / trackOffset; } // 防止速度过快一闪而过,最大值只能为平均速度的 2 倍 speed = Math.min(speed, this.defaultSpeed * 2); var normalizedDanmu = __assign(__assign({}, danmu), { offset: trackWidth, speed: speed, width: width }); this.objToElm.set(normalizedDanmu, danmuDom); this.elmToObj.set(danmuDom, normalizedDanmu); track.push(normalizedDanmu); track.offset = trackWidth + normalizedDanmu.width * 1.2; return true; }; RollingCommander.prototype.findTrack = function () { var _this = this; var failCode = -1; var idx = failCode; var max = -Infinity; this.each(function (track, index) { var trackOffset = track.offset; if (trackOffset > _this.trackWidth) { return failCode; } var t = _this.trackWidth - trackOffset; // 策略为找到剩余空间最大的轨道进行插入 if (t > max) { idx = index; max = t; } }); return idx; }; RollingCommander.prototype.extractDanmu = function () { var isAdded; for (var i = 0; i < this.waitingQueue.length;) { isAdded = this.add(this.waitingQueue[i]); // 若有一次无法添加成功,说明无轨道可用,终止剩余弹幕的 add 尝试 if (!isAdded) { break; } this.waitingQueue.shift(); } }; RollingCommander.prototype.render = function () { var _this = this; this.extractDanmu(); var objToElm = this.objToElm; var trackHeight = this.trackHeight; this.each(function (track, trackIdx) { var shouldRemove = false; var removeIndex = -1; track.each(function (danmu, danmuIdx) { if (!objToElm.has(danmu)) { return; } if (danmu.static) { return; } var danmuDom = objToElm.get(danmu); var offset = danmu.offset; danmuDom.style.transform = "translate(" + offset + "px, " + trackIdx * trackHeight + "px)"; // 每一帧后弹幕的偏移量都会减少 speed 大小的距离 danmu.offset -= danmu.speed; if (danmu.offset < 0 && Math.abs(danmu.offset) > danmu.width) { shouldRemove = true; removeIndex = danmuIdx; } }); track.updateOffset(); if (shouldRemove) { _this.removeElementFromTrack(track, removeIndex); track.remove(removeIndex); } }); }; RollingCommander.prototype.removeElementFromTrack = function (track, removedIdx) { var danmu = track.danmus[removedIdx]; if (!danmu) { return; } var danmuDom = this.objToElm.get(danmu); this.objToElm.delete(danmu); this.elmToObj.delete(danmuDom); this.removeElement(danmuDom); }; return RollingCommander; }(BaseRolling)); export default RollingCommander; //# sourceMappingURL=rolling.js.map