mirror of
https://github.com/danbulant/osuVisualizer
synced 2026-06-17 05:21:04 +00:00
Implement BPM visualizer
This commit is contained in:
parent
5b1148733e
commit
8df5ffd202
17 changed files with 1541 additions and 70 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
|
@ -9,6 +9,10 @@ lerna-debug.log*
|
|||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
|
||||
|
||||
# build
|
||||
public/build
|
||||
public/build/*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
|
|
|
|||
18
package-lock.json
generated
18
package-lock.json
generated
|
|
@ -3637,6 +3637,24 @@
|
|||
"os-tmpdir": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"osu-buffer": {
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/osu-buffer/-/osu-buffer-1.3.5.tgz",
|
||||
"integrity": "sha512-9I1JTXwOrkmurmvpUsnOc+StCb4w9nF1KLA52BIDAllXxIf6cw6/xlT+hdz8QIjG4D8DPWRcLyX/1MxNNo7XzA=="
|
||||
},
|
||||
"osu-db-parser": {
|
||||
"version": "1.0.35",
|
||||
"resolved": "https://registry.npmjs.org/osu-db-parser/-/osu-db-parser-1.0.35.tgz",
|
||||
"integrity": "sha512-oG4aSRyzXvVw4XLrghn1usbSxQhlTLJo08ZRbVTAp2+3xP0n1kyn4cG75aGWoOu6M0MU89QL/vhSgYBEyiIc1w==",
|
||||
"requires": {
|
||||
"osu-buffer": "^1.3.2"
|
||||
}
|
||||
},
|
||||
"osu-parser": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/osu-parser/-/osu-parser-0.3.3.tgz",
|
||||
"integrity": "sha1-b8V7qXPfD8pcVU6ligz3keHUUNg="
|
||||
},
|
||||
"p-cancelable": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"name": "osu",
|
||||
"productName": "osu",
|
||||
"version": "1.0.0",
|
||||
"description": "My Electron application description",
|
||||
"description": "Osu! visualizer",
|
||||
"main": "src/index.js",
|
||||
"scripts": {
|
||||
"start": "concurrently \"npm:svelte-dev\" \"electron-forge start\"",
|
||||
|
|
@ -27,7 +27,8 @@
|
|||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {
|
||||
"name": "osu"
|
||||
"name": "osu",
|
||||
"authors": "Daniel Bulant"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
@ -51,6 +52,8 @@
|
|||
"concurrently": "^5.3.0",
|
||||
"electron-reload": "^1.5.0",
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"osu-db-parser": "^1.0.35",
|
||||
"osu-parser": "^0.3.3",
|
||||
"sirv-cli": "^1.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
main.svelte-2x1evt{text-align:center;padding:1em;max-width:240px;margin:0 auto}h1.svelte-2x1evt{color:#ff3e00;text-transform:uppercase;font-size:4em;font-weight:100}@media(min-width: 640px){main.svelte-2x1evt{max-width:none}}
|
||||
main.svelte-5atqf{position:relative;width:100vw;height:100vh}.background.svelte-5atqf{position:fixed;z-index:0;left:0;right:0;width:100vw;height:100vh}.menu.svelte-5atqf{position:absolute;z-index:1;left:0;right:0;width:100vw;height:100vh}
|
||||
.info.svelte-1j9fr45.svelte-1j9fr45{opacity:1;position:relative;top:0;left:0;width:100vw;height:80px;transition:opacity 0.6s;z-index:1}.volume.svelte-1j9fr45.svelte-1j9fr45{opacity:1;position:fixed;z-index:2;right:0;bottom:0;border-radius:50%;color:black;font-size:30px}.hidden.svelte-1j9fr45.svelte-1j9fr45{opacity:0;transition:opacity 1s}.info.svelte-1j9fr45 .song.svelte-1j9fr45{color:white;position:absolute;padding:5px 5px 5px 25px;top:0;right:0;text-align:right;background:black;background:linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.5) 15%, rgba(0,0,0,0.5) 100%)}.info.svelte-1j9fr45 .song h2.svelte-1j9fr45{margin:0}.info.svelte-1j9fr45 .controls.svelte-1j9fr45{height:50px;display:flex}.info.svelte-1j9fr45 .controls div.svelte-1j9fr45{height:100%}.info.svelte-1j9fr45 .controls img.svelte-1j9fr45{height:100%;filter:invert(100%)}
|
||||
.main.svelte-yh70k3.svelte-yh70k3{width:100%;height:100%;background-size:cover;background-repeat:no-repeat}@keyframes svelte-yh70k3-bpm{from{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}to{width:525px;height:525px;top:calc(50vh - 262.5px);left:calc(50vw - 262.5px)}}@keyframes svelte-yh70k3-bpmShadow{0%{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}70%{width:510px;height:510px;top:calc(50vh - 255px);left:calc(50vw - 255px)}100%{width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}}.main.svelte-yh70k3 img.svelte-yh70k3{position:fixed;width:500px;height:500px;top:calc(50vh - 250px);left:calc(50vw - 250px)}.main.svelte-yh70k3 .logo.svelte-yh70k3{animation-name:svelte-yh70k3-bpm;animation-iteration-count:infinite;animation-direction:alternate}.main.svelte-yh70k3 .shadow.svelte-yh70k3{opacity:0.2;animation-name:svelte-yh70k3-bpmShadow;animation-iteration-count:infinite;animation-delay:50ms}
|
||||
|
||||
/*# sourceMappingURL=bundle.css.map */
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
|
|
@ -7,7 +7,7 @@ html, body {
|
|||
body {
|
||||
color: #333;
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
padding: 0px;
|
||||
box-sizing: border-box;
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
|
||||
}
|
||||
|
|
|
|||
41
public/images/logo.svg
Normal file
41
public/images/logo.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 58 KiB |
1
public/images/music_forward.svg
Normal file
1
public/images/music_forward.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" ?><svg id="blue_copy" style="enable-background:new 0 0 100 100;" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="Layer_8_copy_4_1_"><path d="M41.762,27.26v8.294c0,0.571,0.305,1.1,0.8,1.385l20.212,11.669c1.066,0.616,1.066,2.155,0,2.771L42.562,63.048 c-0.495,0.286-0.8,0.814-0.8,1.385v8.294c0,1.231,1.333,2.001,2.399,1.385l39.375-22.733c1.066-0.616,1.066-2.155,0-2.771 L44.161,25.875C43.095,25.259,41.762,26.029,41.762,27.26z"/><path d="M83.537,48.608L44.161,25.875c-0.193-0.112-0.395-0.164-0.597-0.19l37.972,21.923c1.066,0.616,1.066,2.155,0,2.771 L42.161,73.112c-0.1,0.058-0.205,0.092-0.308,0.126c0.308,0.914,1.401,1.398,2.308,0.874l39.375-22.733 C84.603,50.763,84.603,49.224,83.537,48.608z"/><path d="M41.762,27.26v8.294c0,0.571,0.305,1.1,0.8,1.385l20.212,11.669 c1.066,0.616,1.066,2.155,0,2.771L42.562,63.048c-0.495,0.286-0.8,0.814-0.8,1.385v8.294c0,1.231,1.333,2.001,2.399,1.385 l39.375-22.733c1.066-0.616,1.066-2.155,0-2.771L44.161,25.875C43.095,25.259,41.762,26.029,41.762,27.26z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/><path d="M14.664,27.273v8.294c0,0.571,0.305,1.1,0.8,1.385l20.212,11.669c1.066,0.616,1.066,2.155,0,2.771L15.464,63.061 c-0.495,0.286-0.8,0.814-0.8,1.385v8.294c0,1.231,1.333,2.001,2.399,1.385l39.375-22.733c1.066-0.616,1.066-2.155,0-2.771 L17.063,25.888C15.997,25.272,14.664,26.042,14.664,27.273z"/><path d="M56.438,48.621L17.063,25.888c-0.193-0.112-0.395-0.164-0.597-0.19l37.972,21.923c1.066,0.616,1.066,2.155,0,2.771 L15.063,73.125c-0.1,0.058-0.205,0.092-0.308,0.126c0.308,0.914,1.401,1.398,2.308,0.874l39.375-22.733 C57.505,50.776,57.505,49.237,56.438,48.621z"/><path d="M14.664,27.273v8.294c0,0.571,0.305,1.1,0.8,1.385l20.212,11.669 c1.066,0.616,1.066,2.155,0,2.771L15.464,63.061c-0.495,0.286-0.8,0.814-0.8,1.385v8.294c0,1.231,1.333,2.001,2.399,1.385 l39.375-22.733c1.066-0.616,1.066-2.155,0-2.771L17.063,25.888C15.997,25.272,14.664,26.042,14.664,27.273z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/></g></svg>
|
||||
|
After Width: | Height: | Size: 2.1 KiB |
1
public/images/music_pause.svg
Normal file
1
public/images/music_pause.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" ?><svg id="blue_copy" style="enable-background:new 0 0 100 100;" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="Layer_7_copy"><path d="M39.806,72.858h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.119c0-2.176,1.764-3.94,3.94-3.94h8.915 c2.176,0,3.94,1.764,3.94,3.94v37.799C43.746,71.094,41.982,72.858,39.806,72.858z"/><path d="M68.109,72.821h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.082c0-2.176,1.764-3.94,3.94-3.94h8.915 c2.176,0,3.94,1.764,3.94,3.94v37.799C72.049,71.057,70.285,72.821,68.109,72.821z"/><path d="M40.489,27.248c0.769,0.719,1.257,1.735,1.257,2.871v37.799c0,2.176-1.764,3.94-3.94,3.94h-8.915 c-0.234,0-0.46-0.03-0.683-0.069c0.704,0.658,1.643,1.069,2.683,1.069h8.915c2.176,0,3.94-1.764,3.94-3.94V31.119 C43.746,29.177,42.338,27.573,40.489,27.248z"/><path d="M68.792,27.211c0.769,0.719,1.257,1.735,1.257,2.871v37.799c0,2.176-1.764,3.94-3.94,3.94h-8.915 c-0.234,0-0.46-0.03-0.683-0.069c0.704,0.658,1.643,1.069,2.683,1.069h8.915c2.176,0,3.94-1.764,3.94-3.94V31.082 C72.049,29.14,70.641,27.535,68.792,27.211z"/><path d="M39.806,72.858h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.119 c0-2.176,1.764-3.94,3.94-3.94h8.915c2.176,0,3.94,1.764,3.94,3.94v37.799C43.746,71.094,41.982,72.858,39.806,72.858z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/><path d="M68.109,72.821h-8.915c-2.176,0-3.94-1.764-3.94-3.94V31.082 c0-2.176,1.764-3.94,3.94-3.94h8.915c2.176,0,3.94,1.764,3.94,3.94v37.799C72.049,71.057,70.285,72.821,68.109,72.821z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
1
public/images/music_play.svg
Normal file
1
public/images/music_play.svg
Normal file
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" ?><svg id="blue_copy" style="enable-background:new 0 0 100 100;" version="1.1" viewBox="0 0 100 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><g id="Layer_4_copy"><path d="M31.356,25.677l38.625,22.3c1.557,0.899,1.557,3.147,0,4.046l-38.625,22.3c-1.557,0.899-3.504-0.225-3.504-2.023V27.7 C27.852,25.902,29.798,24.778,31.356,25.677z"/><path d="M69.981,47.977l-38.625-22.3c-0.233-0.134-0.474-0.21-0.716-0.259l37.341,21.559c1.557,0.899,1.557,3.147,0,4.046 l-38.625,22.3c-0.349,0.201-0.716,0.288-1.078,0.301c0.656,0.938,1.961,1.343,3.078,0.699l38.625-22.3 C71.538,51.124,71.538,48.876,69.981,47.977z"/><path d="M31.356,25.677l38.625,22.3c1.557,0.899,1.557,3.147,0,4.046 l-38.625,22.3c-1.557,0.899-3.504-0.225-3.504-2.023V27.7C27.852,25.902,29.798,24.778,31.356,25.677z" style="fill:none;stroke:#000000;stroke-miterlimit:10;"/></g></svg>
|
||||
|
After Width: | Height: | Size: 916 B |
|
|
@ -4,7 +4,7 @@
|
|||
<meta charset='utf-8'>
|
||||
<meta name='viewport' content='width=device-width,initial-scale=1'>
|
||||
|
||||
<title>Svelte app</title>
|
||||
<title>Osu visualizer</title>
|
||||
|
||||
<link rel='icon' type='image/png' href='./favicon.png'>
|
||||
<link rel='stylesheet' href='./global.css'>
|
||||
|
|
|
|||
|
|
@ -1,28 +1,41 @@
|
|||
<script>
|
||||
let name = "world";
|
||||
import Menu from "./Menu.svelte";
|
||||
import Visualizer from "./Visualizer.svelte";
|
||||
|
||||
var songData = {};
|
||||
|
||||
var osuData = {};
|
||||
</script>
|
||||
|
||||
<main>
|
||||
<h1>Hello {name}!</h1>
|
||||
<p>Visit the <a href="https://svelte.dev/tutorial">Svelte tutorial</a> to learn how to build Svelte apps.</p>
|
||||
<div class="background">
|
||||
<Visualizer bind:songData bind:osuData/>
|
||||
</div>
|
||||
<div class="menu">
|
||||
<Menu bind:song={songData} bind:osuData/>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<style>
|
||||
main {
|
||||
text-align: center;
|
||||
padding: 1em;
|
||||
max-width: 240px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
h1 {
|
||||
color: #ff3e00;
|
||||
text-transform: uppercase;
|
||||
font-size: 4em;
|
||||
font-weight: 100;
|
||||
}
|
||||
@media (min-width: 640px) {
|
||||
main {
|
||||
max-width: none;
|
||||
}
|
||||
}
|
||||
main {
|
||||
position: relative;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
.background {
|
||||
position: fixed;
|
||||
z-index: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
.menu {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
right: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
179
src/Menu.svelte
Normal file
179
src/Menu.svelte
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
<script>
|
||||
export var osuData;
|
||||
export var song;
|
||||
|
||||
var last = Date.now();
|
||||
var lastVolumeUpdate = Date.now() - 5000;
|
||||
var dialogActive = false;
|
||||
var now = Date.now();
|
||||
|
||||
setInterval(() => {
|
||||
now = Date.now();
|
||||
}, 500);
|
||||
|
||||
var playing = true;
|
||||
|
||||
function resetPool() {
|
||||
if(!osuData.songs) return false;
|
||||
osuData.songPool = osuData.songs.filter(v => true);
|
||||
let a = osuData.songPool;
|
||||
for (let i = a.length - 1; i > 0; i--) { // shuffle
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[a[i], a[j]] = [a[j], a[i]];
|
||||
}
|
||||
song = osuData.songPool.shift();
|
||||
}
|
||||
|
||||
function playNext() {
|
||||
if(song.audio) {
|
||||
song.audio.pause();
|
||||
}
|
||||
if(osuData.songPool.length) {
|
||||
song = osuData.songPool.shift();
|
||||
} else {
|
||||
resetPool();
|
||||
}
|
||||
}
|
||||
|
||||
$: resetPool(osuData.songs);
|
||||
|
||||
$: console.log(song);
|
||||
|
||||
$: {
|
||||
if(song && song.folder && !song.audio) {
|
||||
song.audio = new Audio(process.env.USERPROFILE + "/AppData/Local/osu!/Songs/" + song.folder + "/" + song.audioFile);
|
||||
song.audio.play();
|
||||
|
||||
song.audio.onended = () => {
|
||||
playNext();
|
||||
}
|
||||
song.audio.onpause = () => {
|
||||
playing = false;
|
||||
}
|
||||
song.audio.onplay = () => {
|
||||
playing = true;
|
||||
}
|
||||
if ('mediaSession' in navigator) {
|
||||
navigator.mediaSession.metadata = new MediaMetadata({
|
||||
title: song.song,
|
||||
artist: song.artist,
|
||||
album: "Osu! visualizer",
|
||||
artwork: [
|
||||
{ src: process.env.USERPROFILE + "/AppData/Local/osu!/Data/bt/" + song.id + ".jpg", type: 'image/jpeg' },
|
||||
]
|
||||
});
|
||||
|
||||
navigator.mediaSession.setActionHandler('play', function() { playing = true; song.audio.play(); });
|
||||
navigator.mediaSession.setActionHandler('pause', function() { playing = false; song.audio.pause(); });
|
||||
navigator.mediaSession.setActionHandler('nexttrack', function() { playNext()});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function togglePlay() {
|
||||
playing = !playing;
|
||||
if(playing) {
|
||||
song.audio.play();
|
||||
} else {
|
||||
song.audio.pause();
|
||||
}
|
||||
}
|
||||
|
||||
function updateVolume(e) {
|
||||
if(!song || !song.audio || !e.altKey) return;
|
||||
lastVolumeUpdate = Date.now();
|
||||
var volume = song.audio.volume;
|
||||
volume += e.deltaY * -0.0005;
|
||||
song.audio.volume = Math.min(1, Math.max(volume, 0));
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
song = song;
|
||||
}, 200);
|
||||
</script>
|
||||
|
||||
<svelte:window on:mousemove={() => last = Date.now()} on:wheel={e => updateVolume(e)} />
|
||||
|
||||
<div class="menu">
|
||||
<div class="info" class:hidden={now - last > 2000}>
|
||||
{#if song}
|
||||
<div class="song">
|
||||
<h2>{song.artist} - {song.song}</h2>
|
||||
<div class="controls">
|
||||
<div class="play" on:click={togglePlay}>
|
||||
<img src="images/music_{playing ? "pause" : "play"}.svg" alt="{playing ? "Pause" : "Play"} music" title="{playing ? "Pause" : "Play"} music">
|
||||
</div>
|
||||
<div class="forward" on:click={playNext}>
|
||||
<img src="images/music_forward.svg" alt="Skip the song" title="Skip the song">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{#if now - lastVolumeUpdate < 4000 && song && song.audio}
|
||||
<div class="volume" class:hidden={now - lastVolumeUpdate > 2000}>
|
||||
<div class="slider">
|
||||
<div class="percent">
|
||||
{Math.round(song.audio.volume * 100)}%
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.info {
|
||||
opacity: 1;
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 80px;
|
||||
transition: opacity 0.6s;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.volume {
|
||||
opacity: 1;
|
||||
position: fixed;
|
||||
z-index: 2;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
border-radius: 50%;
|
||||
color: black;
|
||||
font-size: 30px;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
opacity: 0;
|
||||
transition: opacity 1s;
|
||||
}
|
||||
|
||||
.info .song {
|
||||
color: white;
|
||||
position: absolute;
|
||||
padding: 5px 5px 5px 25px;
|
||||
top: 0;
|
||||
right: 0;
|
||||
text-align: right;
|
||||
background: black;
|
||||
|
||||
background: linear-gradient(90deg, transparent 0%, rgba(0,0,0,0.5) 15%, rgba(0,0,0,0.5) 100%);
|
||||
}
|
||||
|
||||
.info .song h2 {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.info .controls {
|
||||
height: 50px;
|
||||
display: flex;
|
||||
}
|
||||
.info .controls div {
|
||||
height: 100%;
|
||||
}
|
||||
.info .controls img {
|
||||
height: 100%;
|
||||
filter: invert(100%);
|
||||
}
|
||||
</style>
|
||||
177
src/Visualizer.svelte
Normal file
177
src/Visualizer.svelte
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
<script>
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
const fs = require("fs");
|
||||
const OsuDBParser = require("osu-db-parser");
|
||||
const osuParser = require("osu-parser");
|
||||
export var osuData;
|
||||
export var songData;
|
||||
|
||||
var wallpapers = [];
|
||||
try {
|
||||
wallpapers = fs.readdirSync(process.env.USERPROFILE + "/AppData/Local/osu!/Data/bg");
|
||||
} catch(e) {
|
||||
console.error("Osu backgrounds weren't found. You must have osu installed and started at least once.", e);
|
||||
alert("Osu backgrounds not found!");
|
||||
}
|
||||
|
||||
try {
|
||||
osuData = (new OsuDBParser(Buffer.from(fs.readFileSync(process.env.USERPROFILE + "/AppData/Local/osu!/osu!.db")))).getOsuDBData();
|
||||
console.log(osuData);
|
||||
osuData.songs = osuData.beatmaps.map(v => ({
|
||||
artist: v.artist_name,
|
||||
artist_u: v.artist_name_unicode,
|
||||
audioFile: v.audio_file_name,
|
||||
folder: v.folder_name,
|
||||
song: v.song_title,
|
||||
song_u: v.song_title_unicode,
|
||||
id: v.beatmapset_id,
|
||||
dataFile: `${v.artist_name} - ${v.song_title} (${v.creator_name}) [${v.difficulty}].osu`
|
||||
})).filter((v, i, a) => a.findIndex(x => x.id === v.id) === i);
|
||||
} catch(e) {
|
||||
console.error("Osu DB weren't found. You must have osu installed and started at least once.", e);
|
||||
alert("Osu DB not found!");
|
||||
}
|
||||
|
||||
var wallpaper;
|
||||
function shuffleWallpapers() {
|
||||
wallpaper = wallpapers[Math.floor(Math.random() * wallpapers.length)];
|
||||
}
|
||||
|
||||
var lastSong = null;
|
||||
|
||||
$: {
|
||||
if(songData !== lastSong) {
|
||||
lastSong = songData;
|
||||
shuffleWallpapers();
|
||||
}
|
||||
}
|
||||
function fetchBeatmap() {
|
||||
let file = fs.readFileSync(process.env.USERPROFILE + "/AppData/Local/osu!/Songs/" + songData.folder + "/" + songData.dataFile);
|
||||
songData.beatmap = osuParser.parseContent(file);
|
||||
}
|
||||
$: if(songData && songData.dataFile && !songData.beatmap) fetchBeatmap();
|
||||
|
||||
var mouse = {
|
||||
x: 0.5,
|
||||
y: 0.5
|
||||
};
|
||||
|
||||
const parallaxTreshold = 10;
|
||||
|
||||
function updateMouse(e) {
|
||||
mouse = {
|
||||
x: -(e.clientX / window.innerWidth) * parallaxTreshold - parallaxTreshold/2,
|
||||
y: -(e.clientY / window.innerHeight) * parallaxTreshold - parallaxTreshold/2
|
||||
}
|
||||
}
|
||||
|
||||
var isWidthSmaller = false;
|
||||
|
||||
function resize() {
|
||||
isWidthSmaller = window.innerWidth * 9 < window.innerHeight * 16;
|
||||
}
|
||||
resize();
|
||||
|
||||
var animDuration = 0;
|
||||
var kiaiTime = false;
|
||||
|
||||
setInterval(() => {
|
||||
if(!songData) return;
|
||||
if(!songData.beatmap && songData.dataFile) fetchBeatmap();
|
||||
if(!songData.beatmap) return;
|
||||
|
||||
var tp = null;
|
||||
for(var t of songData.beatmap.timingPoints) {
|
||||
if(t.offset > songData.audio.currentTime * 1000) break;
|
||||
tp = t;
|
||||
}
|
||||
if(!tp) {
|
||||
animDuration = 0;
|
||||
kiaiTime = false;
|
||||
return;
|
||||
}
|
||||
if(tp.beatLength/2 !== animDuration)
|
||||
animDuration = tp.beatLength/2;
|
||||
kiaiTime = tp.kiaiTimeActive;
|
||||
}, 50);
|
||||
</script>
|
||||
|
||||
<svelte:window on:mousemove={updateMouse} on:resize={resize} />
|
||||
|
||||
<div
|
||||
class="main"
|
||||
style="
|
||||
background-image: url('{process.env.USERPROFILE.replace(/\\/g, "/")}/AppData/Local/osu!/Data/bg/{wallpaper}');
|
||||
background-size: {!isWidthSmaller ? `calc(100% + ${parallaxTreshold * 1.5}px) auto` : `auto calc(100% + ${parallaxTreshold * 1.5}px)`};
|
||||
background-position: {mouse.x}px {mouse.y}px;
|
||||
"
|
||||
>
|
||||
<img src="images/logo.svg" alt="logo" class="logo" style="animation-duration: {animDuration}ms;">
|
||||
<img src="images/logo.svg" alt="" class="shadow" style="animation-duration: {animDuration * 2}ms;">
|
||||
</div>
|
||||
|
||||
<style>
|
||||
.main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-size: cover;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
@keyframes bpm {
|
||||
from {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
top: calc(50vh - 250px);
|
||||
left: calc(50vw - 250px);
|
||||
}
|
||||
to {
|
||||
width: 525px;
|
||||
height: 525px;
|
||||
top: calc(50vh - 262.5px);
|
||||
left: calc(50vw - 262.5px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes bpmShadow {
|
||||
0% {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
top: calc(50vh - 250px);
|
||||
left: calc(50vw - 250px);
|
||||
}
|
||||
70% {
|
||||
width: 510px;
|
||||
height: 510px;
|
||||
top: calc(50vh - 255px);
|
||||
left: calc(50vw - 255px);
|
||||
}
|
||||
100% {
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
top: calc(50vh - 250px);
|
||||
left: calc(50vw - 250px);
|
||||
}
|
||||
}
|
||||
|
||||
.main img {
|
||||
position: fixed;
|
||||
width: 500px;
|
||||
height: 500px;
|
||||
top: calc(50vh - 250px);
|
||||
left: calc(50vw - 250px);
|
||||
}
|
||||
|
||||
.main .logo {
|
||||
animation-name: bpm;
|
||||
animation-iteration-count: infinite;
|
||||
animation-direction: alternate;
|
||||
}
|
||||
|
||||
.main .shadow {
|
||||
opacity: 0.2;
|
||||
animation-name: bpmShadow;
|
||||
animation-iteration-count: infinite;
|
||||
animation-delay: 50ms;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -6,12 +6,19 @@ if (require('electron-squirrel-startup')) { // eslint-disable-line global-requir
|
|||
app.quit();
|
||||
}
|
||||
|
||||
app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required');
|
||||
|
||||
const createWindow = () => {
|
||||
// Create the browser window.
|
||||
const mainWindow = new BrowserWindow({
|
||||
width: 800,
|
||||
height: 600,
|
||||
webPreferences: {
|
||||
nodeIntegration: true
|
||||
},
|
||||
autoHideMenuBar: true
|
||||
});
|
||||
mainWindow.setMenu(null);
|
||||
|
||||
// and load the index.html of the app.
|
||||
mainWindow.loadFile(path.join(__dirname, '../public/index.html'));
|
||||
|
|
|
|||
Loading…
Reference in a new issue