Widget:GameSwitcher:修订间差异
来自OGAS数据中枢
更多操作
无编辑摘要 |
无编辑摘要 |
||
| 第47行: | 第47行: | ||
} | } | ||
function moveIndicator( tab ) { | function moveIndicator( tab ) { | ||
var indicator = document.getElementById( 'gf-tab-indicator' ); | var indicator = document.getElementById( 'gf-tab-indicator' ); | ||
var switcher = document.getElementById( 'gf-switcher' ); | var switcher = document.getElementById( 'gf-switcher' ); | ||
if ( !indicator || !switcher ) { return; } | if ( !indicator || !switcher ) { return; } | ||
var | var sr = switcher.getBoundingClientRect(); | ||
var | var tr = tab.getBoundingClientRect(); | ||
indicator.style.width = | indicator.style.width = tr.width + 'px'; | ||
indicator.style.transform = 'translateX(' + ( | indicator.style.transform = 'translateX(' + ( tr.left - sr.left ) + 'px)'; | ||
} | } | ||
var currentGame = 'gf'; | var currentGame = 'gf'; | ||
var switching = false; | var switching = false; | ||
var pending = null; /* { game, tabEl } */ | |||
function doSwitch( game, tabEl ) { | |||
var slides = document.querySelectorAll( '#gf-homepage .gf-hero-slide' ); | var slides = document.querySelectorAll( '#gf-homepage .gf-hero-slide' ); | ||
var panels = document.querySelectorAll( '#gf-homepage .gf-content-panel' ); | var panels = document.querySelectorAll( '#gf-homepage .gf-content-panel' ); | ||
| 第72行: | 第69行: | ||
var inSlide = document.getElementById( 'hero-' + game ); | var inSlide = document.getElementById( 'hero-' + game ); | ||
/* | /* Ken Burns重置 */ | ||
if ( inSlide ) { | if ( inSlide ) { | ||
var inFg = inSlide.querySelector( '.gf-hero-fg' ); | var inFg = inSlide.querySelector( '.gf-hero-fg' ); | ||
if ( inFg ) { | if ( inFg ) { | ||
inFg.style.transition = 'none'; | inFg.style.transition = 'none'; | ||
inFg.style.transform = window.innerWidth > 1200 | inFg.style.transform = window.innerWidth > 1200 | ||
? 'translateX(-50%) scale(1.06)' | ? 'translateX(-50%) scale(1.06)' | ||
: 'scale(1.06)'; | : 'scale(1.06)'; | ||
| 第95行: | 第92行: | ||
} | } | ||
/* tab | /* tab与指示器立即响应,不等动画 */ | ||
tabs.forEach( function ( t ) { | tabs.forEach( function ( t ) { | ||
var on = t.getAttribute( 'data-game' ) === game; | var on = t.getAttribute( 'data-game' ) === game; | ||
| 第101行: | 第98行: | ||
t.setAttribute( 'aria-selected', on ? 'true' : 'false' ); | t.setAttribute( 'aria-selected', on ? 'true' : 'false' ); | ||
} ); | } ); | ||
if ( tabEl ) { moveIndicator( tabEl ); } | if ( tabEl ) { moveIndicator( tabEl ); } | ||
/* 内容面板 */ | /* 内容面板立即切换 */ | ||
panels.forEach( function ( p ) { | panels.forEach( function ( p ) { | ||
p.classList.toggle( 'active', p.id === 'content-' + game ); | p.classList.toggle( 'active', p.id === 'content-' + game ); | ||
} ); | } ); | ||
currentGame = game; | |||
switching = true; | |||
setTimeout( function () { | setTimeout( function () { | ||
slides.forEach( function ( s ) { | slides.forEach( function ( s ) { s.style.zIndex = ''; } ); | ||
switching = false; | switching = false; | ||
/* 动画结束后执行期间积压的最后一次请求 */ | |||
if ( pending && pending.game !== currentGame ) { | |||
var p = pending; | |||
pending = null; | |||
doSwitch( p.game, p.tabEl ); | |||
} else { | |||
pending = null; | |||
} | |||
}, 720 ); | }, 720 ); | ||
} | |||
function switchGame( game, tabEl ) { | |||
if ( game === currentGame ) { return; } | |||
if ( switching ) { | |||
/* 记录最新目标,覆盖之前积压的 */ | |||
pending = { game: game, tabEl: tabEl }; | |||
/* 指示器和tab状态立即跟手 */ | |||
var tabs = document.querySelectorAll( '#gf-homepage .gf-tab' ); | |||
tabs.forEach( function ( t ) { | |||
var on = t.getAttribute( 'data-game' ) === game; | |||
t.classList.toggle( 'active', on ); | |||
t.setAttribute( 'aria-selected', on ? 'true' : 'false' ); | |||
} ); | |||
if ( tabEl ) { moveIndicator( tabEl ); } | |||
return; | |||
} | |||
doSwitch( game, tabEl ); | |||
} | } | ||
| 第123行: | 第145行: | ||
if ( !tabs.length ) { return; } | if ( !tabs.length ) { return; } | ||
Object.keys( heroImages ).forEach( function ( game ) { | Object.keys( heroImages ).forEach( function ( game ) { | ||
getWikiImageUrl( heroImages[ game ], function ( url ) { | getWikiImageUrl( heroImages[ game ], function ( url ) { | ||
var bg = document.getElementById( 'hero-' + game + '-bg' ); | var bg = document.getElementById( 'hero-' + game + '-bg' ); | ||
var fg = document.getElementById( 'hero-' + game + '-fg' ); | var fg = document.getElementById( 'hero-' + game + '-fg' ); | ||
var val = 'url("' + url + '")'; | var val = 'url("' + url + '")'; | ||
if ( bg ) { bg.style.backgroundImage = val; } | if ( bg ) { bg.style.backgroundImage = val; } | ||
| 第136行: | 第157行: | ||
applyFadeColor(); | applyFadeColor(); | ||
var firstActive = document.querySelector( '#gf-homepage .gf-tab.active' ); | var firstActive = document.querySelector( '#gf-homepage .gf-tab.active' ); | ||
if ( firstActive ) { | if ( firstActive ) { | ||
setTimeout( function () { moveIndicator( firstActive ); }, 50 ); | setTimeout( function () { moveIndicator( firstActive ); }, 50 ); | ||
} | } | ||
| 第155行: | 第174行: | ||
} ); | } ); | ||
window.addEventListener( 'resize', function () { | window.addEventListener( 'resize', function () { | ||
var active = document.querySelector( '#gf-homepage .gf-tab.active' ); | var active = document.querySelector( '#gf-homepage .gf-tab.active' ); | ||
2026年6月20日 (六) 22:15的版本
本Widget为少女前线系列多游戏首页提供切换交互逻辑。
不接受参数,直接在首页调用:{{#widget:GFHomepageSwitcher}}