Spaces:
Running
Running
Add 1 files
Browse files- index.html +186 -0
index.html
CHANGED
|
@@ -103,6 +103,33 @@
|
|
| 103 |
font-size: 0.7rem;
|
| 104 |
line-height: 1.1;
|
| 105 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
</style>
|
| 107 |
</head>
|
| 108 |
<body class="min-h-screen">
|
|
@@ -122,26 +149,56 @@
|
|
| 122 |
<h2 class="text-2xl font-bold mb-4 text-amber-200 border-b border-amber-900 pb-2">Choose Your Dice</h2>
|
| 123 |
<div class="grid grid-cols-3 gap-4 mb-6">
|
| 124 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="4">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 125 |
<div class="text-amber-200 text-lg font-bold">D4</div>
|
| 126 |
<div class="shape-name text-gray-400">Tetrahedron</div>
|
| 127 |
</div>
|
| 128 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="6">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 129 |
<div class="text-amber-200 text-lg font-bold">D6</div>
|
| 130 |
<div class="shape-name text-gray-400">Cube</div>
|
| 131 |
</div>
|
| 132 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="8">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
<div class="text-amber-200 text-lg font-bold">D8</div>
|
| 134 |
<div class="shape-name text-gray-400">Octahedron</div>
|
| 135 |
</div>
|
| 136 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="10">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
<div class="text-amber-200 text-lg font-bold">D10</div>
|
| 138 |
<div class="shape-name text-gray-400">Pentagonal Trapezohedron</div>
|
| 139 |
</div>
|
| 140 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="12">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 141 |
<div class="text-amber-200 text-lg font-bold">D12</div>
|
| 142 |
<div class="shape-name text-gray-400">Dodecahedron</div>
|
| 143 |
</div>
|
| 144 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="20">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
<div class="text-amber-200 text-lg font-bold">D20</div>
|
| 146 |
<div class="shape-name text-gray-400">Icosahedron</div>
|
| 147 |
</div>
|
|
@@ -330,6 +387,9 @@
|
|
| 330 |
// Set up dice selection
|
| 331 |
setupDiceSelection();
|
| 332 |
|
|
|
|
|
|
|
|
|
|
| 333 |
// Set up roll button
|
| 334 |
document.getElementById('rollButton').addEventListener('click', rollDice);
|
| 335 |
|
|
@@ -337,6 +397,132 @@
|
|
| 337 |
animate();
|
| 338 |
}
|
| 339 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 340 |
// Set up dice selection
|
| 341 |
function setupDiceSelection() {
|
| 342 |
const diceSelectors = document.querySelectorAll('.dice-selector');
|
|
|
|
| 103 |
font-size: 0.7rem;
|
| 104 |
line-height: 1.1;
|
| 105 |
}
|
| 106 |
+
|
| 107 |
+
.dice-preview {
|
| 108 |
+
width: 40px;
|
| 109 |
+
height: 40px;
|
| 110 |
+
margin: 0 auto 5px;
|
| 111 |
+
position: relative;
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
.dice-preview-container {
|
| 115 |
+
width: 100%;
|
| 116 |
+
height: 100%;
|
| 117 |
+
transform-style: preserve-3d;
|
| 118 |
+
transition: transform 1s;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
.dice-face {
|
| 122 |
+
position: absolute;
|
| 123 |
+
width: 100%;
|
| 124 |
+
height: 100%;
|
| 125 |
+
border: 1px solid rgba(255,255,255,0.2);
|
| 126 |
+
display: flex;
|
| 127 |
+
align-items: center;
|
| 128 |
+
justify-content: center;
|
| 129 |
+
font-size: 12px;
|
| 130 |
+
font-weight: bold;
|
| 131 |
+
color: white;
|
| 132 |
+
}
|
| 133 |
</style>
|
| 134 |
</head>
|
| 135 |
<body class="min-h-screen">
|
|
|
|
| 149 |
<h2 class="text-2xl font-bold mb-4 text-amber-200 border-b border-amber-900 pb-2">Choose Your Dice</h2>
|
| 150 |
<div class="grid grid-cols-3 gap-4 mb-6">
|
| 151 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="4">
|
| 152 |
+
<div class="dice-preview">
|
| 153 |
+
<div class="dice-preview-container" id="d4-preview">
|
| 154 |
+
<!-- Faces will be added by JS -->
|
| 155 |
+
</div>
|
| 156 |
+
</div>
|
| 157 |
<div class="text-amber-200 text-lg font-bold">D4</div>
|
| 158 |
<div class="shape-name text-gray-400">Tetrahedron</div>
|
| 159 |
</div>
|
| 160 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="6">
|
| 161 |
+
<div class="dice-preview">
|
| 162 |
+
<div class="dice-preview-container" id="d6-preview">
|
| 163 |
+
<!-- Faces will be added by JS -->
|
| 164 |
+
</div>
|
| 165 |
+
</div>
|
| 166 |
<div class="text-amber-200 text-lg font-bold">D6</div>
|
| 167 |
<div class="shape-name text-gray-400">Cube</div>
|
| 168 |
</div>
|
| 169 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="8">
|
| 170 |
+
<div class="dice-preview">
|
| 171 |
+
<div class="dice-preview-container" id="d8-preview">
|
| 172 |
+
<!-- Faces will be added by JS -->
|
| 173 |
+
</div>
|
| 174 |
+
</div>
|
| 175 |
<div class="text-amber-200 text-lg font-bold">D8</div>
|
| 176 |
<div class="shape-name text-gray-400">Octahedron</div>
|
| 177 |
</div>
|
| 178 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="10">
|
| 179 |
+
<div class="dice-preview">
|
| 180 |
+
<div class="dice-preview-container" id="d10-preview">
|
| 181 |
+
<!-- Faces will be added by JS -->
|
| 182 |
+
</div>
|
| 183 |
+
</div>
|
| 184 |
<div class="text-amber-200 text-lg font-bold">D10</div>
|
| 185 |
<div class="shape-name text-gray-400">Pentagonal Trapezohedron</div>
|
| 186 |
</div>
|
| 187 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="12">
|
| 188 |
+
<div class="dice-preview">
|
| 189 |
+
<div class="dice-preview-container" id="d12-preview">
|
| 190 |
+
<!-- Faces will be added by JS -->
|
| 191 |
+
</div>
|
| 192 |
+
</div>
|
| 193 |
<div class="text-amber-200 text-lg font-bold">D12</div>
|
| 194 |
<div class="shape-name text-gray-400">Dodecahedron</div>
|
| 195 |
</div>
|
| 196 |
<div class="dice-selector p-3 bg-gray-800 rounded-lg cursor-pointer text-center border border-gray-700" data-sides="20">
|
| 197 |
+
<div class="dice-preview">
|
| 198 |
+
<div class="dice-preview-container" id="d20-preview">
|
| 199 |
+
<!-- Faces will be added by JS -->
|
| 200 |
+
</div>
|
| 201 |
+
</div>
|
| 202 |
<div class="text-amber-200 text-lg font-bold">D20</div>
|
| 203 |
<div class="shape-name text-gray-400">Icosahedron</div>
|
| 204 |
</div>
|
|
|
|
| 387 |
// Set up dice selection
|
| 388 |
setupDiceSelection();
|
| 389 |
|
| 390 |
+
// Set up dice previews
|
| 391 |
+
setupDicePreviews();
|
| 392 |
+
|
| 393 |
// Set up roll button
|
| 394 |
document.getElementById('rollButton').addEventListener('click', rollDice);
|
| 395 |
|
|
|
|
| 397 |
animate();
|
| 398 |
}
|
| 399 |
|
| 400 |
+
// Set up dice previews
|
| 401 |
+
function setupDicePreviews() {
|
| 402 |
+
// D4 Preview
|
| 403 |
+
createDicePreview('d4-preview', 4, '#8b5a2b');
|
| 404 |
+
|
| 405 |
+
// D6 Preview
|
| 406 |
+
createDicePreview('d6-preview', 6, '#9b111e');
|
| 407 |
+
|
| 408 |
+
// D8 Preview
|
| 409 |
+
createDicePreview('d8-preview', 8, '#005b96');
|
| 410 |
+
|
| 411 |
+
// D10 Preview
|
| 412 |
+
createDicePreview('d10-preview', 10, '#5e8c31');
|
| 413 |
+
|
| 414 |
+
// D12 Preview
|
| 415 |
+
createDicePreview('d12-preview', 12, '#7d26cd');
|
| 416 |
+
|
| 417 |
+
// D20 Preview
|
| 418 |
+
createDicePreview('d20-preview', 20, '#d4af37');
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
+
// Create a dice preview
|
| 422 |
+
function createDicePreview(containerId, sides, color) {
|
| 423 |
+
const container = document.getElementById(containerId);
|
| 424 |
+
container.innerHTML = '';
|
| 425 |
+
|
| 426 |
+
// Create faces based on dice type
|
| 427 |
+
if (sides === 4) {
|
| 428 |
+
// Tetrahedron (4 triangular faces)
|
| 429 |
+
for (let i = 0; i < 4; i++) {
|
| 430 |
+
const face = document.createElement('div');
|
| 431 |
+
face.className = 'dice-face';
|
| 432 |
+
face.style.backgroundColor = color;
|
| 433 |
+
face.style.clipPath = 'polygon(50% 0%, 0% 100%, 100% 100%)';
|
| 434 |
+
face.style.transform = `rotateX(${i * 120}deg) rotateY(0deg) translateZ(20px)`;
|
| 435 |
+
face.textContent = i+1;
|
| 436 |
+
container.appendChild(face);
|
| 437 |
+
}
|
| 438 |
+
container.style.transform = 'rotateX(20deg) rotateY(20deg)';
|
| 439 |
+
}
|
| 440 |
+
else if (sides === 6) {
|
| 441 |
+
// Cube (6 square faces)
|
| 442 |
+
const positions = [
|
| 443 |
+
{ transform: 'rotateY(0deg) translateZ(20px)', color: color }, // front
|
| 444 |
+
{ transform: 'rotateY(180deg) translateZ(20px)', color: color }, // back
|
| 445 |
+
{ transform: 'rotateY(90deg) translateZ(20px)', color: color }, // right
|
| 446 |
+
{ transform: 'rotateY(-90deg) translateZ(20px)', color: color }, // left
|
| 447 |
+
{ transform: 'rotateX(90deg) translateZ(20px)', color: color }, // top
|
| 448 |
+
{ transform: 'rotateX(-90deg) translateZ(20px)', color: color } // bottom
|
| 449 |
+
];
|
| 450 |
+
|
| 451 |
+
for (let i = 0; i < 6; i++) {
|
| 452 |
+
const face = document.createElement('div');
|
| 453 |
+
face.className = 'dice-face';
|
| 454 |
+
face.style.backgroundColor = positions[i].color;
|
| 455 |
+
face.style.transform = positions[i].transform;
|
| 456 |
+
face.textContent = i+1;
|
| 457 |
+
container.appendChild(face);
|
| 458 |
+
}
|
| 459 |
+
container.style.transform = 'rotateX(20deg) rotateY(20deg)';
|
| 460 |
+
}
|
| 461 |
+
else if (sides === 8) {
|
| 462 |
+
// Octahedron (8 triangular faces)
|
| 463 |
+
for (let i = 0; i < 8; i++) {
|
| 464 |
+
const face = document.createElement('div');
|
| 465 |
+
face.className = 'dice-face';
|
| 466 |
+
face.style.backgroundColor = color;
|
| 467 |
+
face.style.clipPath = 'polygon(50% 0%, 0% 100%, 100% 100%)';
|
| 468 |
+
face.style.transform = `rotateX(${i * 90}deg) rotateY(${i % 2 === 0 ? 0 : 180}deg) translateZ(15px)`;
|
| 469 |
+
face.textContent = i+1;
|
| 470 |
+
container.appendChild(face);
|
| 471 |
+
}
|
| 472 |
+
container.style.transform = 'rotateX(20deg) rotateY(20deg)';
|
| 473 |
+
}
|
| 474 |
+
else if (sides === 10) {
|
| 475 |
+
// Pentagonal Trapezohedron (10 kite-shaped faces)
|
| 476 |
+
for (let i = 0; i < 10; i++) {
|
| 477 |
+
const face = document.createElement('div');
|
| 478 |
+
face.className = 'dice-face';
|
| 479 |
+
face.style.backgroundColor = color;
|
| 480 |
+
face.style.clipPath = 'polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)';
|
| 481 |
+
face.style.transform = `rotateX(${i * 36}deg) rotateY(${i % 2 === 0 ? 0 : 180}deg) translateZ(15px)`;
|
| 482 |
+
face.textContent = i+1;
|
| 483 |
+
container.appendChild(face);
|
| 484 |
+
}
|
| 485 |
+
container.style.transform = 'rotateX(20deg) rotateY(20deg)';
|
| 486 |
+
}
|
| 487 |
+
else if (sides === 12) {
|
| 488 |
+
// Dodecahedron (12 pentagonal faces)
|
| 489 |
+
for (let i = 0; i < 12; i++) {
|
| 490 |
+
const face = document.createElement('div');
|
| 491 |
+
face.className = 'dice-face';
|
| 492 |
+
face.style.backgroundColor = color;
|
| 493 |
+
face.style.clipPath = 'polygon(50% 0%, 100% 38%, 82% 100%, 18% 100%, 0% 38%)';
|
| 494 |
+
face.style.transform = `rotateX(${i * 30}deg) rotateY(${i % 2 === 0 ? 0 : 180}deg) translateZ(15px)`;
|
| 495 |
+
face.textContent = i+1;
|
| 496 |
+
container.appendChild(face);
|
| 497 |
+
}
|
| 498 |
+
container.style.transform = 'rotateX(20deg) rotateY(20deg)';
|
| 499 |
+
}
|
| 500 |
+
else if (sides === 20) {
|
| 501 |
+
// Icosahedron (20 triangular faces)
|
| 502 |
+
for (let i = 0; i < 20; i++) {
|
| 503 |
+
const face = document.createElement('div');
|
| 504 |
+
face.className = 'dice-face';
|
| 505 |
+
face.style.backgroundColor = color;
|
| 506 |
+
face.style.clipPath = 'polygon(50% 0%, 0% 100%, 100% 100%)';
|
| 507 |
+
face.style.transform = `rotateX(${i * 72}deg) rotateY(${i % 2 === 0 ? 0 : 180}deg) translateZ(15px)`;
|
| 508 |
+
face.textContent = i+1;
|
| 509 |
+
container.appendChild(face);
|
| 510 |
+
}
|
| 511 |
+
container.style.transform = 'rotateX(20deg) rotateY(20deg)';
|
| 512 |
+
}
|
| 513 |
+
|
| 514 |
+
// Add rotation animation
|
| 515 |
+
setInterval(() => {
|
| 516 |
+
const currentTransform = container.style.transform;
|
| 517 |
+
const matches = currentTransform.match(/rotateX\((\d+)deg\) rotateY\((\d+)deg\)/);
|
| 518 |
+
if (matches) {
|
| 519 |
+
const x = parseInt(matches[1]);
|
| 520 |
+
const y = parseInt(matches[2]);
|
| 521 |
+
container.style.transform = `rotateX(${x}deg) rotateY(${y + 2}deg)`;
|
| 522 |
+
}
|
| 523 |
+
}, 100);
|
| 524 |
+
}
|
| 525 |
+
|
| 526 |
// Set up dice selection
|
| 527 |
function setupDiceSelection() {
|
| 528 |
const diceSelectors = document.querySelectorAll('.dice-selector');
|