Project stuff
10
.gitmodules
vendored
|
@ -1,3 +1,9 @@
|
|||
[submodule "views/projects/midsim"]
|
||||
path = views/projects/midsim
|
||||
[submodule "views/projects/item/midsim"]
|
||||
path = views/projects/item/midsim
|
||||
url = https://git.abtmtr.link/MeowcaTheoRange/Mid-Simulator
|
||||
[submodule "views/projects/item/clock"]
|
||||
path = views/projects/item/clock
|
||||
url = https://git.abtmtr.link/MeowcaTheoRange/Clock
|
||||
[submodule "views/projects/item/dice"]
|
||||
path = views/projects/item/dice
|
||||
url = https://git.abtmtr.link/MeowcaTheoRange/DiceApp
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
"dev": "nodemon --exec 'rm -rf output/*;gulp;node debug.js' --ext '*' --ignore 'output/*'"
|
||||
},
|
||||
"devDependencies": {
|
||||
"gulp": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"gulp": "^4.0.2",
|
||||
"express": "^4.18.2",
|
||||
"through2": "^4.0.2"
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@
|
|||
<script src="/scripts/windows.js"></script>
|
||||
<script src="/scripts/accessibility.js"></script>
|
||||
<script src="./scripts/data_get_whoami.js"></script>
|
||||
<script src="/projects/hex/scripts/index.js"></script>
|
||||
<script src="/projects/item/hex/scripts/index.js"></script>
|
||||
<script>
|
||||
window.manager = new WindowManager(
|
||||
document.getElementById("WindowHolder")
|
||||
|
|
7
views/projects/item/clock/README.md
Normal file
|
@ -0,0 +1,7 @@
|
|||
# Clock
|
||||
|
||||
Budda dawg. Dawg with the budda. Put the budda on 'im :]
|
||||
|
||||
Partially done on a SMART Board. It was painful.
|
||||
|
||||
[jqtp.js](/jqtp.js) courtesy of [furf](https://github.com/furf) ([JQuery Touch Punch](https://github.com/furf/jquery-ui-touch-punch))
|
BIN
views/projects/item/clock/assets/chemistry.png
Normal file
After Width: | Height: | Size: 830 B |
BIN
views/projects/item/clock/assets/clock.png
Normal file
After Width: | Height: | Size: 1.5 KiB |
BIN
views/projects/item/clock/assets/clock2.png
Normal file
After Width: | Height: | Size: 1 KiB |
BIN
views/projects/item/clock/assets/hourglass.png
Normal file
After Width: | Height: | Size: 986 B |
BIN
views/projects/item/clock/assets/interro.png
Normal file
After Width: | Height: | Size: 874 B |
BIN
views/projects/item/clock/assets/mark.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
views/projects/item/clock/assets/none.png
Normal file
After Width: | Height: | Size: 143 B |
BIN
views/projects/item/clock/assets/rainbow.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
views/projects/item/clock/assets/sport.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
views/projects/item/clock/assets/sussy.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
views/projects/item/clock/assets/tile.png
Normal file
After Width: | Height: | Size: 453 B |
BIN
views/projects/item/clock/assets/tile2.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
views/projects/item/clock/assets/tones/beethoven.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/megalo.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/none.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/ringer.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/ringer2.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/sweet.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/tone.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/twinkle.mp3
Normal file
BIN
views/projects/item/clock/assets/tones/violin.mp3
Normal file
BIN
views/projects/item/clock/assets/trans.png
Normal file
After Width: | Height: | Size: 423 B |
150
views/projects/item/clock/canvas.js
Normal file
|
@ -0,0 +1,150 @@
|
|||
var tone = new Audio();
|
||||
|
||||
document.querySelectorAll(".clock").forEach((clock) => {
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.resetTransform();
|
||||
ctx.translate(32, 32);
|
||||
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--foreground');
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = "round";
|
||||
update();
|
||||
});
|
||||
document.querySelectorAll(".timer").forEach((clock) => {
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.resetTransform();
|
||||
ctx.translate(32, 32);
|
||||
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--foreground');
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = "round";
|
||||
update();
|
||||
});
|
||||
function update() {
|
||||
document.querySelectorAll(".clock").forEach((clock, i) => {
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--foreground');
|
||||
if (clock.classList.contains("main-clock")) return;
|
||||
ctx.resetTransform();
|
||||
ctx.translate(32, 32);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = "round";
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
var now = new Date();
|
||||
var hour = now.toLocaleTimeString(undefined, {
|
||||
timeZone: clock.dataset.timezone,
|
||||
hour: "2-digit",
|
||||
hour12: false
|
||||
}) % 12;
|
||||
var minute = now.getMinutes();
|
||||
clock.querySelector(".timezone").innerHTML = now.toLocaleDateString(undefined, {
|
||||
timeZone: clock.dataset.timezone,
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
weekday: "long",
|
||||
timeZoneName: 'long'
|
||||
});
|
||||
clock.querySelector(".title").innerHTML = now.toLocaleTimeString(undefined, {
|
||||
timeZone: clock.dataset.timezone,
|
||||
hc: "h12", timeStyle: "short"
|
||||
});
|
||||
ctx.clearRect(-32,-32, 64, 64);
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, 30, 0, Math.PI * 2);
|
||||
ctx.stroke();
|
||||
drawHand(ctx, (hour*Math.PI/6)+(minute*Math.PI/(6*60)), 16);
|
||||
drawHand(ctx, (minute*Math.PI/30), 24);
|
||||
});
|
||||
}
|
||||
|
||||
function drawHand(ctx, pos, length) {
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0,0);
|
||||
ctx.rotate(pos);
|
||||
ctx.lineTo(0, -length);
|
||||
ctx.stroke();
|
||||
ctx.rotate(-pos);
|
||||
}
|
||||
|
||||
var theClock = document.querySelector(".main-clock");
|
||||
var prevMin = new Date().getMinutes();
|
||||
function updateMain() {
|
||||
var canvas = theClock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
var now = new Date();
|
||||
var hour = now.getHours() % 12;
|
||||
var minute = now.getMinutes();
|
||||
if (prevMin != minute) update();
|
||||
prevMin = minute;
|
||||
theClock.querySelector(".timezone").innerHTML = now.toLocaleDateString(undefined, {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
weekday: "long",
|
||||
timeZoneName: 'long'
|
||||
});
|
||||
theClock.querySelector(".title").innerHTML = now.toLocaleTimeString(undefined, {
|
||||
hc: "h12", timeStyle: "short"
|
||||
});
|
||||
ctx.clearRect(-32,-32, 64, 64);
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, 30, 0, Math.PI * 2);
|
||||
ctx.stroke();
|
||||
drawHand(ctx, (hour*Math.PI/6)+(minute*Math.PI/(6*60)), 16);
|
||||
drawHand(ctx, (minute*Math.PI/30), 24);
|
||||
window.requestAnimationFrame(updateMain);
|
||||
}
|
||||
|
||||
window.requestAnimationFrame(updateMain);
|
||||
|
||||
function updateTimer() {
|
||||
document.querySelectorAll(".timer-enabled").forEach((clock, i) => {
|
||||
var timer = clock.dataset.time;
|
||||
var mins = Math.floor(timer / 60);
|
||||
mins = (mins < 10 ? "0" + mins : mins);
|
||||
var secs = timer % 60;
|
||||
secs = (secs < 10 ? "0" + secs : secs);
|
||||
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.strokeStyle = getComputedStyle(document.documentElement).getPropertyValue('--foreground');
|
||||
ctx.resetTransform();
|
||||
ctx.translate(32, 32);
|
||||
ctx.lineWidth = 2;
|
||||
ctx.lineCap = "round";
|
||||
var canvas = clock.querySelector("canvas");
|
||||
var ctx = canvas.getContext("2d");
|
||||
clock.querySelector(".mins").innerHTML = mins;
|
||||
clock.querySelector(".seconds").innerHTML = secs;
|
||||
ctx.clearRect(-32,-32, 64, 64);
|
||||
ctx.beginPath();
|
||||
ctx.arc(0, 0, 30, 0, Math.PI * 2);
|
||||
ctx.stroke();
|
||||
drawHand(ctx, (secs*Math.PI/30), 16);
|
||||
});
|
||||
}
|
||||
|
||||
setInterval(() => {
|
||||
document.querySelectorAll(".timer-enabled:not(.timer-paused)").forEach((clock, i) => {
|
||||
var timer = clock.dataset.time;
|
||||
var bool = clock.dataset.ctp == "true";
|
||||
clock.dataset.time--;
|
||||
if (bool) {
|
||||
document.querySelector(".poplight .press").classList.remove("popped");
|
||||
}
|
||||
if (timer <= 0) {
|
||||
clock.classList.remove("timer-enabled");
|
||||
tone.src = "./assets/tones/" + clock.dataset.tone + ".mp3";
|
||||
tone.currentTime = 0;
|
||||
tone.play();
|
||||
if (bool) {
|
||||
document.querySelector(".poplight .press").classList.add("popped");
|
||||
}
|
||||
}
|
||||
});
|
||||
updateTimer();
|
||||
}, 1000);
|
||||
updateTimer();
|
BIN
views/projects/item/clock/favicon.ico
Normal file
After Width: | Height: | Size: 1.1 KiB |
356
views/projects/item/clock/index.html
Normal file
|
@ -0,0 +1,356 @@
|
|||
<!DOCTYPE html>
|
||||
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
|
||||
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
|
||||
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
|
||||
<!--[if gt IE 8]> <html class="no-js"> <!--<![endif]-->
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>FunnyClock²</title>
|
||||
<link rel="stylesheet" href="./styles/root.css">
|
||||
<link rel="stylesheet" href="./styles/clock.css">
|
||||
<link rel="stylesheet" href="./styles/style.css">
|
||||
<link rel="stylesheet" href="./styles/dialog.css">
|
||||
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined" rel="stylesheet" />
|
||||
<script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
|
||||
<script src="https://code.jquery.com/ui/1.13.0/jquery-ui.min.js" integrity="sha256-hlKLmzaRlE8SCJC1Kw8zoUbU8BxA+8kR3gseuKfMjxA=" crossorigin="anonymous"></script>
|
||||
<script src="jqtp.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="back"></div>
|
||||
<div id="backconstrain"></div>
|
||||
<div class="header">
|
||||
<div>
|
||||
<button class="material-symbols-outlined hiw" data-title="Menu" onclick="this.parentElement.parentElement.classList.toggle('wide')">menu</button>
|
||||
<sep></sep>
|
||||
<button class="material-symbols-outlined" data-title="Add World Clock" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-timezone--').classList.add('open');">schedule</button>
|
||||
<button class="material-symbols-outlined" data-title="Add Timer" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-timer--').classList.add('open');">timer</button>
|
||||
<button class="material-symbols-outlined" data-title="Add Note" onclick="addNote();">description</button>
|
||||
<button class="material-symbols-outlined" data-title="Add Checklist" onclick="addChecklist();">checklist</button>
|
||||
</div>
|
||||
<div>
|
||||
<button class="material-symbols-outlined" data-title="Customize Color" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-dialog--').classList.add('open');">palette</button>
|
||||
<button class="material-symbols-outlined" data-title="Open Fullscreen" onclick="openFullscreen();">fullscreen</button>
|
||||
<button class="material-symbols-outlined" data-title="About FunnyClock²" onclick="document.querySelector('.header').classList.remove('wide');document.querySelector('.scr-about--').classList.add('open');">info</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="body">
|
||||
<div class="clock main-clock">
|
||||
<canvas width="64" height="64"></canvas><!--
|
||||
--><div class="labels">
|
||||
<h1 class="title">Loading...</h1><br />
|
||||
<p class="timezone">Loading...</p>
|
||||
</div><br />
|
||||
<textarea class="txt" title="Notes" placeholder="Take some notes..." oninput='this.style.height = "";this.style.height = this.scrollHeight + "px"'></textarea>
|
||||
</div>
|
||||
<div class="dialog" id="updatedialog" style="display: none;">
|
||||
<p class="dlg-top">There's an update!</p>
|
||||
<p>You should restart - there's a new update of FunnyClock².</p>
|
||||
<small id="updatesha">If you can see this message, well, you shouldn't! It's an error~!</small>
|
||||
<br />
|
||||
<div>
|
||||
<button onclick="location.reload(true)">UPDATE</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="poplight">
|
||||
<button class="hide material-symbols-outlined" data-title="Toggle Poplight Size" onclick="checkHeight(this.parentElement)">unfold_less</button>
|
||||
<div class="drag material-symbols-outlined" data-title="Drag Poplight" ondblclick="checkHeight(this.parentElement)">open_with</div>
|
||||
<button class="press material-symbols-outlined popped" onclick="this.classList.toggle('popped')"></button>
|
||||
</div>
|
||||
<div class="scrim-over-- scr-dialog--">
|
||||
<div class="dialog" id="colordia">
|
||||
<form id="color">
|
||||
<p class="dlg-top">Customize Color</p>
|
||||
<input type="radio" name="color" id="colorred" value="#FF0000|#400000|#800000|#FFFFFF" /><!--
|
||||
--><label for="colorred" style="background-color:#800000">RED</label><!--
|
||||
--><input type="radio" name="color" id="coloramber" value="#f2aa58|#582007|#7c300a|#FFFFFF" /><!--
|
||||
--><label for="coloramber" style="background-color:#7c300a">AMBER</label><!--
|
||||
--><input type="radio" name="color" id="colororange" value="#FF8000|#402000|#804000|#FFFFFF" /><!--
|
||||
--><label for="colororange" style="background-color:#804000">ORANGE</label><!--
|
||||
--><input type="radio" name="color" id="coloryellow" value="#FFFF00|#404000|#808000|#FFFFFF" /><!--
|
||||
--><label for="coloryellow" style="background-color:#808000">YELLOW</label><!--
|
||||
--><input type="radio" name="color" id="colorgreen" value="#00FF00|#003000|#006000|#FFFFFF" /><!--
|
||||
--><label for="colorgreen" style="background-color:#006000">GREEN</label><!--
|
||||
--><input type="radio" name="color" id="colorblue" value="#00FFFF|#003040|#006080|#FFFFFF" /><!--
|
||||
--><label for="colorblue" style="background-color:#006080">BLUE</label><!--
|
||||
--><input type="radio" name="color" id="colornavy" value="#5865f2|#08116a|#0b168e|#FFFFFF" /><!--
|
||||
--><label for="colornavy" style="background-color:#0b168e">NAVY</label><!--
|
||||
--><input type="radio" name="color" id="colorpurple" value="#FF00FF|#300030|#600060|#FFFFFF" /><!--
|
||||
--><label for="colorpurple" style="background-color:#600060">PURPLE</label><!--
|
||||
--><input type="radio" name="color" id="colordark" value="#FFFF00|#202020|#404040|#FFFFFF" checked /><!--
|
||||
--><label for="colordark" style="background-color:#404040">DARK</label><!--
|
||||
--><input type="radio" name="color" id="colorlight" value="#FFFF00|#d0d0d0|#b0b0b0|#000000" /><!--
|
||||
--><label for="colorlight" style="background-color:#d0d0d0;color:#000000;">LIGHT</label><br /><!--
|
||||
--><input type="radio" name="color" id="colortrans" value="#FF00FF|url(../assets/trans.png)|#004040|#FFFFFF" /><!--
|
||||
--><label for="colortrans" style="background:url(./assets/trans.png)">TRANS</label><!--
|
||||
--><input type="radio" name="color" id="colorrainbow" value="#FFFFFF|url(../assets/rainbow.png)|#400000|#FFFFFF" /><!--
|
||||
--><label for="colorrainbow" style="background:url(./assets/rainbow.png)">RAINBOW</label><br />
|
||||
<p class="dlg-top">Customize Background</p>
|
||||
<input type="radio" name="background" id="bgnone" value="../assets/none.png" /><!--
|
||||
--><label for="bgnone" style="background-image: url(./assets/none.png)">NOTHING</label><!--
|
||||
--><input type="radio" name="background" id="bgclocks" value="../assets/clock.png" checked /><!--
|
||||
--><label for="bgclocks" style="background-image: url(./assets/clock.png)">CLOCKS</label><!--
|
||||
--><input type="radio" name="background" id="bgclockstwo" value="../assets/clock2.png" /><!--
|
||||
--><label for="bgclockstwo" style="background-image: url(./assets/clock2.png)">CLOCKS 2</label><!--
|
||||
--><input type="radio" name="background" id="bgsus" value="../assets/sussy.png" /><!--
|
||||
--><label for="bgsus" style="background-image: url(./assets/sussy.png)">SUSSY</label><!--
|
||||
--><input type="radio" name="background" id="bghour" value="../assets/hourglass.png" /><!--
|
||||
--><label for="bghour" style="background-image: url(./assets/hourglass.png)">WORKING</label><!--
|
||||
--><input type="radio" name="background" id="bginter" value="../assets/interro.png" /><!--
|
||||
--><label for="bginter" style="background-image: url(./assets/interro.png)">INTERRO</label><!--
|
||||
--><input type="radio" name="background" id="bgbad" value="../assets/chemistry.png" /><!--
|
||||
--><label for="bgbad" style="background-image: url(./assets/chemistry.png)">CHEMIST</label><!--
|
||||
--><input type="radio" name="background" id="bgsport" value="../assets/sport.png" /><!--
|
||||
--><label for="bgsport" style="background-image: url(./assets/sport.png)">SPORT</label><!--
|
||||
--><input type="radio" name="background" id="bgmark" value="../assets/mark.png" /><!--
|
||||
--><label for="bgmark" style="background-image: url(./assets/mark.png)">MARK</label><!--
|
||||
--><input type="radio" name="background" id="bgtile" value="../assets/tile.png" /><!--
|
||||
--><label for="bgtile" style="background-image: url(./assets/tile.png)">TILE</label><!--
|
||||
--><input type="radio" name="background" id="bgtiletwo" value="../assets/tile2.png" /><!--
|
||||
--><label for="bgtiletwo" style="background-image: url(./assets/tile2.png)">DIAG</label><br />
|
||||
<div>
|
||||
<input type="submit" name="action" value="DONE"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrim-over-- scr-timezone--">
|
||||
<div class="dialog" id="timezonedia">
|
||||
<p class="dlg-top">Select Timezone</p>
|
||||
<form id="timezone">
|
||||
<select name="timezone" title="Timezone">
|
||||
<option value="Etc/GMT">GMT</option>
|
||||
<option value="Etc/GMT-1">GMT+1 ECT</option>
|
||||
<option value="Etc/GMT-2">GMT+2 ART</option>
|
||||
<option value="Etc/GMT-3">GMT+3 EAT</option>
|
||||
<option value="Etc/GMT-4">GMT+4 NET</option>
|
||||
<option value="Etc/GMT-5">GMT+5 IET</option>
|
||||
<option value="Etc/GMT-6">GMT+6 BST</option>
|
||||
<option value="Etc/GMT-7">GMT+7 VST</option>
|
||||
<option value="Etc/GMT-8">GMT+8 CTT</option>
|
||||
<option value="Etc/GMT-9">GMT+9 JST</option>
|
||||
<option value="Etc/GMT-10">GMT+10 AET</option>
|
||||
<option value="Etc/GMT-11">GMT+11 SST</option>
|
||||
<option value="Etc/GMT+1">GMT-1 ???</option>
|
||||
<option value="Etc/GMT+2">GMT-2 ???</option>
|
||||
<option value="Etc/GMT+3">GMT-3 BET</option>
|
||||
<option value="Etc/GMT+4">GMT-4 PRT</option>
|
||||
<option value="Etc/GMT+5">GMT-5 EST</option>
|
||||
<option value="Etc/GMT+6">GMT-6 CST</option>
|
||||
<option value="Etc/GMT+7">GMT-7 MST</option>
|
||||
<option value="Etc/GMT+8">GMT-8 PST</option>
|
||||
<option value="Etc/GMT+9">GMT-9 AST</option>
|
||||
<option value="Etc/GMT+10">GMT-10 HST</option>
|
||||
<option value="Etc/GMT+11">GMT-11 ???</option>
|
||||
<option value="Etc/GMT+12">GMT12</option>
|
||||
</select>
|
||||
<div>
|
||||
<input type="submit" name="action" value="DONE"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrim-over-- scr-timer--">
|
||||
<div class="dialog" id="timerdia">
|
||||
<p class="dlg-top">Configure Timer</p>
|
||||
<form id="timerform">
|
||||
<!-- <Peter... the="horse" is h=ere /> -->
|
||||
<input type="number" name="minute" placeholder="05" min="00" value="05" /><span>:</span><input type="number" name="second" placeholder="00" min="00" value="00" max="59" /><br />
|
||||
<input type="checkbox" name="ctp" id="ctp" /> <label for="ctp">Connected To Poplight (running = on, done = off)</label><br />
|
||||
<p class="dlg-top">Configure Tone</p>
|
||||
<input type="radio" name="tone" id="tonebeet" value="beethoven" /><!--
|
||||
--><label for="tonebeet">BEETHOVEN</label><!--
|
||||
--><input type="radio" name="tone" id="tonemegalo" value="megalo" /><!--
|
||||
--><label for="tonemegalo">MEGALO</label><!--
|
||||
--><input type="radio" name="tone" id="toneringer" value="ringer" /><!--
|
||||
--><label for="toneringer">RINGER</label><!--
|
||||
--><input type="radio" name="tone" id="toneringertwo" value="ringer2" /><!--
|
||||
--><label for="toneringertwo">RINGER 2</label><!--
|
||||
--><input type="radio" name="tone" id="tonesweet" value="sweet" /><!--
|
||||
--><label for="tonesweet">DANCE</label><!--
|
||||
--><input type="radio" name="tone" id="tonetone" value="tone" checked /><!--
|
||||
--><label for="tonetone">DRY</label><!--
|
||||
--><input type="radio" name="tone" id="tonetwinkle" value="twinkle" /><!--
|
||||
--><label for="tonetwinkle">TWINKLE</label><!--
|
||||
--><input type="radio" name="tone" id="toneviolin" value="violin" /><!--
|
||||
--><label for="toneviolin">VIOLIN</label><!--
|
||||
--><input type="radio" name="tone" id="tonenone" value="none" /><!--
|
||||
--><label for="tonenone">NONE</label>
|
||||
<div>
|
||||
<input type="submit" name="action" value="DONE"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrim-over-- scr-about--">
|
||||
<div class="dialog" id="aboutdia">
|
||||
<p class="dlg-top">About FunnyClock²</p>
|
||||
<form id="aboutform">
|
||||
<!-- FUCK -->
|
||||
<p>FunnyClock² is the successor of FunnyClock, an application made for my school to show when smartboards are idle.</p>
|
||||
<p>FunnyClock was originally a single-file local webpage hosted on the computers of the teachers, and now with FunnyClock², it's a multi-file customizable suite for clocks and timers.</p>
|
||||
<p class="dlg-top">Special Thanks to</p>
|
||||
<ul>
|
||||
<li>Josh, science and tech teacher</li>
|
||||
<li>Everyone who accepted my pitch for the FunnyClock² app</li>
|
||||
<li>Among Us (Sussy background)</li>
|
||||
<li>Portal 2 (Tile background)</li>
|
||||
<li>Kaboom.js (Mark background)</li>
|
||||
<li>Material Design (UI inspiration)</li>
|
||||
</ul>
|
||||
<div>
|
||||
<input type="submit" name="action" value="OK"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="scrim--" onclick="document.querySelector('.header').classList.remove('wide')"> </div>
|
||||
<script>
|
||||
$(".poplight").draggable({
|
||||
containment: $("#backconstrain"),
|
||||
handle: "div.drag",
|
||||
drag: (e, u) => {
|
||||
var bottom = ($(window).height() - u.position.top);
|
||||
if ((bottom < 210 && bottom >= 78) && !u.helper[0].classList.contains("hidden")) {
|
||||
u.position.top = ($(window).height() - 210);
|
||||
} else if (bottom < 78) {
|
||||
u.helper[0].classList.add("hidden");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function checkHeight(el) {
|
||||
var bottom = ($(window).height() - el.getBoundingClientRect().top);
|
||||
if (bottom < 210) {
|
||||
el.classList.add('hidden');
|
||||
} else {
|
||||
el.classList.toggle('hidden');
|
||||
}
|
||||
}
|
||||
|
||||
var elem = document.documentElement;
|
||||
|
||||
function openFullscreen() {
|
||||
if (document.fullscreenElement == null) {
|
||||
if (elem.requestFullscreen) {
|
||||
elem.requestFullscreen();
|
||||
} else if (elem.webkitRequestFullscreen) { /* Safari */
|
||||
elem.webkitRequestFullscreen();
|
||||
} else if (elem.msRequestFullscreen) { /* IE11 */
|
||||
elem.msRequestFullscreen();
|
||||
}
|
||||
} else {
|
||||
if (document.exitFullscreen) {
|
||||
document.exitFullscreen();
|
||||
} else if (document.webkitExitFullscreen) { /* Safari */
|
||||
document.webkitExitFullscreen();
|
||||
} else if (document.msExitFullscreen) { /* IE11 */
|
||||
document.msExitFullscreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelector("#color").addEventListener("submit", (e) => {
|
||||
const formData = new FormData(e.target);
|
||||
var colors = formData.get("color").split("|");
|
||||
localStorage.setItem("colors", formData.get("color"));
|
||||
console.log(colors);
|
||||
localStorage.setItem("background", formData.get("background"));
|
||||
document.documentElement.style.setProperty('--main-color', colors[0]);
|
||||
document.documentElement.style.setProperty('--background', colors[1]);
|
||||
document.documentElement.style.setProperty('--background-light', colors[2]);
|
||||
document.documentElement.style.setProperty('--foreground', colors[3]);
|
||||
document.documentElement.style.setProperty('--background-image', "url(" + formData.get("background") + ")");
|
||||
document.querySelector('.scr-dialog--').classList.remove('open');
|
||||
event.preventDefault();
|
||||
})
|
||||
|
||||
var colors = (localStorage.getItem("colors") ?? "#FFFF00|#202020|#404040|#FFFFFF").split("|");
|
||||
document.documentElement.style.setProperty('--main-color', colors[0]);
|
||||
document.documentElement.style.setProperty('--background', colors[1]);
|
||||
document.documentElement.style.setProperty('--background-light', colors[2]);
|
||||
document.documentElement.style.setProperty('--foreground', colors[3]);
|
||||
document.documentElement.style.setProperty('--background-image', "url(" + (localStorage.getItem("background") ?? "../assets/clock.png") + ")");
|
||||
|
||||
document.querySelector("#color").addEventListener("change", (e) => {
|
||||
const formData = new FormData(document.querySelector("#color"));
|
||||
var colors = formData.get("color").split("|");
|
||||
document.documentElement.style.setProperty('--main-color', colors[0]);
|
||||
document.documentElement.style.setProperty('--background', colors[1]);
|
||||
document.documentElement.style.setProperty('--foreground', colors[3]);
|
||||
document.documentElement.style.setProperty('--background-light', colors[2]);
|
||||
})
|
||||
|
||||
document.querySelector("#timerform").addEventListener("submit", (e) => {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(e.target);
|
||||
var checked = formData.get("ctp") == "on";
|
||||
var time = (parseInt(formData.get("minute")) * 60) + parseInt(formData.get("second"));
|
||||
document.querySelector(".body").insertAdjacentHTML( "beforeend", `<div class="timer timer-enabled" data-time="${time}" data-orig="${time}" data-ctp="${checked}" data-tone="${formData.get("tone")}">
|
||||
<canvas width="64" height="64"></canvas><!--
|
||||
--><div class="labels">
|
||||
<h1 class="time"><span class="mins">00</span>:<span class="seconds">00</span></h1><br />
|
||||
</div><br />
|
||||
<button class="deleteclock material-symbols-outlined" onclick="this.parentElement.remove()">close</button>
|
||||
<button class="normalclock material-symbols-outlined" onclick="this.parentElement.classList.toggle('timer-paused');">pause</button>
|
||||
<button class="normalclock material-symbols-outlined" onclick="this.parentElement.dataset.time = this.parentElement.dataset.orig;this.parentElement.classList.add('timer-enabled');updateTimer()">refresh</button>
|
||||
</div>`);
|
||||
if (checked) {
|
||||
document.querySelector(".poplight .press").classList.remove("popped");
|
||||
}
|
||||
updateTimer();
|
||||
document.querySelector('.scr-timer--').classList.remove('open');
|
||||
})
|
||||
|
||||
document.querySelector("#aboutform").addEventListener("submit", (e) => {
|
||||
event.preventDefault();
|
||||
document.querySelector('.scr-about--').classList.remove('open');
|
||||
})
|
||||
|
||||
document.querySelector("#timezone").addEventListener("submit", (e) => {
|
||||
event.preventDefault();
|
||||
const formData = new FormData(e.target);
|
||||
document.querySelector(".body").insertAdjacentHTML( "beforeend", `<div class="clock" data-timezone="${formData.get("timezone")}">
|
||||
<canvas width="64" height="64"></canvas><!--
|
||||
--><div class="labels">
|
||||
<h1 class="title">Loading...</h1><br />
|
||||
<p class="timezone">Loading...</p>
|
||||
</div><br />
|
||||
<button class="deleteclock material-symbols-outlined" onclick="this.parentElement.remove()">close</button>
|
||||
</div>`);
|
||||
update();
|
||||
document.querySelector('.scr-timezone--').classList.remove('open');
|
||||
})
|
||||
|
||||
function addNote() {
|
||||
document.querySelector(".body").insertAdjacentHTML( "beforeend", `<div class="noteobject">
|
||||
<textarea class="txt" title="Notes" placeholder="Take some notes..." oninput='this.style.height = "";this.style.height = this.scrollHeight + "px"'></textarea>
|
||||
<button class="deleteclock material-symbols-outlined" onclick="this.parentElement.remove()">close</button>
|
||||
</div>`);
|
||||
}
|
||||
|
||||
function addChecklist() {
|
||||
document.querySelector(".body").insertAdjacentHTML( "beforeend", `<div class="noteobject">
|
||||
<div class="lister">
|
||||
<div class="checkobject">
|
||||
<button onclick="this.parentElement.remove();" class="deleteclock material-symbols-outlined">close</button>
|
||||
<input type="text" placeholder="Checklist item" />
|
||||
</div>
|
||||
</div>
|
||||
<button class="deleteclock material-symbols-outlined" onclick="this.parentElement.remove()">close</button>
|
||||
<button class="normalclock material-symbols-outlined" onclick="addCheckbox(this.parentElement.querySelector('.lister'));">add</button>
|
||||
</div>`);
|
||||
}
|
||||
|
||||
function addCheckbox(obj) {
|
||||
obj.insertAdjacentHTML( "beforeend", `<div class="checkobject">
|
||||
<button onclick="this.parentElement.remove();" class="deleteclock material-symbols-outlined">close</button>
|
||||
<input type="text" placeholder="Checklist item" />
|
||||
</div>`);
|
||||
}
|
||||
</script>
|
||||
<script src="./canvas.js"></script>
|
||||
<script src="./update.js"></script>
|
||||
</body>
|
||||
</html>
|
11
views/projects/item/clock/jqtp.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
/*!
|
||||
* jQuery UI Touch Punch 0.2.3
|
||||
*
|
||||
* Copyright 2011–2014, Dave Furfero
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
*
|
||||
* Depends:
|
||||
* jquery.ui.widget.js
|
||||
* jquery.ui.mouse.js
|
||||
*/
|
||||
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);
|
148
views/projects/item/clock/styles/clock.css
Normal file
|
@ -0,0 +1,148 @@
|
|||
|
||||
.body {
|
||||
width: calc(100vw - 64px);
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
left: 64px;
|
||||
top: 0;
|
||||
padding: 0 16px;
|
||||
box-sizing: border-box;
|
||||
z-index: 1;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.body .clock, .body .timer, .body .noteobject {
|
||||
width: 100%;
|
||||
min-height: max-content;
|
||||
border-radius: 8px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
color: var(--foreground);
|
||||
margin: 16px 0;
|
||||
zoom: 1.25;
|
||||
}
|
||||
|
||||
.body .clock::before, .body .timer::before, .body .noteobject::before {
|
||||
content: "";
|
||||
background-color: #FFFFFF40;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.body .timer-paused::before {
|
||||
content: "";
|
||||
background-color: #40404040;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
backdrop-filter: blur(8px);
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.body .clock h1, .body .timer h1, .body .noteobject h1 {
|
||||
margin: 0;
|
||||
margin-top: 16px;
|
||||
padding: 0;
|
||||
color: var(--foreground);
|
||||
font-weight: lighter;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.body .clock div.labels, .body .timer div.labels, .body .noteobject div.labels {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.body .clock div.labels *, .body .timer div.labels *, .body .noteobject div.labels * {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
color: var(--foreground);
|
||||
font-weight: lighter;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
canvas {
|
||||
margin: 0;
|
||||
margin-right: 16px;
|
||||
padding: 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: none;
|
||||
width: 100%;
|
||||
margin-top: 8px;
|
||||
box-sizing: border-box;
|
||||
height: max-content;
|
||||
font-size: 48px;
|
||||
max-height: 100%;
|
||||
padding: 8px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.deleteclock {
|
||||
margin-top: 16px;
|
||||
min-width: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: #FF000080;
|
||||
color: var(--foreground);
|
||||
border-radius: 16px;
|
||||
transition: background-color 0.125s;
|
||||
}
|
||||
|
||||
.deleteclock:focus {
|
||||
background-color: #FF0000A0;
|
||||
}
|
||||
|
||||
.deleteclock:hover {
|
||||
background-color: #FF0000C0;
|
||||
}
|
||||
|
||||
.deleteclock:active {
|
||||
background-color: #FF0000FF;
|
||||
}
|
||||
|
||||
.normalclock {
|
||||
margin-top: 16px;
|
||||
min-width: 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
padding: 0;
|
||||
border: none;
|
||||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
border-radius: 16px;
|
||||
transition: background-color 0.125s;
|
||||
}
|
||||
|
||||
.normalclock:focus {
|
||||
background-color: #00000030;
|
||||
}
|
||||
|
||||
.normalclock:hover {
|
||||
background-color: #00000010;
|
||||
}
|
||||
|
||||
.normalclock:active {
|
||||
background-color: #00000020;
|
||||
}
|
186
views/projects/item/clock/styles/dialog.css
Normal file
|
@ -0,0 +1,186 @@
|
|||
.scrim-over--.open {
|
||||
background-color: #0006;
|
||||
backdrop-filter: blur(4px);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
@keyframes myAnim {
|
||||
from {
|
||||
box-shadow: 0px 0px 6px -6px #FFFFFF80;
|
||||
}
|
||||
to {
|
||||
box-shadow: 0px 0px 6px 32px #FFFFFF00;
|
||||
}
|
||||
}
|
||||
|
||||
#updatedialog {
|
||||
box-shadow: 0px 0px 6px 32px #FFFFFF00;
|
||||
animation: myAnim 2s ease 0s infinite normal forwards;
|
||||
}
|
||||
|
||||
#updatedialog button {
|
||||
animation: myAnim 2s ease 1s infinite normal forwards;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.body .dialog {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.scrim-over--.open .dialog, .dialog.open {
|
||||
display: inline-block !important;
|
||||
}
|
||||
|
||||
.dialog {
|
||||
min-width: 320px;
|
||||
max-width: calc(100vw - 64px);
|
||||
min-height: 128px;
|
||||
max-height: calc(100vh - 64px);
|
||||
background-color: var(--background-light);
|
||||
transition: background-color 0.125s;
|
||||
color: var(--foreground);
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
box-sizing: border-box;
|
||||
pointer-events: auto;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.dialog p {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.dialog .dlg-top {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
font-size: 18px;
|
||||
margin: 8px 0;
|
||||
}
|
||||
|
||||
.dialog div {
|
||||
text-align: right;
|
||||
margin-top: 8px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.dialog div input[type=submit], .dialog div button {
|
||||
margin: 0;
|
||||
padding: 8px;
|
||||
height: 32px;
|
||||
box-sizing: border-box;
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: var(--main-color);
|
||||
font-weight: bold;
|
||||
border-radius: 4px;
|
||||
transition: background-color 0.125s, color 0.125s;
|
||||
}
|
||||
|
||||
.dialog div input:focus, .dialog div button:focus {
|
||||
background-color: #00000020;
|
||||
}
|
||||
|
||||
.dialog div input:hover, .dialog div button:hover {
|
||||
background-color: #00000040;
|
||||
}
|
||||
|
||||
.dialog div input:active, .dialog div button:active {
|
||||
background-color: #00000080;
|
||||
}
|
||||
|
||||
input[type="radio"] {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
input[type="radio"] + label {
|
||||
display: inline-block;
|
||||
margin: 8px;
|
||||
padding: 0;
|
||||
width: 96px;
|
||||
height: 64px;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 0 4px 2px rgba(0,0,0,0.25);
|
||||
color: #FFFFFF;
|
||||
transition: border 0.25s;
|
||||
box-sizing: border-box;
|
||||
border: 8px solid transparent;
|
||||
background-size: 96px;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
input[type="radio"] + label[for^="bg"] {
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
input[type="radio"]:checked + label {
|
||||
border: 8px solid #FFF6;
|
||||
}
|
||||
|
||||
input[type="radio"]:focus + label {
|
||||
outline: 4px solid white;
|
||||
}
|
||||
|
||||
.dialog select {
|
||||
width: 100%;
|
||||
margin: 8px 0;
|
||||
box-sizing: border-box;
|
||||
height: max-content;
|
||||
max-height: 100%;
|
||||
padding: 8px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.dialog input[type="number"] {
|
||||
width: 16ch;
|
||||
margin: 8px 0;
|
||||
box-sizing: border-box;
|
||||
height: max-content;
|
||||
max-height: 100%;
|
||||
padding: 8px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.checkobject input[type="text"] {
|
||||
width: 100%;
|
||||
margin: 8px 0;
|
||||
box-sizing: border-box;
|
||||
height: max-content;
|
||||
max-height: 100%;
|
||||
padding: 8px;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
font-size: 48px;
|
||||
background-color: #00000040;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.checkobject {
|
||||
display: flex;
|
||||
gap: 12px;
|
||||
flex-direction: row;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
align-content: space-around;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.checkobject .deleteclock {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
7
views/projects/item/clock/styles/root.css
Normal file
|
@ -0,0 +1,7 @@
|
|||
:root {
|
||||
--main-color: #FFFF00;
|
||||
--background: #202020;
|
||||
--background-light: #404040;
|
||||
--foreground: #FFFFFF;
|
||||
--background-image: url("../assets/clock.png");
|
||||
}
|
338
views/projects/item/clock/styles/style.css
Normal file
|
@ -0,0 +1,338 @@
|
|||
body {
|
||||
background: var(--background);
|
||||
background-size: 100vw 100vh;
|
||||
image-rendering: -webkit-optimize-contrast;
|
||||
image-rendering: crisp-edges;
|
||||
transition: background 0.125s;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
#back {
|
||||
background-image: var(--background-image);
|
||||
background-size: 128px;
|
||||
background-position: center;
|
||||
opacity: 0.35;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
#backconstrain {
|
||||
position: fixed;
|
||||
height: calc(100vh + 128px);
|
||||
width: calc(100vw - 36px);
|
||||
left: 20px;
|
||||
top: 64px;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: monospace;
|
||||
}
|
||||
|
||||
.header {
|
||||
width: 64px;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-between;
|
||||
align-content: stretch;
|
||||
align-items: center;
|
||||
z-index: 9;
|
||||
transition: width 0.125s;
|
||||
}
|
||||
|
||||
.header.wide {
|
||||
width: 256px;
|
||||
}
|
||||
.scrim--, .scrim-over-- {
|
||||
display: inline-block;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 8;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
background-color: transparent;
|
||||
backdrop-filter: none;
|
||||
pointer-events: none;
|
||||
transition: background-color 0.125s, backdrop-filter 0.125s;
|
||||
}
|
||||
.scrim-over-- {
|
||||
z-index: 10;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
.header.wide ~ .scrim-- {
|
||||
background-color: #0006;
|
||||
backdrop-filter: blur(4px);
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.header::before {
|
||||
background-color: #FFFFFF40;
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
backdrop-filter: blur(8px);
|
||||
}
|
||||
|
||||
.header div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
align-content: space-around;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
height: 50%;
|
||||
}
|
||||
|
||||
.header div:first-child {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.header div:last-child {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.header button {
|
||||
height: 48px;
|
||||
width: 100%;
|
||||
border-radius: 24px;
|
||||
border: none;
|
||||
padding: 12px;
|
||||
margin: none;
|
||||
background-color: transparent;
|
||||
transition: background-color 0.125s;
|
||||
color: var(--foreground);
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
}
|
||||
.header.wide button {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header button:hover {
|
||||
background-color: #FFFFFF40;
|
||||
}
|
||||
|
||||
.header button::after {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
content: attr(data-title);
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
height: 12px;
|
||||
box-sizing: content-box;
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
left: calc(100% + 16px);
|
||||
border-radius: 4px;
|
||||
top: calc(50% - 14px);
|
||||
transition: color 0.125s, width 0.125s;
|
||||
width: 0;
|
||||
padding: 8px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.header:not(.wide) button:hover::after {
|
||||
background-color: #202020;
|
||||
color: #FFFFFF;
|
||||
width: initial;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.header:not(.wide) button:focus::after {
|
||||
background-color: #202020;
|
||||
color: #FFFFFF;
|
||||
width: initial;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.header.wide button::after {
|
||||
left: 48px;
|
||||
top: calc(50% - 7px);
|
||||
color: var(--foreground);
|
||||
width: initial;
|
||||
height: 14px;
|
||||
padding: 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.header button:focus {
|
||||
background-color: #FFFFFF20;
|
||||
}
|
||||
|
||||
.header button:active {
|
||||
background-color: #FFFFFF80;
|
||||
}
|
||||
|
||||
sep {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
height: 0;
|
||||
background-color: transparent;
|
||||
border: 1px dashed var(--foreground);
|
||||
margin: 4px;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.poplight {
|
||||
position: fixed;
|
||||
right: 16px;
|
||||
bottom: 16px;
|
||||
width: 192px;
|
||||
height: 192px;
|
||||
transition: bottom 0.125s;
|
||||
z-index: 9;
|
||||
}
|
||||
|
||||
.poplight.hidden {
|
||||
bottom: -128px;
|
||||
}
|
||||
|
||||
.poplight button.hide {
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
right: 48px;
|
||||
top: -48px;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
border-radius: 16px;
|
||||
background-color: transparent;
|
||||
color: var(--foreground);
|
||||
}
|
||||
|
||||
.poplight button.hide::after {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
content: attr(data-title);
|
||||
font-family: monospace;
|
||||
font-size: 12px;
|
||||
height: 12px;
|
||||
box-sizing: content-box;
|
||||
background-color: transparent;
|
||||
color: transparent;
|
||||
right: 0;
|
||||
border-radius: 4px;
|
||||
top: -48px;
|
||||
transition: color 0.125s, width 0.125s;
|
||||
width: 0;
|
||||
padding: 8px 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.poplight button.hide:not(:disabled):hover::after {
|
||||
background-color: #202020;
|
||||
color: #FFFFFF;
|
||||
width: initial;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.poplight button.hide:not(:disabled):focus {
|
||||
background-color: #FFFFFF20;
|
||||
}
|
||||
|
||||
.poplight button.hide:disabled {
|
||||
color: #808080;
|
||||
}
|
||||
|
||||
.poplight button.hide:not(:disabled):hover {
|
||||
background-color: #FFFFFF40;
|
||||
}
|
||||
|
||||
.poplight button.hide:not(:disabled):active {
|
||||
background-color: #FFFFFF80;
|
||||
}
|
||||
|
||||
.poplight button.press {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 96px;
|
||||
background-color: #808080;
|
||||
overflow: hidden;
|
||||
border: none;
|
||||
font-size: 96px;
|
||||
transition: top 0.125s, right 0.125s, width 0.125s, height 0.125s, background-color 0.125s, color 0.125s, font-size 0.125s;
|
||||
}
|
||||
|
||||
.poplight.hidden button.press {
|
||||
top: -48px;
|
||||
right: 96px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
border-radius: 128px;
|
||||
font-size: 24px;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.poplight button.press.popped {
|
||||
background-color: var(--main-color);
|
||||
box-shadow: 0px 0px 32px 0px var(--main-color);
|
||||
}
|
||||
|
||||
.poplight button.press::after {
|
||||
position: absolute;
|
||||
content: "devices";
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
border-radius: 128px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.poplight button.press:hover::after {
|
||||
background-color: #ffffff40;
|
||||
}
|
||||
|
||||
.poplight button.press:active::after {
|
||||
background-color: #ffffff80;
|
||||
}
|
||||
|
||||
.poplight button.press.popped::after {
|
||||
content: "phonelink_off";
|
||||
}
|
||||
|
||||
.poplight .drag {
|
||||
position: absolute;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
right: 0;
|
||||
top: -48px;
|
||||
margin: 0;
|
||||
padding: 4px;
|
||||
border: none;
|
||||
border-radius: 16px;
|
||||
box-sizing: border-box;
|
||||
user-select: none;
|
||||
background-color: transparent;
|
||||
color: var(--foreground);
|
||||
}
|
23
views/projects/item/clock/update.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
function reqData(start) {
|
||||
console.log("Pinged API server. Starting: " + start);
|
||||
var donedata = (e) => {
|
||||
var resp = e;
|
||||
var prevSha = "A";
|
||||
if (!start) prevSha = window.sessionStorage.getItem("commitsha");
|
||||
|
||||
if (resp != prevSha) {
|
||||
window.sessionStorage.setItem("commitsha", resp);
|
||||
if (start) return;
|
||||
document.querySelector("#updatesha").innerHTML = `from job v. ${prevSha} to job v. ${resp}`;
|
||||
document.querySelector("#updatedialog").classList.add("open");
|
||||
}
|
||||
};
|
||||
|
||||
fetch("https://ClockCheckGithub.meowcatheorange.repl.co")
|
||||
.then(x => x.text())
|
||||
.then(y => donedata(y));
|
||||
}
|
||||
|
||||
setInterval(reqData, 60000);
|
||||
|
||||
reqData(true);
|
BIN
views/projects/item/dice/assets/ProFontWindows.ttf
Normal file
58
views/projects/item/dice/index.html
Normal file
|
@ -0,0 +1,58 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Dice Tool</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="style.css">
|
||||
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
|
||||
</head>
|
||||
<body class="compactMode">
|
||||
<div class="headerBar">
|
||||
<div style="float: left; text-align: left;">
|
||||
Dice Tool
|
||||
</div>
|
||||
<div style="float: right; text-align: right;">
|
||||
<button class="material-icons toc" onclick="document.body.classList.toggle('compactMode');">build</button>
|
||||
<button class="material-icons" onclick="rollAllDie(cont)">shuffle</button>
|
||||
<button class="material-icons" onclick="if (confirm('Are you sure you want to remove everything?')) $('.content').find('.die').remove()">cancel</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fab">
|
||||
<button class="material-icons" title="Add Dice" onclick="addDie(cont);">add_circle</button>
|
||||
<button class="material-icons" title="Add Counter" onclick="addDie(cont, 1, 'Counter', true);">pin</button>
|
||||
<button class="material-icons" title="Add Bag" onclick="addDieBag(cont);">create_new_folder</button>
|
||||
</div>
|
||||
<div class="content" ondrop="drop(event)" ondragover="allowDrop(event)"><div class="dropHere"></div></div>
|
||||
<templates>
|
||||
<template id="dieUI"><div class="die rollable{IS_COUNTER}" id="{RAND_ID}" draggable="true" ondragstart="drag(event)">
|
||||
<div>
|
||||
<span class="material-icons icon ident">casino</span><input class="title hos" placeholder="Name" type="text" value="{TITLE_DIE}" onfocusout="this.setAttribute('value', this.value);" />
|
||||
<input class="die-color hos" type="color" value="transparent" onchange="this.setAttribute('value', this.value);this.parentElement.parentElement.style.backgroundColor = this.value;" />
|
||||
<button class="material-icons icon indi neg" onclick="tp(this).remove()">delete</button><br class="hos" />
|
||||
<div class="hideIfCounter"><button class="material-icons icon indi pos" title="Roll die" onclick="rollDie(ht(tpp(this)))">shuffle</button></div>
|
||||
</div>
|
||||
<div style="text-align: right;">
|
||||
<button class="material-icons icon hos" onclick="changeVal(ht($(this)), -1)">remove</button>
|
||||
<button class="material-icons icon hos" onclick="changeVal(ht($(this)), 1)">add</button>
|
||||
<span class="hideIfCounter hos"><button class="material-icons icon" title="Cut die to value" onclick="cutVal(ht(tp(this)))">content_cut</button></span><br />
|
||||
<span><h2 class="die-value">{DIE_VALUE}</h2><span class="hideIfCounter hos"> / <input class="die-sides" type="number" min="1" max="10000" value="{DIE_SIDES}" onfocusout="this.setAttribute('value', this.value);" /></span></span>
|
||||
</div>
|
||||
</div></template>
|
||||
<template id="dieBagUI"><div class="die bag" id="{RAND_ID}" draggable="true" ondragstart="drag(event)">
|
||||
<div>
|
||||
<span class="material-icons icon ident">folder</span><input class="title hos" placeholder="Name" type="text" value="{TITLE_DIE}" onfocusout="this.setAttribute('value', this.value);" /><input class="die-color hos" tabIndex="0" type="color" value="transparent" onchange="this.setAttribute('value', this.value);this.parentElement.parentElement.style.backgroundColor = this.value;" />
|
||||
<button class="material-icons icon indi neg" onclick="if (confirm('Are you sure you want to remove this bag?')) tp(this).remove()">delete</button><br class="hos" />
|
||||
<button class="material-icons icon indi pos" title="Roll all dies inside" onclick="rollAllDie(ht(tp(this)))">shuffle</button>
|
||||
<button class="material-icons icon indi pos hos" title="Add Dice" onclick="addDie(tp(this).find('.dropHere').get(0))">add_circle</button>
|
||||
<button class="material-icons icon indi pos hos" title="Add Counter" onclick="addDie(tp(this).find('.dropHere').get(0), 1, 'Counter', true)">pin</button>
|
||||
<button class="material-icons icon indi pos hos" title="Add Bag" onclick="addDieBag(tp(this).find('.dropHere').get(0))">create_new_folder</button>
|
||||
</div>
|
||||
<div class="dropHere"></div>
|
||||
</div></template>
|
||||
</templates>
|
||||
<script src="script.js"></script>
|
||||
</body>
|
||||
</html>
|
65
views/projects/item/dice/script.js
Normal file
|
@ -0,0 +1,65 @@
|
|||
var cont = document.querySelector(".content > div");
|
||||
var dieTemp = document.querySelector("template#dieUI");
|
||||
var dieBagTemp = document.querySelector("template#dieBagUI");
|
||||
|
||||
var ids = {
|
||||
die: 0,
|
||||
bag: 0
|
||||
};
|
||||
function addDie(ctx, int, name, count) {
|
||||
ctx.innerHTML += dieTemp.innerHTML
|
||||
.replace("{RAND_ID}", "die" + ids.die)
|
||||
.replace("{TITLE_DIE}", name ?? "")
|
||||
.replace("{DIE_SIDES}", int ?? "6")
|
||||
.replace("{IS_COUNTER}", count ? " counter" : "")
|
||||
.replace("{DIE_VALUE}", Math.round(Math.random() * ((int ?? 6) - 1)) + 1);
|
||||
ids.die++;
|
||||
}
|
||||
function addDieBag(ctx) {
|
||||
ctx.innerHTML += dieBagTemp.innerHTML
|
||||
.replace("{RAND_ID}", "dieBag" + ids.bag)
|
||||
.replace("{TITLE_DIE}", "");
|
||||
ids.bag++;
|
||||
}
|
||||
function rollDie(thisObj) {
|
||||
var val = thisObj.querySelector('.die-value');
|
||||
var sides = thisObj.querySelector('.die-sides');
|
||||
val.innerHTML = Math.round(Math.random() * (sides.value - 1)) + 1;
|
||||
}
|
||||
function rollAllDie(ctx) {
|
||||
var allDies = ctx.querySelectorAll(".rollable");
|
||||
console.log(allDies, ctx);
|
||||
allDies.forEach((v) => {
|
||||
rollDie(v);
|
||||
})
|
||||
}
|
||||
|
||||
function cutVal(thisObj) {
|
||||
var val = thisObj.parentElement.querySelector('.die-value');
|
||||
var sides = thisObj.parentElement.querySelector('.die-sides');
|
||||
sides.value = val.innerHTML;
|
||||
}
|
||||
|
||||
function changeVal(thisObj, int) {
|
||||
var val = thisObj.parentElement.querySelector('.die-value');
|
||||
val.innerHTML = parseInt(val.innerHTML) + int;
|
||||
}
|
||||
|
||||
function allowDrop(ev) {
|
||||
ev.preventDefault();
|
||||
}
|
||||
|
||||
function drag(ev) {
|
||||
ev.dataTransfer.setData("element", ev.target.id);
|
||||
}
|
||||
|
||||
function drop(ev) {
|
||||
if (!ev.target.classList.contains("dropHere")) return;
|
||||
ev.preventDefault();
|
||||
var data = ev.dataTransfer.getData("element");
|
||||
ev.target.appendChild(document.getElementById(data));
|
||||
}
|
||||
|
||||
var tp = (t) => {return $(t).parent().parent()};
|
||||
var tpp = (t) => {return $(t).parent().parent().parent()};
|
||||
var ht = (t) => {return t.get(0)};
|
375
views/projects/item/dice/style.css
Normal file
|
@ -0,0 +1,375 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;900&display=swap');
|
||||
@font-face {
|
||||
font-family: 'PFW';
|
||||
src: url('assets/ProFontWindows.ttf');
|
||||
}
|
||||
|
||||
:root {
|
||||
--mainColor: #f80;
|
||||
--mainColorThemed: #fdb;
|
||||
--mainColorThemedLight: #fed;
|
||||
--mainFG: #000;
|
||||
--mainFGDark: #FFF;
|
||||
--mainFGTP: #0002;
|
||||
--mainFGDarkTP: #FFF2;
|
||||
--mainFGTP4: #0008;
|
||||
--mainFGDarkTP4: #FFF8;
|
||||
--negColor: #f00;
|
||||
--negColorThemed: #fbb;
|
||||
--negColorThemedLight: #fdd;
|
||||
--posColor: #f80;
|
||||
--posColorThemed: #ffd0a0;
|
||||
--material-outline-boxshadow: #0004 0 0 4px;
|
||||
--material-outline-border: none;
|
||||
}
|
||||
|
||||
* {
|
||||
font-family: 'PFW', 'Roboto', 'Lucida Sans', 'Lucida Sans Regular', 'Lucida Grande', 'Lucida Sans Unicode', Geneva, Verdana, sans-serif;
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--mainColorThemed: #840;
|
||||
--mainColorThemedLight: #420;
|
||||
--mainFG: #FFF;
|
||||
--mainFGDark: #000;
|
||||
--mainFGTP: #FFF2;
|
||||
--mainFGDarkTP: #0002;
|
||||
--mainFGTP4: #FFF8;
|
||||
--mainFGDarkTP4: #0008;
|
||||
--negColorThemed: #800;
|
||||
--negColorThemedLight: #400;
|
||||
--posColorThemed: #840;
|
||||
--posColorThemedLight: #630;
|
||||
--material-outline-boxshadow: none;
|
||||
--material-outline-border: var(--mainFGTP) 1px solid;
|
||||
}
|
||||
}
|
||||
|
||||
body {padding:0;margin:0;background-color:var(--mainColorThemedLight);}
|
||||
|
||||
.headerBar {
|
||||
width: 100%;
|
||||
height: 56px;
|
||||
z-index: 9;
|
||||
display: inline-grid;
|
||||
grid-template-columns: auto auto;
|
||||
grid-template-rows: 40px;
|
||||
position: fixed;
|
||||
-webkit-user-select: none;
|
||||
user-select: none;
|
||||
top: 0;
|
||||
background-color: var(--mainColorThemed);
|
||||
box-shadow: var(--material-outline-boxshadow);
|
||||
border-bottom: var(--material-outline-border);
|
||||
line-height: 40px;
|
||||
color: var(--mainFG);
|
||||
font-size: 24px;
|
||||
font-weight: bold;
|
||||
padding: 8px 16px;
|
||||
box-sizing: border-box;
|
||||
transition: box-shadow 0.25s, background-color 0.25s;
|
||||
}
|
||||
|
||||
.fab {
|
||||
position: fixed;
|
||||
z-index: 9;
|
||||
background-color: var(--mainColorThemed);
|
||||
border-radius: 64px;
|
||||
height: 64px;
|
||||
width: 192px;
|
||||
right: 32px;
|
||||
bottom: 32px;
|
||||
display: grid;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
grid-template-columns: auto auto auto;
|
||||
box-shadow: #0004 0 0 4px 0;
|
||||
}
|
||||
|
||||
.fab button {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
color: var(--mainFG);
|
||||
font-size: 32px;
|
||||
}
|
||||
.fab button:hover {
|
||||
background-color: var(--mainFGTP);
|
||||
}
|
||||
.fab button:active {
|
||||
transition: none;
|
||||
background-color: var(--mainColor);
|
||||
}
|
||||
|
||||
.headerBar button {
|
||||
height: 40px;
|
||||
background-color: transparent;
|
||||
padding: 4px; margin: 0;
|
||||
margin-left: 8px;
|
||||
color: var(--mainFG);
|
||||
border: none;
|
||||
border-radius: 40px;
|
||||
transition: background 0.25s;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.headerBar button:hover {
|
||||
background-color: var(--mainFGTP);
|
||||
}
|
||||
|
||||
.content {
|
||||
background-color: var(--mainColorThemedLight);
|
||||
color: var(--mainFG);
|
||||
height: calc(100vh - 56px);
|
||||
margin-top: 56px;
|
||||
overflow-y: auto;
|
||||
box-sizing: border-box;
|
||||
padding: 0 64px;
|
||||
}
|
||||
.content > div:empty::before {
|
||||
position: absolute;
|
||||
top: 56px;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
content: "No dice.";
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
.content > div {
|
||||
padding-bottom: 64px;
|
||||
min-height: calc(100% - 16px);
|
||||
box-sizing:border-box;
|
||||
}
|
||||
|
||||
templates, template {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div.die {
|
||||
width: 100%;
|
||||
border: var(--material-outline-border);
|
||||
box-shadow: var(--material-outline-boxshadow);
|
||||
color: var(--mainFG);
|
||||
margin: 16px 0;
|
||||
border-radius: 8px;
|
||||
padding: 16px;
|
||||
padding-bottom: 8px;
|
||||
box-sizing: border-box;
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
animation-name: horizontal-shaking;
|
||||
animation-duration: 0.25s;
|
||||
}
|
||||
|
||||
.counter .hideIfCounter {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.compactMode .hos {
|
||||
display: none;
|
||||
}
|
||||
div.hideIfCounter {
|
||||
display: inline-block;
|
||||
}
|
||||
body:not(.compactMode) .headerBar button.toc {
|
||||
color: var(--posColor);
|
||||
}
|
||||
|
||||
.compactMode div.die h2 {
|
||||
height: 32px;
|
||||
line-height: 32px;
|
||||
margin-top: -16px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
div.bag {
|
||||
grid-template-columns: auto;
|
||||
grid-template-rows: auto auto;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
div.die > div {
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
div.bag > div.dropHere {
|
||||
border: var(--mainFGTP) 1px solid;
|
||||
border-radius: 4px;
|
||||
padding: 16px;
|
||||
padding-bottom: 64px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
div.bag > div.dropHere:empty {
|
||||
padding: 32px;
|
||||
}
|
||||
div.bag > div.dropHere:empty::before {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
box-sizing: border-box;
|
||||
content: "No dice.";
|
||||
font-size: 24px;
|
||||
}
|
||||
|
||||
div.die h2 {
|
||||
padding: 0; margin: 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
div.die input {
|
||||
border-radius: 4px;
|
||||
padding: 4px;
|
||||
margin: 0;
|
||||
font-size: 16px;
|
||||
margin-bottom: 8px;
|
||||
background-color: var(--mainFGDarkTP4);
|
||||
border: 1px solid var(--mainFGTP);
|
||||
color: var(--mainFG);
|
||||
outline: none;
|
||||
transition: border 0.25s, border-radius 0.25s, background-color 0.25s;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.die input[type=color] {
|
||||
height: 34px;
|
||||
width: 34px;
|
||||
margin-left: -8px;
|
||||
position: absolute;
|
||||
left: -10000px;
|
||||
}
|
||||
div.bag > div > input[type=color] {
|
||||
margin-left: 0;
|
||||
}
|
||||
|
||||
div.die input[type=color]:hover {
|
||||
position: static;
|
||||
}
|
||||
div.die input[type=color]:focus {
|
||||
position: static;
|
||||
}
|
||||
|
||||
div.die input[type=text]:hover + input[type=color] {
|
||||
position: static;
|
||||
}
|
||||
|
||||
div.die .die-value {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div.die input.die-sides {
|
||||
vertical-align: baseline;
|
||||
width: 48px;
|
||||
height: 24px;
|
||||
}
|
||||
div.die input.title {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
div.die input:focus {
|
||||
background-color: var(--mainFGTP);
|
||||
border: 1px solid var(--mainFG);
|
||||
}
|
||||
|
||||
div.die input.title:not(:placeholder-shown) {
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
div.die input.title:not(:placeholder-shown):hover {
|
||||
border-bottom: 1px solid var(--mainFG);
|
||||
}
|
||||
|
||||
div.die button {
|
||||
border-radius: 4px;
|
||||
padding: 8px;
|
||||
margin: 0;
|
||||
font-size: 12px;
|
||||
background-color: transparent;
|
||||
border: 1px solid var(--mainFGTP);
|
||||
color: var(--mainFG);
|
||||
transition: background-color 0.25s;
|
||||
}
|
||||
|
||||
div.die button.icon {
|
||||
margin-bottom: 8px;
|
||||
font-size: 19px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
div.die button:hover {
|
||||
background-color: var(--mainFGTP);
|
||||
}
|
||||
div.die button:active {
|
||||
border: 1px solid var(--mainFG);
|
||||
}
|
||||
|
||||
.indi.neg {
|
||||
background-color: var(--negColorThemed);
|
||||
}
|
||||
|
||||
.indi.neg:hover {
|
||||
background-color: var(--negColorThemedLight);
|
||||
}
|
||||
|
||||
.indi.pos {
|
||||
background-color: var(--posColorThemed);
|
||||
}
|
||||
|
||||
.ident {
|
||||
font-size: 19px;
|
||||
vertical-align: top;
|
||||
margin: 6px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
@media (max-width: 675px) {
|
||||
div.content {
|
||||
padding: 0 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 875px) {
|
||||
div.content {
|
||||
padding: 0 20%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1200px) {
|
||||
div.content {
|
||||
padding: 0 10%;
|
||||
padding-top: 16px;
|
||||
padding-bottom: 16px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
div.content > div {
|
||||
column-count: 2;
|
||||
}
|
||||
div.die {
|
||||
break-inside: avoid-column;
|
||||
list-style-type: none;
|
||||
margin-top: 0;
|
||||
border: var(--mainFGTP) 1px solid;
|
||||
box-shadow: none;
|
||||
}
|
||||
div.bag {
|
||||
column-span: all;
|
||||
margin-top: 16px;
|
||||
}
|
||||
div.bag div.dropHere {
|
||||
column-count: 2;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1775px) {
|
||||
div.content > div {
|
||||
column-count: 3;
|
||||
}
|
||||
}
|
545
views/projects/item/midsim/code/charts.js
Normal file
|
@ -0,0 +1,545 @@
|
|||
import { kaboom } from "../deps.js";
|
||||
|
||||
export var charts = [
|
||||
{
|
||||
id: "tutorial",
|
||||
name: "Tutorial",
|
||||
speed: 5, // How much seconds it takes to get from Right Stage to the hitmarker
|
||||
bpm: 135, // Song BPM
|
||||
events: {
|
||||
preload: function() {
|
||||
loadSound("hitsoundJellyBean", "sounds/hitsoundJellyBean.wav");
|
||||
loadSound("hitsoundCarterRedacted", "sounds/hitsoundJellyBean.wav");
|
||||
loadSound("hitsoundMarc", "sounds/hitsoundJellyBean.wav");
|
||||
loadSound("hitsoundRedVelvety", "sounds/hitsoundRedVelvety.wav");
|
||||
loadSound("hitsoundMarkyMark", "sounds/burp.mp3");
|
||||
loadSprite("JellyBeanPre", "sprites/previews/JellyBeanPre.png");
|
||||
loadSprite("RedVelvetyPre", "sprites/previews/RedVelvetyPre.png");
|
||||
loadSprite("MarkyMarkPre", "sprites/previews/MarkyMarkPre.png");
|
||||
loadSprite("CarterRedactedPre", "sprites/previews/CarterRedactedPre.png");
|
||||
loadSprite("MarcPre", "sprites/previews/MarcPre.png");
|
||||
loadSprite("tutorialBG0", "sprites/bgCake.png");
|
||||
loadSprite("tutorialFG0", "sprites/fgCake0.png");
|
||||
loadSprite("tutorialFG1", "sprites/fgCake1.png");
|
||||
loadSprite("Marctutorial", "sprites/marcCake.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 3,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 3,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 4,
|
||||
to: 5,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 6,
|
||||
to: 8,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
})
|
||||
loadSprite("CarterRedactedtutorial", "sprites/carterredactedCake.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 3,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 3,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 4,
|
||||
to: 5,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 6,
|
||||
to: 8,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
})
|
||||
loadSprite("MarkyMarktutorial", "sprites/markymarkCake.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 4,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 3,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 4,
|
||||
to: 7,
|
||||
speed: 40
|
||||
},
|
||||
miss: {
|
||||
from: 8,
|
||||
to: 10,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
})
|
||||
loadSprite("RedVelvetytutorial", "sprites/redvelvetyCake.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 4,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 3,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 4,
|
||||
to: 5,
|
||||
speed: 20
|
||||
},
|
||||
dox: {
|
||||
from: 6,
|
||||
to: 7,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 8,
|
||||
to: 10,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
})
|
||||
loadSprite("JellyBeantutorial", "sprites/jellybeanCake.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 4,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 3,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 4,
|
||||
to: 5,
|
||||
speed: 20
|
||||
},
|
||||
dox: {
|
||||
from: 6,
|
||||
to: 7,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 8,
|
||||
to: 10,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
characters: [
|
||||
["JellyBean", "JellyBean", 186, 0],
|
||||
["RedVelvety", "RedVelvety", 186, 0],
|
||||
["Marc", "Marc", 186, 0],
|
||||
["CarterRedacted", "CarterRedacted", 186, 0],
|
||||
["MarkyMark", "Mark", 186, 0]
|
||||
],
|
||||
noteTypes: {
|
||||
"J": noteDefault,
|
||||
},
|
||||
makeScript: {
|
||||
customChar: false,
|
||||
customBG: false,
|
||||
charPos: [],
|
||||
script: function() {
|
||||
add([
|
||||
sprite("tutorialFG1"),
|
||||
layer("fg"),
|
||||
scale(1)
|
||||
]);
|
||||
return {returnType: null};
|
||||
}
|
||||
},
|
||||
chart: "................................................................................................................................J...........J.J...........J.J.J.............J.J.................J...........J.J...........J.J...J...............................J...........J.J...........J.J.J.............J.J...J.............J...........J.J...........J.J...J...............................J...........J.J...........J.J.J.............J.J...J.............J...........J.J...........J.J...J...............................J...........J.J...........J.J.J.............J.J...J...J...J.J...J...........J.J...........J.J...J...............................J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J...................................J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.....J.............................J.J.J.J.J.J.J.J.J.J.J.J.J.J.J...................................J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.....J.J.....J.J.....J...........J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.................................J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.....J.J.....J.J.....J.J.....J...................................................................................................................................J...........J.J...........J.J.J.............J.J...J...J...J.J...J...........J.J...........J.J...J...............................J...........J.J...........J.J.J.............J.J...J...J...J.J...J...........J.J...........J.J...J...............................J...........J.J...........J.J.J.............J.J...J...J...J.J...J...........J.J...........J.J...J...............................J...........J.J...........J.J.J.............J.J...J...J...J.J...J...........J.J...........J.J...J...............................................................................................................................................................................................................................................................",
|
||||
scale: 1 //Texture Scale (too lazy to upsize sprites sometimes)
|
||||
},
|
||||
{
|
||||
id: "faith",
|
||||
name: "Friendly Faith Plate",
|
||||
speed: 2,
|
||||
bpm: 120,
|
||||
events: {
|
||||
preload: function() {
|
||||
loadSound("faith", "sounds/The Friendly Faith Plate.mp3"); //120
|
||||
loadSound("hitsoundFaithPlate", "sounds/hitsoundFaithPlate.mp3");
|
||||
loadSprite("FaithPlatePre", "sprites/previews/FaithPlatePre.png");
|
||||
loadSprite("faithBG0", "sprites/bgFaith.png");
|
||||
loadSprite("faithFG0", "sprites/fgFaith.png");
|
||||
loadSprite("FaithPlatefaith", "sprites/faithplateFaith.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 3,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 3,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 4,
|
||||
to: 5,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 6,
|
||||
to: 8,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
characters: [
|
||||
["FaithPlate", "Faith Plate", 0, 0]
|
||||
],
|
||||
noteTypes: {
|
||||
"J": noteDefault,
|
||||
},
|
||||
makeScript: {
|
||||
customChar: false,
|
||||
customBG: false,
|
||||
charPos: [],
|
||||
script: function() {
|
||||
return {returnType: null};
|
||||
}
|
||||
},
|
||||
chart: "................................................................................................................................J...J...J...JJJJJ...J...J...J...J.J.J.J.J.J.J.J.JJJJJJJJJ.J.J.JJJ.J.J.J.J.J.JJJJJ.JJJ.J.J.J.J.J.J.JJJ.JJJ.J.J.J.JJJJJJJJJJJJJJJJJ.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.J.JJJ.JJJ.JJJ.JJJ.JJJ.J.J.J.J.JJJ.J.JJJJJJJJJJJJJ.J.J.J.JJJJJ.J.J.J.J.J.J.J.JJJJJ.J.J.J.J.JJ.J..J.JJJ.JJJ.J.J.JJJ.JJJ.J.J.J.JJJJJ.J.J.JJJ.JJJJJJJJJJJJJJJJJ.J.JJJ.J.J.JJJ.J.J.JJJ.J.J.JJJ.J.J.JJJ.J.J.JJJ.J.J.JJJJJJJJJJJJJ.J.J.JJJ.J.JJJ.J.J.JJJ.J.J.JJJ.J.J.J.J.J.J.JJJ.JJJJ.JJ.J.J.J.JJ..J...J.J.J.J.J.J.JJJJJJJJJJJJJ.J.J.J.J.J.J.J.J.J.JJJJJ.J.J.J.J.J.J.J.J...J...J.J.J.J.JJJJJJJJJ.J.J.J.J.J.J.JJJ.J.JJJJJJJJJJJJJJJ.J.J.JJJ.J.JJJ.JJJJJJJJJJJJJJJJJ.J.J.JJJ.J.JJJ.JJJJJJJJJJJJJJJJJ.J.J.JJJ.J.JJJ.JJJJJJJJJJJJJJJJJ.J.J.JJJJ.JJJJJJJJJJJJJJJ.JJJJJJJJJJJJJ..J.JJJ.JJJJJJJJJJ....J.J.JJJJJJJ.J.JJJ.JJJJJJJJJJJJJJJJJJJJJ.J.J.J.JJJ.JJJJJJJJJ....JJJJJJJJJ....JJJJJJJ.JJJJJJJ..JJJ..J.JJJJJJJJJJJJJJJ.JJJJJJJ..JJJ....JJJJJJJJJJJJJJJ.JJJJJJJ..JJJ....JJJJJJJJJJJJJJJ.JJJJJJJJ.JJJ..J.JJJJJJJ.J.JJJ.JJJJJJJJJJJJJ.JJJ.J...JJJ.J.JJJ.JJJJJJJJJJJJJ.JJJ.JJJ.JJJ.J.JJJJJJJJJJJJJJJJJJJJJ.JJJ.JJJ.J.JJJ.JJJJJJJJJJJJJJJJJ.JJJ.JJJ.J.JJJ.JJJJJJJJJJJJJJJ...JJJJ........J...JJJJ........J...JJJJ........J...JJJJ........J.J.JJJJ........JJJ.JJJ.JJJ.J.JJJ.J.JJJJ........JJJ.JJJ.JJJ.JJJJJ.J.JJJJ........JJJ.JJJ.JJJ.J.JJJ.J.JJJJ........JJJ.JJJ.JJJ.JJJJJ.J.JJJJJ.......JJJ.J.............",
|
||||
scale: 4
|
||||
},
|
||||
{
|
||||
id: "green",
|
||||
name: "Green Hill Zone",
|
||||
speed: 2,
|
||||
bpm: 150,
|
||||
events: {
|
||||
preload: function() {
|
||||
loadSound("green", "sounds/GreenHill.wav"); //139
|
||||
loadSound("hitsoundSonicAndTails", "sounds/hitsoundJellyBean.wav");
|
||||
loadSound("hitsoundTails", "sounds/hitsoundJellyBean.wav");
|
||||
loadSprite("SonicAndTailsPre", "sprites/previews/SonicAndTailsPre.png");
|
||||
loadSprite("TailsPre", "sprites/previews/TailsPre.png");
|
||||
loadSprite("sonicBG0", "sprites/SonicBG.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 3,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 6,
|
||||
speed: 10,
|
||||
loop: true
|
||||
}
|
||||
},
|
||||
});
|
||||
loadSprite("sonicFG0", "sprites/SonicFG.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 3,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 0,
|
||||
speed: 20
|
||||
}
|
||||
},
|
||||
});
|
||||
loadSprite("SonicAndTailssonic0", "sprites/SonicMidSim.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 4,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 6,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 7,
|
||||
to: 8,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 9,
|
||||
to: 11,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
});
|
||||
loadSprite("SonicAndTailssonic1", "sprites/TailsMidSim.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 9,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 15,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 16,
|
||||
to: 23,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 24,
|
||||
to: 26,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
});
|
||||
loadSprite("greenBG0", "sprites/SonicBG.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 3,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 6,
|
||||
speed: 10,
|
||||
loop: true
|
||||
}
|
||||
},
|
||||
});
|
||||
loadSprite("greenFG0", "sprites/SonicFG.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 3,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 0,
|
||||
speed: 20
|
||||
}
|
||||
},
|
||||
});
|
||||
loadSprite("SonicAndTailsgreen0", "sprites/SonicMidSim.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 4,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 6,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 7,
|
||||
to: 8,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 9,
|
||||
to: 11,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
});
|
||||
loadSprite("SonicAndTailsgreen1", "sprites/TailsMidSim.png", {
|
||||
sliceX: 3,
|
||||
sliceY: 9,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 0,
|
||||
to: 15,
|
||||
speed: 20
|
||||
},
|
||||
talk: {
|
||||
from: 16,
|
||||
to: 23,
|
||||
speed: 20
|
||||
},
|
||||
miss: {
|
||||
from: 24,
|
||||
to: 26,
|
||||
speed: 10
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
characters: [
|
||||
["SonicAndTails", "Sonic"],
|
||||
["Tails", "Tails"]
|
||||
],
|
||||
noteTypes: {
|
||||
"J": function(time, prevStep, char) {
|
||||
if (char == "Tails") {
|
||||
customNote(time, "J", prevStep, 0, [0, 0, 0], true);
|
||||
} else {
|
||||
noteDefault(time, prevStep)
|
||||
}
|
||||
},
|
||||
"T": function(time, prevStep, char) {
|
||||
if (char == "Tails") {
|
||||
noteDefault(time, prevStep)
|
||||
} else {
|
||||
customNote(time, "T", prevStep, 0, [0, 0, 0], true);
|
||||
}
|
||||
},
|
||||
"D": function(time, prevStep) {
|
||||
noteDefault(time, prevStep);
|
||||
customNote(time, "D", prevStep, 0, [0, 0, 0], true);
|
||||
}
|
||||
},
|
||||
makeScript: {
|
||||
customChar: true,
|
||||
customBG: false,
|
||||
charPos: [],
|
||||
script: function(players, char, bgEl) {
|
||||
var player, player2;
|
||||
bgEl.play("idle");
|
||||
if (char == "Tails") {
|
||||
player = add([
|
||||
sprite("SonicAnd" + char + "green" + "1"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(224, 20),
|
||||
scale(1)
|
||||
])
|
||||
player2 = add([
|
||||
sprite("SonicAnd" + char + "green" + "0"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(20, 108),
|
||||
scale(1)
|
||||
])
|
||||
} else {
|
||||
player = add([
|
||||
sprite(char + "green" + "0"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(20, 108),
|
||||
scale(1)
|
||||
])
|
||||
player2 = add([
|
||||
sprite(char + "green" + "1"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(224, 20),
|
||||
scale(1)
|
||||
])
|
||||
}
|
||||
return {returnType: "character", main: player, empty: player2};
|
||||
}
|
||||
},
|
||||
chart: "................J.....J.....J.....J.....J...J...J.....J.....J...................J.....J.....J...J.....J.....J...J.....J.................................T.T...T.T...T.T...T...........T.T.T...T.T...T.T...T.............T.T...T.T...T.T...T...........T.T.T...T.T...T.T...T.....T.......J.J...J.J...D.J.T.J.T...T.....J.J.J...J.J...D.J.T.J.T...T.......J.J...J.J...D.J.T.J.T...T.....J.J.J...J.J...D.J.T.J.D...D.....J.....J.....J.....J.T.D.T.J.....J.....J.....J.....J.T.D.T.J.....J.....J.....J.....J.T.D.T.J.T.T.T...T.T.T...T.T.T.T.T.T.T.........J.J...J.J...J.J...J...........J.J.J...J.J...J.J...J.............J.J...J.J...J.J...J...........J.J.J...J.J...J.J...J.....J.......T.T...T.T...D.T.J.T.J...J.....T.T.T...T.T...D.T.J.T.J...J.......T.T...T.T...D.T.J.T.J...J.....T.T.T...T.T...D.T.J.T.J.T.D.....T.....T.....T.....T.J.D.J.T.....T.....T.....T.....T.J.D.J.T.....T.....T.....T.....T.J.D.J.T.J.J.J...J.J.J...J.J.J.J.J.J.J................................................................................................................................................................",
|
||||
scale: 1
|
||||
},
|
||||
{
|
||||
id: "sonic",
|
||||
name: "Emerald Hill Zone",
|
||||
speed: 2,
|
||||
bpm: 139,
|
||||
events: {
|
||||
preload: function() {
|
||||
loadSound("tutorial", "sounds/Getting it Done.mp3"); //135
|
||||
loadSound("faith", "sounds/The Friendly Faith Plate.mp3"); //120
|
||||
loadSound("sonic", "sounds/SonicInMidSim.wav"); //139
|
||||
loadSound("green", "sounds/GreenHill.wav"); //139
|
||||
}
|
||||
},
|
||||
characters: [
|
||||
["SonicAndTails", "Sonic"],
|
||||
["Tails", "Tails"]
|
||||
],
|
||||
noteTypes: {
|
||||
"J": function(time, prevStep, char) {
|
||||
if (char == "Tails") {
|
||||
customNote(time, "J", prevStep, 0, [0, 0, 0], true);
|
||||
} else {
|
||||
noteDefault(time, prevStep)
|
||||
}
|
||||
},
|
||||
"T": function(time, prevStep, char) {
|
||||
if (char == "Tails") {
|
||||
noteDefault(time, prevStep)
|
||||
} else {
|
||||
customNote(time, "T", prevStep, 0, [0, 0, 0], true);
|
||||
}
|
||||
},
|
||||
"D": function(time, prevStep) {
|
||||
noteDefault(time, prevStep);
|
||||
customNote(time, "D", prevStep, 0, [0, 0, 0], true);
|
||||
}
|
||||
},
|
||||
makeScript: {
|
||||
customChar: true,
|
||||
customBG: false,
|
||||
charPos: [],
|
||||
script: function(players, char, bgEl) {
|
||||
var player, player2;
|
||||
bgEl.play("idle");
|
||||
if (char == "Tails") {
|
||||
player = add([
|
||||
sprite("SonicAnd" + char + "green" + "1"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(224, 20),
|
||||
scale(1)
|
||||
])
|
||||
player2 = add([
|
||||
sprite("SonicAnd" + char + "green" + "0"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(20, 108),
|
||||
scale(1)
|
||||
])
|
||||
} else {
|
||||
player = add([
|
||||
sprite(char + "green" + "0"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(20, 108),
|
||||
scale(1)
|
||||
])
|
||||
player2 = add([
|
||||
sprite(char + "green" + "1"),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(224, 20),
|
||||
scale(1)
|
||||
])
|
||||
}
|
||||
return {returnType: "character", main: player, empty: player2};
|
||||
}
|
||||
},
|
||||
chart: "..................................................J.J.J.J.J.JJ....J.J.J.J..J.........JJJJ.J.JJ.J..................T.T.T.T.T.TT....T...T.T..T........TTT.T.T.TT.T..................J.J.J.J.J.J.J.J.J...J...........J.J.J.J.J.JJ..J.................T.T.T.T.T.T.T.T.T...T...........T.T.T.T.T.TT..T...............J.....J.....J.J.J.JJ....T.TT........J.J.J.J.J.J.J.J...J.........T.....T.....T.T.T.TT....J.JJ....DD.D.............................................................",
|
||||
scale: 1
|
||||
},
|
||||
]
|
||||
|
||||
export function noteDefault(time, prevStep) {
|
||||
add([
|
||||
rect(10, 50),
|
||||
pos(width(), 20),
|
||||
color(232, 3, 252),
|
||||
("note" + prevStep),
|
||||
"note",
|
||||
{
|
||||
created: time,
|
||||
type: "J",
|
||||
empty: false,
|
||||
normal: true
|
||||
}
|
||||
]);
|
||||
}
|
||||
|
||||
export function customNote(time, letter, prevStep, w, colorArray, empty, funclol) {
|
||||
add([
|
||||
rect(w, 50),
|
||||
pos(width(), 20),
|
||||
colorArray ? color(colorArray[0], colorArray[1], colorArray[2]) : color(0, 0, 0),
|
||||
("note" + prevStep),
|
||||
"note",
|
||||
{
|
||||
created: time,
|
||||
type: letter,
|
||||
function: funclol,
|
||||
empty: empty,
|
||||
normal: funclol != undefined ? false : true
|
||||
}
|
||||
]);
|
||||
}
|
175
views/projects/item/midsim/code/easing.js
Normal file
|
@ -0,0 +1,175 @@
|
|||
export var easings = { // Easings taken from https://easings.net/
|
||||
linear: (x) => {
|
||||
return x;
|
||||
},
|
||||
easeInSine: (x) => {
|
||||
return 1 - Math.cos((x * Math.PI) / 2);
|
||||
},
|
||||
easeOutSine: (x) => {
|
||||
return Math.sin((x * Math.PI) / 2);
|
||||
},
|
||||
easeInOutSine: (x) => {
|
||||
return -(Math.cos(Math.PI * x) - 1) / 2;
|
||||
},
|
||||
easeInQuad: (x) => {
|
||||
return x * x;
|
||||
},
|
||||
easeOutQuad: (x) => {
|
||||
return 1 - (1 - x) * (1 - x);
|
||||
},
|
||||
easeInOutQuad: (x) => {
|
||||
return x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2;
|
||||
},
|
||||
easeInCubic: (x) => {
|
||||
return x * x * x;
|
||||
},
|
||||
easeOutCubic: (x) => {
|
||||
return 1 - Math.pow(1 - x, 3);
|
||||
},
|
||||
easeInOutCubic: (x) => {
|
||||
return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
|
||||
},
|
||||
easeInQuart: (x) => {
|
||||
return x * x * x * x;
|
||||
},
|
||||
easeOutQuart: (x) => {
|
||||
return 1 - Math.pow(1 - x, 4);
|
||||
},
|
||||
easeInOutQuart: (x) => {
|
||||
return x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2;
|
||||
},
|
||||
easeInQuint: (x) => {
|
||||
return x * x * x * x * x;
|
||||
},
|
||||
easeOutQuint: (x) => {
|
||||
return 1 - Math.pow(1 - x, 5);
|
||||
},
|
||||
easeInOutQuint: (x) => {
|
||||
return x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2;
|
||||
},
|
||||
easeInExpo: (x) => {
|
||||
return x === 0 ? 0 : Math.pow(2, 10 * x - 10);
|
||||
},
|
||||
easeOutExpo: (x) => {
|
||||
return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);
|
||||
},
|
||||
easeInOutExpo: (x) => {
|
||||
return x === 0
|
||||
? 0
|
||||
: x === 1
|
||||
? 1
|
||||
: x < 0.5 ? Math.pow(2, 20 * x - 10) / 2
|
||||
: (2 - Math.pow(2, -20 * x + 10)) / 2;
|
||||
},
|
||||
easeInCirc: (x) => {
|
||||
return 1 - Math.sqrt(1 - Math.pow(x, 2));
|
||||
},
|
||||
easeOutCirc: (x) => {
|
||||
return Math.sqrt(1 - Math.pow(x - 1, 2));
|
||||
},
|
||||
easeInOutCirc: (x) => {
|
||||
return x < 0.5
|
||||
? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2
|
||||
: (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2;
|
||||
},
|
||||
easeInBack: (x) => {
|
||||
const c1 = 1.70158;
|
||||
const c3 = c1 + 1;
|
||||
return c3 * x * x * x - c1 * x * x;
|
||||
},
|
||||
easeOutBack: (x) => {
|
||||
const c1 = 1.70158;
|
||||
const c3 = c1 + 1;
|
||||
return 1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2);
|
||||
},
|
||||
easeInOutBack: (x) => {
|
||||
const c1 = 1.70158;
|
||||
const c2 = c1 * 1.525;
|
||||
return x < 0.5
|
||||
? (Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2
|
||||
: (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
|
||||
},
|
||||
easeInBounce: (x) => {
|
||||
return 1 - easings.easeOutBounce(1 - x);
|
||||
},
|
||||
easeOutBounce: (x) => {
|
||||
const n1 = 7.5625;
|
||||
const d1 = 2.75;
|
||||
|
||||
if (x < 1 / d1) {
|
||||
return n1 * x * x;
|
||||
} else if (x < 2 / d1) {
|
||||
return n1 * (x -= 1.5 / d1) * x + 0.75;
|
||||
} else if (x < 2.5 / d1) {
|
||||
return n1 * (x -= 2.25 / d1) * x + 0.9375;
|
||||
} else {
|
||||
return n1 * (x -= 2.625 / d1) * x + 0.984375;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: (x) => {
|
||||
return x < 0.5
|
||||
? (1 - easings.easeOutBounce(1 - 2 * x)) / 2
|
||||
: (1 + easings.easeOutBounce(2 * x - 1)) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
export var tweentypes = {
|
||||
FOREVER: (t, st, tl) => {
|
||||
if (t - st >= tl) {
|
||||
return "FOREVER";
|
||||
}
|
||||
return "CONTINUE";
|
||||
},
|
||||
LERPFOREVER: (t, st, tl) => {
|
||||
return "LF";
|
||||
},
|
||||
PINGPONG: (t, st, tl) => {
|
||||
if (t - st >= tl) {
|
||||
return "PING";
|
||||
}
|
||||
return "CONTINUE";
|
||||
},
|
||||
NORMAL: (t, st, tl) => {
|
||||
if (t - st >= tl) {
|
||||
return "CALLBACK";
|
||||
}
|
||||
return "CONTINUE";
|
||||
}
|
||||
}
|
||||
|
||||
export function tween(func, attrs, timeLen, minVal, maxVal, ease, type, onFinish) {
|
||||
var minVal = minVal != undefined ? minVal : func[attrs[0]];
|
||||
var ease = ease != undefined ? ease : easings.linear;
|
||||
var type = type != undefined ? type : tweentypes.NORMAL;
|
||||
var stTime = time();
|
||||
var onFinish = onFinish != undefined ? onFinish : "ud";
|
||||
var upd = onUpdate(() => {
|
||||
switch (type(time(), stTime, timeLen)) {
|
||||
case "CALLBACK":
|
||||
for (let h in attrs) {
|
||||
func[attrs[h]] = maxVal;
|
||||
}
|
||||
upd();
|
||||
return onFinish == "ud" ? true : onFinish();
|
||||
case "FOREVER":
|
||||
stTime = time();
|
||||
break;
|
||||
case "CONTINUE":
|
||||
for (let h in attrs) {
|
||||
func[attrs[h]] = minVal;
|
||||
}
|
||||
break;
|
||||
case "PING":
|
||||
var buffer = minVal;
|
||||
minVal = maxVal;
|
||||
maxVal = buffer;
|
||||
stTime = time();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
for (let i in attrs) {
|
||||
func[attrs[i]] = lerp(minVal, maxVal, ease((time() - stTime) / timeLen));
|
||||
}
|
||||
});
|
||||
}
|
981
views/projects/item/midsim/code/main.js
Normal file
|
@ -0,0 +1,981 @@
|
|||
"use strict";
|
||||
import { kaboom, easings, tween, tweentypes } from "../deps.js";
|
||||
import { charts } from "./charts.js";
|
||||
|
||||
// initialize context
|
||||
kaboom({
|
||||
width: 700,
|
||||
height: 400,
|
||||
background: [ 0, 0, 0 ],
|
||||
crisp: true,
|
||||
touchToMouse: true,
|
||||
canvas: document.querySelector("#kaboom"),
|
||||
font: "MidSim",
|
||||
scale: 1,
|
||||
|
||||
});
|
||||
var ismobile = isTouch();
|
||||
|
||||
load(new Promise((resolve, reject) => {
|
||||
loadFont("unscii", "sprites/unscii_8x8.png", 8, 8, {chars: " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"});
|
||||
loadFont("MidSim", "sprites/MidSimFont2.png", 10, 10, {chars: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz:;><^%-.!?/()[]\"'|1234567890"});
|
||||
// Music
|
||||
loadSound("gameover", "sounds/gameover.mp3");
|
||||
//
|
||||
|
||||
// Sounds
|
||||
loadSound("nullHit", "sounds/nullHit.mp3");
|
||||
loadSound("score", "sounds/score.mp3");
|
||||
loadSound("metro", "sounds/metro.wav");
|
||||
loadSound("explode", "sounds/explode.mp3");
|
||||
//
|
||||
|
||||
//Menus
|
||||
loadSprite("bgCake", "sprites/bgCake.png");
|
||||
loadSprite("jellybeanTitle", "sprites/jellybeanTitle.png");
|
||||
loadSprite("logo", "sprites/logo.png");
|
||||
loadSprite("jellybeanFail", "sprites/jellybeanFail.png");
|
||||
//
|
||||
|
||||
// Main Game
|
||||
loadSprite("noteClick", "sprites/noteClick.png", {
|
||||
sliceX: 4,
|
||||
sliceY: 2,
|
||||
anims: {
|
||||
idle: {
|
||||
from: 7,
|
||||
to: 7,
|
||||
speed: 30
|
||||
},
|
||||
click: {
|
||||
from: 0,
|
||||
to: 7,
|
||||
speed: 60
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
for (let ided in charts) {
|
||||
console.log("Loading game assets...");
|
||||
charts[ided].events.preload();
|
||||
console.log("Assets of song " + charts[ided].name + " loaded.");
|
||||
}
|
||||
|
||||
resolve("All assets loaded.");
|
||||
}));
|
||||
|
||||
scene("Game", (idx, noTrans) => {
|
||||
var song = charts[idx.song].id; //Also Chart access
|
||||
var char = charts[idx.song].characters[idx.character][0];
|
||||
var hitsound = "hitsound" + charts[idx.song].characters[idx.character][0];
|
||||
var chart = charts[idx.song].chart;
|
||||
var crochet = ((60 / charts[idx.song].bpm) * 1000);
|
||||
var board = width() - strumLine;
|
||||
var curBeat;
|
||||
var prevBeat;
|
||||
var prevStep;
|
||||
var curStep;
|
||||
var autoplay = false;
|
||||
var debugMode = false;
|
||||
var score = 0;
|
||||
var combo = 0;
|
||||
var health = 1;
|
||||
var font = "MidSim";
|
||||
if (char == "MarkyMark") {
|
||||
font = "unscii";
|
||||
}
|
||||
|
||||
// Music
|
||||
var strumLine = width() / 2;
|
||||
const music = play(charts[idx.song].id, {
|
||||
volume: 1,
|
||||
loop: false
|
||||
});
|
||||
const underlay = play("score", {
|
||||
volume: 1,
|
||||
loop: false
|
||||
});
|
||||
music.pause()
|
||||
wait(charts[idx.song].speed, () => {
|
||||
underlay.pause();
|
||||
music.play();
|
||||
underlay.play(music.time() + charts[idx.song].speed);
|
||||
});
|
||||
|
||||
// Sprites
|
||||
layers([
|
||||
"bg",
|
||||
"JELLYBEAN",
|
||||
"SKELETONS",
|
||||
"fg",
|
||||
"ui0",
|
||||
"ui1"
|
||||
], "ui0");
|
||||
var players = {
|
||||
main: 0,
|
||||
empty: 0,
|
||||
};
|
||||
var bg;
|
||||
var tweenVals = {
|
||||
fade: 1,
|
||||
triggered: false
|
||||
}
|
||||
tween(tweenVals, ["fade"], 1, 1, 0, easings.easeOutCirc, tweentypes.NORMAL);
|
||||
if (!charts[idx.song].makeScript.customChar) {
|
||||
players.main = add([
|
||||
sprite(char + song),
|
||||
layer("JELLYBEAN"),
|
||||
"dances",
|
||||
pos(charts[idx.song].characters[idx.character][2], charts[idx.song].characters[idx.character][3]),
|
||||
scale(charts[idx.song].scale)
|
||||
]);
|
||||
}
|
||||
if (!charts[idx.song].makeScript.customBG) {
|
||||
bg = add([
|
||||
sprite(song + "BG0"),
|
||||
layer("bg"),
|
||||
scale(charts[idx.song].scale)
|
||||
]);
|
||||
const fg = add([
|
||||
sprite(song + "FG0"),
|
||||
(song == "faith" ? layer("bg") : layer("fg")),
|
||||
scale(charts[idx.song].scale)
|
||||
]);
|
||||
}
|
||||
var script = charts[idx.song].makeScript.script(players, char, bg);
|
||||
if (script.returnType != undefined && script.returnType == "character") {
|
||||
players.main = script.main;
|
||||
players.empty = script.empty;
|
||||
}
|
||||
const noteClick = add([
|
||||
sprite("noteClick"),
|
||||
scale(0.25),
|
||||
pos(strumLine, 15)
|
||||
])
|
||||
const bspButton = add([
|
||||
pos(0, 0),
|
||||
color(CYAN),
|
||||
text(ismobile ? "<" : "BACKSPACE TO EXIT", {
|
||||
size: ismobile? 32 : 20, // 48 pixels tall
|
||||
}),
|
||||
area({
|
||||
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||||
}),
|
||||
"back"
|
||||
])
|
||||
const entButton = add([
|
||||
pos(width(), 0),
|
||||
origin("topright"),
|
||||
color(YELLOW),
|
||||
text(ismobile ? "||" : "ENTER TO PAUSE", {
|
||||
size: ismobile? 32 : 20, // 48 pixels tall
|
||||
}),
|
||||
area({
|
||||
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||||
}),
|
||||
"ent"
|
||||
])
|
||||
// Gameplay
|
||||
onUpdate(() => {
|
||||
if (health > 1) health = 1;
|
||||
if (health < 0) {
|
||||
health = 0;
|
||||
if(!tweenVals.triggered) {
|
||||
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||||
underlay.stop();
|
||||
music.stop();
|
||||
go("Lose", score, idx);
|
||||
});
|
||||
underlay.pause();
|
||||
music.pause();
|
||||
tweenVals.triggered = true;
|
||||
}
|
||||
}
|
||||
if (music.time() > music.duration() && health >= 0) {
|
||||
if(!tweenVals.triggered) {
|
||||
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||||
go("Help");
|
||||
});
|
||||
tweenVals.triggered = true;
|
||||
}
|
||||
}
|
||||
strumLine = lerp(18, width() / 2, health);
|
||||
noteClick.pos.x = strumLine - 5;
|
||||
curBeat = Math.floor(((music.time() * 1000) / crochet) * 10) / 10;
|
||||
curStep = Math.floor((music.time() * 1000) / (crochet / 4));
|
||||
prevBeat = Math.floor(((underlay.time() * 1000) / crochet));
|
||||
prevStep = Math.floor((underlay.time() * 1000) / (crochet / 4));
|
||||
if (!get("bar" + prevBeat).length) {
|
||||
var bar = add([
|
||||
prevBeat % 4 == 0 ? rect(3, 50) : rect(2, 50),
|
||||
pos(width(), 20),
|
||||
color(255, 255, 255),
|
||||
("bar" + prevBeat),
|
||||
{
|
||||
mainBar: prevBeat % 4 == 0,
|
||||
created: underlay.time()
|
||||
},
|
||||
"bar"
|
||||
]);
|
||||
}
|
||||
if (get("note" + prevStep).length <= 0) {
|
||||
makeNote(charts[idx.song].chart[Math.floor(prevStep)]);
|
||||
}
|
||||
if (!underlay.isPaused()) {
|
||||
every("bar", (j) => {
|
||||
j.pos.x = lerp(width(), strumLine, (underlay.time() - j.created) / charts[idx.song].speed);
|
||||
if(j.pos.x <= strumLine) {
|
||||
beatHit();
|
||||
if (debugMode) play("metro", {detune: j.mainBar ? 200 : 0});
|
||||
destroy(j);
|
||||
}
|
||||
if (charts[idx.song].events.onBeat != undefined) {
|
||||
charts[idx.song].events.onBeat(curBeat);
|
||||
}
|
||||
});
|
||||
every("note", (j) => {
|
||||
j.pos.x = lerp(width(), strumLine, (underlay.time() - j.created) / charts[idx.song].speed);
|
||||
if(autoplay) {
|
||||
if(j.pos.x <= strumLine && !j.empty) {
|
||||
play(hitsound);
|
||||
players.main.play("talk"); //Check this area later, you want to add in Note Modularity!
|
||||
destroy(j);
|
||||
}
|
||||
} else {
|
||||
if(j.pos.x <= strumLine - 20 && !j.empty) {
|
||||
score -= 200;
|
||||
destroy(j);
|
||||
play("explode");
|
||||
players.main.play("miss");
|
||||
shake(5);
|
||||
combo = 0;
|
||||
health -= 0.1;
|
||||
}
|
||||
}
|
||||
if(j.pos.x <= strumLine && j.empty) {
|
||||
if (!j.normal) {
|
||||
j.function(j.empty, curBeat, j.type);
|
||||
}
|
||||
destroy(j);
|
||||
players.empty?.play("talk");
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
var mt;
|
||||
onKeyPress("enter", () => {
|
||||
if (!underlay.isPaused()) {
|
||||
underlay.pause();
|
||||
music.pause();
|
||||
mt = [underlay.time(), music.time()];
|
||||
} else {
|
||||
underlay.play(mt[0]);
|
||||
music.play(mt[1]);
|
||||
}
|
||||
});
|
||||
onKeyPress("space", () => {judgeHitsLol()});
|
||||
onKeyPress("backspace", () => {
|
||||
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||||
underlay.stop();
|
||||
music.stop();
|
||||
go("Help");
|
||||
});
|
||||
underlay.pause();
|
||||
music.pause();
|
||||
});
|
||||
onKeyPress("a", () => {autoplay = !autoplay});
|
||||
onKeyPress("d", () => {debugMode = !debugMode});
|
||||
onClick("back", () => {
|
||||
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||||
underlay.stop();
|
||||
music.stop();
|
||||
go("Help");
|
||||
});
|
||||
underlay.pause();
|
||||
music.pause();
|
||||
});
|
||||
onClick("ent", () => {
|
||||
if (!underlay.isPaused()) {
|
||||
underlay.pause();
|
||||
music.pause();
|
||||
mt = [underlay.time(), music.time()];
|
||||
} else {
|
||||
underlay.play(mt[0]);
|
||||
music.play(mt[1]);
|
||||
}
|
||||
});
|
||||
onClick(() => {judgeHitsLol()});
|
||||
onDraw(() => {
|
||||
drawLine({
|
||||
p1: vec2(0, 20),
|
||||
p2: vec2(width(), 20),
|
||||
width: 2,
|
||||
color: rgb(255, 255, 255),
|
||||
})
|
||||
drawLine({
|
||||
p1: vec2(0, 70),
|
||||
p2: vec2(width(), 70),
|
||||
width: 2,
|
||||
color: rgb(255, 255, 255),
|
||||
})
|
||||
drawLines({ // 80 * 240, 20 * 60
|
||||
pts: [ vec2(strumLine, 18), vec2(strumLine + 10, 18), vec2(strumLine + 10, 72), vec2(strumLine, 72), vec2(strumLine, 18) ],
|
||||
width: 2,
|
||||
pos: vec2(100, 200),
|
||||
color: rgb(255, 255, 255),
|
||||
})
|
||||
drawText({
|
||||
text: "MID-SIMULATOR DEMO",
|
||||
size: 20,
|
||||
pos: vec2(0, height() - 20),
|
||||
font: font
|
||||
});
|
||||
if (debugMode) {
|
||||
drawText({
|
||||
text: underlay.time() * 1000,
|
||||
size: 20,
|
||||
pos: vec2(0, 20),
|
||||
font: font
|
||||
});
|
||||
drawText({
|
||||
text: curBeat,
|
||||
size: 20,
|
||||
pos: vec2(0, 40),
|
||||
font: font
|
||||
});
|
||||
drawText({
|
||||
text: prevStep + "/" + (charts[idx.song].chart.length - 1),
|
||||
size: 20,
|
||||
pos: vec2(0, 60),
|
||||
font: font
|
||||
});
|
||||
drawText({
|
||||
text: (charts[idx.song].chart[Math.floor(prevStep)] ? charts[idx.song].chart[Math.floor(prevStep)] : "."),
|
||||
size: 20,
|
||||
pos: vec2(0, 80),
|
||||
font: font
|
||||
});
|
||||
drawText({
|
||||
text: (charts[idx.song].chart[Math.floor(curStep)] ? charts[idx.song].chart[Math.floor(curStep)] : "."),
|
||||
size: 20,
|
||||
pos: vec2(0, 100),
|
||||
font: font
|
||||
});
|
||||
drawText({
|
||||
text: "Health: " + health,
|
||||
size: 20,
|
||||
pos: vec2(strumLine, 120),
|
||||
font: font
|
||||
});
|
||||
}
|
||||
drawText({
|
||||
text: "Score: " + score,
|
||||
size: 20,
|
||||
pos: vec2(strumLine, 80),
|
||||
font: font
|
||||
});
|
||||
drawText({
|
||||
text: "Combo: " + combo,
|
||||
size: 20,
|
||||
pos: vec2(strumLine, 100),
|
||||
font: font
|
||||
});
|
||||
if (autoplay) {
|
||||
drawText({
|
||||
text: "AUTOPLAY",
|
||||
size: 20,
|
||||
pos: vec2(strumLine, debugMode? 140: 120),
|
||||
font: font
|
||||
});
|
||||
}
|
||||
drawRect({
|
||||
width: 702,
|
||||
height: 402,
|
||||
pos: vec2(-1, -1),
|
||||
color: BLACK,
|
||||
opacity: tweenVals.fade
|
||||
})
|
||||
})
|
||||
|
||||
//Functions
|
||||
|
||||
function makeNote(letter) {
|
||||
if (charts[idx.song].noteTypes.hasOwnProperty(letter)) {
|
||||
charts[idx.song].noteTypes[letter](underlay.time(), prevStep, char);
|
||||
}
|
||||
}
|
||||
function judgeHitsLol() {
|
||||
var iv = false;
|
||||
var hits = 0;
|
||||
every("note", (j) => {
|
||||
if (!iv) {
|
||||
if (!j.empty) {
|
||||
var str = "No Rating";
|
||||
var theColor = WHITE;
|
||||
if(j.pos.x >= strumLine - 20) {
|
||||
if(j.pos.x <= strumLine + 22) {
|
||||
hits++;
|
||||
iv = true;
|
||||
if (!j.normal) {
|
||||
j.function(j.empty, curBeat, j.type);
|
||||
}
|
||||
destroy(j); //Destroys note. No score.
|
||||
noteClick.play("click");
|
||||
combo += 1;
|
||||
str = "MID";
|
||||
theColor = RED;
|
||||
}
|
||||
if(j.pos.x <= strumLine + 12) {
|
||||
play(hitsound); //Plays sound!
|
||||
players.main.play("talk");
|
||||
score += 20;
|
||||
health += 0.01;
|
||||
str = "Perfect!";
|
||||
theColor = MAGENTA;
|
||||
}
|
||||
if(j.pos.x <= strumLine + 5) {
|
||||
score += 50;
|
||||
health += 0.02;
|
||||
str = "Perfect!!";
|
||||
}
|
||||
if(j.pos.x <= strumLine - 3) {
|
||||
score += 50;
|
||||
health -= 0.01;
|
||||
str = "Perfect!";
|
||||
}
|
||||
if(j.pos.x <= strumLine - 8) {
|
||||
score -= 100;
|
||||
health -= 0.02;
|
||||
str = "Overshot";
|
||||
theColor = CYAN;
|
||||
}
|
||||
}
|
||||
if (str != "No Rating") {
|
||||
var origpos = strumLine - 16;
|
||||
var ratingtxt = add([
|
||||
text(str, {
|
||||
size: 30, // 48 pixels tall
|
||||
}),
|
||||
pos(origpos, 48),
|
||||
color(theColor),
|
||||
origin("right")
|
||||
]);
|
||||
tween(ratingtxt.pos, ["y"], 5, 48, 300, easings.easeOutSine, tweentypes.NORMAL);
|
||||
tween(ratingtxt, ["opacity"], 5, 1, 0, easings.easeOutSine, tweentypes.NORMAL, function() {
|
||||
destroy(ratingtxt);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
if (hits <= 0) {
|
||||
play("nullHit");
|
||||
}
|
||||
}
|
||||
function beatHit() {
|
||||
every("dances", (obj) => {
|
||||
if (obj.curAnim() != "talk" && obj.curAnim() != "miss") {
|
||||
obj.play("idle");
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
scene("Help", (noTrans) => {
|
||||
var index = {
|
||||
character: 0,
|
||||
song: 0
|
||||
}
|
||||
var tweenVals = {
|
||||
fade: 0
|
||||
}
|
||||
if (!noTrans) tween(tweenVals, ["fade"], 1, 1, 0, easings.easeOutCirc, tweentypes.NORMAL);
|
||||
const bg = add([
|
||||
sprite("bgCake")
|
||||
]);
|
||||
onDraw(() => {
|
||||
if (!ismobile) {
|
||||
drawText({
|
||||
text: "D: ENABLE DEBUG MODE",
|
||||
size: 30,
|
||||
pos: vec2(25, 25)
|
||||
});
|
||||
drawText({
|
||||
text: "A: ENABLE AUTOPLAY",
|
||||
size: 30,
|
||||
pos: vec2(25, 60)
|
||||
});
|
||||
}
|
||||
drawText({
|
||||
text: ismobile ? "TAP TO HIT NOTES" : "SPACE/CLICK: HIT NOTE",
|
||||
size: 30,
|
||||
pos: ismobile ? vec2(25, 60) : vec2(25, 95)
|
||||
});
|
||||
drawText({
|
||||
text: charts[index.song].characters[index.character][1] + " ("+ (index.character + 1) +"/"+ charts[index.song].characters.length +")",
|
||||
size: 30,
|
||||
pos: vec2(width() / 2, 200),
|
||||
origin: "top"
|
||||
});
|
||||
drawText({
|
||||
text: charts[index.song].name,
|
||||
size: 30,
|
||||
pos: vec2(width() / 2, 160),
|
||||
origin: "top"
|
||||
});
|
||||
drawSprite({
|
||||
sprite: charts[index.song].characters[index.character][0] + "Pre",
|
||||
width: 64,
|
||||
height: 64,
|
||||
pos: vec2((width() / 2) - 34, 248)
|
||||
});
|
||||
drawRect({
|
||||
width: 702,
|
||||
height: 402,
|
||||
pos: vec2(-1, -1),
|
||||
color: BLACK,
|
||||
opacity: tweenVals.fade
|
||||
})
|
||||
})
|
||||
add([
|
||||
pos(0, 140),
|
||||
rect(700, 200),
|
||||
color(0, 0, 0)
|
||||
])
|
||||
var lt = add([
|
||||
pos(10, 200),
|
||||
text("<", {
|
||||
size: 30
|
||||
}),
|
||||
area({
|
||||
height: 30,
|
||||
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||||
width: 30,
|
||||
cursor: "pointer"
|
||||
}),
|
||||
"LeftText"
|
||||
])
|
||||
var rt = add([
|
||||
pos(width() - 10, 200),
|
||||
origin("topright"),
|
||||
text(">", {
|
||||
size: 30
|
||||
}),
|
||||
area({
|
||||
height: 30,
|
||||
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||||
width: 30,
|
||||
cursor: "pointer"
|
||||
}),
|
||||
"RightText"
|
||||
])
|
||||
var dt = add([
|
||||
pos(10, 160),
|
||||
text("%", {
|
||||
size: 30
|
||||
}),
|
||||
area({
|
||||
height: 30,
|
||||
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||||
width: 30,
|
||||
cursor: "pointer"
|
||||
}),
|
||||
"DownText"
|
||||
])
|
||||
var ut = add([
|
||||
pos(width() - 10, 160),
|
||||
origin("topright"),
|
||||
text("^", {
|
||||
size: 30
|
||||
}),
|
||||
area({
|
||||
height: 30,
|
||||
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||||
width: 30,
|
||||
cursor: "pointer"
|
||||
}),
|
||||
"UpText"
|
||||
])
|
||||
var clickText = add([
|
||||
pos(width() / 2, height() - 45),
|
||||
text(ismobile ? "TAP HERE TO START" : "SPACE TO START", {
|
||||
size: 30
|
||||
}),
|
||||
origin("top"),
|
||||
area({
|
||||
height: 30,
|
||||
offset: ismobile ? vec2(canvas.offsetLeft, canvas.offsetTop) : vec2(0, 0),
|
||||
width: 700,
|
||||
cursor: "pointer"
|
||||
}),
|
||||
"TEXT TEXT"
|
||||
])
|
||||
function changeIdx(amt) {
|
||||
index.character += amt;
|
||||
if (index.character < 0) {
|
||||
index.character = charts[index.song].characters.length - 1;
|
||||
} else if (index.character >= charts[index.song].characters.length) {
|
||||
index.character = 0;
|
||||
}
|
||||
}
|
||||
function changeSongIdx(amt) {
|
||||
index.song += amt;
|
||||
index.character = 0;
|
||||
if (index.song < 0) {
|
||||
index.song = charts.length - 1;
|
||||
} else if (index.song >= charts.length) {
|
||||
index.song = 0;
|
||||
}
|
||||
}
|
||||
|
||||
onKeyPress("left", () => {changeIdx(-1)});
|
||||
onKeyPress("right", () => {changeIdx(1)});
|
||||
onKeyPress("down", () => {changeSongIdx(-1)});
|
||||
onKeyPress("up", () => {changeSongIdx(1)});
|
||||
onKeyPress("`", () => {go("Chart", index.song)});
|
||||
onKeyPress("D", () => {go("Chart", index.song)});
|
||||
onKeyPress("/", () => {go("Chart", index.song)});
|
||||
onKeyPress("7", () => {go("Chart", index.song)});
|
||||
lt.onClick(() => {changeIdx(-1)});
|
||||
rt.onClick(() => {changeIdx(1)});
|
||||
dt.onClick(() => {changeSongIdx(-1)});
|
||||
ut.onClick(() => {changeSongIdx(1)});
|
||||
onKeyPress("space", () => {
|
||||
tween(tweenVals, ["fade"], 1, 0, 1, easings.easeOutCirc, tweentypes.NORMAL, function () {
|
||||
go("Game", index);
|
||||
});
|
||||
});
|
||||
clickText.onClick(() => {go("Game", index);/*losemus.stop();*/});
|
||||
});
|
||||
|
||||
scene("Title", () => {
|
||||
const bg = add([
|
||||
sprite("bgCake")
|
||||
]);
|
||||
const jb = add([
|
||||
sprite("jellybeanTitle"),
|
||||
pos(0, height() - 320)
|
||||
]);
|
||||
const logo = add([
|
||||
sprite("logo"),
|
||||
pos(0, 0),
|
||||
scale(0.5, 0.5)
|
||||
]);
|
||||
onDraw(() => {
|
||||
drawText({
|
||||
text: "SPACE TO START",
|
||||
size: 30,
|
||||
origin: "top",
|
||||
pos: vec2(width() / 2, height() - 45)
|
||||
});
|
||||
})
|
||||
onKeyPress("space", () => {go("Help", true);/*losemus.stop();*/});
|
||||
onClick(() => {go("Help", true);/*losemus.stop();*/});
|
||||
onTouchStart(() => {go("Help", true);/*losemus.stop();*/});
|
||||
});
|
||||
|
||||
scene("Lose", (score, song) => {
|
||||
const lost = add([
|
||||
sprite("jellybeanFail"),
|
||||
"dances",
|
||||
pos((width() / 2) - 162, height() / 2 - 162)
|
||||
])
|
||||
const losemus = play("gameover", {
|
||||
volume: 1,
|
||||
loop: true
|
||||
});
|
||||
onDraw(() => {
|
||||
drawText({
|
||||
text: "OUCHIE!",
|
||||
size: 60,
|
||||
pos: vec2(0, height() - 120)
|
||||
});
|
||||
drawText({
|
||||
text: ismobile ? "TAP TO RESTART" : "SPACE TO RESTART",
|
||||
size: 30,
|
||||
pos: vec2(0, height() - 60)
|
||||
});
|
||||
drawText({
|
||||
text: "SCORE: " + score,
|
||||
size: 30,
|
||||
pos: vec2(0, height() - 30)
|
||||
});
|
||||
})
|
||||
onKeyPress("space", () => {go("Game", song);losemus.stop();});
|
||||
onClick(() => {go("Game", song);losemus.stop();});
|
||||
});
|
||||
|
||||
scene("Chart", (idx) => {
|
||||
var chart = charts[idx].chart;
|
||||
var crochet = ((60 / charts[idx].bpm) * 1000);
|
||||
var curBeat;
|
||||
var curStep;
|
||||
var songTime = 0;
|
||||
var tool = "J";
|
||||
const music = play(charts[idx].id, {
|
||||
volume: 1,
|
||||
loop: false
|
||||
});
|
||||
music.pause();
|
||||
|
||||
var lastTargeted = 4;
|
||||
var tempChart = Array.from(Array(Math.floor((music.duration() * 1000) / (crochet / 4))), () => ".");
|
||||
// Incredibly redundant, sadly I don't care
|
||||
var coords = [
|
||||
width() * 0.1,
|
||||
width() * 0.2,
|
||||
width() * 0.3,
|
||||
width() * 0.4,
|
||||
width() * 0.5,
|
||||
width() * 0.6,
|
||||
width() * 0.7,
|
||||
width() * 0.8,
|
||||
width() * 0.9
|
||||
];
|
||||
var theEmpty = add([
|
||||
pos(width() * 0.2, height() * 0.8),
|
||||
rect(60, 60),
|
||||
text(".", {
|
||||
size: 48, // 48 pixels tall
|
||||
width: 60
|
||||
}),
|
||||
color(255, 255, 255),
|
||||
outline(4, WHITE),
|
||||
origin("center"),
|
||||
area(),
|
||||
"theEmpty"
|
||||
]);
|
||||
var theJ = add([
|
||||
pos(width() * 0.4, height() * 0.8),
|
||||
rect(60, 60),
|
||||
text("J", {
|
||||
size: 48, // 48 pixels tall
|
||||
width: 60
|
||||
}),
|
||||
color(255, 255, 255),
|
||||
outline(4, WHITE),
|
||||
origin("center"),
|
||||
area(),
|
||||
"theJ"
|
||||
]);
|
||||
var theP = add([
|
||||
pos(width() * 0.6, height() * 0.8),
|
||||
rect(60, 30),
|
||||
text("P", {
|
||||
size: 24, // 48 pixels tall
|
||||
width: 60
|
||||
}),
|
||||
color(255, 255, 255),
|
||||
outline(4, WHITE),
|
||||
origin("center"),
|
||||
area(),
|
||||
"theP"
|
||||
]);
|
||||
var theD = add([
|
||||
pos(width() * 0.6, height() * 0.8 + 30),
|
||||
rect(60, 30),
|
||||
text("D", {
|
||||
size: 24, // 48 pixels tall
|
||||
width: 60
|
||||
}),
|
||||
color(255, 255, 255),
|
||||
outline(4, WHITE),
|
||||
origin("center"),
|
||||
area(),
|
||||
"theD"
|
||||
]);
|
||||
var consoleButton = add([
|
||||
pos(width() * 0.8, height() * 0.8),
|
||||
rect(60, 60),
|
||||
text("EXPORT", {
|
||||
size: 30, // 48 pixels tall
|
||||
}),
|
||||
color(255, 255, 255),
|
||||
outline(4, WHITE),
|
||||
origin("center"),
|
||||
area(),
|
||||
"consoleButton"
|
||||
]);
|
||||
onClick("theEmpty", (o) => {tool = "."})
|
||||
onClick("theJ", (o) => {tool = "J"})
|
||||
onClick("theP", (o) => {tool = "P"})
|
||||
onClick("theD", (o) => {tool = "D"})
|
||||
onClick("consoleButton", (o) => {console.log(tempChart.join(""));})
|
||||
onUpdate(() => {
|
||||
curBeat = Math.floor(((music.time() * 1000) / crochet) * 10) / 10;
|
||||
curStep = Math.floor((music.time() * 1000) / (crochet / 4));
|
||||
if (mousePos().y >= height() * 0.4 && mousePos().y < (height() / 2) + 34) { // I shouldve used a Switch Case here :/
|
||||
if (mousePos().x < width() * 0.15) {
|
||||
// blk0
|
||||
lastTargeted = 0;
|
||||
} else if (mousePos().x < width() * 0.25) {
|
||||
// blk1
|
||||
lastTargeted = 1;
|
||||
} else if (mousePos().x < width() * 0.35) {
|
||||
// blk2
|
||||
lastTargeted = 2;
|
||||
} else if (mousePos().x < width() * 0.45) {
|
||||
// blk3
|
||||
lastTargeted = 3;
|
||||
} else if (mousePos().x < width() * 0.55) {
|
||||
// blk4
|
||||
lastTargeted = 4;
|
||||
} else if (mousePos().x < width() * 0.65) {
|
||||
// blk5
|
||||
lastTargeted = 5;
|
||||
} else if (mousePos().x < width() * 0.75) {
|
||||
// blk6
|
||||
lastTargeted = 6;
|
||||
} else if (mousePos().x < width() * 0.85) {
|
||||
// blk7
|
||||
lastTargeted = 7;
|
||||
} else if (mousePos().x < width()) {
|
||||
// blk8
|
||||
lastTargeted = 8;
|
||||
}
|
||||
}
|
||||
});
|
||||
onMouseDown(() => {
|
||||
if (mousePos().y >= height() * 0.4 && mousePos().y < (height() / 2) + 34) {
|
||||
tempChart[curStep + lastTargeted] = tool;
|
||||
}
|
||||
});
|
||||
onDraw(() => {
|
||||
drawText({
|
||||
text: songTime * 1000,
|
||||
size: 20,
|
||||
pos: vec2(0, )
|
||||
});
|
||||
drawText({
|
||||
text: music.time() * 1000,
|
||||
size: 20,
|
||||
pos: vec2(0, 20)
|
||||
});
|
||||
drawText({
|
||||
text: curBeat,
|
||||
size: 20,
|
||||
pos: vec2(0, 40)
|
||||
});
|
||||
drawText({
|
||||
text: curStep + "/" + (tempChart.length - 1),
|
||||
size: 20,
|
||||
pos: vec2(0, 60)
|
||||
});
|
||||
drawText({
|
||||
text: tool,
|
||||
size: 50,
|
||||
pos: vec2(width() / 2, height() * 0.65),
|
||||
origin: "center"
|
||||
});
|
||||
drawLine({
|
||||
p1: vec2(coords[lastTargeted] - 30, (height() / 2) + 30),
|
||||
p2: vec2(coords[lastTargeted] + 30, (height() / 2) + 30),
|
||||
width: 4,
|
||||
color: rgb(255, 0, 0),
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep] ? tempChart[curStep] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[0], height() / 2),
|
||||
color: curStep % 4 == 0 ? RED : MAGENTA,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 1] ? tempChart[curStep + 1] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[1], height() / 2),
|
||||
color: (curStep + 1) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 2] ? tempChart[curStep + 2] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[2], height() / 2),
|
||||
color: (curStep + 2) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 3] ? tempChart[curStep + 3] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[3], height() / 2),
|
||||
color: (curStep + 3) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 4] ? tempChart[curStep + 4] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[4], height() / 2),
|
||||
color: (curStep + 4) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 5] ? tempChart[curStep + 5] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[5], height() / 2),
|
||||
color: (curStep + 5) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 6] ? tempChart[curStep + 6] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[6], height() / 2),
|
||||
color: (curStep + 6) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 7] ? tempChart[curStep + 7] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[7], height() / 2),
|
||||
color: (curStep + 7) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
drawText({
|
||||
text: tempChart[curStep + 8] ? tempChart[curStep + 8] : "",
|
||||
size: 30,
|
||||
pos: vec2(coords[8], height() / 2),
|
||||
color: (curStep + 8) % 4 == 0 ? RED : WHITE,
|
||||
origin: "center"
|
||||
})
|
||||
});
|
||||
|
||||
onKeyPress("left", () => {
|
||||
music.pause();
|
||||
songTime = songTime - ((crochet / 4) / 1000);
|
||||
try {
|
||||
music.play(songTime);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
songTime = 0;
|
||||
music.play(0);
|
||||
}
|
||||
music.pause();
|
||||
});
|
||||
onKeyPress("right", () => {
|
||||
music.pause();
|
||||
songTime = songTime + ((crochet / 4) / 1000);
|
||||
try {
|
||||
music.play(songTime);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
songTime = 0;
|
||||
music.play(0);
|
||||
}
|
||||
music.pause();
|
||||
});
|
||||
onKeyPress("space", () => {
|
||||
if (!music.isPaused()) {
|
||||
music.pause();
|
||||
songTime = music.time();
|
||||
} else {
|
||||
try {
|
||||
music.play(songTime);
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
songTime = 0;
|
||||
music.play(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
go("Title");
|
6
views/projects/item/midsim/deps.js
Normal file
|
@ -0,0 +1,6 @@
|
|||
import kaboom from "https://unpkg.com/kaboom@2000.2.9/dist/kaboom.mjs";
|
||||
import { easings, tween, tweentypes } from "./code/easing.js"
|
||||
|
||||
export {
|
||||
kaboom, easings, tween, tweentypes
|
||||
}
|
17
views/projects/item/midsim/index.html
Normal file
|
@ -0,0 +1,17 @@
|
|||
<!DOCTYPE html>
|
||||
<html style="height: 100vh; width: 100vw; overflow: hidden; margin: 0; padding: 0;">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<title>Mid Sim</title>
|
||||
</head>
|
||||
<body style="background-color: black; height: 100vh; width: 100vw; margin: 0; padding: 0; overflow: hidden;">
|
||||
<canvas id="kaboom"></canvas>
|
||||
<script src="code/main.js" type="module"></script> <!-- I hate how the scrollbar is still there on Replit -->
|
||||
<style>
|
||||
#kaboom {position: absolute;top: calc(50vh - 200px);left: calc(50vw - 350px);}
|
||||
</style>
|
||||
</body>
|
||||
|
||||
</html>
|
BIN
views/projects/item/midsim/sounds/Getting it Done.mp3
Normal file
BIN
views/projects/item/midsim/sounds/GreenHill.wav
Normal file
BIN
views/projects/item/midsim/sounds/SonicInMidSim.wav
Normal file
BIN
views/projects/item/midsim/sounds/The Friendly Faith Plate.mp3
Normal file
BIN
views/projects/item/midsim/sounds/burp.mp3
Normal file
BIN
views/projects/item/midsim/sounds/explode.mp3
Normal file
BIN
views/projects/item/midsim/sounds/gameover.mp3
Normal file
BIN
views/projects/item/midsim/sounds/hitsoundFaithPlate.mp3
Normal file
BIN
views/projects/item/midsim/sounds/hitsoundJellyBean.wav
Normal file
BIN
views/projects/item/midsim/sounds/hitsoundRedVelvety.wav
Normal file
BIN
views/projects/item/midsim/sounds/metro.wav
Normal file
BIN
views/projects/item/midsim/sounds/nullHit.mp3
Normal file
BIN
views/projects/item/midsim/sounds/score.mp3
Normal file
BIN
views/projects/item/midsim/sprites/321go.png
Normal file
After Width: | Height: | Size: 4.8 KiB |
BIN
views/projects/item/midsim/sprites/MidSimFont2.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
views/projects/item/midsim/sprites/SonicBG.png
Normal file
After Width: | Height: | Size: 36 KiB |
BIN
views/projects/item/midsim/sprites/SonicFG.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
views/projects/item/midsim/sprites/SonicMidSim.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
views/projects/item/midsim/sprites/TailsMidSim.png
Normal file
After Width: | Height: | Size: 37 KiB |
BIN
views/projects/item/midsim/sprites/bgCake.png
Normal file
After Width: | Height: | Size: 187 KiB |
BIN
views/projects/item/midsim/sprites/bgFaith.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
views/projects/item/midsim/sprites/carterredactedCake.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
views/projects/item/midsim/sprites/faithplateFaith.png
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
views/projects/item/midsim/sprites/fgCake0.png
Normal file
After Width: | Height: | Size: 9.3 KiB |
BIN
views/projects/item/midsim/sprites/fgCake1.png
Normal file
After Width: | Height: | Size: 9.9 KiB |
BIN
views/projects/item/midsim/sprites/fgFaith.png
Normal file
After Width: | Height: | Size: 944 B |
BIN
views/projects/item/midsim/sprites/jellybeanCake.png
Normal file
After Width: | Height: | Size: 68 KiB |
BIN
views/projects/item/midsim/sprites/jellybeanFail.png
Normal file
After Width: | Height: | Size: 4.6 KiB |
BIN
views/projects/item/midsim/sprites/jellybeanTitle.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
views/projects/item/midsim/sprites/logo.png
Normal file
After Width: | Height: | Size: 23 KiB |
BIN
views/projects/item/midsim/sprites/marcCake.png
Normal file
After Width: | Height: | Size: 16 KiB |
BIN
views/projects/item/midsim/sprites/markymarkCake.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
views/projects/item/midsim/sprites/noteClick.png
Normal file
After Width: | Height: | Size: 7.3 KiB |
After Width: | Height: | Size: 249 B |
BIN
views/projects/item/midsim/sprites/previews/FaithPlatePre.png
Normal file
After Width: | Height: | Size: 206 B |
BIN
views/projects/item/midsim/sprites/previews/JellyBeanPre.png
Normal file
After Width: | Height: | Size: 230 B |
BIN
views/projects/item/midsim/sprites/previews/MarcPre.png
Normal file
After Width: | Height: | Size: 173 B |
BIN
views/projects/item/midsim/sprites/previews/MarkyMarkPre.png
Normal file
After Width: | Height: | Size: 179 B |
BIN
views/projects/item/midsim/sprites/previews/RedVelvetyPre.png
Normal file
After Width: | Height: | Size: 236 B |
BIN
views/projects/item/midsim/sprites/previews/SonicAndTailsPre.png
Normal file
After Width: | Height: | Size: 283 B |
BIN
views/projects/item/midsim/sprites/previews/TailsPre.png
Normal file
After Width: | Height: | Size: 287 B |
BIN
views/projects/item/midsim/sprites/redvelvetyCake.png
Normal file
After Width: | Height: | Size: 28 KiB |
BIN
views/projects/item/midsim/sprites/unscii_8x8.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
59
views/projects/item/wm/index.html
Normal file
|
@ -0,0 +1,59 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>MTRUWSaDMfHTML5</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="/styles/normal.css" />
|
||||
<link rel="stylesheet" href="/styles/windows.css" />
|
||||
<link rel="stylesheet" href="./styles/endplorer.css" />
|
||||
<style>
|
||||
@import url("https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@100;200;300;400;500;600;700;800;900&display=swap");
|
||||
|
||||
:root {
|
||||
--base-scale: 16px;
|
||||
|
||||
--background-color: hsl(0, 0%, 15%);
|
||||
--color: hsl(0, 0%, 85%);
|
||||
--accent-color: hsl(0, 0%, 50%);
|
||||
--accent-color-fg: hsl(0, 0%, 95%);
|
||||
--font-family: "Lexend Deca";
|
||||
--document-width: 40em;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<$ loader.html $>
|
||||
<header>
|
||||
<section>
|
||||
<h1>MTRUWSaDMfHTML5</h1>
|
||||
</section>
|
||||
<section id="accessibility" hidden></section>
|
||||
</header>
|
||||
<section>
|
||||
<button
|
||||
onclick="window.top.manager.createWindow('./pages/welcome.html', false)"
|
||||
>
|
||||
Test</button
|
||||
><br />
|
||||
<input id="url" type="url" />
|
||||
<button
|
||||
onclick="window.top.manager.createWindow(document.querySelector('#url').value, false)"
|
||||
>
|
||||
Open URL
|
||||
</button>
|
||||
</section>
|
||||
<div id="WindowHolder"></div>
|
||||
<script src="./scripts/endplorer.js"></script>
|
||||
<script src="/scripts/windows.js"></script>
|
||||
<script src="/scripts/accessibility.js"></script>
|
||||
<script src="/scripts/interface.js"></script>
|
||||
<script>
|
||||
window.manager = new WindowManager(
|
||||
document.getElementById("WindowHolder")
|
||||
);
|
||||
window.taskbar = new TaskbarObject(window.top.manager);
|
||||
window.top.manager.createWindow("./pages/welcome.html", false);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
33
views/projects/item/wm/pages/welcome.html
Normal file
|
@ -0,0 +1,33 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Welcome!</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<link rel="stylesheet" href="/styles/normal.css" />
|
||||
<style>
|
||||
@import url("https://fonts.googleapis.com/css2?family=Lexend+Deca:wght@100;200;300;400;500;600;700;800;900&display=swap");
|
||||
|
||||
:root {
|
||||
--font-family: "Lexend Deca";
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<$ loader.html $>
|
||||
<header>
|
||||
<section>
|
||||
<h1>Welcome to MTRUWSaDMfHTML5!</h1>
|
||||
<p>
|
||||
(MeowcaTheoRange's Unnecessary Windowing System and Desktop Manager
|
||||
for HTML5)
|
||||
</p>
|
||||
<p>A basic windowing system made in HTML5 and JavaScript.</p>
|
||||
</section>
|
||||
<section id="accessibility" hidden></section>
|
||||
</header>
|
||||
<section id="accessibility" hidden></section>
|
||||
<script src="/scripts/accessibility.js"></script>
|
||||
<script src="/scripts/interface.js"></script>
|
||||
</body>
|
||||
</html>
|
110
views/projects/item/wm/scripts/endplorer.js
Normal file
|
@ -0,0 +1,110 @@
|
|||
class TaskbarObject {
|
||||
parentManager;
|
||||
taskbarObject;
|
||||
|
||||
taskbarStart;
|
||||
|
||||
children;
|
||||
|
||||
constructor(manager) {
|
||||
this.parentManager = manager;
|
||||
this.taskbarObject = TaskbarObject.createTaskbar(this);
|
||||
this.parentManager.addExtension(this, "taskbarObject");
|
||||
this.parentManager.overscan_bottom = "2.5625em";
|
||||
|
||||
this.taskbarStart = this.taskbarObject.querySelector(".taskbar-start");
|
||||
|
||||
this.children = [];
|
||||
|
||||
this.parentManager.managerObject.addEventListener("windowcreate", (e) =>
|
||||
this.addToTabs(e)
|
||||
);
|
||||
|
||||
this.parentManager.managerObject.addEventListener("windowdestroy", (e) =>
|
||||
this.removeFromTabs(e)
|
||||
);
|
||||
|
||||
this.parentManager.managerObject.addEventListener("windowfocus", (e) =>
|
||||
this.refocusTabs(e)
|
||||
);
|
||||
|
||||
this.parentManager.managerObject.addEventListener(
|
||||
"windowmanager_title",
|
||||
(e) => this.updateTab(e)
|
||||
);
|
||||
}
|
||||
|
||||
addToTabs(e) {
|
||||
const button = document.createElement("button");
|
||||
button.classList.add("taskbar-button");
|
||||
|
||||
button.addEventListener("click", (e2) => this.event_raiseWindow(e, e2));
|
||||
|
||||
console.log(button);
|
||||
|
||||
this.children.splice(e.detail.windowId, 0, button);
|
||||
this.taskbarStart.appendChild(button);
|
||||
}
|
||||
|
||||
removeFromTabs(e) {
|
||||
const button = this.children[e.detail.windowId];
|
||||
|
||||
console.log(this.children, e.detail.windowId);
|
||||
|
||||
this.children.splice(e.detail.windowId, 1);
|
||||
this.taskbarStart.removeChild(button);
|
||||
}
|
||||
|
||||
updateTab(e, mode) {
|
||||
const button = this.children[e.detail.windowId];
|
||||
|
||||
button.textContent = e.detail.title;
|
||||
}
|
||||
|
||||
refocusTabs(e) {
|
||||
this.parentManager.children.forEach((child) => {
|
||||
if (child.focusOrder <= 0) {
|
||||
this.children[child.windowId].classList.add("taskbar-button-focusing");
|
||||
} else
|
||||
this.children[child.windowId].classList.remove(
|
||||
"taskbar-button-focusing"
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.parentManager.overscan_bottom = "0px";
|
||||
}
|
||||
|
||||
event_raiseWindow(e, e2) {
|
||||
if (e.detail.focusOrder <= 0) {
|
||||
e.detail.minimizeWindow();
|
||||
} else {
|
||||
this.parentManager.raiseWindow(e.detail);
|
||||
}
|
||||
refocusTabs();
|
||||
}
|
||||
|
||||
static createTaskbar(taskbarRef) {
|
||||
const taskbarObject = document.createElement("div");
|
||||
taskbarObject.classList.add("taskbar-object");
|
||||
taskbarObject.tabIndex = "0";
|
||||
taskbarObject.style.zIndex = taskbarRef.parentManager.maxZIndex + 1;
|
||||
|
||||
{
|
||||
const taskbarStart = document.createElement("div");
|
||||
taskbarStart.classList.add("taskbar-start");
|
||||
|
||||
taskbarObject.appendChild(taskbarStart);
|
||||
}
|
||||
|
||||
{
|
||||
const taskbarEnd = document.createElement("div");
|
||||
taskbarEnd.classList.add("taskbar-end");
|
||||
|
||||
taskbarObject.appendChild(taskbarEnd);
|
||||
}
|
||||
|
||||
return taskbarObject;
|
||||
}
|
||||
}
|
46
views/projects/item/wm/styles/endplorer.css
Normal file
|
@ -0,0 +1,46 @@
|
|||
.taskbar-object {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
vertical-align: middle;
|
||||
user-select: none;
|
||||
|
||||
background-color: var(--accent-color);
|
||||
color: var(--accent-color-fg);
|
||||
border: var(--border-style);
|
||||
overflow: hidden;
|
||||
padding: 0.25em;
|
||||
}
|
||||
|
||||
.taskbar-object > .taskbar-start {
|
||||
text-align: start;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
.taskbar-object > .taskbar-end {
|
||||
text-align: end;
|
||||
height: 2em;
|
||||
}
|
||||
|
||||
.taskbar-object > .taskbar-start > button {
|
||||
height: 2em;
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
margin-inline-end: 0.25em;
|
||||
border: var(--border-style);
|
||||
background-color: transparent;
|
||||
color: currentColor;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
font-size: 1em;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.taskbar-object > .taskbar-start > button.taskbar-button-focusing {
|
||||
background-color: var(--accent-color-fg);
|
||||
color: var(--accent-color);
|
||||
}
|
Before Width: | Height: | Size: 453 KiB After Width: | Height: | Size: 453 KiB |
Before Width: | Height: | Size: 821 KiB After Width: | Height: | Size: 821 KiB |
Before Width: | Height: | Size: 677 KiB After Width: | Height: | Size: 677 KiB |
Before Width: | Height: | Size: 827 KiB After Width: | Height: | Size: 827 KiB |
Before Width: | Height: | Size: 740 KiB After Width: | Height: | Size: 740 KiB |