| <!DOCTYPE html> |
| <html lang="tr"> |
| <head> |
| <meta charset="UTF-8"> |
| <title>Dental AI 3D Viewer - Professional Prototip</title> |
| <style> |
| body { margin: 0; overflow: hidden; background: #000; font-family: sans-serif; } |
| |
| |
| #overlay { |
| position: absolute; top: 20px; right: 20px; |
| width: 200px; cursor: pointer; border: 3px solid #ff0000; |
| display: none; |
| transition: all 0.3s ease; |
| z-index: 100; |
| } |
| |
| |
| .fullscreen { |
| position: fixed !important; |
| top: 50% !important; left: 50% !important; |
| transform: translate(-50%, -50%) !important; |
| width: 60% !important; |
| max-width: 800px; |
| border: 5px solid #fff; |
| box-shadow: 0 0 20px rgba(255,255,255,0.5); |
| } |
| |
| #hint { |
| position: absolute; bottom: 20px; left: 20px; |
| color: white; background: rgba(0,0,0,0.5); padding: 10px; |
| border-radius: 5px; pointer-events: none; |
| } |
| </style> |
| </head> |
| <body> |
|
|
| <div id="hint"></div> |
| <img id="overlay" src="crop.png" alt="Detaylı Röntgen"> |
|
|
| <script type="importmap"> |
| { "imports": { |
| "three": "https://unpkg.com/three@0.160.0/build/three.module.js", |
| "three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/" |
| }} |
| </script> |
|
|
| <script type="module"> |
| import * as THREE from 'three'; |
| import { STLLoader } from 'three/addons/loaders/STLLoader.js'; |
| import { OrbitControls } from 'three/addons/controls/OrbitControls.js'; |
| |
| const scene = new THREE.Scene(); |
| const camera = new THREE.PerspectiveCamera(75, window.innerWidth/window.innerHeight, 0.1, 1000); |
| const renderer = new THREE.WebGLRenderer({ antialias: true }); |
| renderer.setSize(window.innerWidth, window.innerHeight); |
| document.body.appendChild(renderer.domElement); |
| |
| scene.add(new THREE.AmbientLight(0xffffff, 1)); |
| camera.position.set(0, 0, 100); |
| |
| let boneMesh, marker; |
| const loader = new STLLoader(); |
| |
| |
| loader.load('bone.stl', (geometry) => { |
| geometry.center(); |
| boneMesh = new THREE.Mesh(geometry, new THREE.MeshNormalMaterial()); |
| boneMesh.scale.set(0.5, 0.5, 0.5); |
| scene.add(boneMesh); |
| |
| const mGeo = new THREE.SphereGeometry(3, 32, 32); |
| marker = new THREE.Mesh(mGeo, new THREE.MeshBasicMaterial({ color: 0xff0000 })); |
| marker.position.set(10, 5, -20); |
| boneMesh.add(marker); |
| }); |
| |
| const controls = new OrbitControls(camera, renderer.domElement); |
| const raycaster = new THREE.Raycaster(); |
| const mouse = new THREE.Vector2(); |
| const overlay = document.getElementById('overlay'); |
| |
| |
| window.addEventListener('mousemove', (event) => { |
| mouse.x = (event.clientX / window.innerWidth) * 2 - 1; |
| mouse.y = -(event.clientY / window.innerHeight) * 2 + 1; |
| |
| raycaster.setFromCamera(mouse, camera); |
| if (!marker) return; |
| |
| const intersects = raycaster.intersectObject(marker); |
| if (intersects.length > 0) { |
| document.body.style.cursor = 'pointer'; |
| marker.material.color.set(0xff5555); |
| } else { |
| document.body.style.cursor = 'default'; |
| marker.material.color.set(0xff0000); |
| } |
| }); |
| |
| window.addEventListener('click', (event) => { |
| raycaster.setFromCamera(mouse, camera); |
| const intersects = raycaster.intersectObject(marker); |
| |
| if (intersects.length > 0) { |
| overlay.style.display = 'block'; |
| } else if (event.target !== overlay) { |
| overlay.style.display = 'none'; |
| overlay.classList.remove('fullscreen'); |
| } |
| }); |
| |
| overlay.addEventListener('click', (e) => { |
| e.stopPropagation(); |
| overlay.classList.toggle('fullscreen'); |
| }); |
| |
| function animate() { |
| requestAnimationFrame(animate); |
| controls.update(); |
| renderer.render(scene, camera); |
| } |
| animate(); |
| </script> |
| </body> |
| </html> |