◆少前百科是非盈利性、非官方的少女前线维基百科。
◆如果您发现某些内容错误/空缺,请勇于修正/添加!参与进来其实很容易!点这里 加入少前百科
◆有任何意见、建议、纠错,欢迎在 GFwiki:反馈与建议 提出和讨论。编辑事务讨论QQ群:597764980,微博@GFwiki少前百科
◆To foreigners,You can use twitter to contact us.
Icon Nyto Silver.png

Widget:AvgPlayer

来自少前百科GFwiki
跳转至: 导航搜索

<template id="end-tpl">

回放结束

</template>

<template id="bgm-tpl"><audio controls preload loop style="display: none;"></audio></template> <template id="se-tpl"><audio class="avgsound" controls preload style="display: none;"></audio></template>

<template id="pic-tpl">

</template> <template id="log-tpl">

</template>

<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.21/lodash.min.js"></script> <script> var charPicDict = {}, bgDict = {}, bgmDict = {}, seDict = {}; const urlDicts = new Map([

 ['DOLL', charPicDict], ['BGCG', bgDict], ['BGM', bgmDict], ['SE', seDict]

]); var avgParser, imgInUse, ongoingScene, shotNum, lineNum; const endTpl = document.getElementById('end-tpl').content.children[0],

 bgmTpl = document.getElementById('bgm-tpl').content.children[0],
 seTpl = document.getElementById('se-tpl').content.children[0],
 picTpl = document.getElementById('pic-tpl').content.children[0];

let readingLine = false; let handleAvgClickEvent, clearStageOuter; let volumeInput, speedInput;

function fetchResUrl(res) {

 return new Promise(function(resolve, reject) {
   fetch('/index.php?title=JSON:AVG' + res + '&action=raw').then(function(response) {
     return response.text();
   }).then(function(resolved) {
     let obj = JSON.parse(resolved.replace(/\/\*\s{1,4}\d{1,4}\s{1,4}\*\//g, ).replace(',\n}', '\n}'));
     Object.assign(urlDicts.get(res), obj);
   }).then(() => { resolve(true); }).catch(e => {console.log(e);});
 });

}

function playerMain(modules) {

 (async function() {
   await Promise.all([fetchResUrl('BGCG'), fetchResUrl('BGM'), fetchResUrl('SE'), getPicPrefabs()]).then(function(results) {
     if (results.every(r => r)) {
       handleAvgClickEvent = modules[0].throttledAvgClickEventHandler;
       clearStageOuter = modules[0].clearStage;
       avgParser = new modules[1].default();
       document.querySelectorAll('.avgchoice').forEach(e => e.addEventListener('click', startPlay));
       
       let volumeControl = document.createElement('label');
       volumeInput = document.createElement('input');
       volumeInput.type = 'range';
       volumeInput.min = 0;
       volumeInput.max = 15;
       volumeInput.value = 10;
       volumeInput.addEventListener('input', function() {
         this.nextSibling.nodeValue = this.value*10 + '%';
         for (const audio of document.querySelectorAll('#avgbgm, .main-bgm, .avgsound')) {
           audio.volume = 0.5*this.value/10;
         }
       });
       volumeControl.append('音量:', volumeInput, '100%');
       document.getElementById('avgdiv').insertAdjacentElement('beforebegin', volumeControl);
       
       let speedLabel = document.createElement('label');
       speedLabel.htmlFor = 'avgspeedinput';
       speedLabel.textContent = 'X\u2009' + 1;
       speedInput = document.createElement('input');
       speedInput.id = 'avgspeedinput';
       speedInput.type = 'range';
       speedInput.min = 1;
       speedInput.max = 10;
       speedInput.value = 1;
       speedInput.addEventListener('input', function() {
         this.labels[0].textContent = 'X\u2009' + this.value;
       });
       document.getElementById('avgspeed').append(speedLabel, speedInput);
     }
   });
 })();

}

var getPrefabPath;

function getPicPrefabs() {

 return new Promise(function(resolve, reject) {
   mw.loader.using('ext.gadget.md5hasher').then(function() {
     getPrefabPath = function(code) {
       const prefab = 'AVG_Pic_' + code + '.txt';
       return '/images/' + window.gfUtils.createWikiPathPart(prefab) + '/' + prefab;
     };
   }).then(function() {
     const prefabcodes = [0, 2, 3, 4, 5, 6, 7, 8, 9].concat([...Array(26)].map((_, i) => String.fromCharCode(i + 97)));
     Promise.all([...prefabcodes.map(c => fetch(getPrefabPath(c)))])
     .then(results => Promise.all(results.map(r => r.json())))
     .then(jsons => jsons.reduce((acc, cur) => Object.assign(acc, cur)))
     .then(alljson => { Object.assign(urlDicts.get('DOLL'), alljson); })
     .then(() => { resolve(true); }).catch(e => {console.log(e);});
   });
 });

}

function startPlay() {

 const playUrl = this.getAttribute('link');
 fetch(playUrl).then(function(response) {
   return response.text();
 }).then(function(script) {
   avgParser.setScript(script);
   return avgParser.parse();
 }).then(function(scene) {
   console.log(scene);
   if (ongoingScene) {
     clearStageOuter();
   }
   ongoingScene = scene;
   imgInUse = new Map();
   shotNum = -1;
   lineNum = 0;
   for (const shot of ongoingScene) {
     if (shot.chars?.pics) {
       for (const pic of shot.chars.pics) {
         if (pic.file && !imgInUse.get(pic.file)) {
           let img = new Image();
           img.src = pic.file;
           imgInUse.set(pic.file, img);
         }
       }
     }
   }
   if (window.pauseMainBgm) {
     window.pauseMainBgm();
   }
   avgbox.addEventListener('click', handleAvgClickEvent);
 }).catch(error => console.error(error));

}

Promise.all([

 import('/index.php?title=Widget:AvgPlayer/player.js&action=raw&ctype=text/javascript'),
 import('/index.php?title=Widget:AvgPlayer/parser.js&action=raw&ctype=text/javascript')

]).then(playerMain); </script>