mirror of
https://github.com/JeremyLikness/vanillajs-deck
synced 2024-11-13 00:54:57 +00:00
Initial pass at structure
This commit is contained in:
commit
3ef6273404
47
css/style.css
Normal file
47
css/style.css
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
body {
|
||||||
|
padding: 5px;
|
||||||
|
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3 {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
max-width: 100%;
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#main {
|
||||||
|
height: 80vh;
|
||||||
|
padding: 1em;
|
||||||
|
background: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#footer-left {
|
||||||
|
vertical-align: middle;
|
||||||
|
height: 15vh;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#footer-left img {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
div#footer-right {
|
||||||
|
font-size: 2em;
|
||||||
|
height: 15vh;
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextslide {
|
||||||
|
display: none;
|
||||||
|
}
|
BIN
images/devnexus.png
Normal file
BIN
images/devnexus.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.7 KiB |
BIN
images/logo.png
Normal file
BIN
images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
30
index.html
Normal file
30
index.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en-us">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<title>Vanilla.js</title>
|
||||||
|
<base href="/" target="_blank">
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta name="description" content="DevNexus presentation Vanilla.js: Modern 1st Party JavaScript">
|
||||||
|
<meta http-equiv="Content-Security-Policy"
|
||||||
|
content="default-src 'self'; child-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'self'; img-src 'self'; media-src 'self'; object-src 'none'; style-src 'self';">
|
||||||
|
<link rel="shortcut icon" href="/images/logo.png" type="image/png" />
|
||||||
|
<link rel="stylesheet" href="css/style.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<script type="module" src="./js/app.js"></script>
|
||||||
|
<div id="main">
|
||||||
|
<h1>DevNexus</h1>
|
||||||
|
<h2>We are getting things ready...</h2>
|
||||||
|
</div>
|
||||||
|
<div id="footer-left">
|
||||||
|
<img src="./images/devnexus.png" alt="DevNexus logo" title="DevNexus logo" />
|
||||||
|
</div>
|
||||||
|
<div id="footer-right">
|
||||||
|
<a href="https://twitter.com/JeremyLikness">@JeremyLikness</a>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
24
js/app.js
Normal file
24
js/app.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { getJson } from "./jsonLoader.js"
|
||||||
|
import { loadSlides } from "./slideLoader.js"
|
||||||
|
import { Navigator } from "./navigator.js"
|
||||||
|
|
||||||
|
const state = {
|
||||||
|
manifest: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
const app = async () => {
|
||||||
|
|
||||||
|
state.deck = document.getElementById("main");
|
||||||
|
|
||||||
|
// load the manifest
|
||||||
|
state.manifest = await getJson("slides/manifest.json");
|
||||||
|
|
||||||
|
// load the slides
|
||||||
|
state.slides = await loadSlides(state.manifest.start);
|
||||||
|
|
||||||
|
// initialize the navigation
|
||||||
|
state.navigator = new Navigator(state.slides, state.deck);
|
||||||
|
};
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", app);
|
||||||
|
|
4
js/jsonLoader.js
Normal file
4
js/jsonLoader.js
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export async function getJson(path) {
|
||||||
|
const response = await fetch(path);
|
||||||
|
return await response.json();
|
||||||
|
};
|
48
js/navigator.js
Normal file
48
js/navigator.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
export class Navigator {
|
||||||
|
|
||||||
|
constructor(slides, deck) {
|
||||||
|
this._deck = deck;
|
||||||
|
this._slides = slides;
|
||||||
|
this.jumpTo(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentIndex() {
|
||||||
|
return this._currentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
get currentSlide() {
|
||||||
|
return this._slides[this._currentIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
get totalSlides() {
|
||||||
|
return this._slides.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasPrevious() {
|
||||||
|
return this._currentIndex > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get hasNext() {
|
||||||
|
return this._currentIndex < (this.totalSlides - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
jumpTo(slideIdx) {
|
||||||
|
if (slideIdx >= 0 && slideIdx < this.totalSlides) {
|
||||||
|
this._currentIndex = slideIdx;
|
||||||
|
this._deck.innerHTML = '';
|
||||||
|
this._deck.appendChild(this.currentSlide.html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
next() {
|
||||||
|
if (this.hasNext) {
|
||||||
|
this.jumpTo(this.currentIndex + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
previous() {
|
||||||
|
if (this.hasPrevious) {
|
||||||
|
this.jumpTo(this.currentIndex - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
28
js/slide.js
Normal file
28
js/slide.js
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
export class Slide {
|
||||||
|
|
||||||
|
constructor(text) {
|
||||||
|
this._text = text;
|
||||||
|
this._html = document.createElement('div');
|
||||||
|
this._html.innerHTML = text;
|
||||||
|
this._title = this._html.querySelectorAll("title")[0].innerText;
|
||||||
|
const hasNext = this._html.querySelectorAll("nextslide");
|
||||||
|
if (hasNext.length > 0) {
|
||||||
|
this._nextSlideName = hasNext[0].innerText;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this._nextSlideName = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get title() {
|
||||||
|
return this._title;
|
||||||
|
}
|
||||||
|
|
||||||
|
get html() {
|
||||||
|
return this._html;
|
||||||
|
}
|
||||||
|
|
||||||
|
get nextSlide() {
|
||||||
|
return this._nextSlideName;
|
||||||
|
}
|
||||||
|
}
|
25
js/slideLoader.js
Normal file
25
js/slideLoader.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { Slide } from "./slide.js"
|
||||||
|
|
||||||
|
async function loadSlide(slideName) {
|
||||||
|
const response = await fetch(`./slides/${slideName}.html`);
|
||||||
|
const slide = await response.text();
|
||||||
|
return new Slide(slide);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function loadSlides(start) {
|
||||||
|
var next = start;
|
||||||
|
const slides = [];
|
||||||
|
const cycle = {};
|
||||||
|
while (next) {
|
||||||
|
const nextSlide = await loadSlide(next);
|
||||||
|
if (!cycle[nextSlide.title]) {
|
||||||
|
slides.push(nextSlide);
|
||||||
|
cycle[nextSlide.title] = nextSlide;
|
||||||
|
next = nextSlide.nextSlide;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return slides;
|
||||||
|
}
|
5
slides/001-title.html
Normal file
5
slides/001-title.html
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<title>Vanilla.js: Modern 1st Party JavaScript</title>
|
||||||
|
<h1>Vanilla.js: Modern 1st Party JavaScript</h1>
|
||||||
|
<h2>Jeremy Likness</h2>
|
||||||
|
<h3>Cloud Advocate, Microsoft</h3>
|
||||||
|
<nextslide>002-stuff</nextslide>
|
2
slides/002-stuff.html
Normal file
2
slides/002-stuff.html
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
<title>More Stuff</title>
|
||||||
|
<h1>More Stuff</h1>
|
4
slides/manifest.json
Normal file
4
slides/manifest.json
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"title": "Vanilla.js: Modern 1st Party JavaScript",
|
||||||
|
"start": "001-title"
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user