From ebe4e85fada030568261059503852cf0fed68e3e Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Sun, 3 Mar 2019 17:22:29 +0100 Subject: [PATCH] Implement basic background animation for closed screen. --- .gitignore | 1 + package.json | 16 +++++++++ public/foobar.css | 21 +++++++++++- public/index.php | 2 +- src/closed.js | 80 +++++++++++++++++++++++++++++++++++++++++++ src/index.js | 9 +++++ templates/closed.html | 12 +++++++ webpack.config.js | 9 +++++ 8 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 package.json create mode 100644 src/closed.js create mode 100644 src/index.js create mode 100644 templates/closed.html create mode 100644 webpack.config.js diff --git a/.gitignore b/.gitignore index 011894d..ecff874 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ vendor node_modules .php_cs.cache +public/bundle.js diff --git a/package.json b/package.json new file mode 100644 index 0000000..0586d23 --- /dev/null +++ b/package.json @@ -0,0 +1,16 @@ +{ + "name": "isdefoobaropen.nl", + "version": "1.0.0", + "description": "Source code for isdefoobaropen.nl", + "main": "index.js", + "repository": "gitea@git.bertptrs.nl:bert/isdefoobaropen.nl.git", + "author": "Bert Peters ", + "license": "GPLv3", + "private": true, + "dependencies": { + }, + "devDependencies": { + "webpack": "^4.29.6", + "webpack-cli": "^3.2.3" + } +} diff --git a/public/foobar.css b/public/foobar.css index 926f9b5..a2a2a29 100644 --- a/public/foobar.css +++ b/public/foobar.css @@ -61,6 +61,16 @@ transform: rotate(360deg); } } +@keyframes fadeOut { + 0% { + opacity: 1; + } + + 100% { + opacity: 0; + } +} + body.open { height:100%; background-color: #a3d165; @@ -96,5 +106,14 @@ animation:starrotation 10s; -o-animation:starration 10s; /* Opera */ -o-animation-iteration-count: infinite; -o-animation-timing-function: linear; - +} + +.closed_notice { + position: absolute; + font-weight: bold; + font-size: 16pt; + text-transform: uppercase; + animation: fadeOut 3s forwards; + animation-timing-function: linear; + animation-iteration-count: 1; } diff --git a/public/index.php b/public/index.php index a8ec2f8..89168ea 100644 --- a/public/index.php +++ b/public/index.php @@ -4,5 +4,5 @@ require_once '../vendor/autoload.php'; if (\FooBar\Configuration::loadConfig()->isOpen()) { require 'isOpen.php'; } else { - require 'isGesloten.php'; + require '../templates/closed.html'; } diff --git a/src/closed.js b/src/closed.js new file mode 100644 index 0000000..b61f279 --- /dev/null +++ b/src/closed.js @@ -0,0 +1,80 @@ +/** + * This file contains the animation logic for the closed screen. + * + * In it, we fill the screen evenly with "closed" messages. The locations are + */ +/** + * Contains the state for this demo. + * + * @type {{popups: Array, popup_index: number}} + */ +const state = { + popups: [], + popup_index: 0, +}; + +const MAX_POPUPS = 200; + +function startClosedAnimation() { + window.setInterval(animationTick, 100); +} + +function minDist(x, y) { + let min = 0; + let element; + for (element of state.popups) { + if (element == null) { + continue; + } + + const dx = x - element.x; + const dy = y - element.y; + const dist = Math.sqrt(dx * dx + dy * dy); + min = Math.min(dist, min); + } + + return min; +} + +function animationTick() { + const index = state.popup_index; + if (state.popups.length >= MAX_POPUPS) { + document.body.removeChild(state.popups[index].element); + state.popups[index] = null; + } + + const width = window.innerWidth; + const height = window.innerHeight; + + // Generate new candidates + const candidates = []; + for (let i = 0; i < MAX_POPUPS; ++i) { + candidates.push({x: Math.random() * width, y: Math.random() * height}); + } + + let best = candidates[0]; + let max = minDist(candidates[0].x, candidates[0].y); + let candidate; + for (candidate of candidates) { + const dist = minDist(candidate.x, candidate.y); + if (dist > max) { + best = candidate; + max = dist; + } + } + + let element = document.createElement('div'); + element.innerText = 'Nee'; + element.classList.add('closed_notice'); + element.style.left = best.x + 'px'; + element.style.top = best.y + 'px'; + element.style.transform = 'rotate(' + (Math.random() * 360) + 'deg)'; + + document.body.appendChild(element); + best.element = element; + + state.popups[index] = best; + state.popup_index = (index + 1) % MAX_POPUPS; +} + +export {startClosedAnimation} diff --git a/src/index.js b/src/index.js new file mode 100644 index 0000000..e87c5b4 --- /dev/null +++ b/src/index.js @@ -0,0 +1,9 @@ +import {startClosedAnimation} from "./closed"; + +window.addEventListener('load', function () { + if (document.body.classList.contains('open')) { + // TODO: leave it in HTML/CSS for now. + } else { + startClosedAnimation(); + } +}); diff --git a/templates/closed.html b/templates/closed.html new file mode 100644 index 0000000..7e98ef6 --- /dev/null +++ b/templates/closed.html @@ -0,0 +1,12 @@ + + + + + + Nee... • IsDeFooBarOpen.nl + + + + + + diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..801c42e --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,9 @@ +const path = require('path'); + +module.exports = { + entry: './src/index.js', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'public') + } +}; \ No newline at end of file