打开/关闭菜单
26
6675
46
1.2万
OGAS数据中枢
打开/关闭外观设置菜单
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。

Widget:GF立绘切换:修订间差异

来自OGAS数据中枢
弃权者留言 | 贡献
创建页面,内容为“<!-- Widget:GF立绘切换 参数(由模板传入,Widget 扩展用 {{{param}}} 语法接收): 立绘1~5 图片文件名(含扩展名) 立绘1说明~5 标签文字 页面 SUBPAGENAME,用于隔离同页多个 infobox 的 id --> <style> .gf-sw{width:100%;display:flex;flex-direction:column;} .gf-sw-slides{width:100%;position:relative;} .gf-sw-slide{display:none;flex-direction:column;align-items:center;width:100%;} .gf-sw-…”
 
弃权者留言 | 贡献
无编辑摘要
(未显示同一用户的39个中间版本)
第1行: 第1行:
<!--
<script type="text/javascript">
  Widget:GF立绘切换
  参数(由模板传入,Widget 扩展用 {{{param}}} 语法接收):
    立绘1~5      图片文件名(含扩展名)
    立绘1说明~5  标签文字
    页面        SUBPAGENAME,用于隔离同页多个 infobox 的 id
-->
<style>
.gf-sw{width:100%;display:flex;flex-direction:column;}
.gf-sw-slides{width:100%;position:relative;}
.gf-sw-slide{display:none;flex-direction:column;align-items:center;width:100%;}
.gf-sw-slide.gf-active{display:flex;}
.gf-sw-slide img{width:100%;height:auto;display:block;}
.gf-sw-tabs{display:flex;flex-wrap:wrap;border-top:1px solid #c8ccd1;background:#f8f9fa;}
.gf-sw-tab{flex:1 1 0;min-width:0;padding:5px 3px;font-size:.82em;text-align:center;cursor:pointer;border:none;border-right:1px solid #c8ccd1;background:transparent;color:#202122;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background .12s;}
.gf-sw-tab:last-child{border-right:none;}
.gf-sw-tab:hover{background:#eaecf0;}
.gf-sw-tab.gf-active{background:#fff;color:#3366cc;font-weight:bold;box-shadow:inset 0 -2px 0 #3366cc;}
.gf-sw-missing{padding:24px 8px;text-align:center;color:#54595d;font-size:.9em;line-height:1.8;}
</style>


<div class="gf-sw" id="gf-sw-{{{页面}}}">
(function () {
  <div class="gf-sw-slides">
    var bgList = [
    <!-- 有立绘才渲染对应 slide,文件名由 MediaWiki 解析后传入 -->
        { name: "图鉴背景", file: "图鉴背景.jpg" },
    {{{立绘1|__MISSING__}}}<!--SPLITHERE-->
        { name: "默认背景", file: "默认背景.jpg" },
    {{{立绘2|}}}<!--SPLITHERE-->
        { name: "临时作战室", file: "临时作战室.jpg" },
    {{{立绘3|}}}<!--SPLITHERE-->
        { name: "荒街涂鸦", file: "荒街涂鸦.jpg" },
    {{{立绘4|}}}<!--SPLITHERE-->
        { name: "旧日都市", file: "旧日都市.jpg" },
    {{{立绘5|}}}<!--SPLITHERE-->
        { name: "平安夜一角", file: "平安夜一角.jpg" },
    {{{立绘1说明|常态}}}<!--SPLITHERE-->
        { name: "平安夜小屋", file: "平安夜小屋.jpg" },
    {{{立绘2说明|立绘2}}}<!--SPLITHERE-->
        { name: "春节酒吧", file: "春节酒吧.jpg" },
    {{{立绘3说明|立绘3}}}<!--SPLITHERE-->
        { name: "教堂", file: "教堂.jpg" },
    {{{立绘4说明|立绘4}}}<!--SPLITHERE-->
        { name: "温馨咖啡厅", file: "温馨咖啡厅.jpg" },
    {{{立绘5说明|立绘5}}}<!--SPLITHERE-->
        { name: "花火之夏", file: "花火之夏.jpg" },
  </div>
        { name: "盛夏海滩", file: "盛夏海滩.jpg" },
</div>
        { name: "月圆人长久", file: "月圆人长久.jpg" },
        { name: "幸存者的万圣节", file: "幸存者的万圣节.jpg" },
        { name: "冬幕将至", file: "冬幕将至.jpg" },
        { name: "逢魔之刻", file: "逢魔之刻.jpg" },
        { name: "幻梦花海", file: "幻梦花海.jpg" },
        { name: "闲庭雪情", file: "闲庭雪情.jpg" },
        { name: "落暮之城", file: "落暮之城.jpg" },
        { name: "夕晖湖畔", file: "夕晖湖畔.jpg" },
        { name: "星夜之庭", file: "星夜之庭.jpg" },
        { name: "昼光之庭", file: "昼光之庭.jpg" },
        { name: "芙洛拉花径", file: "芙洛拉花径.jpg" },
        { name: "藏身处", file: "藏身处.jpg" },
        { name: "迷幻梦境", file: "迷幻梦境.jpg" },
        { name: "风吟", file: "风吟.jpg" },
        { name: "午后静室", file: "午后静室.jpg" },
        { name: "鹫羽大厅", file: "鹫羽大厅.jpg" },
        { name: "月下庆宴", file: "月下庆宴.jpg" }
    ];


<script>
    function getImgUrl(filename, fallbackSrc, callback) {
(function(){
        var api = (window.mw && mw.Api) ? new mw.Api() : null;
  var wrap = document.currentScript.previousElementSibling;
        if (api) {
  // Widget 扩展把参数直接渲染进 HTML,我们用注释分隔符拆出来
            api.get({
  var raw = wrap.querySelector('.gf-sw-slides').innerHTML;
                action: 'query',
  var parts = raw.split('<!--SPLITHERE-->').map(function(s){ return s.trim(); });
                prop: 'imageinfo',
  // parts[0..4] = 立绘1..5 文件名(MediaWiki 已将 [[Image:X]] 渲染成 <img>,
                titles: 'File:' + filename,
  //  但这里传的是纯文件名,需要我们自己构造 wiki 图片 URL)
                iiprop: 'url'
  // ── 注意:Widget 里无法用 [[Image:]] 语法,文件名要拼 URL ──
            }).done(function (data) {
  // gf-ogas.wiki 的图片路径规则与标准 MediaWiki 相同:
                var pages = data.query.pages;
  //  /wiki/Special:FilePath/文件名
                for (var id in pages) {
  var files  = parts.slice(0,5);
                    if (pages[id].imageinfo) {
  var labels = parts.slice(5,10);
                        callback(pages[id].imageinfo[0].url);
                        return;
                    }
                }
                fallback();
            }).fail(fallback);
        } else {
            fallback();
        }


  var slides = wrap.querySelector('.gf-sw-slides');
        function fallback() {
  var validSlides = [];
            if (!fallbackSrc) { callback(null); return; }
  slides.innerHTML = '';


  files.forEach(function(fname, i){
            callback('/wiki/Special:FilePath/' + encodeURIComponent(filename));
    fname = fname.replace(/<!--.*?-->/g,'').trim();
         }
    if(!fname || fname === '__MISSING__'){
      if(i === 0){
         slides.innerHTML = '<div class="gf-sw-missing">啊嘞?!<br/>怎么回事<br/>这个妹子怎么没有头的样子……</div>';
      }
      return;
     }
     }
    var div = document.createElement('div');
    div.className = 'gf-sw-slide' + (validSlides.length === 0 ? ' gf-active' : '');
    var img = document.createElement('img');
    img.src = '/wiki/Special:FilePath/' + encodeURIComponent(fname);
    img.alt = labels[i] || fname;
    img.style.width = '100%';
    div.appendChild(img);
    slides.appendChild(div);
    validSlides.push({el: div, label: labels[i] || ('立绘' + (i+1))});
  });


  // 只有多张时才渲染标签栏
    function switchImage(container, filename, onDone) {
  if(validSlides.length <= 1) return;
        container.classList.add('loading');
        var mainWrap = container.querySelector('.gf-main-img');
        var oldImg = container.querySelector('img');
        var fallback = oldImg ? oldImg.src : null;


  var tabBar = document.createElement('div');
        getImgUrl(filename, fallback, function (url) {
  tabBar.className = 'gf-sw-tabs';
            if (!url) { container.classList.remove('loading'); if (onDone) onDone(); return; }
  validSlides.forEach(function(item, i){
 
     var btn = document.createElement('button');
            var preload = new Image();
     btn.className = 'gf-sw-tab' + (i === 0 ? ' gf-active' : '');
            preload.onload = function () {
    btn.textContent = item.label;
                if (mainWrap) {
    btn.addEventListener('click', function(){
                    mainWrap.innerHTML = '';
      validSlides.forEach(function(s, j){
                    var img = document.createElement('img');
        s.el.classList.toggle('gf-active', j === i);
                    img.src = url;
      });
                    mainWrap.appendChild(img);
      tabBar.querySelectorAll('.gf-sw-tab').forEach(function(b, j){
                } else {
        b.classList.toggle('gf-active', j === i);
                    mainWrap = document.createElement('div');
      });
                    mainWrap.className = 'gf-main-img';
     });
                    var img = document.createElement('img');
     tabBar.appendChild(btn);
                    img.src = url;
  });
                    mainWrap.appendChild(img);
  wrap.appendChild(tabBar);
                    container.insertBefore(mainWrap, container.firstChild);
                }
                container.classList.remove('loading');
                if (onDone) onDone();
            };
            preload.onerror = function () {
                container.classList.remove('loading');
                if (onDone) onDone();
            };
            preload.src = url;
        });
     }
 
    function initBox(box) {
        if (box.dataset.ready) return;
        box.dataset.ready = '1';
 
        var leftPanel  = box.querySelector('.gf-left-panel');
        var container  = box.querySelector('.gf-image-container');
        var overlay     = box.querySelector('.gf-switcher-overlay');
        var toggle      = box.querySelector('.gf-switcher-toggle');
        var viewBtn    = box.querySelector('.gf-view-original');
        var groupBtns  = box.querySelectorAll('.gf-group-btn');
        var variantLists= box.querySelectorAll('.gf-variant-list');
 
        var selector = document.createElement('select');
        selector.className = 'gf-bg-selector';
        bgList.forEach(function (bg) {
            var opt = document.createElement('option');
            opt.value = '/wiki/Special:FilePath/' + encodeURIComponent(bg.file);
            opt.innerText = bg.name;
            selector.appendChild(opt);
        });
        container.appendChild(selector);
        selector.onclick  = function (e) { e.stopPropagation(); };
        selector.onchange = function () {
            leftPanel.style.backgroundImage = "url('" + this.value + "')";
        };
 
        if (toggle) {
            toggle.onclick = function () { overlay.classList.toggle('collapsed'); };
        }
 
        function getActiveVariant() {
            return box.querySelector('.gf-switch-btn.active');
        }
 
        groupBtns.forEach(function (gbtn) {
            gbtn.onclick = function () {
                var gid = gbtn.dataset.group;
 
                groupBtns.forEach(function (b) { b.classList.remove('active'); });
                gbtn.classList.add('active');
 
                variantLists.forEach(function (vl) {
                    if (vl.dataset.group === gid) {
                        vl.classList.remove('collapsed');
                    } else {
                        vl.classList.add('collapsed');
                    }
                });
 
                var targetList = box.querySelector('.gf-variant-list[data-group="' + gid + '"]');
                if (!targetList) return;
                var firstBtn = targetList.querySelector('.gf-switch-btn');
                if (!firstBtn) return;
 
                box.querySelectorAll('.gf-switch-btn').forEach(function (b) { b.classList.remove('active'); });
                firstBtn.classList.add('active');
 
                switchImage(container, firstBtn.dataset.filename);
            };
        });
 
        box.querySelectorAll('.gf-switch-btn').forEach(function (vbtn) {
            vbtn.onclick = function (e) {
                e.stopPropagation();
                if (vbtn.classList.contains('active')) return;
 
                box.querySelectorAll('.gf-switch-btn').forEach(function (b) { b.classList.remove('active'); });
                vbtn.classList.add('active');
 
                switchImage(container, vbtn.dataset.filename);
            };
        });
 
        if (viewBtn) {
            viewBtn.onclick = function (e) {
                e.stopPropagation();
                var active = getActiveVariant();
                if (!active) return;
                var filename = active.dataset.filename;
                if (window.mw) {
                    window.open(
                        mw.config.get('wgArticlePath').replace('$1', 'File:' + filename),
                        '_blank'
                    );
                }
            };
        }
    }
 
    function injectStyles() {
        var style = document.createElement('style');
        style.textContent = [
            '.gf-switcher-list::-webkit-scrollbar { display: none; }',
            '.gf-switcher-list { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; }'
        ].join('\n');
        document.head.appendChild(style);
     }
 
    function initAll() {
        injectStyles();
        document.querySelectorAll('.gf-infobox-new').forEach(initBox);
    }
 
    var tries = 0;
     var timer = setInterval(function () {
        tries++;
        if (window.mw && mw.loader && mw.loader.using) {
            clearInterval(timer);
            mw.loader.using(['mediawiki.api']).then(initAll);
        } else if (tries > 60) {
            clearInterval(timer);
            initAll();
        }
    }, 100);
})();
})();
</script>
</script>

2026年5月16日 (六) 15:06的版本

<script type="text/javascript">

(function () {

   var bgList = [
       { name: "图鉴背景", file: "图鉴背景.jpg" },
       { name: "默认背景", file: "默认背景.jpg" },
       { name: "临时作战室", file: "临时作战室.jpg" },
       { name: "荒街涂鸦", file: "荒街涂鸦.jpg" },
       { name: "旧日都市", file: "旧日都市.jpg" },
       { name: "平安夜一角", file: "平安夜一角.jpg" },
       { name: "平安夜小屋", file: "平安夜小屋.jpg" },
       { name: "春节酒吧", file: "春节酒吧.jpg" },
       { name: "教堂", file: "教堂.jpg" },
       { name: "温馨咖啡厅", file: "温馨咖啡厅.jpg" },
       { name: "花火之夏", file: "花火之夏.jpg" },
       { name: "盛夏海滩", file: "盛夏海滩.jpg" },
       { name: "月圆人长久", file: "月圆人长久.jpg" },
       { name: "幸存者的万圣节", file: "幸存者的万圣节.jpg" },
       { name: "冬幕将至", file: "冬幕将至.jpg" },
       { name: "逢魔之刻", file: "逢魔之刻.jpg" },
       { name: "幻梦花海", file: "幻梦花海.jpg" },
       { name: "闲庭雪情", file: "闲庭雪情.jpg" },
       { name: "落暮之城", file: "落暮之城.jpg" },
       { name: "夕晖湖畔", file: "夕晖湖畔.jpg" },
       { name: "星夜之庭", file: "星夜之庭.jpg" },
       { name: "昼光之庭", file: "昼光之庭.jpg" },
       { name: "芙洛拉花径", file: "芙洛拉花径.jpg" },
       { name: "藏身处", file: "藏身处.jpg" },
       { name: "迷幻梦境", file: "迷幻梦境.jpg" },
       { name: "风吟", file: "风吟.jpg" },
       { name: "午后静室", file: "午后静室.jpg" },
       { name: "鹫羽大厅", file: "鹫羽大厅.jpg" },
       { name: "月下庆宴", file: "月下庆宴.jpg" }
   ];
   function getImgUrl(filename, fallbackSrc, callback) {
       var api = (window.mw && mw.Api) ? new mw.Api() : null;
       if (api) {
           api.get({
               action: 'query',
               prop: 'imageinfo',
               titles: 'File:' + filename,
               iiprop: 'url'
           }).done(function (data) {
               var pages = data.query.pages;
               for (var id in pages) {
                   if (pages[id].imageinfo) {
                       callback(pages[id].imageinfo[0].url);
                       return;
                   }
               }
               fallback();
           }).fail(fallback);
       } else {
           fallback();
       }
       function fallback() {
           if (!fallbackSrc) { callback(null); return; }
           callback('/wiki/Special:FilePath/' + encodeURIComponent(filename));
       }
   }
   function switchImage(container, filename, onDone) {
       container.classList.add('loading');
       var mainWrap = container.querySelector('.gf-main-img');
       var oldImg = container.querySelector('img');
       var fallback = oldImg ? oldImg.src : null;
       getImgUrl(filename, fallback, function (url) {
           if (!url) { container.classList.remove('loading'); if (onDone) onDone(); return; }
           var preload = new Image();
           preload.onload = function () {
               if (mainWrap) {
                   mainWrap.innerHTML = ;
                   var img = document.createElement('img');
                   img.src = url;
                   mainWrap.appendChild(img);
               } else {
                   mainWrap = document.createElement('div');
                   mainWrap.className = 'gf-main-img';
                   var img = document.createElement('img');
                   img.src = url;
                   mainWrap.appendChild(img);
                   container.insertBefore(mainWrap, container.firstChild);
               }
               container.classList.remove('loading');
               if (onDone) onDone();
           };
           preload.onerror = function () {
               container.classList.remove('loading');
               if (onDone) onDone();
           };
           preload.src = url;
       });
   }
   function initBox(box) {
       if (box.dataset.ready) return;
       box.dataset.ready = '1';
       var leftPanel   = box.querySelector('.gf-left-panel');
       var container   = box.querySelector('.gf-image-container');
       var overlay     = box.querySelector('.gf-switcher-overlay');
       var toggle      = box.querySelector('.gf-switcher-toggle');
       var viewBtn     = box.querySelector('.gf-view-original');
       var groupBtns   = box.querySelectorAll('.gf-group-btn');
       var variantLists= box.querySelectorAll('.gf-variant-list');
       var selector = document.createElement('select');
       selector.className = 'gf-bg-selector';
       bgList.forEach(function (bg) {
           var opt = document.createElement('option');
           opt.value = '/wiki/Special:FilePath/' + encodeURIComponent(bg.file);
           opt.innerText = bg.name;
           selector.appendChild(opt);
       });
       container.appendChild(selector);
       selector.onclick  = function (e) { e.stopPropagation(); };
       selector.onchange = function () {
           leftPanel.style.backgroundImage = "url('" + this.value + "')";
       };
       if (toggle) {
           toggle.onclick = function () { overlay.classList.toggle('collapsed'); };
       }
       function getActiveVariant() {
           return box.querySelector('.gf-switch-btn.active');
       }
       groupBtns.forEach(function (gbtn) {
           gbtn.onclick = function () {
               var gid = gbtn.dataset.group;
               groupBtns.forEach(function (b) { b.classList.remove('active'); });
               gbtn.classList.add('active');
               variantLists.forEach(function (vl) {
                   if (vl.dataset.group === gid) {
                       vl.classList.remove('collapsed');
                   } else {
                       vl.classList.add('collapsed');
                   }
               });
               var targetList = box.querySelector('.gf-variant-list[data-group="' + gid + '"]');
               if (!targetList) return;
               var firstBtn = targetList.querySelector('.gf-switch-btn');
               if (!firstBtn) return;
               box.querySelectorAll('.gf-switch-btn').forEach(function (b) { b.classList.remove('active'); });
               firstBtn.classList.add('active');
               switchImage(container, firstBtn.dataset.filename);
           };
       });
       box.querySelectorAll('.gf-switch-btn').forEach(function (vbtn) {
           vbtn.onclick = function (e) {
               e.stopPropagation();
               if (vbtn.classList.contains('active')) return;
               box.querySelectorAll('.gf-switch-btn').forEach(function (b) { b.classList.remove('active'); });
               vbtn.classList.add('active');
               switchImage(container, vbtn.dataset.filename);
           };
       });
       if (viewBtn) {
           viewBtn.onclick = function (e) {
               e.stopPropagation();
               var active = getActiveVariant();
               if (!active) return;
               var filename = active.dataset.filename;
               if (window.mw) {
                   window.open(
                       mw.config.get('wgArticlePath').replace('$1', 'File:' + filename),
                       '_blank'
                   );
               }
           };
       }
   }
   function injectStyles() {
       var style = document.createElement('style');
       style.textContent = [
           '.gf-switcher-list::-webkit-scrollbar { display: none; }',
           '.gf-switcher-list { scrollbar-width: none; -ms-overflow-style: none; -webkit-overflow-scrolling: touch; }'
       ].join('\n');
       document.head.appendChild(style);
   }
   function initAll() {
       injectStyles();
       document.querySelectorAll('.gf-infobox-new').forEach(initBox);
   }
   var tries = 0;
   var timer = setInterval(function () {
       tries++;
       if (window.mw && mw.loader && mw.loader.using) {
           clearInterval(timer);
           mw.loader.using(['mediawiki.api']).then(initAll);
       } else if (tries > 60) {
           clearInterval(timer);
           initAll();
       }
   }, 100);

})(); </script>