JSFiddle - React, Tailwind, and code Playground
by Rolf
HTML
<header></header>
<main id="scene">
<die-3d style="top: 20vh; left: 30vw;"></die-3d>
<die-3d style="top: 20vh; left: 60vw;"></die-3d>
<die-3d style="top: 60vh; left: 30vw;"></die-3d>
<die-3d style="top: 60vh; left: 60vw;"></die-3d>
</main>
CSS
:root {
--table-size: 600px;
--cards-height: 250px;
}
body {
position: relative;
margin: 0; padding: 0; height: 100vh;
background: linear-gradient(0deg, #333 20%, #666 100%);
perspective: calc(var(--perspective) * var(--table-size)/10);
overflow: hidden;
}
header {
position: absolute; display: inline-block;
background-color: #fff8;
}
#scene {
transform-style: preserve-3d;
background: linear-gradient(to right, #aaa8 0%, #aaa8 2%, transparent 5%) top left / 50px 50px,
linear-gradient(to bottom, #aaa8 0%, #aaa8 2%, transparent 5%) top left / 50px 50px;
width: 100vw;
height: 100vh;
padding-top: 30vh;
transform: rotateY(calc(1deg * var(--sceneRotation)))
rotateX(calc(1deg * var(--sceneTilt)));
}
die-3d {
--size: 100px;
--face: ivory;
--dot: #338;
--speed: .2s;
animaxtion: 5s linear infinite cube-toss;
}
@keyframes cube-toss {
0% { transform: rotate3d( 1, 0, 1, 0deg); }
20% { transform: rotate3d( 0, 1, 1, 72deg); }
40% { transform: rotate3d( -1, 1, 0, 144deg); }
60% { transform: rotate3d( -1, 0,-1, 216deg); }
80% { transform: rotate3d( 0, 1,-1, 288deg); }
100% { transform: rotate3d( 1, 0, 1, 360deg); }
}
@keyframes cube-tosrs {
0% { transform: rotateX(0.00turn) rotateY(0.00turn); }
16% { transform: rotateX(0.33turn) rotateY(0.50turn); }
33% { transform: rotateX(0.67turn) rotateY(1.00turn); }
50% { transform: rotateX(1.00turn) rotateY(1.50turn); }
66% { transform: rotateX(1.33turn) rotateY(2.00turn); }
83% { transform: rotateX(1.67turn) rotateY(2.50turn); }
100% { transform: rotateX(2.00turn) rotateY(3.00turn); }
}
JavaScript
/* global document, console, localStorage */
// Above comment to make JSLint happy
"use strict";
// Teil 1: Szene drehen, kippen, Perspektive ändern
updateScene("sceneRotation")
updateScene("sceneTilt")
updateScene("perspective")
showSceneInfo();
document.addEventListener("keydown", function(keyEvent) {
console.log(keyEvent);
switch(keyEvent.key) {
case '1': updateScene("sceneRotation", -5); break;
case '2': updateScene("sceneRotation", +5); break;
case 'q': updateScene("sceneTilt", -5); break;
case 'a': updateScene("sceneTilt", +5); break;11
case '+': updateScene("perspective", +1); break;
case '-': updateScene("perspective", -1); break;
case 't': runTest();
}
showSceneInfo();
});
function getSceneProperty(property) {
let storedValue = localStorage.getItem(property);
if (storedValue == null)
storedValue = property == "perspective" ? 30 : 0;
return parseInt(storedValue);
}
function updateScene(property, delta = 0) {
let value = getSceneProperty(property) + delta;
document.documentElement.style.setProperty("--"+property, value);
localStorage.setItem(property, value);
}
function showSceneInfo() {
let rotation = getSceneProperty("sceneRotation");
let tilt = getSceneProperty("sceneTilt");
let perspective = getSceneProperty("perspective");
document.querySelector("body > header").textContent = `rotation: ${rotation}, tilt=${tilt}, perspective: ${perspective}`;
}
function setStyle(element, name, value) {
// console.log("set " + name + " to " + value);
element.style.setProperty(name, value);
}
// Teil 2: Die Custom Element
/* global customElements, HTMLElement */
class DieElement extends HTMLElement {
// Das Element soll auf Änderungen des face Attributs reagieren
static get observedAttributes() {
return ['face'];
}
// Callback für Reaktion auf Änderung von Attributen.
// Würfel entsprechend des face-Wertes ausrichten
attributeChangedCallback(name,...