Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Transformer Matrix Visualization - Aligned</title> | |
| <style> | |
| body { | |
| margin: 0; | |
| font-family: 'Segoe UI', 'Roboto', 'Oxygen', sans-serif; | |
| background-color: #000000; | |
| color: #e0e0e0; | |
| overflow: hidden; | |
| } | |
| #button-container { | |
| position: absolute; | |
| top: 20px; | |
| left: 50%; | |
| transform: translateX(-50%); | |
| z-index: 100; | |
| display: flex; | |
| gap: 15px; | |
| background-color: rgba(10, 10, 10, 0.7); | |
| padding: 10px 20px; | |
| border-radius: 12px; | |
| border: 1px solid rgba(255, 255, 255, 0.2); | |
| } | |
| .focus-btn { | |
| background-color: #222; | |
| color: #ddd; | |
| border: 1px solid #444; | |
| padding: 8px 16px; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| font-size: 16px; | |
| font-weight: bold; | |
| transition: background-color 0.3s, color 0.3s; | |
| } | |
| .focus-btn:hover { | |
| background-color: #0077be; | |
| color: #fff; | |
| } | |
| #tooltip { | |
| position: absolute; | |
| display: none; | |
| padding: 12px; | |
| background-color: rgba(10, 10, 25, 0.9); | |
| border: 1px solid #0077be; | |
| border-radius: 8px; | |
| pointer-events: none; | |
| font-size: 14px; | |
| z-index: 101; | |
| } | |
| #tooltip h3 { margin: 0 0 8px 0; color: #8ac8ff; } | |
| #tooltip p { margin: 0; } | |
| canvas { display: block; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="button-container"></div> | |
| <div id="tooltip"></div> | |
| <div id="canvas-container"></div> | |
| <script type="importmap"> | |
| { | |
| "imports": { | |
| "three": "https://unpkg.com/three@0.165.0/build/three.module.js", | |
| "three/addons/": "https://unpkg.com/three@0.165.0/examples/jsm/", | |
| "gsap": "https://unpkg.com/gsap@3.12.5/index.js" | |
| } | |
| } | |
| </script> | |
| <script type="module"> | |
| import * as THREE from 'three'; | |
| import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; | |
| import { gsap } from 'gsap'; | |
| // --- Scene Setup --- | |
| const scene = new THREE.Scene(); | |
| const container = document.getElementById('canvas-container'); | |
| const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 200000); | |
| camera.position.set(0, 200, 1500); | |
| const renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| container.appendChild(renderer.domElement); | |
| const controls = new OrbitControls(camera, renderer.domElement); | |
| controls.enableDamping = true; | |
| controls.dampingFactor = 0.05; | |
| const gridHelper = new THREE.GridHelper(400000, 400, 0x333333, 0x222222); | |
| scene.add(gridHelper); | |
| // This group will hold all models to make centering easy | |
| const allModelsGroup = new THREE.Group(); | |
| scene.add(allModelsGroup); | |
| const models = []; | |
| const collidableObjects = []; | |
| const colorPalette = [ | |
| new THREE.Color(0x6a0dad), new THREE.Color(0x0077be), | |
| new THREE.Color(0x00a896), new THREE.Color(0xdc3958), | |
| new THREE.Color(0xf7ac3d), | |
| ]; | |
| function createMatrixModel(name, params) { | |
| const modelGroup = new THREE.Group(); | |
| const representativeCount = Math.floor(Math.max(400, params / 2e6)); | |
| const gridSide = Math.floor(Math.sqrt(representativeCount)); | |
| const instanceCount = gridSide * gridSide; | |
| const squareSize = 5; | |
| const modelWidth = gridSide * squareSize; | |
| const geometry = new THREE.PlaneGeometry(squareSize * 0.9, squareSize * 0.9); | |
| const material = new THREE.MeshBasicMaterial({ side: THREE.DoubleSide }); | |
| const mesh = new THREE.InstancedMesh(geometry, material, instanceCount); | |
| const dummy = new THREE.Object3D(); | |
| let i = 0; | |
| for (let x = 0; x < gridSide; x++) { | |
| for (let y = 0; y < gridSide; y++) { | |
| dummy.position.set( | |
| (x - gridSide / 2) * squareSize, | |
| (y - gridSide / 2) * squareSize, | |
| 0 | |
| ); | |
| dummy.updateMatrix(); | |
| mesh.setMatrixAt(i, dummy.matrix); | |
| const color = colorPalette[Math.floor(Math.random() * colorPalette.length)]; | |
| mesh.setColorAt(i, color); | |
| i++; | |
| } | |
| } | |
| mesh.instanceMatrix.needsUpdate = true; | |
| mesh.instanceColor.needsUpdate = true; | |
| modelGroup.add(mesh); | |
| modelGroup.userData = { name, params }; | |
| mesh.userData = { modelName: name, params }; | |
| models.push({ name, group: modelGroup, params }); | |
| collidableObjects.push(mesh); | |
| // Return the group and its calculated width for layout purposes | |
| return { modelGroup, modelWidth }; | |
| } | |
| // --- NEW: Ordered Model Definitions & Linear Layout --- | |
| const modelDefinitions = [ | |
| { name: '1000B', params: 1000e9 }, { name: '405B', params: 405e9 }, | |
| { name: '70B', params: 70e9 }, { name: '4B', params: 4e9 }, | |
| { name: '1B', params: 1e9 }, { name: '0.2B', params: 0.2e9 }, | |
| ]; | |
| let currentX = 0; | |
| modelDefinitions.forEach((def) => { | |
| const { modelGroup, modelWidth } = createMatrixModel(def.name, def.params); | |
| // Add padding based on the size of the model | |
| const padding = modelWidth * 0.5; | |
| // Position the model along the X axis | |
| modelGroup.position.x = currentX + modelWidth / 2; | |
| // Add the model to the main group | |
| allModelsGroup.add(modelGroup); | |
| // Update the X-coordinate for the next model | |
| currentX += modelWidth + padding; | |
| }); | |
| // Center the entire line of models at the world origin | |
| const sceneBox = new THREE.Box3().setFromObject(allModelsGroup); | |
| const sceneCenter = new THREE.Vector3(); | |
| sceneBox.getCenter(sceneCenter); | |
| allModelsGroup.position.x = -sceneCenter.x; | |
| // --- UI and Camera Control --- | |
| const buttonContainer = document.getElementById('button-container'); | |
| models.forEach(model => { | |
| const btn = document.createElement('button'); | |
| btn.className = 'focus-btn'; | |
| btn.innerText = model.name; | |
| btn.onclick = () => focusOnModel(model); | |
| buttonContainer.appendChild(btn); | |
| }); | |
| function focusOnModel(model) { | |
| const modelWorldPosition = new THREE.Vector3(); | |
| model.group.getWorldPosition(modelWorldPosition); | |
| const modelBox = new THREE.Box3().setFromObject(model.group); | |
| const modelSize = new THREE.Vector3(); | |
| modelBox.getSize(modelSize); | |
| const cameraDistance = modelSize.y / (2 * Math.tan(camera.fov * Math.PI / 360)) * 1.5; // Frame based on height | |
| const cameraZ = Math.max(cameraDistance, modelSize.x); // Ensure we are far enough to see the width | |
| const cameraTargetPosition = new THREE.Vector3( | |
| modelWorldPosition.x, | |
| modelWorldPosition.y, | |
| modelWorldPosition.z + cameraZ | |
| ); | |
| gsap.to(camera.position, { | |
| x: cameraTargetPosition.x, | |
| y: cameraTargetPosition.y, | |
| z: cameraTargetPosition.z, | |
| duration: 2.5, | |
| ease: 'power3.inOut' | |
| }); | |
| gsap.to(controls.target, { | |
| x: modelWorldPosition.x, | |
| y: modelWorldPosition.y, | |
| z: modelWorldPosition.z, | |
| duration: 2.5, | |
| ease: 'power3.inOut' | |
| }); | |
| } | |
| // --- Interactivity & Render Loop --- | |
| const raycaster = new THREE.Raycaster(); | |
| const mouse = new THREE.Vector2(); | |
| const tooltip = document.getElementById('tooltip'); | |
| window.addEventListener('mousemove', (event) => { | |
| mouse.x = (event.clientX / window.innerWidth) * 2 - 1; | |
| mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; | |
| tooltip.style.left = (event.clientX + 15) + 'px'; | |
| tooltip.style.top = (event.clientY + 15) + 'px'; | |
| }); | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| controls.update(); | |
| raycaster.setFromCamera(mouse, camera); | |
| const intersects = raycaster.intersectObjects(collidableObjects); | |
| if (intersects.length > 0) { | |
| const data = intersects[0].object.userData; | |
| tooltip.style.display = 'block'; | |
| tooltip.innerHTML = ` | |
| <h3>${data.modelName} Model</h3> | |
| <p><strong>Parameters:</strong> ${data.params.toLocaleString()}</p> | |
| `; | |
| } else { | |
| tooltip.style.display = 'none'; | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| // Focus on the first model (1000B) to start | |
| if (models.length > 0) { | |
| focusOnModel(models[0]); | |
| } | |
| animate(); | |
| </script> | |
| <footer>fredmo - 2025 </footer> | |
| </body> | |
| </html> |