diff --git a/index.html b/index.html index e675e00..5ac9da6 100644 --- a/index.html +++ b/index.html @@ -5,12 +5,32 @@ Janus Presentation Framework - + +

Janus Presentations

Hotkey powered, multi-window presentations

-
Press Page Down to continue.
+
+ Press Escape for commands. Page Up / Page Down to navigate. +

Hotkeys

@@ -24,7 +44,7 @@ Toggle Presenter Mode: F1
-
+

Self-scaling cover images with object-fit

@@ -47,7 +67,7 @@

The end.

- + diff --git a/scripts/shortcut.js b/libs/openjs-shortcut/shortcut.js similarity index 100% rename from scripts/shortcut.js rename to libs/openjs-shortcut/shortcut.js diff --git a/scripts/app.js b/scripts/app.js index 8e07faf..17fe629 100644 --- a/scripts/app.js +++ b/scripts/app.js @@ -4,7 +4,10 @@ var slides = [], currentSlideNumber = 0, slideNext, - slidePrev; + slidePrev, + commandBar, + commandField, + commandBarVisible = true; function $(selector) { return document.querySelector(selector); @@ -13,11 +16,13 @@ return Array.prototype.slice.call(document.querySelectorAll(selector), 0); } - function setCurrentSlide(newSlideNumber) { + function setCurrentSlide(newSlideNumber, storeChange) { newSlideNumber = Math.max(Math.min(newSlideNumber, slides.length - 1), 0); if (newSlideNumber !== currentSlideNumber) { currentSlideNumber = newSlideNumber; - localStorage.setItem('janus-currentSlideNumber', currentSlideNumber); + if (storeChange) { + localStorage.setItem('janus-currentSlideNumber', currentSlideNumber); + } } slides.forEach(function (item, index, array) { if (index < currentSlideNumber) { @@ -35,15 +40,65 @@ } var sessionListener = function(e) { - console.log(e); if (e.url === window.location.href) { if (e.key === 'janus-currentSlideNumber') { - setCurrentSlide(+e.newValue); + setCurrentSlide(+e.newValue, false); } } }; + var toggleCommandBar = function() { + if (commandBarVisible) { + commandBar.style.display = 'none'; + commandBarVisible = false; + } else { + commandBar.style.display = 'flex'; + commandField.value = ''; + commandField.focus(); + commandBarVisible = true; + } + } + + var commandListener = function(event) { + var typed = String.fromCharCode(event.keyCode).toLowerCase(); + console.log(event); + console.log(typed); + if (/[0-9]/.test(typed)) { + return; + } else if (event.keyCode === 13) { + runCommand(commandField.value); + toggleCommandBar(); + } else if (/[spc]/.test(typed)) { + runCommand(commandField.value + typed); + toggleCommandBar(); + } + }; + + var runCommand = function(command) { + var s = command.split(); + if (s.length === 1 && /^[0-9]+$/.test(s[0])) { + setCurrentSlide(+s[0], true); + } else if (s.length === 1) { + switch(s[0]) { + case 's': + document.body.classList.toggle('simulate-projection'); + break; + case 'p': + document.body.classList.toggle('show-notes'); + break; + case 'c': + window.open(window.location.href, '_blank'); + break; + } + } + } + var init = function() { + commandField = $('#commandField'); + commandField.addEventListener('keydown', commandListener); + commandBar = $('body > nav'); + toggleCommandBar(); + slides = $$('main>section, [janus-timeline]'); currentSlideNumber = 0; shortcut.add('F1', function() { @@ -53,17 +108,19 @@ window.open(window.location.href, '_blank'); }); shortcut.add('Page_down', function() { - setCurrentSlide(currentSlideNumber + 1); + setCurrentSlide(currentSlideNumber + 1, true); }); shortcut.add('Page_up', function() { - setCurrentSlide(currentSlideNumber - 1); + setCurrentSlide(currentSlideNumber - 1, true); }); + shortcut.add('Escape', toggleCommandBar); var storedSlideNumber; if (storedSlideNumber = localStorage.getItem('janus-currentSlideNumber')) { - setCurrentSlide(storedSlideNumber); + setCurrentSlide(storedSlideNumber, false); } else { setCurrentSlide(0); } + document.body.classList.remove('is-loading'); }; document.addEventListener('DOMContentLoaded', init); diff --git a/styles/main.css b/styles/main.css index fafbbb3..f44b35b 100644 --- a/styles/main.css +++ b/styles/main.css @@ -8,7 +8,6 @@ :root { box-sizing: border-box; - line-height: 1.5; font-family: sans-serif; font-size: calc(2vw + 2em); } @@ -24,6 +23,10 @@ code { h1 { font-size: 1.5rem; + position: relative; + margin: 0 -10vw; + padding: 0 10vw 0.1em; + background-color: rgba(255, 255, 255, 0.2); } h2 { font-size: 1rem; @@ -43,6 +46,25 @@ body { overflow: hidden; } +body.is-loading:after { + content: 'Loading...'; + font-size: 0.5em; + line-height: 100vh; + color: white; + background-image: linear-gradient(45deg, #030, #000, #003); + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + text-align: center; + z-index: 100; +} + +body.simulate-projection { + filter: brightness(1.5) contrast(0.65); +} + main { margin-top: 0; perspective: 100vmin; @@ -51,6 +73,51 @@ main { } /* Components */ +nav { + flex-wrap: wrap; + display: flex; + position: fixed; + top: 0; + left: 0; + right: 0; + padding: 0.25em 0.25em 4em; + transition: transform ease 0.5s; + font-size: 0.5rem; + z-index: 2; + background-image: linear-gradient(to top, hsla(0, 0%, 0%, 0), hsla(0, 0%, 0%, 0.5)); +} + +nav > label { + flex: 0 0 auto; + padding-right: 1ch; +} + +nav > input { + flex: 1 1 auto; + padding: 0; + font-size: inherit; + border: none; + background: transparent; + color: inherit; +} + +nav > input:invalid { + color: red; +} + +ul.help { + width: 100%; + flex-shrink: 0; + font-size: 0.5em; +} + +ul.help li { + display: inline-block; + background-color: hsla(0, 0%, 100%, 0.2); + border-radius: 0.5em; + padding: 0 0.5em; +} + section { position: absolute; z-index: 1; @@ -68,6 +135,12 @@ section { transform-origin: 50% 50%; } +/* +section > * { + transform: rotate(-7deg); +} +*/ + [janus-timeline='past'] { transition: transform ease-in 0.5s, opacity ease-in 0.5s, visibility step-end 0.5s; } @@ -76,10 +149,8 @@ section { transition: transform ease-out 0.5s, opacity ease-out 0.5s, visibility step-start 0.5s; } -@media not print { - [janus-timeline='future'] { - visibility: hidden; - } +[janus-timeline='future'] { + visibility: hidden; } body.show-notes section [janus-timeline='future'] { @@ -119,6 +190,7 @@ img.cover { width: 100%; object-fit: cover; z-index: -1; + transform: none; } body.show-notes section {