126 lines
4.6 KiB
Cheetah
Executable File
126 lines
4.6 KiB
Cheetah
Executable File
{{template "lightbase/head" .}}
|
|
<div role="main" aria-label="{{if .IsSigned}}{{ctx.Locale.Tr "dashboard"}}{{else}}{{ctx.Locale.Tr "home"}}{{end}}"
|
|
style="
|
|
width: 100%;
|
|
flex: 1;
|
|
overflow: hidden;">
|
|
<div id="three-container"
|
|
style="
|
|
background-color: #f6f7fa;
|
|
">
|
|
|
|
</div>
|
|
</div>
|
|
<script type="module">
|
|
import * as THREE from 'https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.module.js';
|
|
let camera, scene, renderer, parentTransform, sphereInter;
|
|
const radius = 100;
|
|
let theta = 0;
|
|
|
|
init();
|
|
|
|
function init() {
|
|
// Get the container div
|
|
const container = document.getElementById('three-container');
|
|
|
|
// Camera setup
|
|
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 1, 10000);
|
|
|
|
// Scene setup
|
|
scene = new THREE.Scene();
|
|
scene.background = new THREE.Color(0xf0f0f0);
|
|
|
|
// Sphere for intersection (no longer needed, but kept for completeness)
|
|
const geometry = new THREE.SphereGeometry(5);
|
|
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
|
|
sphereInter = new THREE.Mesh(geometry, material);
|
|
sphereInter.visible = false;
|
|
scene.add(sphereInter);
|
|
|
|
// Line geometry
|
|
const lineGeometry = new THREE.BufferGeometry();
|
|
const points = [];
|
|
const point = new THREE.Vector3();
|
|
const direction = new THREE.Vector3();
|
|
|
|
for (let i = 0; i < 50; i++) {
|
|
direction.x += Math.random() - 0.5;
|
|
direction.y += Math.random() - 0.5;
|
|
direction.z += Math.random() - 0.5;
|
|
direction.normalize().multiplyScalar(10);
|
|
point.add(direction);
|
|
points.push(point.x, point.y, point.z);
|
|
}
|
|
|
|
lineGeometry.setAttribute('position', new THREE.Float32BufferAttribute(points, 3));
|
|
|
|
// Parent transform
|
|
parentTransform = new THREE.Object3D();
|
|
parentTransform.position.set(Math.random() * 40 - 20, Math.random() * 40 - 20, Math.random() * 40 - 20);
|
|
parentTransform.rotation.set(Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI);
|
|
parentTransform.scale.set(Math.random() + 0.5, Math.random() + 0.5, Math.random() + 0.5);
|
|
|
|
// Add lines or line segments
|
|
for (let i = 0; i < 50; i++) {
|
|
const lineMaterial = new THREE.LineBasicMaterial({ color: Math.random() * 0xffffff });
|
|
let object;
|
|
|
|
if (Math.random() > 0.5) {
|
|
object = new THREE.Line(lineGeometry, lineMaterial);
|
|
} else {
|
|
object = new THREE.LineSegments(lineGeometry, lineMaterial);
|
|
}
|
|
|
|
object.position.set(Math.random() * 400 - 200, Math.random() * 400 - 200, Math.random() * 400 - 200);
|
|
object.rotation.set(Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI, Math.random() * 2 * Math.PI);
|
|
object.scale.set(Math.random() + 0.5, Math.random() + 0.5, Math.random() + 0.5);
|
|
|
|
parentTransform.add(object);
|
|
}
|
|
|
|
scene.add(parentTransform);
|
|
|
|
// Renderer
|
|
renderer = new THREE.WebGLRenderer({ antialias: true });
|
|
renderer.setPixelRatio(window.devicePixelRatio);
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
renderer.setAnimationLoop(animate);
|
|
|
|
// Append the renderer's canvas to the container div
|
|
container.appendChild(renderer.domElement);
|
|
|
|
// Event listener
|
|
window.addEventListener('resize', onWindowResize);
|
|
}
|
|
|
|
// Handle window resize
|
|
function onWindowResize() {
|
|
camera.aspect = window.innerWidth / window.innerHeight;
|
|
camera.updateProjectionMatrix();
|
|
renderer.setSize(window.innerWidth, window.innerHeight);
|
|
}
|
|
|
|
// Animation loop
|
|
function animate() {
|
|
render();
|
|
}
|
|
|
|
// Render scene
|
|
function render() {
|
|
theta += 0.1;
|
|
|
|
camera.position.x = radius * Math.sin(THREE.MathUtils.degToRad(theta));
|
|
camera.position.y = radius * Math.sin(THREE.MathUtils.degToRad(theta));
|
|
camera.position.z = radius * Math.cos(THREE.MathUtils.degToRad(theta));
|
|
camera.lookAt(scene.position);
|
|
|
|
camera.updateMatrixWorld();
|
|
|
|
// Render the scene
|
|
renderer.render(scene, camera);
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
{{template "base/footer" .}} |