◆少前百科是非盈利性、非官方的少女前线维基百科。 ◆如果您发现某些内容错误/空缺,请勇于修正/添加!参与进来其实很容易!点这里 加入少前百科。 ◆有任何意见、建议、纠错,欢迎在 GFwiki:反馈与建议 提出和讨论。编辑事务讨论QQ群:597764980,微博@GFwiki少前百科 ◆To foreigners,You can use twitter to contact us. |
“Widget:AvgPlayer/player.js”的版本间的差异
第432行: | 第432行: | ||
logDiv.children[0].textContent = curShot.chars?.speaker || ''; | logDiv.children[0].textContent = curShot.chars?.speaker || ''; | ||
let logLine = document.createElement('p'); | let logLine = document.createElement('p'); | ||
− | + | logLine.innerHTML = curShot.lines[lineNum]; | |
− | |||
− | |||
logLine.replaceChildren(logLine.textContent); | logLine.replaceChildren(logLine.textContent); | ||
logDiv.children[1].appendChild(logLine); | logDiv.children[1].appendChild(logLine); | ||
第445行: | 第443行: | ||
} else { | } else { | ||
let logLine = document.createElement('p'); | let logLine = document.createElement('p'); | ||
− | + | logLine.innerHTML = curShot.lines[lineNum]; | |
− | |||
− | |||
logLine.replaceChildren(logLine.textContent); | logLine.replaceChildren(logLine.textContent); | ||
logFragment.lastElementChild.children[1].appendChild(logLine); | logFragment.lastElementChild.children[1].appendChild(logLine); |
2023年10月9日 (一) 00:27的版本
const avgdiv = document.getElementById('avgdiv');
const avgbox = avgdiv.querySelector('#avgbox');
const avgbg = avgbox.querySelector('#avgbackground'),
avgword = avgbox.querySelector('#avgword'),
avgspeaker = avgbox.querySelector('#avgspeaker'),
avgline = avgbox.querySelector('#avgline'),
optionList = avgbox.querySelector('#avgbranchdiv'),
avgblack = avgbox.querySelector('#avgblack'),
avglog = avgbox.querySelector('#avglog'),
avgauto = avgbox.querySelector('#avgauto'),
avghideui = avgbox.querySelector('#avghideui');
avgblack.addEventListener('transitionend', regulateClickAccess);
const logBox = avgword.cloneNode(true);
logBox.id = 'avglogbox';
logBox.children[0].id = '';
logBox.children[1].id = '';
const xAnchors = new Map([
[1, ['50']],
[2, ['35', '65']]
]);
const blackTypes = new Map([[1, 'black'], [-1, 'white'], [0, '']]);
let toEnterBlack = 0,
enteringBlack = false,
exitingBlack = false,
masks = new Set(),
newMasks = new Set(),
removingMasks = false,
logOpen = false,
autoPlay = false,
interrupt = false,
atTag = false,
charId = 0;
let logFragment = document.createDocumentFragment();
const logTpl = document.getElementById('log-tpl').content.children[0];
function readLine() {
const wholeHTML = ongoingScene[shotNum].lines[lineNum];
const html = interrupt ? wholeHTML : wholeHTML.slice(0, ++charId);
if (html == ongoingScene[shotNum].lines[lineNum]) {
interrupt = false;
readingLine = false;
charId = 0;
if (autoPlay) {
setTimeout(() => avgbox.click(), 2000);
}
return;
}
avgline.innerHTML = html;
const char = html.slice(-1);
if (char === '<') {
atTag = true;
} else if (char === '>') {
atTag = false;
}
if (atTag) {
return readLine();
}
setTimeout(readLine, 25);
}
function speak(curShot) {
avgspeaker.textContent = curShot.chars?.speaker || '';
avgword.style.visibility = curShot.lines[lineNum]?.length ? null : 'hidden';
readingLine = true;
readLine();
}
function removePic(e) {
e.style.transform = 'translate(-53%,-50%)';
e.style.opacity = 0;
setTimeout(() => e.remove(), 300);
}
function addPic(e) {
setTimeout(() => {
e.style.transform = null;
e.style.opacity = 1;
}, 5);
}
function arrangeChars(chars) {
const prevPics = avgbox.querySelectorAll('.avgdollpic');
const currPics = chars?.pics?.map(e => e.code);
if (!currPics?.length) {
prevPics.forEach(removePic);
} else {
const done = currPics.map(e => false);
prevPics.forEach(e => {
const i = currPics.indexOf(e.getAttribute('name-data'));
if (i == -1) {
removePic(e);
} else if (chars.pics[i].position) {
const xAnchor = xAnchors.get(currPics.length)[i];
e.style.left = `calc(${xAnchor}% + ${chars.pics[i].position[0]*0.625}px)`;
e.style.top = `calc(50% = ${chars.pics[i].position[1]*0.625}px)`;
if (!chars.allDark && i == chars.speakerIndex) {
e.classList.add('speakerPic');
} else {
e.classList.remove('speakerPic');
}
done[i] = true;
} else {
e.style.left = xAnchors.get(currPics.length)[i] + '%';
e.style.top = '50%';
if (!chars.allDark && i == chars.speakerIndex) {
e.classList.add('speakerPic');
} else {
e.classList.remove('speakerPic');
}
done[i] = true;
}
});
chars.pics.forEach((pic, i) => {
if (!pic.file) {
return;
}
if (!done[i]) {
const dollpic = picTpl.cloneNode(true);
dollpic.children[1].src = pic.file;
if (!chars.allDark && i == chars.speakerIndex) {
dollpic.classList.add('speakerPic');
}
if (chars.teles?.includes(i)) {
dollpic.classList.add('tele');
}
dollpic.setAttribute('name-data', pic.code);
dollpic.style.opacity = 0;
dollpic.style.transform = 'translate(-53%,-50%)';
const xAnchor = xAnchors.get(currPics.length)[i];
if (pic.position) {
dollpic.style.left = `calc(${xAnchor}% + ${pic.position[0]*0.625}px)`;
dollpic.style.top = `calc(50% - ${pic.position[1]*0.625}px)`;
} else {
dollpic.style.left = xAnchor + '%';
dollpic.style.top = '50%';
}
addPic(avgbox.appendChild(dollpic));
}
});
}
}
function applyEffects(effects) {
let narrator = false;
newMasks.clear();
for (const effect of effects) {
switch (effect.tagName) {
case 'bin':
const bgcg = new Image();
bgcg.src = bgDict[effect.content];
avgbg.replaceChildren(bgcg);
break;
case 'bgm':
let avgbgm = document.getElementById('avgbgm');
if (effect.content == 'BGM_Empty') {
document.getElementById('avgbgm')?.remove();
} else {
if (!avgbgm) {
avgbgm = bgmTpl.cloneNode();
avgbgm.id = 'avgbgm';
avgdiv.appendChild(avgbgm);
}
avgbgm.addEventListener('error', function() {
console.error(`Error ${this.error.code}; details: ${this.error.message}`, shotNum, effect.content);
})
avgbgm.volume = 0.5*volumeInput.value/10;
avgbgm.src = bgmDict[effect.content] || '/images/' + window.gfUtils.createWikiPathPart(effect.content+'.mp3') + '/' + effect.content+'.mp3';
avgbgm.play().catch(error => console.error(error));
}
break;
case 'narrator':
narrator = true;
break;
case 'se':
case 'se1':
case 'se2':
case 'se3':
const avgse = seTpl.cloneNode();
avgse.addEventListener('error', function() {
console.error(`Error ${this.error.code}; details: ${this.error.message}`, shotNum, effect.content);
});
avgse.volume = 0.5*volumeInput.value/10;
avgse.src = seDict[effect.content] || '/images/' + window.gfUtils.createWikiPathPart(effect.content+'.mp3') + '/' + effect.content+'.mp3';
avgse.addEventListener('ended', function() {this.remove();});
avgdiv.appendChild(avgse);
avgse.play();
break;
case '黑屏1':
case '黑点1':
toEnterBlack = 1;
break;
case '黑屏2':
case '黑点2':
case '睁眼':
break;
case '白屏1':
toEnterBlack = -1;
break;
case '白屏2':
break;
case '回忆':
masks.add('memory');
newMasks.add('memory');
break;
case '关闭蒙版':
removingMasks = true;
break;
}
}
if (narrator != avgword.classList.contains('narrator')) {
if (toEnterBlack) {
setTimeout(() => avgword.classList.toggle('narrator'), 1000);
} else {
avgword.classList.toggle('narrator');
}
}
}
function handleAvgClickEvent(event) {
let curShot = ongoingScene[shotNum];
switch (event.target.id) {
case 'avglog':
event.stopPropagation();
if (readingLine) {
readingLine = false;
}
if (avgword.classList.contains('narrator')) {
if (logOpen) {
logBox.children[1].replaceChildren();
logBox.className = '';
setTimeout(() => {
logBox.style.opacity = 0;
avgcontrol.className = '';
}, 167);
setTimeout(() => {
logBox.remove();
logOpen = false;
if (autoPlay) {
setTimeout(() => avgbox.click(), 1000);
}
}, 375);
} else {
avgword.insertAdjacentElement('afterend', logBox);
setTimeout(() => {
logBox.style.opacity = 1;
logBox.className = 'log';
}, 5);
avgcontrol.className = 'log';
logOpen = true;
setTimeout(() => {
logBox.children[1].append(logFragment.cloneNode(true));
}, 380);
}
} else {
avgspeaker.replaceChildren();
avgline.replaceChildren();
if (logOpen) {
avgword.classList.remove('log');
setTimeout(() => {
avgcontrol.className = '';
avgspeaker.textContent = curShot.chars?.speaker || '';
avgline.innerHTML = curShot.lines[lineNum];
logOpen = false;
if (autoPlay) {
setTimeout(() => {avgbox.click();}, 1000);
}
}, 375);
} else {
avgword.classList.add('log');
avgcontrol.className = 'log';
logOpen = true;
setTimeout(() => {
avgline.append(logFragment.cloneNode(true));
}, 375);
}
}
break;
case 'avgauto':
event.stopPropagation();
autoPlay = !autoPlay;
avgauto.classList.toggle('on');
if (!readingLine) {
setTimeout(playShot, 1000);
}
break;
case 'avghideui':
event.stopPropagation();
avgbox.classList.add('hide');
break;
default:
if (event.target == optionList) {
event.stopPropagation();
} else if (event.target.classList.contains('avgbranch')) {
event.stopPropagation();
jumpTo(event);
} else if (enteringBlack || exitingBlack) {
event.stopPropagation();
} else if (readingLine) {
event.stopPropagation();
if (!interrupt) {
interrupt = true;
}
} else if (avgbox.classList.contains('hide')) {
event.stopPropagation();
avgbox.classList.remove('hide');
} else if (!logOpen) {
if (toEnterBlack) {
enteringBlack = true;
avgblack.classList.add(blackTypes.get(toEnterBlack));
}
playShot();
}
}
}
function regulateClickAccess() {
if (enteringBlack) {
exitingBlack = true;
avgblack.classList.remove(blackTypes.get(toEnterBlack));
enteringBlack = false;
toEnterBlack = 0;
} else if (exitingBlack) {
exitingBlack = false;
}
}
function playJumpShot(index) {
optionList.className = '';
optionList.style.display = 'none';
optionList.replaceChildren();
shotNum = index;
let curShot = ongoingScene[index];
lineNum = 0;
arrangeChars(curShot.chars);
applyEffects(curShot.effects);
if (!curShot.chars && !curShot.lines[0].length) {
return setTimeout(playShot, 1000);
}
avgspeaker.textContent = curShot.chars?.speaker || '';
if (!curShot.lines[lineNum]?.length) {
avgword.style.visibility = 'hidden';
} else {
avgword.style.visibility = 'visible';
}
readingLine = true;
readLine();
}
function jumpTo(event) {
event.stopPropagation();
playJumpShot(+event.currentTarget.getAttribute('index'));
}
function clearStage() {
toEnterBlack = 0;
enteringBlack = false;
exitingBlack = false;
removingMasks = false;
masks.clear();
newMasks.clear();
readingLine = false;
autoPlay = false;
logOpen = false;
interrupt = false;
charId = 0;
avgbg.replaceChildren();
optionList.replaceChildren();
logFragment.replaceChildren();
logBox.remove();
avgdiv.querySelectorAll('.avgdollpic, audio').forEach(e => e.remove());
avgspeaker.textContent = '';
avgline.replaceChildren();
avgbox.className = '';
avgword.className = '';
avgblack.className = '';
optionList.className = '';
avgword.removeAttribute('style');
avgbox.playEnd = false;
}
function playShotMain(curShot) {
arrangeChars(curShot.chars);
applyEffects(curShot.effects);
newMasks.forEach(m => avgbox.classList.add(m));
if (removingMasks) {
masks.forEach(m => avgbox.classList.remove(m));
removingMasks = false;
masks.clear();
}
if (!lineNum && curShot.lines[lineNum]?.length) {
setTimeout(() => {
avgword.style.opacity = 1;
avgword.style.transform = null;
setTimeout(() => speak(curShot), 200);
}, 200);
} else {
speak(curShot);
}
}
function playShot() {
if (avgbox.playEnd) {
avgbox.removeEventListener('click', throttledAvgClickEventHandler);
setTimeout(() => {
if (window.canPlayMainBgm && window.resumeMainBgm) {
window.resumeMainBgm();
}
}, 2000);
clearStage();
return;
}
let curShot = ongoingScene[shotNum];
if (curShot === undefined || lineNum == curShot.lines.length - 1) {
shotNum = curShot?.exit ? curShot.exit : shotNum + 1;
curShot = ongoingScene[shotNum];
lineNum = 0;
} else lineNum++;
if (curShot === undefined) {
avgbox.playEnd = true;
return;
}
if (!lineNum) {
avgspeaker.replaceChildren();
avgline.replaceChildren();
avgword.style.opacity = 0;
if (!avgword.classList.contains('narrator')) {
avgword.style.transform = 'scaleY(0)';
}
if (curShot.lines[0].length) {
let logDiv = logTpl.cloneNode(true);
logFragment.appendChild(logDiv);
logDiv.children[0].textContent = curShot.chars?.speaker || '';
let logLine = document.createElement('p');
logLine.innerHTML = curShot.lines[lineNum];
logLine.replaceChildren(logLine.textContent);
logDiv.children[1].appendChild(logLine);
}
if (toEnterBlack) {
setTimeout(() => playShotMain(curShot), 2000);
} else {
playShotMain(curShot);
}
} else {
let logLine = document.createElement('p');
logLine.innerHTML = curShot.lines[lineNum];
logLine.replaceChildren(logLine.textContent);
logFragment.lastElementChild.children[1].appendChild(logLine);
}
if (!curShot.chars && !curShot.lines[0].length) {
setTimeout(() => {
avgbox.click();
}, 100);
} else if (lineNum) {
speak(curShot);
}
if (curShot.optionTag) {
const cg = curShot.optionTag == 'cg';
if (cg) {
optionList.classList.add('cg-options');
}
curShot.options.forEach((e, i) => {
const optionItem = document.createElement('div');
optionItem.className = 'avgbranch';
if (cg) {
const scaleRatioHalf = avgbox.getBoundingClientRect().width / 1920;
const [xoff, yoff] = e.split(',');
optionItem.style.left = `calc(50% + ${xoff*scaleRatioHalf}px)`;
optionItem.style.top = `calc(50% - ${yoff*scaleRatioHalf}px)`;
} else {
optionItem.textContent = e;
}
optionItem.setAttribute('index', curShot.entries.get(+i+1));
optionItem.addEventListener('click', jumpTo);
optionList.appendChild(optionItem);
});
optionList.style.display = 'block';
}
}
const throttledAvgClickEventHandler = _.throttle(handleAvgClickEvent, 100, { 'trailing': false });
export { throttledAvgClickEventHandler, clearStage };