Mediawiki:common.js
| Строка 2218: | Строка 2218: | ||
$('.roles-container').hide(); | $('.roles-container').hide(); | ||
updateVisibility(); | updateVisibility(); | ||
} | |||
}; | |||
var AprilFoolsCubeTransitionModule = { | |||
overlay: null, | |||
clockTimer: null, | |||
audioContext: null, | |||
audioReady: false, | |||
started: false, | |||
// === БЫСТРЫЕ ПЕРЕКЛЮЧАТЕЛИ === | |||
// Сейчас: только ?prank=1 | |||
ENABLE_BY_FLAG: true, | |||
ENABLE_FOR_ALL_ON_APRIL_FIRST: false, | |||
ENABLE_FOR_ALL_ALWAYS: false, | |||
// ============================ | |||
init: function () { | |||
if (this.started) return; | |||
this.started = true; | |||
if (!window.mw || !mw.config || !mw.config.get('wgIsMainPage')) { | |||
return; | |||
} | |||
if (!this.shouldRun()) { | |||
return; | |||
} | |||
// Чтобы не повторялось на каждый переход в рамках сессии | |||
if (sessionStorage.getItem('april-fools-cube-shown') === '1') { | |||
return; | |||
} | |||
sessionStorage.setItem('april-fools-cube-shown', '1'); | |||
this.injectStyles(); | |||
this.createOverlay(); | |||
this.initAudioUnlock(); | |||
var self = this; | |||
this.showOverlay(); | |||
setTimeout(function () { | |||
self.startExitTransition(); | |||
}, 6500); | |||
}, | |||
shouldRun: function () { | |||
if (this.ENABLE_FOR_ALL_ALWAYS) { | |||
return true; | |||
} | |||
if (this.ENABLE_FOR_ALL_ON_APRIL_FIRST && this.isAprilFirst()) { | |||
return true; | |||
} | |||
if (this.ENABLE_BY_FLAG && this.hasPrankFlag()) { | |||
return true; | |||
} | |||
return false; | |||
}, | |||
isAprilFirst: function () { | |||
var now = new Date(); | |||
return now.getMonth() === 3 && now.getDate() === 1; | |||
}, | |||
hasPrankFlag: function () { | |||
var params = new URLSearchParams(window.location.search); | |||
return params.get('prank') === '1'; | |||
}, | |||
injectStyles: function () { | |||
if (document.getElementById('april-fools-cube-styles')) return; | |||
var style = document.createElement('style'); | |||
style.id = 'april-fools-cube-styles'; | |||
style.textContent = | |||
'#april-fools-overlay{' + | |||
'position:fixed;' + | |||
'inset:0;' + | |||
'z-index:2147483647;' + | |||
'background:#000;' + | |||
'display:flex;' + | |||
'align-items:center;' + | |||
'justify-content:center;' + | |||
'opacity:0;' + | |||
'visibility:hidden;' + | |||
'transform:translateZ(0);' + | |||
'will-change:transform,opacity;' + | |||
'overflow:hidden;' + | |||
'}' + | |||
'#april-fools-overlay.active{' + | |||
'opacity:1;' + | |||
'visibility:visible;' + | |||
'}' + | |||
'#april-fools-overlay img{' + | |||
'width:100%;' + | |||
'height:100%;' + | |||
'object-fit:cover;' + | |||
'display:block;' + | |||
'user-select:none;' + | |||
'-webkit-user-drag:none;' + | |||
'pointer-events:none;' + | |||
'}' + | |||
'#april-fools-overlay.exiting{' + | |||
'transform-origin:left center;' + | |||
'animation:aprilCubeOut 900ms cubic-bezier(0.2,0.8,0.2,1) forwards;' + | |||
'}' + | |||
'@keyframes aprilCubeOut{' + | |||
'0%{' + | |||
'transform:perspective(1400px) rotateY(0deg) translateX(0);' + | |||
'opacity:1;' + | |||
'}' + | |||
'100%{' + | |||
'transform:perspective(1400px) rotateY(-88deg) translateX(-34vw);' + | |||
'opacity:0;' + | |||
'}' + | |||
'}'; | |||
document.head.appendChild(style); | |||
}, | |||
createOverlay: function () { | |||
var overlay = document.createElement('div'); | |||
overlay.id = 'april-fools-overlay'; | |||
var image = document.createElement('img'); | |||
image.alt = 'Wikipedia homepage'; | |||
image.src = 'https://upload.wikimedia.org/wikipedia/commons/d/d4/2019_Screenshot_of_English_Wikipedia_homepage.png'; | |||
overlay.appendChild(image); | |||
document.body.appendChild(overlay); | |||
this.overlay = overlay; | |||
}, | |||
showOverlay: function () { | |||
if (!this.overlay) return; | |||
this.overlay.classList.add('active'); | |||
}, | |||
startExitTransition: function () { | |||
if (!this.overlay) return; | |||
this.stopClockTick(); | |||
this.playCubeShiftSound(); | |||
var self = this; | |||
this.overlay.classList.add('exiting'); | |||
this.overlay.addEventListener('animationend', function handleEnd() { | |||
self.overlay.removeEventListener('animationend', handleEnd); | |||
if (self.overlay && self.overlay.parentNode) { | |||
self.overlay.parentNode.removeChild(self.overlay); | |||
} | |||
self.overlay = null; | |||
}); | |||
}, | |||
initAudioUnlock: function () { | |||
try { | |||
var Ctx = window.AudioContext || window.webkitAudioContext; | |||
if (!Ctx) return; | |||
this.audioContext = new Ctx(); | |||
} catch (e) { | |||
return; | |||
} | |||
var self = this; | |||
function unlock() { | |||
if (!self.audioContext) return; | |||
self.audioContext.resume().then(function () { | |||
self.audioReady = true; | |||
self.startClockTick(); | |||
}).catch(function () { | |||
self.audioReady = false; | |||
}); | |||
document.removeEventListener('pointerdown', unlock); | |||
document.removeEventListener('keydown', unlock); | |||
document.removeEventListener('touchstart', unlock); | |||
} | |||
document.addEventListener('pointerdown', unlock, { once: true }); | |||
document.addEventListener('keydown', unlock, { once: true }); | |||
document.addEventListener('touchstart', unlock, { once: true }); | |||
if (this.audioContext.state === 'running') { | |||
this.audioReady = true; | |||
this.startClockTick(); | |||
} | |||
}, | |||
startClockTick: function () { | |||
if (!this.audioContext || !this.audioReady || this.clockTimer) return; | |||
var self = this; | |||
function tick() { | |||
self.playTick(); | |||
} | |||
tick(); | |||
this.clockTimer = setInterval(tick, 1000); | |||
}, | |||
stopClockTick: function () { | |||
if (this.clockTimer) { | |||
clearInterval(this.clockTimer); | |||
this.clockTimer = null; | |||
} | |||
}, | |||
playTick: function () { | |||
if (!this.audioContext || this.audioContext.state !== 'running') return; | |||
var t = this.audioContext.currentTime; | |||
var osc = this.audioContext.createOscillator(); | |||
var gain = this.audioContext.createGain(); | |||
var hp = this.audioContext.createBiquadFilter(); | |||
hp.type = 'highpass'; | |||
hp.frequency.value = 900; | |||
osc.type = 'square'; | |||
osc.frequency.setValueAtTime(1400, t); | |||
gain.gain.setValueAtTime(0.0001, t); | |||
gain.gain.exponentialRampToValueAtTime(0.08, t + 0.002); | |||
gain.gain.exponentialRampToValueAtTime(0.0001, t + 0.035); | |||
osc.connect(hp); | |||
hp.connect(gain); | |||
gain.connect(this.audioContext.destination); | |||
osc.start(t); | |||
osc.stop(t + 0.04); | |||
}, | |||
playCubeShiftSound: function () { | |||
if (!this.audioContext || this.audioContext.state !== 'running') return; | |||
var t = this.audioContext.currentTime; | |||
var osc = this.audioContext.createOscillator(); | |||
var gain = this.audioContext.createGain(); | |||
var lp = this.audioContext.createBiquadFilter(); | |||
lp.type = 'lowpass'; | |||
lp.frequency.setValueAtTime(1200, t); | |||
lp.frequency.exponentialRampToValueAtTime(220, t + 0.45); | |||
osc.type = 'sawtooth'; | |||
osc.frequency.setValueAtTime(380, t); | |||
osc.frequency.exponentialRampToValueAtTime(90, t + 0.45); | |||
gain.gain.setValueAtTime(0.0001, t); | |||
gain.gain.exponentialRampToValueAtTime(0.18, t + 0.02); | |||
gain.gain.exponentialRampToValueAtTime(0.0001, t + 0.5); | |||
osc.connect(lp); | |||
lp.connect(gain); | |||
gain.connect(this.audioContext.destination); | |||
osc.start(t); | |||
osc.stop(t + 0.52); | |||
} | } | ||
}; | }; | ||
| Строка 2231: | Строка 2499: | ||
// FireworksModule.init(); | // FireworksModule.init(); | ||
// LawCalculatorModule.init(); | // LawCalculatorModule.init(); | ||
EquipmentFilterModule.init() | EquipmentFilterModule.init(); | ||
AprilFoolsCubeTransitionModule.init(); | |||
} | } | ||