<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dice</title>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Barlow&display=swap" rel="stylesheet">
<style>
body {
overflow: hidden;
background-color: midnightblue;
color: white;
font-family: 'Barlow', 'Roboto', 'Source Sans Pro', 'Open Sans', 'Lato', Helvetica, Arial, sans-serif;
}
#header {
position: absolute;
padding-left: 2rem;
}
</style>
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.164.0/build/three.module.js"
}
}
</script>
</head>
<body>
<div id="header">
<h1>3D DICE</h1>
Rotate: <input type="checkbox" id="rotate">
Wireframe: <input type="checkbox" id="wireframe">
<p> Mouse-drag to rotate view, mousewheel to zoom.</p>
</div>
<script type="module">
import * as THREE from 'three';
import { OrbitControls } from 'https://unpkg.com/three@0.164.0/examples/jsm/controls/OrbitControls.js';
import { GLTFLoader } from 'https://unpkg.com/three@0.164.0/examples/jsm/loaders/GLTFLoader.js';
var renderer, scene, camera;
var dice;
var dicematerials = [];
var rotate = false;
function init() {
// renderer
renderer = new THREE.WebGLRenderer({ antialias: true, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// scene
scene = new THREE.Scene();
//scene.background = new THREE.Color( 'skyblue' )
// camera
camera = new THREE.PerspectiveCamera(40, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(5, 0, 5);
scene.add(camera);
// controls
var controls = new OrbitControls(camera, renderer.domElement);
controls.addEventListener('change', render);
controls.minDistance = 3;
controls.maxDistance = 10;
controls.enablePan = false;
// ambient light
scene.add(new THREE.AmbientLight(0xffffff, 1));
// point lights
var pointLight = new THREE.PointLight(0xffffff, 10, 0);
pointLight.position.set(2, 3, 2);
scene.add(pointLight);
var pointLight2 = new THREE.PointLight(0xffffff, 10, 0);
pointLight2.position.set(-2, 3, 2);
scene.add(pointLight2);
dice = new THREE.Group();
// load the model
var loader = new GLTFLoader();
loader.load('dice3b.glb', function (gltf) {
var meshes = [];
gltf.scene.traverse(function (object) {
if (object.isMesh)
meshes.push(object);
});
meshes.forEach(function (mesh) {
mesh.geometry.center();
dicematerials.push(mesh.material);
dice.add(mesh);
});
scene.add(dice);
render();
});
// handle window resize events
window.addEventListener('resize', onWindowResize, false);
// switch between materials and wireframe
document.getElementById('wireframe').addEventListener('click', function () {
for (let i = 0; i < dice.children.length; i++) {
if (this.checked)
dice.children[i].material = new THREE.MeshPhongMaterial({ color: 0x07fa84, emissive: 0x07fa84, wireframe: true });
else
dice.children[i].material = dicematerials[i];
}
render();
});
// switch rotation on or off
document.getElementById('rotate').addEventListener('click', function () {
rotate = this.checked;
});
// set checkboxes unchecked by default
document.getElementById('rotate').checked = false;
document.getElementById('wireframe').checked = false;
}
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
render();
}
function animate() {
requestAnimationFrame(animate);
if (dice != null && rotate) {
dice.rotation.y += 0.01;
dice.rotation.z += 0.01;
}
render();
}
function render() {
renderer.render(scene, camera);
}
init();
animate();
</script>
</body>
</html>