Widget:Flipflop
<style>
article.flipflop-book-instance { display: flex; flex-wrap: nowrap; justify-content: space-between; align-items: center; height: 150px; border-bottom: 1px solid grey; padding: 10px 0 10px 0; } article.flipflop-book-instance:first-of-type { border-top: 1px solid grey; } /* The Modal (background) */ .modal { display: none; /* Hidden by default */ position: fixed; /* Stay in place */ z-index: 1; /* Sit on top */ left: 0; top: 0; width: 100%; /* Full width */ height: 100%; /* Full height */ overflow: auto; /* Enable scroll if needed */ background-color: rgb(0,0,0); /* Fallback color */ background-color: rgba(0,0,0,0.4); /* Black w/ opacity */ }
/* Modal Content/Box */ .modal-content { background-color: #fefefe; margin: 15% auto; /* 15% from the top and centered */ padding: 20px; border: 1px solid #888; width: 80%; /* Could be more or less, depending on screen size */ }
/* The Close Button */ .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; }
.close:hover, .close:focus { color: black; text-decoration: none; cursor: pointer; }
</style>
<script type="text/javascript"> var flipflopBooks = [
// Flick 1 [ { textLeft: "äng", videoUrl: "/images/finssl_flipflop/1_1.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/1_1.png", }, { textLeft: "dal", videoUrl: "/images/finssl_flipflop/1_2.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/1_2.png", }, { textLeft: "backe", videoUrl: "/images/finssl_flipflop/1_3.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/1_3.png", }, { textLeft: "väg", videoUrl: "/images/finssl_flipflop/1_4.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/1_4.png", }, { textLeft: "moln", videoUrl: "/images/finssl_flipflop/1_5.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/1_5.png", }, { textLeft: "skog", videoUrl: "/images/finssl_flipflop/1_6.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/1_6.png", }, { textLeft: "hav", videoUrl: "/images/finssl_flipflop/1_7.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/1_7.png", }, ], // Flick 2 [ { textLeft: "ko", videoUrl: "/images/finssl_flipflop/2_1.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/2_1.png", }, { textLeft: "räv", videoUrl: "/images/finssl_flipflop/2_2.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/2_2.png", }, { textLeft: "älg", videoUrl: "/images/finssl_flipflop/2_3.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/2_3.png", }, { textLeft: "gris", videoUrl: "/images/finssl_flipflop/2_4.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/2_4.png", }, { textLeft: "elefant", videoUrl: "/images/finssl_flipflop/2_5.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/2_5.png", }, { textLeft: "hare", videoUrl: "/images/finssl_flipflop/2_6.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/2_6.png", }, { textLeft: "dinosaurie", videoUrl: "/images/finssl_flipflop/2_7.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/2_7.png", }, ], // Flick 3 [ { textLeft: "cykla", videoUrl: "/images/finssl_flipflop/3_1.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/3_1.png", }, { textLeft: "åka rullbräda", videoUrl: "/images/finssl_flipflop/3_2.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/3_2.png", }, { textLeft: "åka pulka", videoUrl: "/images/finssl_flipflop/3_3.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/3_3.png", }, { textLeft: "köra bil", videoUrl: "/images/finssl_flipflop/3_4.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/3_4.png", }, { textLeft: "flyga", videoUrl: "/images/finssl_flipflop/3_5.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/3_5.png", }, { textLeft: "skrinna", videoUrl: "/images/finssl_flipflop/3_6.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/3_6.png", }, { textLeft: "köra båt", videoUrl: "/images/finssl_flipflop/3_7.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/3_7.png", }, ], // Flick 4 [ { textLeft: "slott", videoUrl: "/images/finssl_flipflop/4_1.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/4_1.png", }, { textLeft: "väderkvarn", videoUrl: "/images/finssl_flipflop/4_2.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/4_2.png", }, { textLeft: "lada", videoUrl: "/images/finssl_flipflop/4_3.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/4_3.png", }, { textLeft: "hus", videoUrl: "/images/finssl_flipflop/4_4.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/4_4.png", }, { textLeft: "fyr", videoUrl: "/images/finssl_flipflop/4_5.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/4_5.png", }, { textLeft: "tält", videoUrl: "/images/finssl_flipflop/4_6.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/4_6.png", }, { textLeft: "fängelse", videoUrl: "/images/finssl_flipflop/4_7.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/4_7.png", }, ], // Flick 5 [ { textLeft: "groda", videoUrl: "/images/finssl_flipflop/5_1.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/5_1.png", }, { textLeft: "hund", videoUrl: "/images/finssl_flipflop/5_2.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/5_2.png", }, { textLeft: "apa", videoUrl: "/images/finssl_flipflop/5_3.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/5_3.png", }, { textLeft: "katt", videoUrl: "/images/finssl_flipflop/5_4.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/5_4.png", }, { textLeft: "mus", videoUrl: "/images/finssl_flipflop/5_5.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/5_5.png", }, { textLeft: "björn", videoUrl: "/images/finssl_flipflop/5_6.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/5_6.png", }, { textLeft: "spindel", videoUrl: "/images/finssl_flipflop/5_7.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/5_7.png", }, ], // Flick 6 [ { textLeft: "läsa", videoUrl: "/images/finssl_flipflop/6_1.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/6_1.png", }, { textLeft: "diska", videoUrl: "/images/finssl_flipflop/6_2.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/6_2.png", }, { textLeft: "måla", videoUrl: "/images/finssl_flipflop/6_3.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/6_3.png", }, { textLeft: "baka", videoUrl: "/images/finssl_flipflop/6_4.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/6_4.png", }, { textLeft: "sticka", videoUrl: "/images/finssl_flipflop/6_5.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/6_5.png", }, { textLeft: "bygga", videoUrl: "/images/finssl_flipflop/6_6.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/6_6.png", }, { textLeft: "sy", videoUrl: "/images/finssl_flipflop/6_7.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/6_7.png", }, ], // Flick 7 [ { textLeft: "prata", videoUrl: "/images/finssl_flipflop/7_1.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/7_1.png", }, { textLeft: "tälva", videoUrl: "/images/finssl_flipflop/7_2.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/7_2.png", }, { textLeft: "titta", videoUrl: "/images/finssl_flipflop/7_3.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/7_3.png", }, { textLeft: "pussas", videoUrl: "/images/finssl_flipflop/7_4.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/7_4.png", }, { textLeft: "spela", videoUrl: "/images/finssl_flipflop/7_5.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/7_5.png", }, { textLeft: "dansa", videoUrl: "/images/finssl_flipflop/7_6.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/7_6.png", }, { textLeft: "bråka", videoUrl: "/images/finssl_flipflop/7_7.mp4", videoType: "video/mp4", imageLeft: "/images/finssl_flipflop/7_7.png", }, ]
]
/**
* Initializes the state of the books, state holds e.g. current page * @param {Array} books * @param {Array} bookState */
function initState(books, bookState) {
books.forEach((el, i) => bookState.push({ bookIndex: i, currentPageIndex: 0, currentPageEl: el[0] }))
}
// Root element used to append other elements to const rootElement = document.querySelector("div#flipflopapp")
var bookState = []; // Initialize book state to start from zero for each book in the flipflopBook array. initState(flipflopBooks, bookState)
/**
* Gives the next possible index in book. * If the index is below zero, give the highest index (indicating going backwards). * If the index is past length of book, give zero (indicating going forwards). * @param {Integer} desiredIndex The index to switch to, if possible * @param {Object} book The book object of pages */
function getNextOrPrevPageIndex(desiredIndex, book) {
if (book[desiredIndex]) return desiredIndex if (desiredIndex < 0) return book.length - 1 if (desiredIndex >= book.length) return 0 return 0
}
/**
* Switches the page within the book the page belongs to * @param {Integer} direction Indicate the direction to switch pages, 1 or -1 * @param {Object} page Page object that holds indexes and element of book */
function switchPage(direction = 1, page) {
const book = flipflopBooks[page.bookIndex] const desiredPageIndex = page.currentPageIndex + direction const newCurrentPageIndex = getNextOrPrevPageIndex(desiredPageIndex, book) bookState[page.bookIndex].currentPageIndex = newCurrentPageIndex const newCurrentPageEl = book[newCurrentPageIndex] bookState[page.bookIndex].currentPageEl = newCurrentPageEl return bookState[page.bookIndex]
}
/**
* Replaces an article DOM Element with a new one * @param {Object} newPage * @param {Element} oldArticle */
function replacePageArticleDOM(newPage, oldArticle) {
const newArticle = getBookPageDOM(newPage) oldArticle.parentNode.replaceChild(newArticle, oldArticle)
}
/**
* Set the first video in the DOM Video Element */
function setVideo(video, bookId) {
const currentBookEl = bookState[bookId].currentPageEl video.setAttribute("src", currentBookEl.videoUrl) video.setAttribute("type", currentBookEl.videoType)
}
/**
* Creates the DOM for a book. * Used to initialize and to update the book page. * @param {Object} page */
function getBookPageDOM(page) {
const article = document.createElement("article") article.id = `flipflop-book-${page.bookIndex}` article.classList.add("flipflop-book-instance") const leftBtn = document.createElement("button") leftBtn.textContent = "←" leftBtn.style.cssText = "height:100%;" const rightBtn = document.createElement("button") rightBtn.textContent = "→" rightBtn.style.cssText = "height:100%;" const leftImg = document.createElement("img") leftImg.src = page.currentPageEl.imageLeft leftImg.style.cssText = "height:100%; width:auto; max-height:150px;" const leftText = document.createElement("span") leftText.textContent = page.currentPageEl.textLeft const playBtn = document.createElement("button") playBtn.textContent = "▶ Spela video" playBtn.style.cssText = "height:100%; width:auto; max-height:150px;" playBtn.className = "playBtn" playBtn.onclick = function () { setVideo(video, page.bookIndex) modal.style.display = "block"; // Override mediawiki default style bodyContent.style.zIndex = "unset"; }
article.appendChild(leftBtn) article.appendChild(leftImg) article.appendChild(leftText) article.appendChild(playBtn) article.appendChild(rightBtn) leftBtn.addEventListener("click", () => { // Switch page backwards in state const newPage = switchPage(-1, page) // Replace old DOM element with new replacePageArticleDOM(newPage, article) }) rightBtn.addEventListener("click", () => { console.log(page) // Switch page forwards in state const newPage = switchPage(1, page) // Replace old DOM element with new replacePageArticleDOM(newPage, article) }) return article
}
/**
* Appends the DOM Elements to the root DOM Element * @param {Array} bookState * @param {Element} rootElement * @param {Element} video Video Element */
function initializeElements(bookState, rootElement, video) {
bookState.forEach((page) => { const article = getBookPageDOM(page) rootElement.appendChild(article) })
} // Get the video player element from DOM const video = document.querySelector("video#flipflop");
// Fill in the DOM Elements for the App initializeElements(bookState, rootElement, video)
// Event listener on when video starts playing video.onplay = (video) => {
console.log("Playing a video:", video)
}
// Get the modal var modal = document.getElementById("playModal");
// Get the element that closes the modal var span = document.getElementsByClassName("close")[0];
// When the user clicks on (x), close the modal span.onclick = function () {
modal.style.display = "none"; // Restore mediawiki default style bodyContent.style.zIndex = 0;
}
// When the user clicks anywhere outside of the modal, close it window.onclick = function (event) {
if (event.target == modal) { modal.style.display = "none"; // Restore mediawiki default style bodyContent.style.zIndex = 0; }
} </script>