<!
DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>3D Icons with Glow on White</title>
  <style>
    body { margin: 0; overflow: hidden; background: #ffffff; }
    canvas { display: block; background: #ffffff; }
  </style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></
script>
<script>
// Scene, Camera, Renderer
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60,
window.innerWidth/window.innerHeight, 0.1, 1000);
camera.position.z = 25;
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setClearColor(0xffffff, 1); // WHITE BACKGROUND
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// Lights
scene.add(new THREE.AmbientLight(0xffffff, 0.8));
const pointLight = new THREE.PointLight(0xffffff, 1.5, 100);
pointLight.position.set(10, 15, 10);
scene.add(pointLight);
// Icon shapes and colors
const iconShapes = ['mail', 'phone', 'chat', 'insta', 'meta', 'fb'];
const colorPalette = [0x03c0f6, 0x1e50ea, 0xb714db];
// Function to create a glowing icon
function createIcon(color, shape) {
  let geometry;
  switch(shape) {
    case 'mail': geometry = new THREE.BoxGeometry(0.8, 0.6, 0.1); break;
    case 'phone': geometry = new THREE.CylinderGeometry(0.2, 0.2, 1.2, 32); break;
    case 'chat': geometry = new THREE.SphereGeometry(0.5, 32, 32); break;
    case 'insta': geometry = new THREE.TorusKnotGeometry(0.3, 0.1, 100, 16); break;
    case 'meta': geometry = new THREE.TorusGeometry(0.5, 0.15, 16, 100); break;
    case 'fb': geometry = new THREE.BoxGeometry(0.5, 0.8, 0.1); break;
    default: geometry = new THREE.SphereGeometry(0.5, 32, 32);
  }
  const material = new THREE.MeshStandardMaterial({
    color: color,
    emissive: color,
    emissiveIntensity: 0.6,
    metalness: 0.3,
    roughness: 0.4
  });
  const mesh = new THREE.Mesh(geometry, material);
  mesh.position.set(
      (Math.random() - 0.5) * 40,
      (Math.random() - 0.5) * 30,
      (Math.random() - 0.5) * 20
    );
    // Movement + Rotation
    mesh.userData = {
       vx: (Math.random() - 0.5) * 0.02,
       vy: (Math.random() - 0.5) * 0.02,
       vz: (Math.random() - 0.5) * 0.02,
       rx: Math.random() * 0.01,
       ry: Math.random() * 0.01
    };
    scene.add(mesh);
    return mesh;
}
// Generate multiple glowing icons
const icons = [];
for (let i = 0; i < 40; i++) {
  const color = colorPalette[Math.floor(Math.random() * colorPalette.length)];
  const shape = iconShapes[Math.floor(Math.random() * iconShapes.length)];
  icons.push(createIcon(color, shape));
}
// Animate
function animate() {
  requestAnimationFrame(animate);
  icons.forEach(icon => {
    icon.rotation.x += icon.userData.rx;
    icon.rotation.y += icon.userData.ry;
    icon.position.x += icon.userData.vx;
    icon.position.y += icon.userData.vy;
    icon.position.z += icon.userData.vz;
      if (Math.abs(icon.position.x) > 20) icon.userData.vx *= -1;
      if (Math.abs(icon.position.y) > 15) icon.userData.vy *= -1;
      if (Math.abs(icon.position.z) > 10) icon.userData.vz *= -1;
    });
    renderer.render(scene, camera);
}
animate();
// Responsive
window.addEventListener('resize', () => {
  camera.aspect = window.innerWidth / window.innerHeight;
  camera.updateProjectionMatrix();
  renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>