Files
presentation-html/assets/app.js
T

42 lines
3.4 KiB
JavaScript

(() => {
const {animate, createTimeline, stagger} = anime;
const reduced = matchMedia('(prefers-reduced-motion: reduce)');
const printMode = location.search.includes('print-pdf');
const seen = new Set(); let active = []; let motion = !reduced.matches;
const motionButton = document.querySelector('#motion');
function settle() {
active.forEach(a => { a.complete(); }); active = [];
document.querySelectorAll('[data-motion]').forEach(e => {e.style.opacity='1';e.style.transform='none';});
}
function run() {
settle(); const slide=Reveal.getCurrentSlide();
if (!slide || seen.has(slide.id) || !motion || reduced.matches || printMode) return;
seen.add(slide.id); const targets=slide.querySelectorAll('[data-motion]');
if (!targets.length) return;
if(slide.id==='sequence') {
const tl=createTimeline({defaults:{duration:300,ease:'outCubic'}});
targets.forEach((e,i)=>tl.add(e,{opacity:[0,1],translateY:[12,0]},i*180));active.push(tl);
} else active.push(animate(targets,{opacity:[0,1],translateY:[12,0],delay:stagger(70),duration:400,ease:'outCubic'}));
}
function motionLabel(){motionButton.textContent=motion&&!reduced.matches?'Motion on':'Motion off';motionButton.setAttribute('aria-pressed',String(motion&&!reduced.matches));}
motionButton.onclick=()=>{motion=!motion;settle();motionLabel();};
reduced.addEventListener('change',()=>{if(reduced.matches)settle();motionLabel();});motionLabel();
addEventListener('beforeprint',settle);
const fs=document.querySelector('#fullscreen');
async function fullscreen(){try{if(document.fullscreenElement)await document.exitFullscreen();else await document.documentElement.requestFullscreen();}catch{fs.textContent='Fullscreen unavailable';}}
fs.onclick=fullscreen;
document.addEventListener('fullscreenchange',()=>{fs.textContent=document.fullscreenElement?'Exit fullscreen':'Enter fullscreen';fs.setAttribute('aria-pressed',String(!!document.fullscreenElement));});
document.addEventListener('keydown',e=>{if(e.key.toLowerCase()==='f'&&!e.ctrlKey&&!e.metaKey&&!e.altKey&&!e.target.matches('input,textarea,[contenteditable]')){e.preventDefault();e.stopPropagation();fullscreen();}},true);
document.querySelectorAll('[data-node]').forEach(node=>{
function select(){const was=node.getAttribute('aria-pressed')==='true';document.querySelectorAll('[data-node]').forEach(n=>n.setAttribute('aria-pressed','false'));node.setAttribute('aria-pressed',String(!was));document.querySelector('#detail').textContent=was?'Select a source to reveal its role. Tab + Enter or Space also works.':node.dataset.detail;}
node.addEventListener('click',select);
node.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();e.stopPropagation();select();}});
});
Reveal.initialize({width:1240,height:700,margin:.08,center:false,hash:true,transition:'none',backgroundTransition:'none',slideNumber:'c/t',view:'slide',keyboard:{70:null},autoAnimate:false}).then(()=>{
if(!location.hash){try{const i=Number(localStorage.getItem('presentation-html-demo-slide'));if(Number.isInteger(i)&&i>=0&&i<Reveal.getTotalSlides())Reveal.slide(i);}catch{}}
run(); window.deckReady=true;
});
Reveal.on('slidechanged',()=>{try{localStorage.setItem('presentation-html-demo-slide',String(Reveal.getIndices().h));}catch{}run();});
window.presentationQA={settle,reduced:()=>reduced.matches,active:()=>active.filter(a=>!a.completed).length};
})();