mirror of
https://github.com/JeremyLikness/vanillajs-deck
synced 2025-12-16 11:14:18 +00:00
Initial pass at structure
This commit is contained in:
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;
|
||||
}
|
||||
Reference in New Issue
Block a user