@qier-player/danmaku
Version:
Powerful danmaku, support many features.
156 lines • 6.17 kB
JavaScript
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