aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBobby <[email protected]>2023-07-12 19:14:06 -0400
committerBobby <[email protected]>2023-07-12 19:14:06 -0400
commit2ce0ccb1106c8b21b2e9d99ecf8e0772cbf6344a (patch)
tree85a9a1ed34e63b66266cbe4578e39a2670456c3e
parent1038819ecd3af7056fba5121ff46a2ac748468f9 (diff)
downloadthatcomputerscientist-2ce0ccb1106c8b21b2e9d99ecf8e0772cbf6344a.tar.xz
thatcomputerscientist-2ce0ccb1106c8b21b2e9d99ecf8e0772cbf6344a.zip
Solitude: Welcome Page Done! Reponds based on `visited` Cookie
-rw-r--r--solitude/urls.py2
-rw-r--r--solitude/views.py14
-rw-r--r--static/@solitude/css/welcome/audio.css1
-rw-r--r--static/@solitude/css/welcome/button.css68
-rw-r--r--static/@solitude/css/welcome/glitch.css574
-rw-r--r--static/@solitude/css/welcome/welcome.css32
-rw-r--r--static/@solitude/js/welcome.js113
-rw-r--r--templates/@solitude/home.html1
-rw-r--r--templates/@solitude/welcome.html209
9 files changed, 801 insertions, 213 deletions
diff --git a/solitude/urls.py b/solitude/urls.py
index c4458ebe..68819664 100644
--- a/solitude/urls.py
+++ b/solitude/urls.py
@@ -5,5 +5,5 @@ from . import views
app_name = 'solitude'
urlpatterns = [
- path('', views.welcome, name='welcome'),
+ path('', views.home, name='home'),
]
diff --git a/solitude/views.py b/solitude/views.py
index da2e06ca..81bc1075 100644
--- a/solitude/views.py
+++ b/solitude/views.py
@@ -1,3 +1,4 @@
+from django.http import HttpResponse
from django.shortcuts import render
from .constants.welcome_playlist import WELCOME_TRACKS
@@ -6,7 +7,12 @@ import json
# Create your views here.
TEMPLATE_BASE_PATH = '@solitude'
-def welcome(request):
- return render(request, f'{TEMPLATE_BASE_PATH}/welcome.html', {
- 'playlist_tracks': str(json.dumps(WELCOME_TRACKS))
- })
+def home(request):
+ is_first_time = request.COOKIES.get('visited', False)
+ if not is_first_time:
+ response = render(request, f'{TEMPLATE_BASE_PATH}/welcome.html', {
+ 'playlist_tracks': str(json.dumps(WELCOME_TRACKS))
+ })
+ response.set_cookie('visited', True)
+ return response
+ return render(request, f'{TEMPLATE_BASE_PATH}/home.html')
diff --git a/static/@solitude/css/welcome/audio.css b/static/@solitude/css/welcome/audio.css
index ca5b144c..5e0d0c58 100644
--- a/static/@solitude/css/welcome/audio.css
+++ b/static/@solitude/css/welcome/audio.css
@@ -139,4 +139,3 @@
.track {
letter-spacing: 0.1rem;
}
-
diff --git a/static/@solitude/css/welcome/button.css b/static/@solitude/css/welcome/button.css
new file mode 100644
index 00000000..48dc5b2e
--- /dev/null
+++ b/static/@solitude/css/welcome/button.css
@@ -0,0 +1,68 @@
+.button {
+ --offset: 10px;
+ --border-size: 2px;
+ display: block;
+ position: relative;
+ padding: 1.5em 3em;
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ border: 0;
+ background: transparent;
+ color: #7679f5;
+ text-transform: uppercase;
+ letter-spacing: 0.25em;
+ outline: none;
+ cursor: pointer;
+ font-weight: bold;
+ border-radius: 0;
+ box-shadow: inset 0 0 0 var(--border-size) currentcolor;
+ transition: background 0.8s ease;
+}
+.button:hover {
+ background: rgba(100, 0, 0, 0.03);
+}
+.button__horizontal,
+.button__vertical {
+ position: absolute;
+ top: var(--horizontal-offset, 0);
+ right: var(--vertical-offset, 0);
+ bottom: var(--horizontal-offset, 0);
+ left: var(--vertical-offset, 0);
+ transition: transform 0.8s ease;
+ will-change: transform;
+}
+.button__horizontal::before,
+.button__vertical::before {
+ content: "";
+ position: absolute;
+ border: inherit;
+}
+.button__horizontal {
+ --vertical-offset: calc(var(--offset) * -1);
+ border-top: var(--border-size) solid currentcolor;
+ border-bottom: var(--border-size) solid currentcolor;
+}
+.button__horizontal::before {
+ top: calc(var(--vertical-offset) - var(--border-size));
+ bottom: calc(var(--vertical-offset) - var(--border-size));
+ left: calc(var(--vertical-offset) * -1);
+ right: calc(var(--vertical-offset) * -1);
+}
+.button:hover .button__horizontal {
+ transform: scaleX(0);
+}
+.button__vertical {
+ --horizontal-offset: calc(var(--offset) * -1);
+ border-left: var(--border-size) solid currentcolor;
+ border-right: var(--border-size) solid currentcolor;
+}
+.button__vertical::before {
+ top: calc(var(--horizontal-offset) * -1);
+ bottom: calc(var(--horizontal-offset) * -1);
+ left: calc(var(--horizontal-offset) - var(--border-size));
+ right: calc(var(--horizontal-offset) - var(--border-size));
+}
+.button:hover .button__vertical {
+ transform: scaleY(0);
+}
diff --git a/static/@solitude/css/welcome/glitch.css b/static/@solitude/css/welcome/glitch.css
new file mode 100644
index 00000000..6b8c8987
--- /dev/null
+++ b/static/@solitude/css/welcome/glitch.css
@@ -0,0 +1,574 @@
+.glitch {
+ position: relative;
+ color: #fff;
+ font-size: 10rem;
+ font-family: "Share", cursive;
+}
+
+.line:not(:first-child) {
+ position: absolute;
+ top: 0;
+ left: 0;
+}
+.line:nth-child(1) {
+ -webkit-animation: clip 3000ms -300ms linear infinite,
+ glitch1 500ms -80ms linear infinite;
+ animation: clip 3000ms -300ms linear infinite,
+ glitch1 500ms -80ms linear infinite;
+}
+@-webkit-keyframes glitch1 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(4px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(5px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(0px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch1 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(4px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(5px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(0px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(2) {
+ -webkit-animation: clip 3000ms -600ms linear infinite,
+ glitch2 500ms -433ms linear infinite;
+ animation: clip 3000ms -600ms linear infinite,
+ glitch2 500ms -433ms linear infinite;
+}
+@-webkit-keyframes glitch2 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(3px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-3px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(4px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch2 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(3px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-3px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(4px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(3) {
+ -webkit-animation: clip 3000ms -900ms linear infinite,
+ glitch3 500ms -664ms linear infinite;
+ animation: clip 3000ms -900ms linear infinite,
+ glitch3 500ms -664ms linear infinite;
+}
+@-webkit-keyframes glitch3 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(4px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(5px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(-2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch3 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(4px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(5px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(-2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(4) {
+ -webkit-animation: clip 3000ms -1200ms linear infinite,
+ glitch4 500ms -276ms linear infinite;
+ animation: clip 3000ms -1200ms linear infinite,
+ glitch4 500ms -276ms linear infinite;
+}
+@-webkit-keyframes glitch4 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-3px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(2px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(-2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch4 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-3px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(2px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(-2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(5) {
+ -webkit-animation: clip 3000ms -1500ms linear infinite,
+ glitch5 500ms -180ms linear infinite;
+ animation: clip 3000ms -1500ms linear infinite,
+ glitch5 500ms -180ms linear infinite;
+}
+@-webkit-keyframes glitch5 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-2px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-4px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch5 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-2px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-4px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(6) {
+ -webkit-animation: clip 3000ms -1800ms linear infinite,
+ glitch6 500ms -954ms linear infinite;
+ animation: clip 3000ms -1800ms linear infinite,
+ glitch6 500ms -954ms linear infinite;
+}
+@-webkit-keyframes glitch6 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-3px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-4px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(1px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch6 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-3px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-4px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(1px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(7) {
+ -webkit-animation: clip 3000ms -2100ms linear infinite,
+ glitch7 500ms -377ms linear infinite;
+ animation: clip 3000ms -2100ms linear infinite,
+ glitch7 500ms -377ms linear infinite;
+}
+@-webkit-keyframes glitch7 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(2px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-1px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(-1px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch7 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(2px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-1px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(-1px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(8) {
+ -webkit-animation: clip 3000ms -2400ms linear infinite,
+ glitch8 500ms -104ms linear infinite;
+ animation: clip 3000ms -2400ms linear infinite,
+ glitch8 500ms -104ms linear infinite;
+}
+@-webkit-keyframes glitch8 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(1px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-2px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(4px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch8 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(1px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-2px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(4px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(9) {
+ -webkit-animation: clip 3000ms -2700ms linear infinite,
+ glitch9 500ms -606ms linear infinite;
+ animation: clip 3000ms -2700ms linear infinite,
+ glitch9 500ms -606ms linear infinite;
+}
+@-webkit-keyframes glitch9 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(1px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-4px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch9 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(1px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(-4px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(2px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+.line:nth-child(10) {
+ -webkit-animation: clip 3000ms -3000ms linear infinite,
+ glitch10 500ms -560ms linear infinite;
+ animation: clip 3000ms -3000ms linear infinite,
+ glitch10 500ms -560ms linear infinite;
+}
+@-webkit-keyframes glitch10 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-1px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(1px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(1px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+@keyframes glitch10 {
+ 0% {
+ transform: translateX(0);
+ }
+ 80% {
+ transform: translateX(0);
+ color: #fff;
+ }
+ 85% {
+ transform: translateX(-1px);
+ color: #4e9a26;
+ }
+ 90% {
+ transform: translateX(1px);
+ color: #ac1212;
+ }
+ 95% {
+ transform: translateX(1px);
+ color: #fff;
+ }
+ 100% {
+ transform: translateX(0);
+ }
+}
+
+@-webkit-keyframes clip {
+ 0% {
+ -webkit-clip-path: polygon(0 100%, 100% 100%, 100% 120%, 0 120%);
+ clip-path: polygon(0 100%, 100% 100%, 100% 120%, 0 120%);
+ }
+ 100% {
+ -webkit-clip-path: polygon(0 -20%, 100% -20%, 100% 0%, 0 0);
+ clip-path: polygon(0 -20%, 100% -20%, 100% 0%, 0 0);
+ }
+}
+
+@keyframes clip {
+ 0% {
+ -webkit-clip-path: polygon(0 100%, 100% 100%, 100% 120%, 0 120%);
+ clip-path: polygon(0 100%, 100% 100%, 100% 120%, 0 120%);
+ }
+ 100% {
+ -webkit-clip-path: polygon(0 -20%, 100% -20%, 100% 0%, 0 0);
+ clip-path: polygon(0 -20%, 100% -20%, 100% 0%, 0 0);
+ }
+}
diff --git a/static/@solitude/css/welcome/welcome.css b/static/@solitude/css/welcome/welcome.css
index 22a1a747..b4fcde6c 100644
--- a/static/@solitude/css/welcome/welcome.css
+++ b/static/@solitude/css/welcome/welcome.css
@@ -11,6 +11,8 @@
*/
@import url("https://fonts.googleapis.com/css2?family=Handlee&family=Poppins:wght@400&family=Share:wght@700&display=swap");
@import url(audio.css);
+@import url(button.css);
+@import url(glitch.css);
:root {
--button-height: 0.5rem;
--button-color: #edd;
@@ -42,7 +44,6 @@
min-height: 100%;
height: 100%;
width: 100%;
- background-color: rgba(0, 0, 0, 0.15);
z-index: -99;
}
@@ -52,6 +53,14 @@
align-items: center;
justify-content: center;
min-height: 100vh;
+ background: repeating-linear-gradient(
+ 0deg,
+ #0e0d0e77 25%,
+ #0e0d0e77 50%,
+ #17181977 50%,
+ #17181977 75%
+ );
+ background-size: 10px 10px;
}
.cwrapper {
@@ -78,21 +87,8 @@ p {
margin-top: 10rem;
}
-.description {
- font-family: "Share", sans-serif;
- font-size: 1rem;
- margin-top: -4rem;
- letter-spacing: 0.1rem;
+@media only screen and (max-width: 600px) {
+ .glitch {
+ font-size: 5rem;
+ }
}
-
-.text-box {
- font-family: "Share", cursive;
-}
-
-.text-box > h1 {
- margin: 0;
- font-size: 10rem;
- color: rgb(255 255 255 / 60%);
- padding: .5em;
-}
-
diff --git a/static/@solitude/js/welcome.js b/static/@solitude/js/welcome.js
new file mode 100644
index 00000000..d8921075
--- /dev/null
+++ b/static/@solitude/js/welcome.js
@@ -0,0 +1,113 @@
+Object.defineProperty(Array.prototype, "shuffle", {
+ value: function () {
+ for (let i = this.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [this[i], this[j]] = [this[j], this[i]];
+ }
+ return this;
+ },
+});
+
+const tracks = Object.entries(playlistTracks)
+ .map((track) => track[1])
+ .shuffle();
+
+const controls = document.querySelector(".controls");
+const audio = document.querySelector("#audio");
+const trackTitle = document.querySelector("#track-title");
+const trackArtist = document.querySelector("#track-artist");
+const albumArt = document.querySelector("#album-art");
+const minElap = document.querySelector("#min-elap");
+const secElap = document.querySelector("#sec-elap");
+const minDur = document.querySelector("#min-dur");
+const secDur = document.querySelector("#sec-dur");
+
+let currentTrack = 0;
+
+const loadAudio = new Promise((resolve, reject) => {
+ audio.addEventListener("canplaythrough", () => {
+ resolve(audio);
+ });
+});
+
+async function playAudio() {
+ audio.src = tracks[currentTrack].location;
+ const duration = audio.duration;
+ audio.play().catch((e) => {
+ window.addEventListener(
+ "click",
+ () => {
+ controls.click();
+ audio.play();
+ },
+ { once: true }
+ );
+ });
+ return audio;
+}
+
+function pauseAudio() {
+ audio.pause();
+}
+
+function nextTrack() {
+ currentTrack = (currentTrack + 1) % tracks.length;
+ audio.currentTime = 0;
+ playTrack();
+}
+
+function playTrack() {
+ const track = tracks[currentTrack];
+ trackTitle.textContent = track.title;
+ trackArtist.textContent = track.artist;
+ albumArt.src = track.cover_art;
+ playAudio().then((audio) => {
+ audio.addEventListener("ended", nextTrack);
+ });
+}
+
+function updateIntervals() {
+ const duration = audio.duration;
+ const currentTime = audio.currentTime;
+ const elapsed = Math.floor(currentTime);
+ const total = Math.floor(duration);
+ const minutesElapsed = Math.floor(elapsed / 60);
+ const secondsElapsed = elapsed % 60;
+ const minutesTotal = Math.floor(total / 60) || 0;
+ const secondsTotal = total % 60 || 0;
+ minElap.textContent =
+ minutesElapsed < 10 ? `0${minutesElapsed}` : minutesElapsed;
+ secElap.textContent =
+ secondsElapsed < 10 ? `0${secondsElapsed}` : secondsElapsed;
+ minDur.textContent = minutesTotal < 10 ? `0${minutesTotal}` : minutesTotal;
+ secDur.textContent = secondsTotal < 10 ? `0${secondsTotal}` : secondsTotal;
+}
+
+function togglePlayPause() {
+ const buttons = Array.from(this.children);
+ let triggeredButton;
+ buttons.forEach((button) => {
+ if (!button.classList.contains("hidden")) {
+ triggeredButton = button;
+ }
+ button.classList.toggle("hidden");
+ });
+ signalTrigger(triggeredButton);
+}
+
+function signalTrigger(button) {
+ const role = button.getAttribute("role");
+ switch (role) {
+ case "play":
+ playAudio();
+ break;
+ case "pause":
+ pauseAudio();
+ break;
+ }
+}
+
+audio.currentTime = 0;
+controls.addEventListener("click", togglePlayPause);
+audio.addEventListener("timeupdate", updateIntervals);
+playTrack();
diff --git a/templates/@solitude/home.html b/templates/@solitude/home.html
new file mode 100644
index 00000000..de6f7fe1
--- /dev/null
+++ b/templates/@solitude/home.html
@@ -0,0 +1 @@
+<h1>Welcome to Solitude</h1> \ No newline at end of file
diff --git a/templates/@solitude/welcome.html b/templates/@solitude/welcome.html
index 9c07dad2..ba4e47d5 100644
--- a/templates/@solitude/welcome.html
+++ b/templates/@solitude/welcome.html
@@ -16,12 +16,23 @@
</div><div id="cover-wrapper">
<div id="welcome-content">
<div class="cwrapper">
- <div class="text-box">
- <h1>THE SOLITUDE</h1>
+ <div class="glitch">
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
+ <div class="line">the solitude</div>
</div>
- </div>
- <p class="description"></p>
- <button id="enter">Enter The Solitude!</button>
+ </div>
+ <button class="button" style="margin-top: 1rem;" onclick="window.location.reload();">
+ Enter Shifoo's Solitude...
+ <div class="button__horizontal"></div>
+ <div class="button__vertical"></div>
+ </button>
<div id="welcome-playlist-player">
<div class="controls">
<button role="play" id="playButton" class="play"></button>
@@ -48,190 +59,10 @@
</div>
</div>
<script>
- Object.defineProperty(Array.prototype, 'shuffle', {
- value: function() {
- for (let i = this.length - 1; i > 0; i--) {
- const j = Math.floor(Math.random() * (i + 1));
- [this[i], this[j]] = [this[j], this[i]];
- }
- return this;
- }
- });
-
- const playlistTracks = JSON.parse("{{ playlist_tracks }}".replace(/&quot;/g, '"'));
- const tracks = Object.entries(playlistTracks).map(track => track[1]).shuffle();
-
- const controls = document.querySelector('.controls');
- const audio = document.querySelector('#audio');
- const trackTitle = document.querySelector('#track-title');
- const trackArtist = document.querySelector('#track-artist');
- const albumArt = document.querySelector('#album-art');
- const minElap = document.querySelector('#min-elap');
- const secElap = document.querySelector('#sec-elap');
- const minDur = document.querySelector('#min-dur');
- const secDur = document.querySelector('#sec-dur');
-
- let currentTrack = 0;
-
- const loadAudio = new Promise((resolve, reject) => {
- audio.addEventListener('canplaythrough', () => {
- resolve(audio);
- });
- });
-
- async function playAudio () {
- audio.src = tracks[currentTrack].location;
- const duration = audio.duration;
- audio.play().catch(e => {
- window.addEventListener('click', () => {
- controls.click();
- audio.play();
- }, { once: true });
- });
- return audio;
- }
-
- function pauseAudio () {
- audio.pause();
- }
-
- function nextTrack () {
- currentTrack = (currentTrack + 1) % tracks.length;
- audio.currentTime = 0;
- playTrack();
- }
-
- function playTrack() {
- const track = tracks[currentTrack];
- trackTitle.textContent = track.title;
- trackArtist.textContent = track.artist;
- albumArt.src = track.cover_art;
- playAudio().then(audio => {
- audio.addEventListener('ended', nextTrack);
- });
- }
-
- function updateIntervals() {
- const duration = audio.duration;
- const currentTime = audio.currentTime;
- const elapsed = Math.floor(currentTime);
- const total = Math.floor(duration);
- const minutesElapsed = Math.floor(elapsed / 60);
- const secondsElapsed = elapsed % 60;
- const minutesTotal = Math.floor(total / 60) || 0;
- const secondsTotal = total % 60 || 0;
- minElap.textContent = minutesElapsed < 10 ? `0${minutesElapsed}` : minutesElapsed;
- secElap.textContent = secondsElapsed < 10 ? `0${secondsElapsed}` : secondsElapsed;
- minDur.textContent = minutesTotal < 10 ? `0${minutesTotal}` : minutesTotal;
- secDur.textContent = secondsTotal < 10 ? `0${secondsTotal}` : secondsTotal;
- }
-
- function togglePlayPause () {
- const buttons = Array.from(this.children);
- let triggeredButton;
- buttons.forEach(button => {
- if (!button.classList.contains('hidden')) {
- triggeredButton = button;
- }
- button.classList.toggle('hidden')
- });
- signalTrigger(triggeredButton);
- };
-
- function signalTrigger (button) {
- const role = button.getAttribute('role');
- switch (role) {
- case 'play':
- playAudio();
- break;
- case 'pause':
- pauseAudio();
- break;
- }
- }
-
- audio.currentTime = 0;
- controls.addEventListener('click', togglePlayPause);
- audio.addEventListener('timeupdate', updateIntervals);
-
- playTrack();
-
- class TextScramble {
- constructor(el) {
- this.el = el
- this.chars = '!<>-_\\/[]{}—=+*^?#________'
- this.update = this.update.bind(this)
- }
- setText(newText) {
- const oldText = this.el.innerText
- const length = Math.max(oldText.length, newText.length)
- const promise = new Promise((resolve) => this.resolve = resolve)
- this.queue = []
- for (let i = 0; i < length; i++) {
- const from = oldText[i] || ''
- const to = newText[i] || ''
- const start = Math.floor(Math.random() * 40)
- const end = start + Math.floor(Math.random() * 40)
- this.queue.push({ from, to, start, end })
- }
- cancelAnimationFrame(this.frameRequest)
- this.frame = 0
- this.update()
- return promise
- }
- update() {
- let output = ''
- let complete = 0
- for (let i = 0, n = this.queue.length; i < n; i++) {
- let { from, to, start, end, char } = this.queue[i]
- if (this.frame >= end) {
- complete++
- output += to
- } else if (this.frame >= start) {
- if (!char || Math.random() < 0.28) {
- char = this.randomChar()
- this.queue[i].char = char
- }
- output += `<span class="dud">${char}</span>`
- } else {
- output += from
- }
- }
- this.el.innerHTML = output
- if (complete === this.queue.length) {
- this.resolve()
- } else {
- this.frameRequest = requestAnimationFrame(this.update)
- this.frame++
- }
- }
- randomChar() {
- return this.chars[Math.floor(Math.random() * this.chars.length)]
- }
- }
-
- const phrases = [
- 'Welcome to Shifoo\'s Solitude',
- 'A Web Dungeon located beyond the Dark Hollows of the Endless Information SuperHighway',
- 'a dark yet tranquil place where all questions end, curiosity begins, the mind awakens,',
- 'and one\'s journey begins anew in the solitude of a serene mind!',
- 'The Solitude awaits your arrival...'
- ]
-
- const el = document.querySelector('.description')
- const fx = new TextScramble(el)
-
- let counter = 0
- const next = () => {
- fx.setText(phrases[counter]).then(() => {
- setTimeout(next, 3200)
- })
- counter = (counter + 1) % phrases.length
- }
-
- next()
-
+ const playlistTracks = JSON.parse(
+ "{{ playlist_tracks }}".replace(/&quot;/g, '"')
+ );
</script>
-
+ <script src="{% static '@solitude/js/welcome.js' %}"></script>
</body>
</html>