aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fonts/VCR_OSD_MONO_1.001.ttfbin0 -> 75864 bytes
-rw-r--r--hg.css59
-rw-r--r--index.html156
-rw-r--r--player.js589
4 files changed, 500 insertions, 304 deletions
diff --git a/fonts/VCR_OSD_MONO_1.001.ttf b/fonts/VCR_OSD_MONO_1.001.ttf
new file mode 100644
index 0000000..dcca687
--- /dev/null
+++ b/fonts/VCR_OSD_MONO_1.001.ttf
Binary files differ
diff --git a/hg.css b/hg.css
index 722f06f..015a3e3 100644
--- a/hg.css
+++ b/hg.css
@@ -2,6 +2,10 @@
font-family: "StreamSter";
src: url(./fonts/Streamster.ttf);
}
+@font-face {
+ font-family: "VCR";
+ src: url(./fonts/VCR_OSD_MONO_1.001.ttf);
+}
#app,
body,
html {
@@ -15,7 +19,7 @@ body {
padding: 0;
margin: 0;
background: #fafafa;
- font-family: "Helvetica Neue", arial, sans-serif;
+ font-family: "VCR", arial, sans-serif;
font-weight: 400;
color: #444;
-webkit-font-smoothing: antialiased;
@@ -131,7 +135,8 @@ h3#track-name {
font-weight: 500;
letter-spacing: 2px;
color: #e91e63;
- font-family: "StreamSter", sans-serif;
+ /* font-family: "StreamSter", sans-serif; */
+ font-family: "VCR", sans-serif;
margin-bottom: 0;
background: rgb(0 0 0 / 71%);
padding: 10px;
@@ -149,7 +154,7 @@ hr {
width: 170px;
margin: 0 auto;
color: #dce3e7;
- font-family: "Droid Serif", serif;
+ font-family: "VCR", serif;
font-size: 13px;
font-style: italic;
line-height: 18px;
@@ -247,19 +252,23 @@ dialog::backdrop {
.controls {
font-style: italic;
font-size: larger;
+ color: #ff0095;
}
.footer {
position: absolute;
bottom: 0px;
- width: 350px;
+ width: 342px;
display: flex;
color: #ffffff;
z-index: 999;
justify-content: center;
+ height: 17px;
}
.footer .footer-items {
+ font-size: 13px;
+ font-family: "VCR", serif;
text-decoration: none;
cursor: pointer;
padding-left: 10px;
@@ -267,15 +276,53 @@ dialog::backdrop {
justify-content: center;
}
+.footer-items#history {
+ margin-top: 3px;
+}
+
canvas {
position: absolute;
top: 0;
}
-.refresh {
+.buttons {
z-index: 999;
cursor: pointer;
position: relative;
- float: right;
user-select: none;
}
+
+.refresh {
+ float: right;
+}
+
+.fullscreen {
+ float: left;
+ float: left;
+ margin-left: 5px;
+ margin-top: 3px;
+ color: #565656;
+}
+
+.fullscreen svg {
+ height: 10px;
+ width: 10px;
+ color: #ffffffff;
+}
+
+.fullscreen:hover * {
+ color: #ffffff;
+}
+
+.hidden {
+ display: none;
+}
+
+.OVR {
+ position: absolute;
+ bottom: 0;
+ z-index: 999;
+ color: #ffff;
+ right: 0;
+ margin-right: 5px;
+}
diff --git a/index.html b/index.html
index bfcf695..8fa8498 100644
--- a/index.html
+++ b/index.html
@@ -1,62 +1,128 @@
<!DOCTYPE html>
<html lang="en">
-
-<head>
- <meta charset="UTF-8">
- <meta http-equiv="X-UA-Compatible" content="IE=edge">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <head>
+ <meta charset="UTF-8" />
+ <meta http-equiv="X-UA-Compatible" content="IE=edge" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Retrowave Player</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/howler/2.2.3/howler.min.js"></script>
<script src="https://unpkg.com/hydra-synth"></script>
- <link rel="stylesheet" href="hg.css">
- <link rel="icon" href="/favicon.ico">
- <link rel="icon" type="image/svg+xml" href="/favicon.svg">
-</head>
+ <link rel="stylesheet" href="hg.css" />
+ <link rel="icon" href="/favicon.ico" />
+ <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
+ </head>
-<body>
+ <body>
<div class="modal" id="intro-modal">
- <div class="modal-bg modal-exit"></div>
- <div class="modal-container">
- <h3 class="text-center">Welcome to Retrowave Player</h3>
- <p class="mt-5">Here are the controls:</p>
- <h4 class="mt-5">Play/Pause <span class="controls">SPACE or Click or Touch</span></h4>
- <h4 class="mt-5">Volume Up <span class="controls">w or Swipe Up</span></h4>
- <h4 class="mt-5">Volume Down <span class="controls">s or Swipe Down</span></h4>
- <h4 class="mt-5">Next Track<span class="controls"> n or Press the Refresh Button</span></h4>
- <p class="mt-5">(You can download the music history of your current browser by clicking the history link on
- the player)</p>
- <p class="mt-5">All the music is fetched from retrowave.ru</p>
- <button class="modal-close modal-exit" id="initButton">X</button>
- </div>
+ <div class="modal-bg modal-exit"></div>
+ <div class="modal-container">
+ <h3 class="text-center">Welcome to Retrowave Player</h3>
+ <p class="mt-5">Here are the controls:</p>
+ <h4 class="mt-5">
+ Play/Pause <span class="controls">SPACE or Click or Touch</span>
+ </h4>
+ <h4 class="mt-5">
+ Volume Up <span class="controls">w or Swipe Up</span>
+ </h4>
+ <h4 class="mt-5">
+ Volume Down <span class="controls">s or Swipe Down</span>
+ </h4>
+ <h4 class="mt-5">
+ Next Track<span class="controls"> n or Press the Refresh Button</span>
+ </h4>
+ <h4 class="mt-5">
+ Toggle Controls<span class="controls"> h</span>
+ </h4>
+ <p class="mt-5">
+ (You can download the music history of your current browser by
+ clicking the history link on the player)
+ </p>
+ <p class="mt-5">All the music is fetched from retrowave.ru</p>
+ <button class="modal-close modal-exit" id="initButton">X</button>
+ </div>
</div>
<div id="app">
- <div class="music-player">
- <div class="no-pause refresh">🔃</div>
- <div class="title-content">
- <div class="intro">Now Playing</div>
- <hr>
- <h3 id="track-name">Retrowave Player</h3>
- </div>
- <div class="gradient-overlay"></div>
- <div class="color-overlay"></div>
- <div class="footer">
- <div id="history" class="no-pause footer-items">history</div>
- <div id="source"><a class="no-pause footer-items" href="https://git.indrajith.dev/retrowave-player/"
- target="_blank">source code</a></div>
- <div id="retrowaveru" class="no-pause"><a class="no-pause footer-items" href="http://retrowave.ru/"
- target="_blank">retrowave.ru</a></div>
- <div id="guestbook" class="no-pause"><a class="no-pause footer-items" href="https://indrajith.atabook.org/"
- target="_blank">guestbook</a></div>
- </div>
- <!-- <div id="upload-info" class="no-pause" title="Upload a playlist (downloaded from history)">Upload</div> -->
+ <div class="music-player">
+ <div title="FULLSCREEN" class="no-pause buttons fullscreen toggleable">
+ <svg
+ class="no-pause"
+ width="800px"
+ height="800px"
+ fill="#000000"
+ version="1.1"
+ viewBox="0 0 384.97 384.97"
+ xml:space="preserve"
+ xmlns="http://www.w3.org/2000/svg"
+ >
+ <g style="fill: #f9f9f9">
+ <g id="Fullscreen" style="fill: #f9f9f9">
+ <path
+ d="m384.97 12.03c0-6.713-5.317-12.03-12.03-12.03h-108.09c-6.833 0-11.922 5.39-11.934 12.223 0 6.821 5.101 11.838 11.934 11.838h96.062l-0.193 96.519c0 6.833 5.197 12.03 12.03 12.03 6.833-0.012 12.03-5.197 12.03-12.03l0.193-108.37c0-0.036-0.012-0.06-0.012-0.084 1e-3 -0.037 0.013-0.061 0.013-0.097z"
+ style="fill: #f9f9f9"
+ />
+ <path
+ d="M120.496,0H12.403c-0.036,0-0.06,0.012-0.096,0.012C12.283,0.012,12.247,0,12.223,0C5.51,0,0.192,5.317,0.192,12.03 L0,120.399c0,6.833,5.39,11.934,12.223,11.934c6.821,0,11.838-5.101,11.838-11.934l0.192-96.339h96.242 c6.833,0,12.03-5.197,12.03-12.03C132.514,5.197,127.317,0,120.496,0z"
+ style="fill: #f9f9f9"
+ />
+ <path
+ d="m120.12 360.91h-96.062v-96.242c0-6.833-5.197-12.03-12.03-12.03s-12.031 5.196-12.031 12.03v108.09c0 0.036 0.012 0.06 0.012 0.084 0 0.036-0.012 0.06-0.012 0.096 0 6.713 5.317 12.03 12.03 12.03h108.09c6.833 0 11.922-5.39 11.934-12.223 1e-3 -6.82-5.1-11.837-11.933-11.837z"
+ style="fill: #f9f9f9"
+ />
+ <path
+ d="m372.75 252.91c-6.833 0-11.85 5.101-11.838 11.934v96.062h-96.242c-6.833 0-12.03 5.197-12.03 12.03s5.197 12.03 12.03 12.03h108.09c0.036 0 0.06-0.012 0.084-0.012 0.036-0.012 0.06 0.012 0.096 0.012 6.713 0 12.03-5.317 12.03-12.03v-108.09c1e-3 -6.833-5.389-11.934-12.222-11.934z"
+ style="fill: #f9f9f9"
+ />
+ </g>
+ </g>
+ </svg>
+ </div>
+ <div class="no-pause buttons refresh toggleable" title="NEXT TRACK">🔃</div>
+ <div class="title-content">
+ <div class="intro">Now Playing</div>
+ <hr />
+ <h3 id="track-name">Retrowave Player</h3>
</div>
+ <div class="gradient-overlay"></div>
+ <div class="color-overlay"></div>
+ <div class="footer toggleable">
+ <div title="DOWNLOAD YOUR PLAYLIST HISTORY" id="history" class="no-pause footer-items">history</div>
+ <div id="source">
+ <a
+ title="SOURCE CODE"
+ class="no-pause footer-items"
+ href="https://git.indrajith.dev/retrowave-player/"
+ target="_blank"
+ >source code</a
+ >
+ </div>
+ <div id="retrowaveru" class="no-pause">
+ <a
+ title="RETROWAVE.RU"
+ class="no-pause footer-items"
+ href="http://retrowave.ru/"
+ target="_blank"
+ >retrowave.ru</a
+ >
+ </div>
+ <div id="guestbook" class="no-pause">
+ <a
+ title="SIGN MY GUESTBOOK"
+ class="no-pause footer-items"
+ href="https://indrajith.atabook.org/"
+ target="_blank"
+ >guestbook</a
+ >
+ </div>
+ </div>
+ <!-- <div id="upload-info" class="no-pause" title="Upload a playlist (downloaded from history)">Upload</div> -->
+ </div>
</div>
<div id="codef-canvas"></div>
+ <div class="OVR hidden"></div>
<input id="file-upload" type="file" accept="application/json" />
<!-- <script src="libs/codef_core.js"></script>
<script src="libs/codef_starfield.js"></script>
<script src="libs/codef_3d.js"></script> -->
<script src="player.js"></script>
-</body>
-
-</html> \ No newline at end of file
+ </body>
+</html>
diff --git a/player.js b/player.js
index 2c7e73f..51ae188 100644
--- a/player.js
+++ b/player.js
@@ -1,293 +1,376 @@
(function () {
- let isPlaying = false;
- let currentTracks = [];
- let cursor = 0;
- let howlerInstance;
- const retroWaveRu = "https://retrowave.ru";
- let titleEl = document.getElementById("track-name");
- let coverArtEl = document.getElementsByClassName("music-player")[0];
- let refreshBtn = document.querySelector(".refresh");
- const modalEl = document.getElementById("intro-modal");
- // const uploadInfoEl = document.getElementById("upload-info");
- const fileUploadEl = document.getElementById("file-upload");
- let volume = 1;
- let effectCanvas;
- let starField;
- let line3D;
- const synthwaveColor = 0xff2975;
-
- openDialog();
- getMusic();
- listenUploadFileChange();
-
- coverArtEl.addEventListener("click", (event) => {
- const isNoPause = event.target.classList.contains("no-pause");
- if (howlerInstance && !isNoPause) {
- togglePlay();
+ let isPlaying = false;
+ let currentTracks = [];
+ let cursor = 0;
+ let howlerInstance;
+ const retroWaveRu = "https://retrowave.ru";
+ let titleEl = document.getElementById("track-name");
+ let coverArtEl = document.getElementsByClassName("music-player")[0];
+ let refreshBtn = document.querySelector(".refresh");
+ let ovr = document.querySelector(".OVR");
+ let fullScreenBtn = document.querySelector(".fullscreen");
+ const modalEl = document.getElementById("intro-modal");
+ // const uploadInfoEl = document.getElementById("upload-info");
+ const fileUploadEl = document.getElementById("file-upload");
+ let volume = 1;
+ let effectCanvas;
+ let starField;
+ let line3D;
+ const synthwaveColor = 0xff2975;
+
+ openDialog();
+ getMusic();
+ listenUploadFileChange();
+
+ function initDynamicTooltips() {
+ document.querySelectorAll("[title]").forEach((element) => {
+ const title = element.getAttribute("title");
+ element.removeAttribute("title");
+ element.setAttribute("data-title", title);
+
+ element.addEventListener("mouseenter", function (e) {
+ const tooltip = document.createElement("div");
+ tooltip.textContent = this.getAttribute("data-title");
+ tooltip.style.cssText = `
+ font-family: "VCR", sans-serif;
+ position: fixed;
+ background:rgb(255, 255, 255);
+ color: #000000;
+ border: 1px solidrgb(0, 0, 0);
+ padding: 4px 8px;
+ font-size: 12px;
+ border-radius: 3px;
+ z-index: 10000;
+ pointer-events: none;
+ white-space: nowrap;
+ `;
+
+ document.body.appendChild(tooltip);
+ this.tooltipEl = tooltip;
+
+ const rect = this.getBoundingClientRect();
+ tooltip.style.left =
+ rect.left + rect.width / 2 - tooltip.offsetWidth / 2 + "px";
+ tooltip.style.top = rect.top - tooltip.offsetHeight - 8 + "px";
+ });
+
+ element.addEventListener("mouseleave", function () {
+ if (this.tooltipEl) {
+ document.body.removeChild(this.tooltipEl);
+ this.tooltipEl = null;
}
+ });
});
+ }
- // uploadInfoEl.addEventListener("click", () => {
- // const confirmText = `Do you really want to change your playlist?\nThis will replace all your retrowave music history.\nIf you are sure about this, make sure to upload a valid json file probably downloaded using history link.`;
-
- // if (confirm(confirmText)) {
- // fileUploadEl.click();
- // }
- // });
-
- function listenUploadFileChange() {
- fileUploadEl.onchange = function () {
- const selectedFile = fileUploadEl.files[0];
- const reader = new FileReader();
- reader.readAsText(selectedFile, "UTF-8");
- reader.onload = function (event) {
- try {
- const uploadedPlaylist = JSON.parse(event.target.result);
- localStorage.setItem("retrowave-history", event.target.result);
-
- } catch (error) {
- alert("malformed/invalid json file");
- }
- };
- };
- }
-
- document.getElementById("initButton")?.addEventListener("click", () => {
- var hydra = new Hydra({ detectAudio: false })
- modalEl.classList.remove("open");
- playMusic();
- initHydra();
- initControls();
- });
-
- document.getElementById("history").addEventListener("click", () => {
- downloadHistory();
- });
-
- document.addEventListener("keyup", (event) => {
- const { key } = event;
- console.log("key pressed", key);
- switch (key) {
- case " ":
- togglePlay();
- break;
- case "a":
- break;
- case "d":
- break;
- case "w":
- volumeUp();
- break;
- case "s":
- volumeDown();
- break;
- case "n":
- playNextTrack();
- break;
-
- }
- });
+ document.addEventListener("DOMContentLoaded", initDynamicTooltips);
- let touchstartX = 0;
- let touchendX = 0;
- let touchstartY = 0;
- let touchendY = 0;
- const musixPlayerEl = document.getElementsByClassName("music-player")[0];
- if (musixPlayerEl) {
- musixPlayerEl.addEventListener("touchstart", (e) => {
- touchstartX = e.changedTouches[0].screenX;
- touchstartY = e.changedTouches[0].screenY;
- });
-
- musixPlayerEl.addEventListener("touchend", (e) => {
- touchendX = e.changedTouches[0].screenX;
- touchendY = e.changedTouches[0].screenY;
- checkDirection();
- });
+ coverArtEl.addEventListener("click", (event) => {
+ const isNoPause = event.target.classList.contains("no-pause");
+ if (howlerInstance && !isNoPause) {
+ togglePlay();
}
-
- function checkDirection() {
- if (touchendX < touchstartX) {
- // Swipe Left
- }
- if (touchendX > touchstartX) {
- // Swipe Right
- }
-
- if (touchendY < touchstartY) {
- volumeUp();
- }
- if (touchendY > touchstartY) {
- volumeDown();
+ });
+
+ // uploadInfoEl.addEventListener("click", () => {
+ // const confirmText = `Do you really want to change your playlist?\nThis will replace all your retrowave music history.\nIf you are sure about this, make sure to upload a valid json file probably downloaded using history link.`;
+
+ // if (confirm(confirmText)) {
+ // fileUploadEl.click();
+ // }
+ // });
+
+ function listenUploadFileChange() {
+ fileUploadEl.onchange = function () {
+ const selectedFile = fileUploadEl.files[0];
+ const reader = new FileReader();
+ reader.readAsText(selectedFile, "UTF-8");
+ reader.onload = function (event) {
+ try {
+ const uploadedPlaylist = JSON.parse(event.target.result);
+ localStorage.setItem("retrowave-history", event.target.result);
+ } catch (error) {
+ alert("malformed/invalid json file");
}
+ };
+ };
+ }
+
+ document.getElementById("initButton")?.addEventListener("click", () => {
+ var hydra = new Hydra({ detectAudio: false });
+ modalEl.classList.remove("open");
+ playMusic();
+ initHydra();
+ initControls();
+ });
+
+ document.getElementById("history").addEventListener("click", () => {
+ downloadHistory();
+ });
+
+ document.addEventListener("keyup", (event) => {
+ const { key } = event;
+ switch (key) {
+ case " ":
+ togglePlay();
+ break;
+ case "a":
+ break;
+ case "d":
+ break;
+ case "w":
+ volumeUp();
+ break;
+ case "s":
+ volumeDown();
+ break;
+ case "n":
+ playNextTrack();
+ break;
+ case "f":
+ toggleFullScreen();
+ break;
+ case "h":
+ toggleControls();
+ break;
+ case 'x':
+ toggleEverything();
}
+ });
+
+ let touchstartX = 0;
+ let touchendX = 0;
+ let touchstartY = 0;
+ let touchendY = 0;
+ const musixPlayerEl = document.getElementsByClassName("music-player")[0];
+ if (musixPlayerEl) {
+ musixPlayerEl.addEventListener("touchstart", (e) => {
+ touchstartX = e.changedTouches[0].screenX;
+ touchstartY = e.changedTouches[0].screenY;
+ });
- function openDialog() {
- modalEl.classList.add("open");
- }
+ musixPlayerEl.addEventListener("touchend", (e) => {
+ touchendX = e.changedTouches[0].screenX;
+ touchendY = e.changedTouches[0].screenY;
+ checkDirection();
+ });
+ }
- async function getMusic() {
- const res = await fetch(
- `https://retrowave.ru/api/v1/tracks?limit=10&cursor=${cursor}`
- ).then((res) => res.json());
- const {
- body: { tracks, cursor: currentCursor },
- } = res;
- cursor = currentCursor;
- currentTracks = tracks;
+ function checkDirection() {
+ if (touchendX < touchstartX) {
+ // Swipe Left
}
-
- function initPlayer() { }
-
- function playMusic() {
- const currentTrack = currentTracks[0];
- const singleTrack = currentTrack.streamUrl;
- const fullTrack = `${retroWaveRu}${singleTrack}`;
- howlerInstance = new Howl({
- src: [fullTrack],
- html5: true,
- onend: function () {
- playNextTrack();
- },
- });
- setVolume();
- isPlaying = true;
- window.hw = howlerInstance
-
- updateInfo(currentTrack);
-
- addToHistory(currentTrack);
- howlerInstance.play();
+ if (touchendX > touchstartX) {
+ // Swipe Right
}
- function volumeDown() {
- console.log(volume);
- if (volume > 0.1) {
- volume -= 0.1;
- }
- setVolume();
+ if (touchendY < touchstartY) {
+ volumeUp();
}
-
- function volumeUp() {
- if (volume < 1) {
- volume += 0.1;
- }
- setVolume();
+ if (touchendY > touchstartY) {
+ volumeDown();
}
+ }
+
+ function openDialog() {
+ modalEl.classList.add("open");
+ }
+
+ async function getMusic() {
+ const res = await fetch(
+ `https://retrowave.ru/api/v1/tracks?limit=10&cursor=${cursor}`
+ ).then((res) => res.json());
+ const {
+ body: { tracks, cursor: currentCursor },
+ } = res;
+ cursor = currentCursor;
+ currentTracks = tracks;
+ }
+
+ function initPlayer() {}
+
+ function playMusic() {
+ const currentTrack = currentTracks[0];
+ const singleTrack = currentTrack.streamUrl;
+ const fullTrack = `${retroWaveRu}${singleTrack}`;
+ howlerInstance = new Howl({
+ src: [fullTrack],
+ html5: true,
+ onend: function () {
+ playNextTrack();
+ },
+ });
+ setVolume();
+ isPlaying = true;
+ window.hw = howlerInstance;
- function setVolume() {
- howlerInstance.volume(volume);
- }
+ updateInfo(currentTrack);
- function togglePlay() {
- isPlaying = !isPlaying;
+ addToHistory(currentTrack);
+ howlerInstance.play();
+ }
- if (isPlaying) {
- howlerInstance.play();
- } else {
- howlerInstance.pause();
- }
+ function volumeDown() {
+ if (volume > 0.1) {
+ volume -= 0.1;
}
+ setVolume();
+ }
- function updateInfo(trackDetails) {
- titleEl.innerText = trackDetails.title;
- document.title = `Now Playing... ${trackDetails.title}`;
- coverArtEl.style.backgroundImage = `url("${retroWaveRu}${trackDetails.artworkUrl}")`;
+ function volumeUp() {
+ if (volume < 1) {
+ volume += 0.1;
}
+ setVolume();
+ }
- function getHistory() {
- let localHistoryStore = localStorage.getItem("retrowave-history") || "[]";
- let historyArray = JSON.parse(localHistoryStore);
- return historyArray;
- }
+ function setVolume() {
+ howlerInstance.volume(volume);
+ }
- function addToHistory(trackDetails) {
- let historyArray = getHistory();
- historyArray.push(trackDetails);
- localStorage.setItem("retrowave-history", JSON.stringify(historyArray));
- }
+ function togglePlay() {
+ isPlaying = !isPlaying;
- function downloadHistory() {
- const historyArray = getHistory();
- let element = document.createElement("a");
- let playListData = '#EXTM3U';
- historyArray.forEach((musicData) => {
- playListData = `${playListData}
+ if (isPlaying) {
+ howlerInstance.play();
+ } else {
+ howlerInstance.pause();
+ }
+ }
+
+ function updateInfo(trackDetails) {
+ titleEl.innerText = trackDetails.title;
+ document.title = `Now Playing... ${trackDetails.title}`;
+ coverArtEl.style.backgroundImage = `url("${retroWaveRu}${trackDetails.artworkUrl}")`;
+ ovr.innerHTML = `${trackDetails.title}`
+ }
+
+ function getHistory() {
+ let localHistoryStore = localStorage.getItem("retrowave-history") || "[]";
+ let historyArray = JSON.parse(localHistoryStore);
+ return historyArray;
+ }
+
+ function addToHistory(trackDetails) {
+ let historyArray = getHistory();
+ historyArray.push(trackDetails);
+ localStorage.setItem("retrowave-history", JSON.stringify(historyArray));
+ }
+
+ function downloadHistory() {
+ const historyArray = getHistory();
+ let element = document.createElement("a");
+ let playListData = "#EXTM3U";
+ historyArray.forEach((musicData) => {
+ playListData = `${playListData}
#EXTINF:${Math.ceil(musicData.duration / 1000)}, ${musicData.title}
https://retrowave.ru/${musicData.streamUrl}
`;
- });
+ });
- element.setAttribute(
- "href",
- "data:audio/x-mpegurl;;charset=utf-8," +
- encodeURIComponent(playListData)
- );
- element.setAttribute("download", "retrowave_playlist.m3u");
+ element.setAttribute(
+ "href",
+ "data:audio/x-mpegurl;;charset=utf-8," + encodeURIComponent(playListData)
+ );
+ element.setAttribute("download", "retrowave_playlist.m3u");
- element.style.display = "none";
- document.body.appendChild(element);
+ element.style.display = "none";
+ document.body.appendChild(element);
- element.click();
+ element.click();
- document.body.removeChild(element);
- }
+ document.body.removeChild(element);
+ }
- function playNextTrack() {
- resetHowler();
- currentTracks.shift();
- if (currentTracks.length <= 3) {
- getMusic();
- }
- playMusic();
+ function playNextTrack() {
+ resetHowler();
+ currentTracks.shift();
+ if (currentTracks.length <= 3) {
+ getMusic();
}
-
- function resetHowler(destroy = false) {
- howlerInstance.stop();
- if (destroy) {
- howlerInstance.unload();
- howlerInstance = null;
- }
+ playMusic();
+ }
+
+ function resetHowler(destroy = false) {
+ howlerInstance.stop();
+ if (destroy) {
+ howlerInstance.unload();
+ howlerInstance = null;
}
+ }
- function initControls() {
- refreshBtn.addEventListener("click", () => {
- playNextTrack();
- });
+ function initControls() {
+ refreshBtn.addEventListener("click", () => {
+ playNextTrack();
+ });
+
+ fullScreenBtn.addEventListener("click", () => {
+ toggleFullScreen();
+ });
+ }
+
+ function toggleFullScreen() {
+ if (!document.fullscreenElement) {
+ document.documentElement.requestFullscreen();
+ } else {
+ if (document.exitFullscreen) {
+ document.exitFullscreen();
+ }
}
+ }
- // function initCodef() {
- // const width = window.innerWidth;
- // const height = window.innerHeight;
- // effectCanvas = new canvas(width, height, 'codef-canvas');
- // starField = new starfield3D(effectCanvas, 500, 2, width, height, width/2, height/2, '#ffffff', 100, 0, 0);
- // line3D = new codef3D(effectCanvas, 320, 75, 1, 1500 );
- // line3D.line({x:-320, y:0, z:0},{x:320, y:0, z:0}, new LineBasicMaterial({ color: synthwaveColor, linewidth:2}));
- // line3D.line({x: 0, y:-240, z:0},{x:0, y:240, z:0}, new LineBasicMaterial({ color: synthwaveColor, linewidth:2}));
- // renderCodeFx();
- // }
-
- // function renderCodeFx() {
- // effectCanvas.fill('#000000');
- // line3D.group.rotation.x+=0.01;
- // line3D.group.rotation.y+=0.02;
- // line3D.group.rotation.z+=0.04;
- // starField.draw();
- // line3D.draw();
- // requestAnimationFrame(renderCodeFx);
- // }
-
- function initHydra() {
- voronoi(350, 0.15)
- .modulateScale(osc(8).rotate(Math.sin(time)), .5)
- .thresh(.8)
- .modulateRotate(osc(7), .4)
- .thresh(.7)
- .diff(src(o0).scale(1.8))
- .modulateScale(osc(2).modulateRotate(o0, .74))
- .diff(src(o0).rotate([-.012, .01, -.002, 0]).scrollY(0, [-1 / 199800, 0].fast(0.7)))
- .brightness([-.02, -.17].smooth().fast(.5))//.modulate(o0, () => a.fft[1] * .2)
- .out()
+ function toggleControls() {
+ const toggleableElements = document.querySelectorAll(".toggleable");
+ toggleableElements.forEach((el) => {
+ el.classList.toggle("hidden");
+ });
+ }
+
+ function toggleEverything() {
+ musixPlayerEl.classList.toggle("hidden");
+ ovr.classList.toggle("hidden");
+ }
+
+ // function initCodef() {
+ // const width = window.innerWidth;
+ // const height = window.innerHeight;
+ // effectCanvas = new canvas(width, height, 'codef-canvas');
+ // starField = new starfield3D(effectCanvas, 500, 2, width, height, width/2, height/2, '#ffffff', 100, 0, 0);
+ // line3D = new codef3D(effectCanvas, 320, 75, 1, 1500 );
+ // line3D.line({x:-320, y:0, z:0},{x:320, y:0, z:0}, new LineBasicMaterial({ color: synthwaveColor, linewidth:2}));
+ // line3D.line({x: 0, y:-240, z:0},{x:0, y:240, z:0}, new LineBasicMaterial({ color: synthwaveColor, linewidth:2}));
+ // renderCodeFx();
+ // }
+
+ // function renderCodeFx() {
+ // effectCanvas.fill('#000000');
+ // line3D.group.rotation.x+=0.01;
+ // line3D.group.rotation.y+=0.02;
+ // line3D.group.rotation.z+=0.04;
+ // starField.draw();
+ // line3D.draw();
+ // requestAnimationFrame(renderCodeFx);
+ // }
+
+ function initHydra() {
+ try {
+ voronoi(350, 0.15)
+ .modulateScale(osc(8).rotate(Math.sin(time)), 0.5)
+ .thresh(0.8)
+ .modulateRotate(osc(7), 0.4)
+ .thresh(0.7)
+ .diff(src(o0).scale(1.8))
+ .modulateScale(osc(2).modulateRotate(o0, 0.74))
+ .diff(
+ src(o0)
+ .rotate([-0.012, 0.01, -0.002, 0])
+ .scrollY(0, [-1 / 199800, 0].fast(0.7))
+ )
+ .brightness([-0.02, -0.17].smooth().fast(0.5)) //.modulate(o0, () => a.fft[1] * .2)
+ .out();
+ } catch (error) {
+ console.error("Hydra initialization failed:", error);
}
+ }
})();