diff --git a/views/archive/ruffle/demo/index.css b/views/archive/ruffle/demo/index.css new file mode 100644 index 00000000..b05c67c1 --- /dev/null +++ b/views/archive/ruffle/demo/index.css @@ -0,0 +1,131 @@ +body { + position: absolute; + top: 0; + left: 0; + margin: 0; + padding: 0; + width: 100%; + height: 100%; + font-family: "Lato", sans-serif; + display: flex; + flex-direction: column; + align-items: center; + background-color: black; +} + +#main { + width: 100%; + height: 100%; + align-self: center; + max-height: calc(100vh - 70px); +} + +#container { + height: calc(100vh - 70px); + width: 100vw; +} + +#player { + width: 100%; + height: 100%; + display: block; +} + +#nav { + width: 100%; + background: #37528c; + border: 0; + border-color: darkgray; + border-bottom: 2px #37528c; + border-style: solid; + box-shadow: 0 5px 5px #37528c; + display: flex; + flex-direction: row; + justify-content: space-around; + align-items: center; + align-self: flex-start; + color: white; + min-height: 45px; + margin-bottom: 15px; +} + +#title { + transition-duration: 0.5s; +} + +#title:hover { + opacity: 0.5; + cursor: pointer; +} + +#title img { + display: inline-block; + height: 32px; + margin-top: 5px; +} + +#file-picker { + margin-top: 7px; +} + +#file-picker select, +#file-picker input { + margin: 0 5px; +} + +#local-file-container { + display: inline-block; + vertical-align: middle; +} + +#sample-swfs-container { + display: none; + vertical-align: middle; +} + +#author-container { + display: none; + font-size: 13px; + text-align: left; +} + +#author { + padding-left: 5px; + color: #ffad33; +} + +@media only screen and (max-width: 800px) { + #local-file-container, + #sample-swfs-container { + display: block; + } + + #nav { + min-height: 65px; + } + + #player { + height: calc(100vh - 90px) !important; + } +} + +@media only screen and (max-width: 600px) { + #local-file-container { + display: none; + } + + #sample-swfs-label { + display: none; + } + + #author-container { + font-size: 12px; + text-align: center; + } + + #nav { + min-height: 85px; + flex-direction: column; + padding-bottom: 2px; + } +} diff --git a/views/archive/ruffle/demo/index.html b/views/archive/ruffle/demo/index.html new file mode 100644 index 00000000..40d4fb09 --- /dev/null +++ b/views/archive/ruffle/demo/index.html @@ -0,0 +1,43 @@ + + + + + + + Ruffle Web Demo + + + + + +
+ + + diff --git a/views/archive/ruffle/demo/index.js b/views/archive/ruffle/demo/index.js new file mode 100644 index 00000000..a5dfd6cf --- /dev/null +++ b/views/archive/ruffle/demo/index.js @@ -0,0 +1,113 @@ +import "./index.css"; + +const { SourceAPI, PublicAPI } = require("ruffle-core"); + +window.RufflePlayer = PublicAPI.negotiate( + window.RufflePlayer, + "local", + new SourceAPI("local") +); + +let ruffle; +let player; + +const container = document.getElementById("main"); +const authorContainer = document.getElementById("author-container"); +const author = document.getElementById("author"); +const sampleFileInputContainer = document.getElementById( + "sample-swfs-container" +); +const sampleFileInput = document.getElementById("sample-swfs"); +const localFileInput = document.getElementById("local-file"); +const animOptGroup = document.getElementById("anim-optgroup"); +const gamesOptGroup = document.getElementById("games-optgroup"); + +// Default config used by the player. +const config = { + letterbox: "on", + logLevel: "warn", +}; + +window.addEventListener("DOMContentLoaded", async () => { + ruffle = window.RufflePlayer.newest(); + player = ruffle.createPlayer(); + player.id = "player"; + container.append(player); + + const response = await fetch("swfs.json"); + if (!response.ok) { + sampleFileInputContainer.style.display = "none"; + return; + } + + const data = await response.json(); + for (const swfData of data.swfs) { + const option = document.createElement("option"); + option.textContent = swfData.title; + option.value = swfData.location; + option.swfData = swfData; + switch (swfData.type) { + case "Animation": + animOptGroup.append(option); + break; + case "Game": + gamesOptGroup.append(option); + break; + } + } + sampleFileInputContainer.style.display = "inline-block"; + + const initialFile = new URLSearchParams(window.location.search).get("file"); + if (initialFile) { + const options = Array.from(sampleFileInput.options); + sampleFileInput.selectedIndex = Math.max( + options.findIndex((swfData) => swfData.value.endsWith(initialFile)), + 0 + ); + } else { + // Load a random file. + sampleFileInput.selectedIndex = + Math.floor(Math.random() * data.swfs.length) + 1; + } + sampleFileSelected(); +}); + +sampleFileInput.addEventListener("change", sampleFileSelected); +localFileInput.addEventListener("change", localFileSelected); + +function sampleFileSelected() { + const swfData = sampleFileInput[sampleFileInput.selectedIndex].swfData; + if (swfData) { + authorContainer.style.display = "block"; + author.textContent = swfData.author; + author.href = swfData.authorLink; + localFileInput.value = null; + player.load({ url: swfData.location, ...config }); + } else { + document.getElementById("main").children[0].remove(); + player = ruffle.create_player(); + player.id = "player"; + container.append(player); + authorContainer.style.display = "none"; + author.textContent = ""; + author.href = ""; + } +} + +function localFileSelected() { + sampleFileInput.selectedIndex = 0; + authorContainer.style.display = "none"; + author.textContent = ""; + author.href = ""; + + const file = localFileInput.files[0]; + if (!file) { + return; + } + + const reader = new FileReader(); + reader.onload = () => { + player.load({ data: reader.result, ...config }); + }; + reader.readAsArrayBuffer(file); +}