371 lines
16 KiB
HTML
371 lines
16 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<title>Dice-Tower</title>
|
|
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
|
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
|
|
<script src="/vendor/color-picker.js"></script>
|
|
<style>
|
|
.w3-theme-l6 { color:#000 !important; background-color:#999999 !important; border-radius: 10px;}
|
|
.w3-theme-l4 { color:#fff !important; background-color:#666666 !important; border-radius: 10px;}
|
|
.w3-theme-l1 { color:#fff !important; background-color:#333333 !important; border-radius: 10px;}
|
|
.collapsible {
|
|
background-color: #333333;
|
|
color: black;
|
|
margin-top: 10px;
|
|
padding: 18px;
|
|
width: 100%;
|
|
border: none;
|
|
text-align: left;
|
|
outline: none;
|
|
font-size: 15px;
|
|
}
|
|
|
|
.content {
|
|
padding: 0 18px;
|
|
display: none;
|
|
overflow: hidden;
|
|
background-color: #999999;
|
|
color: #000;
|
|
border-radius: 10px;
|
|
}
|
|
|
|
button {
|
|
padding: 10px;
|
|
border: #333333 3px solid;
|
|
border-radius: 10px;
|
|
background: #333333;
|
|
color: #fff
|
|
}
|
|
|
|
button:hover {
|
|
background: #444444;
|
|
}
|
|
button:active {
|
|
background: #222222;
|
|
}
|
|
|
|
input {
|
|
margin: 10px;
|
|
}
|
|
|
|
/* The switch - the box around the slider */
|
|
.switch {
|
|
position: relative;
|
|
display: inline-block;
|
|
width: 60px;
|
|
height: 25px;
|
|
}
|
|
|
|
/* Hide default HTML checkbox */
|
|
.switch input {
|
|
opacity: 0;
|
|
width: 0;
|
|
height: 0;
|
|
}
|
|
|
|
/* The slider */
|
|
.slider {
|
|
position: absolute;
|
|
cursor: pointer;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: #ccc;
|
|
-webkit-transition: .4s;
|
|
transition: .4s;
|
|
}
|
|
|
|
.slider:before {
|
|
position: absolute;
|
|
content: "";
|
|
height: 18px;
|
|
width: 26px;
|
|
left: 4px;
|
|
bottom: 4px;
|
|
background-color: white;
|
|
-webkit-transition: .4s;
|
|
transition: .4s;
|
|
}
|
|
|
|
input:checked + .slider {
|
|
background-color: #333333;
|
|
}
|
|
|
|
input:focus + .slider {
|
|
box-shadow: 0 0 1px #333333;
|
|
}
|
|
|
|
input:checked + .slider:before {
|
|
-webkit-transform: translateX(26px);
|
|
-ms-transform: translateX(26px);
|
|
transform: translateX(26px);
|
|
}
|
|
|
|
.overlayButton {
|
|
background: transparent;
|
|
border: none;
|
|
width: 5px;
|
|
height: 5px;
|
|
font-size: large;
|
|
color: #000
|
|
}
|
|
|
|
|
|
.overlayButton:hover {
|
|
background: transparent;
|
|
}
|
|
|
|
.tooltip {
|
|
position: fixed;
|
|
border-radius: 0.5rem;
|
|
padding: 15px;
|
|
color:#fff !important;
|
|
background-color:#333333dd !important
|
|
}
|
|
|
|
#dice-box {
|
|
position: relative;
|
|
box-sizing: border-box;
|
|
width: 100%;
|
|
height: 100%;
|
|
background: transparent;
|
|
background-size: cover;
|
|
}
|
|
|
|
#dice-box canvas {
|
|
width: 100%;
|
|
height: 100%;
|
|
margin: 20px
|
|
}
|
|
</style>
|
|
</head>
|
|
<body class="w3-theme-l1">
|
|
<div class="w3-container w3-content" style="height: 95vh; display: flex; flex-direction: column; justify-content: space-between; padding: 25px">
|
|
<h1 style="text-align: center">Dice-Tower</h1>
|
|
<div class="w3-panel w3-theme-l4 w3-card w3-display-container" style="padding: 25px; text-align: center; margin-bottom: auto">
|
|
<label for="name" id="nameLabel">Name </label><input type="text" id="name" style="width: 75%" required onkeyup="start(event)"/><br/>
|
|
<label for="room" id="roomLabel">Room </label><input type="text" id="room" style="width: 75%" required onkeyup="start(event)"/><br/>
|
|
<button id="start" onclick="start()" style="align-self: center">Start 🞂</button>
|
|
</div>
|
|
<div id="dice-tower" hidden class="w3-panel w3-theme-l4 w3-card w3-display-container" style="padding: 25px; margin-bottom: auto">
|
|
<button type="button" class="collapsible" style="color: white; font-weight: bold">Overlay URLs <a>🞃</a></button>
|
|
|
|
<div class="content">
|
|
<div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline;">
|
|
<label for="overlayId">Dice-Overlay <a style="color: red"> (Only open once) </a> </label>
|
|
<input type="text" readonly id="overlayId" style="flex-grow: 1"/>
|
|
<button popovertarget="overlay-hint" data-trigger="hover" class="overlayButton">🛈</button>
|
|
</div>
|
|
<div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline;">
|
|
<label for="resultsId">All-Results-Overlay </label><input type="text" readonly id="resultsId" style="flex-grow: 1"/><button popovertarget="all-results-hint" data-trigger="hover" class="overlayButton">🛈</button>
|
|
</div>
|
|
<div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline;">
|
|
<label for="myResultsId">My-Results-Overlay </label><input type="text" readonly id="myResultsId" style="flex-grow: 1"/><button popovertarget="my-results-hint" data-trigger="hover" class="overlayButton">🛈</button>
|
|
</div>
|
|
</div>
|
|
<button type="button" class="collapsible" style="color: white; font-weight: bold">Customize Dice <a>🞃</a></button>
|
|
<div class="content">
|
|
<label for="theme">Theme </label>
|
|
<select name="theme" id="theme" style="margin: 25px">
|
|
<option value="default">Default</option>
|
|
<option value="blueGreenMetal">Blue-Green Metal</option>
|
|
<option value="diceOfRolling">Dice of Rolling</option>
|
|
<option value="gemstone">Gemstone</option>
|
|
<option value="gemstoneMarble">Marble Gemstone</option>
|
|
<option value="rock">Rock</option>
|
|
<option value="rust">Rust</option>
|
|
<option value="smooth">Smooth</option>
|
|
<option value="wooden">Wooden</option>
|
|
</select>
|
|
<color-picker id="themeColor"></color-picker>
|
|
<div id="dice-box"></div>
|
|
|
|
<button style="margin-bottom: 20px" id="preview">Preview 🔎</button>
|
|
<button style="margin-bottom: 20px" onclick="saveDice()">Save 💾</button>
|
|
<button popovertarget="save-dice-hint" data-trigger="hover" class="overlayButton">🛈</button>
|
|
</div>
|
|
<div style="display: flex; flex-direction: row; justify-content: space-between; align-items: center; margin: 20px 25px;">
|
|
<label style="font-size: x-large; font-weight: bold;">Roll </label>
|
|
<button style="border: transparent; border-radius: 100%; font-size: x-large; font-weight: bold; height: 50px; width: 50px" onclick="removeDice()">-</button>
|
|
<label style="font-size: x-large; font-weight: bold;" id="dice-amount">1</label>
|
|
<button style="border: transparent; border-radius: 100%; font-size: x-large; font-weight: bold; height: 50px; width: 50px" onclick="addDice()">+</button>
|
|
<button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d4')">D4</button>
|
|
<button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d6')">D6</button>
|
|
<button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d8')">D8</button>
|
|
<button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d10')">D10</button>
|
|
<button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d12')">D12</button>
|
|
<button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d20')">D20</button>
|
|
<button style="font-size: x-large; font-weight: bold;" onclick="rollEasy('d100')">D100</button>
|
|
</div>
|
|
<div style="display: flex; flex-direction: row; justify-content: space-between; align-items: baseline; margin: 20px 25px;">
|
|
<label for="command">Command </label>
|
|
<input type="text" id="command" style="flex-grow: 1" onkeyup="roll(event)"/>
|
|
<button hidden id="roll" onclick="roll()">Roll 🎲</button>
|
|
<button popovertarget="command-hint" data-trigger="hover" class="overlayButton">🛈</button>
|
|
</div>
|
|
|
|
<div style="margin: 20px 25px">
|
|
<label for="resultSwitch">Show all results </label>
|
|
<label class="switch">
|
|
<input type="checkbox" id="resultSwitch">
|
|
<span class="slider"></span>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
<div id="results" hidden class="w3-panel w3-theme-l6 w3-card w3-display-container" style="padding: 25px; flex-grow: 1; margin-bottom: auto">
|
|
<iframe id="resultFrame" title="results" style="width: 100%; height: 85%; overflow: hidden; border: 0" onload="this.height=this.contentWindow.document.body.scrollHeight;" ></iframe>
|
|
</div>
|
|
|
|
<div popover id="overlay-hint" class="tooltip">
|
|
<p style="color: red; font-weight: bold">Only open Overlay once, unless you want multiple results</p>
|
|
<p>Query Params you can Change:</p>
|
|
<ul>
|
|
<li><strong>scale</strong> changes the size of the dice (any value over 1; remove param or set -1 to keep the dice)</li>
|
|
<li><strong>clearAfter</strong> time until dice are cleared (in seconds)</li>
|
|
</ul>
|
|
</div>
|
|
<div popover id="all-results-hint" class="tooltip">
|
|
<p>Shows all Results in this room</p>
|
|
</div>
|
|
<div popover id="my-results-hint" class="tooltip">
|
|
<p>Shows only my Results in this room</p>
|
|
</div>
|
|
<div popover id="save-dice-hint" class="tooltip">
|
|
This saves your current theme and theme color for current Name
|
|
</div>
|
|
<div popover id="command-hint" class="tooltip">
|
|
Example Commands: "1d6", "2d8 1d100", "1d4 and 1d6", "2d20 & 1d2, "5d6+10"
|
|
</div>
|
|
</div>
|
|
<script>
|
|
function addDice() {
|
|
let amount = +document.getElementById('dice-amount').innerText
|
|
document.getElementById('dice-amount').innerText = amount + 1
|
|
}
|
|
|
|
function removeDice() {
|
|
let amount = +document.getElementById('dice-amount').innerText
|
|
if (amount > 1) {
|
|
document.getElementById('dice-amount').innerText = amount - 1
|
|
}
|
|
}
|
|
function url() {
|
|
return window.location.protocol + '//' + window.location.hostname + (window.location.port?.length > 0 ? ':' + window.location.port : '');
|
|
}
|
|
function start(event) {
|
|
if((!event || event.keyCode === 13) && document.getElementById('name').value.length > 0 && document.getElementById('room').value.length > 0) {
|
|
document.getElementById('overlayId').value = url() + '/overlay/' + document.getElementById('room').value + ':' + localStorage.getItem('userId') + '?scale=7&clearAfter=30';
|
|
document.getElementById('resultsId').value = url() + '/overlay/' + document.getElementById('room').value + '/results';
|
|
document.getElementById('myResultsId').value = document.getElementById('resultsId').value + '?name=' + encodeURIComponent(document.getElementById('name').value) + '&user=' + localStorage.getItem('userId');
|
|
document.getElementById('resultFrame').src = document.getElementById('myResultsId').value;
|
|
document.getElementById('roll').hidden = false;
|
|
document.getElementById('start').hidden = true;
|
|
document.getElementById('dice-tower').hidden = false;
|
|
document.getElementById('name').hidden = true;
|
|
document.getElementById('room').hidden = true;
|
|
document.getElementById('results').hidden = false;
|
|
document.getElementById('nameLabel').innerHTML = '<strong style="font-size:x-large;">' + document.getElementById('name').value + '</strong>';
|
|
document.getElementById('roomLabel').innerHTML = '<strong style="font-size:medium;">' + document.getElementById('room').value + '</strong>';
|
|
document.title = document.getElementById('name').value + ' - Dice-Tower';
|
|
|
|
if (localStorage.getItem(document.getElementById('name').value + "-theme")) {
|
|
document.getElementById('theme').value = localStorage.getItem(document.getElementById('name').value + "-theme")
|
|
}
|
|
if (localStorage.getItem(document.getElementById('name').value + "-themeColor")) {
|
|
document.getElementById('themeColor').setColor(localStorage.getItem(document.getElementById('name').value + "-themeColor"));
|
|
}
|
|
}
|
|
}
|
|
|
|
function rollEasy(dice) {
|
|
document.getElementById('command').value = document.getElementById('dice-amount').innerText + dice;
|
|
roll();
|
|
}
|
|
|
|
function roll(event) {
|
|
if((!event || event.keyCode === 13) && document.getElementById('command').value?.length > 0) {
|
|
let httpRequest = new XMLHttpRequest();
|
|
httpRequest.open('POST', url() + '/dice/' + document.getElementById('room').value + ':' + localStorage.getItem(`userId`))
|
|
httpRequest.setRequestHeader('Content-Type', 'application/json')
|
|
httpRequest.send(JSON.stringify({
|
|
name: document.getElementById('name').value,
|
|
command: document.getElementById('command').value,
|
|
themeColor: document.getElementById('themeColor').value,
|
|
theme: document.getElementById('theme').value
|
|
} ))
|
|
}
|
|
}
|
|
|
|
function saveDice() {
|
|
localStorage.setItem(document.getElementById('name').value + "-theme", document.getElementById('theme').value)
|
|
localStorage.setItem(document.getElementById('name').value + "-themeColor", document.getElementById('themeColor').value)
|
|
}
|
|
|
|
let coll = document.getElementsByClassName("collapsible");
|
|
|
|
for (let i = 0; i < coll.length; i++) {
|
|
coll[i].addEventListener("click", function () {
|
|
const content = this.nextElementSibling;
|
|
if (content.style.display === "block") {
|
|
content.style.display = "none";
|
|
this.children[0].innerHTML = "🞃"
|
|
} else {
|
|
content.style.display = "block";
|
|
this.children[0].innerHTML = "🞁"
|
|
}
|
|
});
|
|
}
|
|
|
|
const popover = document.querySelectorAll("[popovertarget][data-trigger='hover']");
|
|
|
|
popover.forEach((e) => {
|
|
const target = document.querySelector("#" + e.getAttribute("popovertarget"));
|
|
e.addEventListener("mouseover",()=>{
|
|
target.showPopover();
|
|
});
|
|
|
|
e.addEventListener("mouseout",()=>{
|
|
target.hidePopover();
|
|
});
|
|
});
|
|
|
|
document.getElementById('resultSwitch').addEventListener('change', function() {
|
|
if (!this.checked) {
|
|
document.getElementById('resultFrame').src = document.getElementById('myResultsId').value;
|
|
} else {
|
|
document.getElementById('resultFrame').src = document.getElementById('resultsId').value;
|
|
}
|
|
})
|
|
|
|
document.addEventListener("DOMContentLoaded", async() => {
|
|
if (!localStorage.getItem("userId")) {
|
|
localStorage.setItem("userId", self.crypto.randomUUID());
|
|
}
|
|
})
|
|
</script>
|
|
<script type="module">
|
|
import DiceBox from "/vendor/dice-box/dice-box.es.js";
|
|
document.addEventListener("DOMContentLoaded", async() => {
|
|
document.getElementById('preview').onclick = async () => {
|
|
document.getElementById('dice-box').replaceChildren(...[])
|
|
const diceBox = new DiceBox("#dice-box", {
|
|
assetPath: "/vendor/assets/",
|
|
theme: document.getElementById('theme').value,
|
|
themeColor: document.getElementById('themeColor').value,
|
|
scale: 14
|
|
});
|
|
await diceBox.init()
|
|
diceBox.roll(['1d2','1d4','1d6','1d8','1d10','1d12','1d20','1d100']);
|
|
}
|
|
})
|
|
|
|
</script>
|
|
</body>
|
|
<footer class="w3-theme-l1 w3-center w3-padding-16">
|
|
<a href="https://git.arindy.de/arindy/dice-tower" target="_blank" class="w3-hover-text-black">Dice-Tower on my GitTea</a>
|
|
</footer>
|
|
</html>
|