Enhance Services Homepage with galaxy background animation and canvas integration
This commit is contained in:
116
index.html
116
index.html
@@ -5,8 +5,10 @@
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title>Services Homepage</title>
|
||||
<link rel="stylesheet" href="/styles.css" />
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<canvas id="galaxy-canvas"></canvas>
|
||||
<header>
|
||||
<h1>My Services</h1>
|
||||
<p class="subtitle">Quick links to the commonly used containers on this host</p>
|
||||
@@ -32,6 +34,120 @@
|
||||
<footer>
|
||||
<small>Generated: static homepage — served by nginx in a container. Edit and rebuild to update.</small>
|
||||
</footer>
|
||||
<script>
|
||||
// Galaxy background animation with mountains
|
||||
(function initGalaxy(){
|
||||
var ww = window.innerWidth;
|
||||
var wh = window.innerHeight;
|
||||
|
||||
var renderer = new THREE.WebGLRenderer({
|
||||
antialias: true,
|
||||
canvas: document.querySelector('#galaxy-canvas'),
|
||||
alpha: false
|
||||
});
|
||||
renderer.setSize(ww, wh);
|
||||
renderer.setClearColor(0x001a2d, 1);
|
||||
|
||||
var scene = new THREE.Scene();
|
||||
scene.fog = new THREE.Fog(0x001a2d, 80, 140);
|
||||
|
||||
var camera = new THREE.PerspectiveCamera(45, ww/wh, 0.1, 200);
|
||||
camera.position.x = 70;
|
||||
camera.position.y = 30;
|
||||
camera.position.z = 5;
|
||||
camera.lookAt(new THREE.Vector3());
|
||||
|
||||
// Create galaxy particles
|
||||
var particles = [];
|
||||
for(var i = 0; i < 20000; i++){
|
||||
var particle = new Particle();
|
||||
particles.push(particle);
|
||||
scene.add(particle.object);
|
||||
}
|
||||
|
||||
function Particle(){
|
||||
var radius = Math.random() * 120 + 5;
|
||||
var height = (Math.random() - 0.5) * 10;
|
||||
var angle = Math.random() * Math.PI * 2;
|
||||
|
||||
this.object = new THREE.Object3D();
|
||||
this.object.position.y = height;
|
||||
|
||||
var geometry = new THREE.SphereGeometry(0.1, 4, 4);
|
||||
var material = new THREE.MeshBasicMaterial({
|
||||
color: 0xffffff
|
||||
});
|
||||
|
||||
var mesh = new THREE.Mesh(geometry, material);
|
||||
mesh.position.x = radius;
|
||||
|
||||
this.object.add(mesh);
|
||||
this.object.rotation.z = angle;
|
||||
|
||||
this.update = function(){
|
||||
this.object.rotation.z += 0.0002 + (120 - radius) * 0.00002;
|
||||
};
|
||||
}
|
||||
|
||||
// Create terrain/mountains
|
||||
var terrain = new THREE.Object3D();
|
||||
var terrainGeometry = new THREE.PlaneGeometry(400, 400, 100, 100);
|
||||
|
||||
// Modify vertices to create mountain landscape
|
||||
var vertices = terrainGeometry.attributes.position.array;
|
||||
for(var i = 0; i < vertices.length; i += 3){
|
||||
var x = vertices[i];
|
||||
var y = vertices[i + 1];
|
||||
var distance = Math.sqrt(x * x + y * y);
|
||||
var height = (Math.random() - 0.5) * 12;
|
||||
height *= Math.max(0, 1 - distance / 180); // Fade height at edges
|
||||
vertices[i + 2] = height;
|
||||
}
|
||||
terrainGeometry.attributes.position.needsUpdate = true;
|
||||
terrainGeometry.computeVertexNormals();
|
||||
|
||||
var terrainMaterial = new THREE.MeshLambertMaterial({
|
||||
color: 0x0a2540,
|
||||
wireframe: true,
|
||||
transparent: true,
|
||||
opacity: 0.7
|
||||
});
|
||||
|
||||
var terrainMesh = new THREE.Mesh(terrainGeometry, terrainMaterial);
|
||||
terrainMesh.rotation.x = -Math.PI / 2;
|
||||
terrainMesh.position.y = -20;
|
||||
terrain.add(terrainMesh);
|
||||
scene.add(terrain);
|
||||
|
||||
// Add ambient light
|
||||
var ambientLight = new THREE.AmbientLight(0x4488ff, 0.4);
|
||||
scene.add(ambientLight);
|
||||
|
||||
// Add directional light for terrain
|
||||
var directionalLight = new THREE.DirectionalLight(0x88ccff, 0.6);
|
||||
directionalLight.position.set(50, 50, 50);
|
||||
scene.add(directionalLight);
|
||||
|
||||
function render(){
|
||||
requestAnimationFrame(render);
|
||||
particles.forEach(function(p){
|
||||
p.update();
|
||||
});
|
||||
terrain.rotation.z += 0.0001;
|
||||
renderer.render(scene, camera);
|
||||
}
|
||||
|
||||
window.addEventListener('resize', function(){
|
||||
ww = window.innerWidth;
|
||||
wh = window.innerHeight;
|
||||
camera.aspect = ww / wh;
|
||||
camera.updateProjectionMatrix();
|
||||
renderer.setSize(ww, wh);
|
||||
});
|
||||
|
||||
render();
|
||||
})();
|
||||
</script>
|
||||
<script>
|
||||
// Fetch services.xml and render the service cards with logos.
|
||||
(async function(){
|
||||
|
||||
Reference in New Issue
Block a user