Files
ArtPlayer/packages/artplayer-plugin-danmuku/src/getDanmuTop.js
T
2019-05-09 21:18:12 +08:00

105 lines
3.0 KiB
JavaScript

import { getRect } from './utils';
function calculatedTop(danmus) {
let top = 0;
const topMap = {};
for (let index = 0; index < danmus.length; index += 1) {
const item = danmus[index];
if (topMap[item.top]) {
topMap[item.top].push(item);
} else {
topMap[item.top] = [item];
}
}
const topMapKeys = Object.keys(topMap);
let maxDiff = 0;
for (let index = 1; index < danmus.length; index += 1) {
const item = danmus[index];
const prev = danmus[index - 1];
const prevTop = prev.top + prev.height;
const diff = item.top - prevTop;
if (diff > maxDiff) {
top = prevTop;
maxDiff = diff;
}
}
if (top === 0) {
let maxRight = 0;
for (let index = 0; index < topMapKeys.length; index += 1) {
let minRight = danmus[0].width;
const topKey = topMapKeys[index];
const danmuArr = topMap[topKey];
for (let index = 0; index < danmuArr.length; index += 1) {
const danmu = danmuArr[index];
if (danmu.right < minRight) {
minRight = danmu.right;
}
}
if (minRight > maxRight) {
maxRight = minRight;
[{ top }] = danmuArr;
}
}
}
if (top === 0) {
[top] = topMapKeys
.filter((item, index) => {
return index !== 0 && index !== topMapKeys.length - 1;
})
.sort((prev, next) => {
return topMap[prev].length - topMap[next].length;
});
}
return top;
}
export default function getDanmuTop(ins, danmu) {
const [marginTop, marginBottom] = ins.option.margin;
const playerData = getRect(ins.art.template.$player);
const danmus = ins.queue
.filter(
item =>
item.mode === danmu.mode &&
item.$state === 'emit' &&
item.$ref &&
item.$ref.style.fontSize === danmu.$ref.style.fontSize &&
parseFloat(item.$ref.style.top) <= playerData.height - marginBottom,
)
.map(item => {
const danmuData = getRect(item.$ref);
const { width, height } = danmuData;
const top = danmuData.top - playerData.top;
const left = danmuData.left - playerData.left;
const right = playerData.width - left - width;
return { top, left, height, width, right };
})
.sort((prev, next) => prev.top - next.top);
if (danmus.length === 0) {
return marginTop;
}
danmus.unshift({
top: 0,
left: 0,
right: 0,
height: marginTop,
width: playerData.width,
});
danmus.push({
top: playerData.height - marginBottom,
left: 0,
right: 0,
height: marginBottom,
width: playerData.width,
});
return calculatedTop(danmus);
}