aboutsummaryrefslogtreecommitdiff
path: root/main.js
blob: 2fc398b0c55f4c6351d36decb4975f67e19c1750 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import * as THREE from 'https://unpkg.com/three@0.160.0/build/three.module.js';
import { createSun } from './sun.js';
import { createMountains } from './mountains.js';

// Scene setup
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x090012);
scene.fog = new THREE.Fog(0x090012, 20, 120);

const camera = new THREE.PerspectiveCamera(
  60,
  window.innerWidth / window.innerHeight,
  0.1,
  500
);
camera.position.set(0, 2, 15);
camera.rotation.x = -0.1;

const renderer = new THREE.WebGLRenderer({
  canvas: document.getElementById('bg'),
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 1.5));

// Grid
const size = 200;
const divisions = 200;
const grid = new THREE.GridHelper(size, divisions, 0xff00ff, 0xff00ff);
grid.material.transparent = true;
grid.material.opacity = 0.4;
scene.add(grid);

// --- Occlusion floor (invisible) ---
const floorGeometry = new THREE.PlaneGeometry(size, size);
const floorMaterial = new THREE.MeshBasicMaterial({
    color: 0x090012,   // matches background
    opacity: 0.5,        // invisible
    transparent: true
});
const floor = new THREE.Mesh(floorGeometry, floorMaterial);
floor.rotation.x = -Math.PI / 2; // horizontal
floor.position.y = 0;             // same height as grid
scene.add(floor);

// Sun
const { sun, glow } = createSun();
scene.add(sun);
scene.add(glow);

let scroll = 0;
let sunAngle = 0;

// Mountains
const mountains = createMountains();
scene.add(mountains);

// Animation function
function animate() {
  scroll += 0.05;
  grid.position.z = scroll % 10;

  renderer.render(scene, camera);
}

// Start loop with pause/resume on tab visibility
renderer.setAnimationLoop(animate);

document.addEventListener('visibilitychange', () => {
  if (document.hidden) {
    renderer.setAnimationLoop(null);
  } else {
    renderer.setAnimationLoop(animate);
  }
});

// Handle window resize
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});