From 7e7c9644c40e8328354395570d7f92bceb998a57 Mon Sep 17 00:00:00 2001 From: Miwory Date: Sun, 31 Aug 2025 00:36:15 +0300 Subject: [PATCH] miwory music player gen 1 & 2 & 3 --- MusicPlayer/Miwory/generation 1/index.html | 24 +++ MusicPlayer/Miwory/generation 1/script.js | 72 +++++++++ MusicPlayer/Miwory/generation 1/style.css | 139 ++++++++++++++++ MusicPlayer/Miwory/generation 2/index.html | 44 +++++ MusicPlayer/Miwory/generation 2/script.js | 83 ++++++++++ MusicPlayer/Miwory/generation 2/style.css | 177 +++++++++++++++++++++ MusicPlayer/Miwory/generation 3/index.html | 10 ++ MusicPlayer/Miwory/generation 3/script.js | 74 +++++++++ MusicPlayer/Miwory/generation 3/style.css | 66 ++++++++ 9 files changed, 689 insertions(+) create mode 100644 MusicPlayer/Miwory/generation 1/index.html create mode 100644 MusicPlayer/Miwory/generation 1/script.js create mode 100644 MusicPlayer/Miwory/generation 1/style.css create mode 100644 MusicPlayer/Miwory/generation 2/index.html create mode 100644 MusicPlayer/Miwory/generation 2/script.js create mode 100644 MusicPlayer/Miwory/generation 2/style.css create mode 100644 MusicPlayer/Miwory/generation 3/index.html create mode 100644 MusicPlayer/Miwory/generation 3/script.js create mode 100644 MusicPlayer/Miwory/generation 3/style.css diff --git a/MusicPlayer/Miwory/generation 1/index.html b/MusicPlayer/Miwory/generation 1/index.html new file mode 100644 index 0000000..39a6367 --- /dev/null +++ b/MusicPlayer/Miwory/generation 1/index.html @@ -0,0 +1,24 @@ +
+
+
+ +
+
+
+ + +
+
+ + +
+
+
+
+
+
+
+
+
diff --git a/MusicPlayer/Miwory/generation 1/script.js b/MusicPlayer/Miwory/generation 1/script.js new file mode 100644 index 0000000..7e63e0d --- /dev/null +++ b/MusicPlayer/Miwory/generation 1/script.js @@ -0,0 +1,72 @@ +let widgetNode = document.getElementById('widget'); +let musicPlayerNode = document.getElementById('player'); +let musicPlayerTitleNode = document.getElementById('title'); +let musicPlayerArtistNode = document.getElementById('artist'); +let musicPlayerBackgroundNode = document.getElementById('background_img'); +let musicPlayerProgress = document.getElementById('progressbar'); +let pausedAt = null; +let trackDuration = 0; +let trackProgress = 0; +let trackEnd = new Date(); + +window.addEventListener('message', function (event) { + let message = event.detail; + let data = message.data; + widgetNode.classList.add('active'); + + if (data == null) { + musicPlayerNode.classList.remove('active'); + return; + }; + + if (!data.is_playing && !pausedAt) { + pausedAt = new Date(); + }; + + if (data.is_playing) { + musicPlayerNode.classList.add('active'); + pausedAt = null; + }; + + trackDuration = data.track.duration; + trackProgress = data.progress; + trackEnd = new Date().getTime() + data.track.duration - data.progress; + + musicPlayerTitleNode.innerText = data.track.name; + musicPlayerArtistNode.innerText = data.track.artists.join(', '); + + if (musicPlayerBackgroundNode.src != data.track.cover) { + musicPlayerBackgroundNode.src = data.track.cover; + }; +}); + +function delay(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +}; + +async function update() { + if (pausedAt && pausedAt.getTime() + 10000 < new Date().getTime()) { + player.classList.remove('active'); + + await delay(100); + return update(); + }; + + var progress; + if (pausedAt) { + progress = trackProgress / trackDuration * 100; + } else { + progress = (trackDuration - (trackEnd - new Date().getTime())) / trackDuration * 100; + }; + + if (progress >= 100) { + progress = 100; + }; + + musicPlayerProgress.style.setProperty('--progress', `${progress}%`); + + await delay(100); + update(); +}; + +update(); diff --git a/MusicPlayer/Miwory/generation 1/style.css b/MusicPlayer/Miwory/generation 1/style.css new file mode 100644 index 0000000..823a43e --- /dev/null +++ b/MusicPlayer/Miwory/generation 1/style.css @@ -0,0 +1,139 @@ +@import url(https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,900;1,900&display=swap); + +#widget { + display: flex; + align-items: center; + justify-content: center; + visibility: hidden +} + +#widget.active { + visibility: visible +} + +#player { + position: relative; + width: 800px; + height: 320px; + overflow: hidden; + border-radius: 30px; + margin-inline: 30px; + color: #fff; + font-family: "Nunito", sans-serif; + font-weight: 900; + opacity: 0; + box-shadow: 0 0 20px 5px rgba(0, 0, 0, .5); + transition: opacity 350ms ease-in-out +} + +#player.active { + opacity: 1 +} + +#player .player_background { + position: absolute; + inset: 0 +} + +#player #background_img { + position: absolute; + width: 100%; + height: 100%; + object-fit: cover; + opacity: .35 +} + +#player .player_background::before { + position: absolute; + content: ""; + inset: 0; + background-color: #1e1e1e +} + +#player .data { + position: relative; + width: calc(100% - 150px); + height: calc(100% - 60px); + display: flex; + flex-direction: column; + gap: 15px; + padding: 30px 75px; + z-index: 99 +} + +#player .source { + display: flex; + opacity: .6; + gap: 10px +} + +#player .source #logo { + width: 30px +} + +#player .data .meta { + display: flex; + flex-direction: column +} + +#player .data .meta #artist, +#player .data .meta #title { + word-break: keep-all; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap +} + +#player .data #source { + font-size: 28px +} + +#player .data #title { + font-size: 42px +} + +#player .data #artist { + font-size: 32px; + opacity: .6 +} + +#player #progressbar { + position: relative; + width: 100%; + height: 30px; + border-radius: 25px; + margin-top: 20px; + --progress: 0% +} + +#player #progressbar .background { + position: absolute; + inset: 0; + border-radius: inherit; + background-color: #d9d9d9; + opacity: .25 +} + +#player #progressbar .progress { + position: absolute; + inset: 0; + border-radius: inherit; + background-color: #c6d3e6; + width: 100%; + max-width: var(--progress); + transition: max-width 200ms ease-in-out +} + +#player #progressbar .pointer { + position: absolute; + top: 50%; + width: 50px; + aspect-ratio: 1; + background-color: #dceaff; + border: 1px solid #737373; + border-radius: 100%; + margin-left: var(--progress); + transform: translate(-50%, -50%); + transition: margin-left 200ms ease-in-out; + z-index: 99 +} diff --git a/MusicPlayer/Miwory/generation 2/index.html b/MusicPlayer/Miwory/generation 2/index.html new file mode 100644 index 0000000..a106a59 --- /dev/null +++ b/MusicPlayer/Miwory/generation 2/index.html @@ -0,0 +1,44 @@ +
+
+
+
+ +
+
+
+ + +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/MusicPlayer/Miwory/generation 2/script.js b/MusicPlayer/Miwory/generation 2/script.js new file mode 100644 index 0000000..3a38bc8 --- /dev/null +++ b/MusicPlayer/Miwory/generation 2/script.js @@ -0,0 +1,83 @@ +let widgetNode = document.getElementById('widget'); +let musicPlayerNode = document.getElementById('player'); +let musicPlayerTitleNode = document.getElementById('title'); +let musicPlayerArtistNode = document.getElementById('artist'); +let musicPlayerNowNode = document.getElementById('now'); +let musicPlayerDurationNode = document.getElementById('duration'); +let musicPlayerBackgroundNode = document.getElementById('background_img'); +let musicPlayerProgress = document.getElementById('progressbar'); +let pausedAt = null; +let trackDuration = 0; +let trackProgress = 0; +let trackEnd = new Date(); + +window.addEventListener('message', function (event) { + let message = event.detail; + let data = message.data; + widgetNode.classList.add('active'); + + if (data == null) { + musicPlayerNode.classList.remove('active'); + return; + }; + + if (!data.is_playing && !pausedAt) { + pausedAt = new Date(); + }; + + if (data.is_playing) { + musicPlayerNode.classList.add('active'); + pausedAt = null; + }; + + trackDuration = data.track.duration; + trackProgress = data.progress; + trackEnd = new Date().getTime() + data.track.duration - data.progress; + + musicPlayerTitleNode.innerText = data.track.name; + musicPlayerArtistNode.innerText = data.track.artists.join(', '); + musicPlayerDurationNode.innerText = formatTime(trackDuration); + + if (musicPlayerBackgroundNode.src != data.track.cover) { + musicPlayerBackgroundNode.src = data.track.cover; + }; +}); + +function formatTime(milliseconds) { + let seconds = milliseconds / 1000; + let minutes = Math.floor(seconds / 60); + let secondsFormatted = (seconds % 60).toFixed(0).padStart(2, '0'); + return `${minutes}:${secondsFormatted}`; +}; + +function delay(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +}; + +async function update() { + if (pausedAt && pausedAt.getTime() + 10000 < new Date().getTime()) { + player.classList.remove('active'); + + await delay(100); + return update(); + }; + + var progress; + if (pausedAt) { + progress = trackProgress / trackDuration * 100; + } else { + progress = (trackDuration - (trackEnd - new Date().getTime())) / trackDuration * 100; + musicPlayerNowNode.innerText = formatTime((trackDuration - (trackEnd - new Date().getTime()))); + }; + + if (progress >= 100) { + progress = 100; + }; + + musicPlayerProgress.style.setProperty('--progress', `${progress}%`); + + await delay(100); + update(); +}; + +update(); diff --git a/MusicPlayer/Miwory/generation 2/style.css b/MusicPlayer/Miwory/generation 2/style.css new file mode 100644 index 0000000..f6ff361 --- /dev/null +++ b/MusicPlayer/Miwory/generation 2/style.css @@ -0,0 +1,177 @@ +@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap'); + +#widget { + display: flex; + align-items: center; + justify-content: center; + visibility: hidden; +} + +#widget.active { + visibility: visible +} + +#player { + display: flex; + flex-direction: column; + gap: 10px; + font-family: "Nunito", sans-serif; + opacity: 0; + margin: 5px 30px; + transition: opacity 350ms ease-in-out; + + --text-color: white; + --background-color: #52363A; + --second-color: #5475af; +} + +#player.active { + opacity: 1; +} + +.main { + display: flex; + gap: 10px; +} + +.player_background { + position: relative; + width: 200px; + height: 200px; + border-radius: 15px; +} + +.player_background::before { + position: absolute; + content: ''; + inset: 0; + border-radius: inherit; + left: -15px; + background-color: var(--background-color); + z-index: -1; +} + +#background_img { + width: 100%; + height: 100%; + border-radius: 0 15px 15px 0; +} + +.data { + display: flex; + flex-direction: column; + justify-content: space-between; + gap: 10px; + width: 500px; +} + +.info { + display: flex; + flex-direction: column; + justify-content: space-evenly; + color: var(--text-color); + background-color: var(--background-color); + border-radius: 10px; + flex: 1 1 0; + padding: 15px; +} + +.info a { + word-break: keep-all; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +#title { + font-size: 28px; + font-weight: 1000; +} + +#artist { + font-size: 22px; + font-weight: 400; +} + +.time { + box-sizing: border-box; + display: flex; + align-items: center; + justify-content: space-between; + width: 100%; + height: 50px; + padding-inline: 15px; + border-radius: 10px; + font-weight: 800; + color: var(--text-color); + background-color: var(--background-color); +} + +.bars { + display: flex; + box-sizing: border-box; + height: 100%; + padding-block: 12px; + gap: 7.5px; +} + +.bar { + width: 7px; + height: 100%; + border-radius: 5px; + background: var(--second-color); + animation: bounce 1s ease-in-out infinite; + transform-origin: center; +} + +.bar:nth-child(1) { animation-duration: 1.6s; animation-delay: 0s; } +.bar:nth-child(2) { animation-duration: 1.8s; animation-delay: 0.1s; } +.bar:nth-child(3) { animation-duration: 2.2s; animation-delay: 0.2s; } +.bar:nth-child(4) { animation-duration: 1.4s; animation-delay: 0.3s; } +.bar:nth-child(5) { animation-duration: 2.4s; animation-delay: 0.4s; } +.bar:nth-child(6) { animation-duration: 1.7s; animation-delay: 0.5s; } +.bar:nth-child(7) { animation-duration: 1.9s; animation-delay: 0.6s; } +.bar:nth-child(8) { animation-duration: 2.3s; animation-delay: 0.7s; } +.bar:nth-child(9) { animation-duration: 1.5s; animation-delay: 0.8s; } +.bar:nth-child(10) { animation-duration: 2.1s; animation-delay: 0.9s; } +.bar:nth-child(11) { animation-duration: 1.8s; animation-delay: 1s; } +.bar:nth-child(12) { animation-duration: 2.0s; animation-delay: 1.1s; } +.bar:nth-child(13) { animation-duration: 1.6s; animation-delay: 1.2s; } +.bar:nth-child(14) { animation-duration: 2.2s; animation-delay: 1.3s; } +.bar:nth-child(15) { animation-duration: 1.9s; animation-delay: 1.4s; } +.bar:nth-child(16) { animation-duration: 1.7s; animation-delay: 1.5s; } +.bar:nth-child(17) { animation-duration: 2.4s; animation-delay: 1.6s; } +.bar:nth-child(18) { animation-duration: 1.4s; animation-delay: 1.7s; } +.bar:nth-child(19) { animation-duration: 2.0s; animation-delay: 1.8s; } +.bar:nth-child(20) { animation-duration: 1.8s; animation-delay: 1.9s; } + +#progressbar { + position: relative; + width: calc(100% + 15px); + height: 20px; + margin-left: -15px; + border-radius: 10px; + background-color: var(--background-color); + overflow: hidden; +} + +#progressbar::after { + position: absolute; + content: ''; + inset: 0; + border-radius: inherit; + width: 100%; + max-width: var(--progress); + background-color: var(--second-color); + transition: max-width 350ms ease-in-out; +} + +@keyframes bounce { + 0%, 100% { + transform: scaleY(0.3); + } + + 50% { + transform: scaleY(1); + } +} diff --git a/MusicPlayer/Miwory/generation 3/index.html b/MusicPlayer/Miwory/generation 3/index.html new file mode 100644 index 0000000..88f6a10 --- /dev/null +++ b/MusicPlayer/Miwory/generation 3/index.html @@ -0,0 +1,10 @@ +
+
+ +
+ + + +
+
+
diff --git a/MusicPlayer/Miwory/generation 3/script.js b/MusicPlayer/Miwory/generation 3/script.js new file mode 100644 index 0000000..3cc4bd7 --- /dev/null +++ b/MusicPlayer/Miwory/generation 3/script.js @@ -0,0 +1,74 @@ +let widgetNode = document.getElementById('widget'); +let musicPlayerNode = document.getElementById('player'); +let musicPlayerTitleNode = document.getElementById('title'); +let musicPlayerArtistNode = document.getElementById('artist'); +let musicPlayerAlbumNode = document.getElementById('album'); +let musicPlayerBackgroundNode = document.getElementById('background_img'); +let musicPlayerProgress = document.getElementById('progressbar'); +let pausedAt = null; +let trackDuration = 0; +let trackProgress = 0; +let trackEnd = new Date(); + +window.addEventListener('message', function (event) { + let message = event.detail; + let data = message.data; + widgetNode.classList.add('active'); + + if (data == null) { + musicPlayerNode.classList.remove('active'); + return; + }; + + if (!data.is_playing && !pausedAt) { + pausedAt = new Date(); + }; + + if (data.is_playing) { + musicPlayerNode.classList.add('active'); + pausedAt = null; + }; + + trackDuration = data.track.duration; + trackProgress = data.progress; + trackEnd = new Date().getTime() + data.track.duration - data.progress; + + musicPlayerTitleNode.innerText = data.track.name; + musicPlayerArtistNode.innerText = data.track.artists.join(', '); + musicPlayerAlbumNode.innerText = `album: ${data.track.album}`; + + if (musicPlayerBackgroundNode.src != data.track.cover) { + musicPlayerBackgroundNode.src = data.track.cover; + }; +}); + +function delay(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +}; + +async function update() { + if (pausedAt && pausedAt.getTime() + 10000 < new Date().getTime()) { + player.classList.remove('active'); + + await delay(100); + return update(); + }; + + var progress; + if (pausedAt) { + progress = trackProgress / trackDuration * 100; + } else { + progress = (trackDuration - (trackEnd - new Date().getTime())) / trackDuration * 100; + }; + + if (progress >= 100) { + progress = 100; + }; + + musicPlayerProgress.style.setProperty('--progress', `${progress}%`); + + await delay(100); + update(); +}; + +update(); diff --git a/MusicPlayer/Miwory/generation 3/style.css b/MusicPlayer/Miwory/generation 3/style.css new file mode 100644 index 0000000..e64cc5a --- /dev/null +++ b/MusicPlayer/Miwory/generation 3/style.css @@ -0,0 +1,66 @@ +@import url('https://fonts.googleapis.com/css2?family=Nunito:ital,wght@0,200..1000;1,200..1000&display=swap'); + +#widget { + display: flex; + align-items: center; + justify-content: center; + visibility: hidden +} + +#widget.active { + visibility: visible +} + +#player { + position: relative; + display: inline-flex; + width: 800px; + height: 320px; + overflow: hidden; + border-radius: 30px; + margin-inline: 30px; + color: #fff; + font-family: "Nunito", sans-serif; + opacity: 0; + background-color: #242424; + transition: opacity 350ms ease-in-out +} + +#player.active { + opacity: 1 +} + +#player #background_img { + height: 100%; + border-radius: 30px; +} + +#player .meta { + display: flex; + flex-direction: column; + width: 450px; + margin: auto; + margin-left: 30px; +} + +#player .meta a { + word-break: keep-all; + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +#player #album { + font-size: 32px; + color: #E47D7D; +} + +#player #title { + font-size: 42px; + font-weight: 900; +} + +#player #artist { + font-size: 40px; + opacity: .6; +}