summaryrefslogtreecommitdiff
path: root/Keyboard V2 - Part 2 - PCB/pcb/index.html
diff options
context:
space:
mode:
authoruser@node5.net <user@node5.net>2026-08-16 21:15:48 +0200
committeruser@node5.net <user@node5.net>2026-08-16 21:18:39 +0200
commit6085a754b4052c2bd803b1805f1461d9134a9b31 (patch)
tree149a8a12c184c4123af1ac9e8a8f2e28f77f6eee /Keyboard V2 - Part 2 - PCB/pcb/index.html
parent3e7f2510bf76d44f0c2940db5588405399a80945 (diff)
keyboard V2 - split into two parts, prototype, pcb. Re-order PCB articleHEADmaster
V2 keyboard was left as a clutter, re-work it. Add a new article for the PCB part that was never properly documented.
Diffstat (limited to 'Keyboard V2 - Part 2 - PCB/pcb/index.html')
-rw-r--r--Keyboard V2 - Part 2 - PCB/pcb/index.html225
1 files changed, 225 insertions, 0 deletions
diff --git a/Keyboard V2 - Part 2 - PCB/pcb/index.html b/Keyboard V2 - Part 2 - PCB/pcb/index.html
new file mode 100644
index 0000000..6ec3e20
--- /dev/null
+++ b/Keyboard V2 - Part 2 - PCB/pcb/index.html
@@ -0,0 +1,225 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>three.js webgl - loaders - VRML loader</title>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
+ <link type="text/css" rel="stylesheet" href="main.css">
+ </head>
+
+ <body>
+ <canvas class="3d_viewer" file="Node5.net_2_PCB"></canvas>
+
+ <div id="overlay">
+ <div id="text">Loading</div>
+ </div>
+
+ <script type="importmap">
+ {
+ "imports": {
+ "three": "./three.module.js"
+ }
+ }
+ </script>
+
+ <script type="module">
+ import * as THREE from 'three';
+ import Stats from './stats.module.js';
+ import { OrbitControls } from './OrbitControls.js';
+ import { VRMLLoader } from './VRMLLoader.js';
+ // import { GUI } from 'three/addons/libs/lil-gui.module.min.js';
+
+ window.addEventListener( 'resize', onWindowResize );
+ window.addEventListener('mousedown', onMouseDown);
+ window.addEventListener("touchstart", onMouseDown);
+
+ var canvases = document.getElementsByClassName('3d_viewer');
+ var canvas = canvases[0];
+
+ let camera, scene, renderer, stats, controls, loader, vrmlScene, model;
+ var spin = true;
+
+ /* // XYZ vector indicators
+ const axesHelper = new THREE.AxesHelper( 5 );
+ scene.add( axesHelper );
+ */
+
+ camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 10, 1e10 );
+ camera.position.set( - 10, 5, 10 );
+
+ scene = new THREE.Scene();
+ scene.add( camera );
+
+ // light
+ const ambientLight = new THREE.AmbientLight( 0xffffff, 1.2 );
+ scene.add( ambientLight );
+ const dirLight = new THREE.DirectionalLight( 0xffffff, 2.0 );
+ dirLight.position.set( 200, 200, 200 );
+ scene.add( dirLight );
+
+ loader = new VRMLLoader();
+ loadAsset(canvas.getAttribute("file"));
+
+ // renderer
+ renderer = new THREE.WebGLRenderer({canvas: canvas});
+ renderer.setPixelRatio( window.devicePixelRatio );
+ renderer.setSize( window.innerWidth, window.innerHeight );
+ renderer.setAnimationLoop( animate );
+ document.body.appendChild( renderer.domElement );
+ renderer.setClearColor( 0xffffff, 0);
+
+ // controls
+ controls = new OrbitControls( camera, renderer.domElement );
+ controls.minDistance = 1;
+ controls.maxDistance = 200;
+ controls.enableDamping = false;
+ controls.enablePan = true;
+
+ // FPS counter
+ //stats = new Stats();
+ //document.body.appendChild( stats.dom );
+
+ function onMouseDown(){
+ spin = false;
+ }
+
+ const fitCameraToCenteredObject = function (camera, object, offset, orbitControls ) {
+ // https://wejn.org/2020/12/cracking-the-threejs-object-fitting-nut/
+ const boundingBox = new THREE.Box3();
+ boundingBox.setFromObject( object );
+
+ var middle = new THREE.Vector3();
+ var size = new THREE.Vector3();
+ boundingBox.getSize(size);
+
+ // figure out how to fit the box in the view:
+ // 1. figure out horizontal FOV (on non-1.0 aspects)
+ // 2. figure out distance from the object in X and Y planes
+ // 3. select the max distance (to fit both sides in)
+ //
+ // The reason is as follows:
+ //
+ // Imagine a bounding box (BB) is centered at (0,0,0).
+ // Camera has vertical FOV (camera.fov) and horizontal FOV
+ // (camera.fov scaled by aspect, see fovh below)
+ //
+ // Therefore if you want to put the entire object into the field of view,
+ // you have to compute the distance as: z/2 (half of Z size of the BB
+ // protruding towards us) plus for both X and Y size of BB you have to
+ // figure out the distance created by the appropriate FOV.
+ //
+ // The FOV is always a triangle:
+ //
+ // (size/2)
+ // +--------+
+ // | /
+ // | /
+ // | /
+ // | F° /
+ // | /
+ // | /
+ // | /
+ // |/
+ //
+ // F° is half of respective FOV, so to compute the distance (the length
+ // of the straight line) one has to: `size/2 / Math.tan(F)`.
+ //
+ // FTR, from https://threejs.org/docs/#api/en/cameras/PerspectiveCamera
+ // the camera.fov is the vertical FOV.
+
+ const fov = camera.fov * ( Math.PI / 180 );
+ const fovh = 2*Math.atan(Math.tan(fov/2) * camera.aspect);
+ let dx = size.z / 2 + Math.abs( size.x / 2 / Math.tan( fovh / 2 ) );
+ let dy = size.z / 2 + Math.abs( size.y / 2 / Math.tan( fov / 2 ) );
+ let cameraZ = Math.max(dx, dy);
+
+ // offset the camera, if desired (to avoid filling the whole canvas)
+ if( offset !== undefined && offset !== 0 ) cameraZ *= offset;
+
+ camera.position.set( 0, 0, cameraZ );
+
+ // set the far plane of the camera so that it easily encompasses the whole object
+ const minZ = boundingBox.min.z;
+ const cameraToFarEdge = ( minZ < 0 ) ? -minZ + cameraZ : cameraZ - minZ;
+
+ camera.far = cameraToFarEdge * 3;
+ camera.updateProjectionMatrix();
+
+ if ( orbitControls !== undefined ) {
+ // set camera to rotate around the center
+ orbitControls.target = new THREE.Vector3(0, 0, 0);
+
+ // prevent camera from zooming out far enough to create far plane cutoff
+ orbitControls.maxDistance = cameraToFarEdge * 2;
+ }
+ };
+
+
+ function loadAsset(asset) {
+
+ loader.load( './' + asset + '.wrl',
+
+ // onLoad callback
+ function ( object ) {
+ vrmlScene = object;
+ scene.add( object );
+
+ document.getElementById('overlay').hidden = true;
+
+ // Center
+ const box = new THREE.Box3().setFromObject( object );
+ const center = box.getCenter( new THREE.Vector3() );
+ object.translateX( object.position.x - center.x );
+ object.translateY( object.position.y - center.y );
+ object.translateZ( object.position.z - center.z );
+ /*
+ object.position.x += ( object.position.x - center.x );
+ object.position.y += ( object.position.y - center.y );
+ object.position.z += ( object.position.z - center.z );
+ */
+ controls.reset();
+ model = object;
+ fitCameraToCenteredObject(camera, model, 1.1, controls);
+ //console.log(model)
+ },
+
+ /*
+ // onProgress callback. Useless because it reaches 100% quickly, then hangs
+ function ( xhr ) {
+ console.log( (xhr.loaded / xhr.total * 100) + '% loaded' );
+ },
+ */
+
+ );
+
+ }
+
+ function onWindowResize() {
+
+ camera.aspect = window.innerWidth / window.innerHeight;
+ camera.updateProjectionMatrix();
+
+ renderer.setSize( window.innerWidth, window.innerHeight );
+
+ }
+
+ function animate() {
+ controls.update(); // to support damping
+
+ //console.log(isMouseDown)
+ if(model && spin){
+ model.rotation.y += 0.0015
+ }
+
+ renderer.render( scene, camera );
+
+ //stats.update();
+
+ }
+
+ addEventListener("resize", (event) => {
+ fitCameraToCenteredObject(camera, model, 1.1, controls);
+ });
+ </script>
+ </body>
+</html>