From b888ae67aa42b476a7b7e59cc36eedf3b745c9e6 Mon Sep 17 00:00:00 2001 From: Luca Date: Wed, 23 Dec 2020 19:37:15 +0100 Subject: [PATCH] Add 'bauchbinde' by fl0rp --- .../assets/Orbitron-VariableFont_wght.ttf | 1 + static/bauchbinde/assets/script.js | 187 +++++++++++++++ static/bauchbinde/assets/style.css | 220 ++++++++++++++++++ static/bauchbinde/index.html | 18 ++ 4 files changed, 426 insertions(+) create mode 120000 static/bauchbinde/assets/Orbitron-VariableFont_wght.ttf create mode 100644 static/bauchbinde/assets/script.js create mode 100644 static/bauchbinde/assets/style.css create mode 100644 static/bauchbinde/index.html diff --git a/static/bauchbinde/assets/Orbitron-VariableFont_wght.ttf b/static/bauchbinde/assets/Orbitron-VariableFont_wght.ttf new file mode 120000 index 0000000..3fd1aff --- /dev/null +++ b/static/bauchbinde/assets/Orbitron-VariableFont_wght.ttf @@ -0,0 +1 @@ +../../Orbitron-VariableFont_wght.ttf \ No newline at end of file diff --git a/static/bauchbinde/assets/script.js b/static/bauchbinde/assets/script.js new file mode 100644 index 0000000..be878b2 --- /dev/null +++ b/static/bauchbinde/assets/script.js @@ -0,0 +1,187 @@ +(() => { + let textEl; + let headline = 'Headline Headline,'; + let speaker = 'Speaker Speaker'; + let isIntro = false; + let holdDuration = 4000; + + function init() { + textEl = document.querySelector('.text'); + textEl.innerHTML = ''; + + if (window.location.search) { + window.location.search.slice(1).split('&').map(x => x.split('=')).forEach(([key, value]) => { + if (key === 'headline') { + headline = decodeURIComponent(value) + ','; + } + if (key === 'speaker') { + speaker = decodeURIComponent(value); + } + if (key === 'intro') { + isIntro = !!value + } + if (key === 'hold') { + holdDuration = parseInt(value); + } + }) + } + + console.debug({speaker, headline}); + + const headlineEl = document.createElement('span'); + headlineEl.classList.add('headline'); + const speakerEl = document.createElement('span'); + speakerEl.classList.add('speaker'); + + Array.from(headline).forEach(letter => { + const letterEl = document.createElement('span'); + letterEl.classList.add('letter'); + letterEl.innerText = letter; + headlineEl.appendChild(letterEl); + }) + Array.from(speaker).forEach(letter => { + const letterEl = document.createElement('span'); + letterEl.classList.add('letter'); + letterEl.innerText = letter; + speakerEl.appendChild(letterEl); + }) + + textEl.appendChild(headlineEl); + textEl.appendChild(document.createTextNode(' ')); + textEl.appendChild(speakerEl); + + const mainTilesEl = document.querySelector('.background .main-tiles'); + mainTilesEl.innerHTML = ''; + + for (let i = 0; i < 16; i++) { + const tile = document.createElement('div'); + tile.classList.add('tile', 'blue'); + mainTilesEl.appendChild(tile); + } + + const secondaryTilesEl = document.querySelector('.background .secondary-tiles'); + secondaryTilesEl.innerHTML = ''; + + for (let i = 0; i < 17; i++) { + const tile = document.createElement('div'); + tile.classList.add('tile'); + if (i === 0 || Math.random() > 0.5) { + tile.classList.add('yellow'); + } else { + tile.classList.add('green'); + } + secondaryTilesEl.appendChild(tile); + } + } + + async function animate() { + if (isIntro) { + await Promise.all([ + slideIn(), + fadeInText(), + ]); + } else { + await Promise.all([ + fadeIn(), + fadeInText(), + ]); + } + await new Promise(r => setTimeout(r, holdDuration)); + await Promise.all([ + fadeOut(), + fadeOutText(), + ]) + } + + async function slideIn() { + const tiles = document.querySelectorAll('.tile'); + + for (const tile of tiles) { + tile.style.animationName = `slide-in-${Math.floor(Math.random() * 10)}`; + tile.style.animationDelay = `${Math.random() * 0.4}s`; + tile.style.animationDuration = `${0.8 + Math.random() * 0.4}s`; + tile.style.animationIterationCount = 1; + tile.style.animationTimingFunction = 'ease-in'; + } + await new Promise(r => setTimeout(r, 600)); + for (const tile of tiles) { + tile.classList.add('visible'); + } + await new Promise(r => setTimeout(r, 1000)); + } + + async function fadeIn() { + const tiles = document.querySelectorAll('.tile'); + + for (const tile of tiles) { + tile.style.animationName = `fade-in`; + tile.style.animationDelay = `${Math.random() * 0.4}s`; + tile.style.animationDuration = `${0.8 + Math.random() * 0.4}s`; + tile.style.animationIterationCount = 1; + tile.style.animationTimingFunction = 'ease-in'; + } + await new Promise(r => setTimeout(r, 600)); + for (const tile of tiles) { + tile.classList.add('visible'); + } + await new Promise(r => setTimeout(r, 1000)); + } + + async function fadeOut() { + const tiles = document.querySelectorAll('.tile'); + + for (const tile of tiles) { + tile.style.animationName = `fade-out`; + tile.style.animationDelay = `${Math.random() * 0.4}s`; + tile.style.animationDuration = `${0.8 + Math.random() * 0.4}s`; + tile.style.animationIterationCount = 1; + tile.style.animationTimingFunction = 'ease-in'; + } + await new Promise(r => setTimeout(r, 600)); + for (const tile of tiles) { + tile.classList.remove('visible'); + } + await new Promise(r => setTimeout(r, 1000)); + } + + async function fadeInText() { + const letters = document.querySelectorAll('.letter'); + + for (const letter of letters) { + letter.style.animationName = `fade-in`; + letter.style.animationDelay = `${Math.random() * 0.4}s`; + letter.style.animationDuration = `${0.8 + Math.random() * 0.4}s`; + letter.style.animationIterationCount = 1; + letter.style.animationTimingFunction = 'ease-in'; + } + await new Promise(r => setTimeout(r, 600)); + for (const tile of letters) { + tile.classList.add('visible'); + } + await new Promise(r => setTimeout(r, 1000)); + } + + async function fadeOutText() { + const letters = document.querySelectorAll('.letter'); + + for (const letter of letters) { + letter.style.animationName = `fade-out`; + letter.style.animationDelay = `${Math.random() * 0.4}s`; + letter.style.animationDuration = `${0.8 + Math.random() * 0.4}s`; + letter.style.animationIterationCount = 1; + letter.style.animationTimingFunction = 'ease-in'; + } + await new Promise(r => setTimeout(r, 600)); + for (const tile of letters) { + tile.classList.remove('visible'); + } + await new Promise(r => setTimeout(r, 1000)); + } + + window.addEventListener('load', async () => { + init(); + await new Promise(r => setTimeout(r, 1000)); + animate(); + }); +})(); + diff --git a/static/bauchbinde/assets/style.css b/static/bauchbinde/assets/style.css new file mode 100644 index 0000000..b76f1aa --- /dev/null +++ b/static/bauchbinde/assets/style.css @@ -0,0 +1,220 @@ +@font-face { + font-family: Orbitron; + src: url('Orbitron-VariableFont_wght.ttf'); +} + +body { + margin: 0; + background-color: #000; + font-family: Orbitron, sans-serif; + font-size: 2vw; + line-height: 2vw; + color: #252826; + /*color: #0e1c23;*/ + text-transform: uppercase; + letter-spacing: 0.1vw; +} + +.headline { + font-weight: 900; +} + +.speaker { + font-size: 0.8em; +} + +.container { + position: fixed; + bottom: 9vw; + left: 12.5vw; + right: 20vw; +} + +.background { + z-index: -20; + width: 100%; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; +} + +.text { + margin-left: 6.25%; + padding: 1vw 1.5vw; +} + +.tiles { + width: 100%; + height: 100%; + display: flex; + flex-direction: row; + align-items: stretch; + justify-content: stretch; +} + +.main-tiles { + margin-left: 6.25%; + transform: translateY(-100%); +} + +.tile { + flex: 1; + position: relative; + opacity: 0; +} + +.tile::before { + content: ''; + position: absolute; + display: block; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); +} + +.tile.blue::before { + background-color: #02fae0; + width: 100%; + height: 100%; + box-shadow: 1px 0 0 0 #02fae0; +} + +.tile.yellow::before { + background-color: #fff900; + width: 50%; + padding-top: 50%; +} + +.tile.green::before { + background-color: #0bcb60; + width: 35%; + padding-top: 35%; +} + +.letter { + opacity: 0; +} + +.visible { + opacity: 1; +} + +@keyframes slide-in-0 { + 0% { + transform: translate(50vw, -100vw) scale(10); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-1 { + 0% { + transform: translate(-40vw, -20vw) scale(2); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-2 { + 0% { + transform: translate(50vw, 20vw) scale(5); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-3 { + 0% { + transform: translate(80vw, -50vw) scale(3); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-4 { + 0% { + transform: translate(-30vw, -50vw) scale(7.5); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-5 { + 0% { + transform: translate(-30vw, 50vw) scale(4); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-6 { + 0% { + transform: translate(5vw, 30vw) scale(2.5); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-7 { + 0% { + transform: translate(-70vw, 100vw) scale(4); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-8 { + 0% { + transform: translate(-4vw, 2vw) scale(2); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes slide-in-9 { + 0% { + transform: translate(2vw, -5vw) scale(2); + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes fade-in { + 0% { + opacity: 0; + } + 100% { + opacity: 1; + } +} + +@keyframes fade-out { + 0% { + opacity: 1; + } + 100% { + opacity: 0; + } +} diff --git a/static/bauchbinde/index.html b/static/bauchbinde/index.html new file mode 100644 index 0000000..372440b --- /dev/null +++ b/static/bauchbinde/index.html @@ -0,0 +1,18 @@ + + + + + Intro + + + + +
+
+
+
+
+
+
+ +