(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]; 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(); } }); // 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(); // initCodef(); }); document.getElementById("history").addEventListener("click", () => { downloadHistory(); }); document.addEventListener("keyup", (event) => { const { key } = event; switch (key) { case "x": togglePlay(); break; case "a": break; case "d": break; case "w": volumeUp(); break; case "s": volumeDown(); break; } }); 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(); }); } function checkDirection() { if (touchendX < touchstartX) { // Swipe Left } if (touchendX > touchstartX) { // Swipe Right } if (touchendY < touchstartY) { volumeUp(); } if (touchendY > touchstartY) { volumeDown(); } } function openDialog() { modalEl.classList.add("open"); } function getMusic() { fetch(`https://retrowave.ru/api/v1/tracks?limit=5&cursor=${cursor}`) .then((res) => res.json()) .then((res) => { 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 () { currentTracks.shift(); if (currentTracks.length <= 3) { getMusic(); } playMusic(); }, }); setVolume(); isPlaying = true; window.hw = howlerInstance updateInfo(currentTrack); addToHistory(currentTrack); howlerInstance.play(); } function volumeDown() { console.log(volume); if (volume > 0.1) { volume -= 0.1; } setVolume(); } function volumeUp() { if (volume < 1) { volume += 0.1; } setVolume(); } function setVolume() { howlerInstance.volume(volume); } function togglePlay() { isPlaying = !isPlaying; 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}")`; } 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.style.display = "none"; document.body.appendChild(element); element.click(); document.body.removeChild(element); } // 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() } })();