Snippets Astralis 360 View – Bootstrap 5

🏷️ Extraits & Composants HTML 📅 01/04/2026 13:00:00 👤 Mezgani said
Bootstrap 5 Vue 360 Astralis Style Full Background Template Bootstrap Snippets Html

Template de vue 360° en full background avec un style Astralis moderne, compatible Bootstrap 5.

<!DOCTYPE html>
<html lang="fr">
<head>
  <meta charset="UTF-8" />
  <meta name="copyright" content="MEZGANI Said" />
  <meta name="author" content="AngularForAll" />
  <meta name="robots" content="noindex, nofollow" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <title>Snippets Astralis View360 01 | AngularForAll</title>
<style>
    /* RESET & FULLSCREEN MODERN STYLE */
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      width: 100vw;
      height: 100vh;
      overflow: hidden;
      background: #03050b;
      font-family: 'Segoe UI', 'Inter', system-ui, -apple-system, sans-serif;
    }

    /* canvas occupe tout l'espace, en fond */
    #canvas-container {
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 1;
    }

    /* surcouche subtile pour lisibilité + style moderne */
    .info {
      position: relative;
      z-index: 10;
      pointer-events: none;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-between;
      width: 100%;
      height: 100%;
      padding: 1.8rem 2rem;
      color: rgba(255, 255, 255, 0.9);
      text-shadow: 0 0 20px rgba(0,0,0,0.6);
      backdrop-filter: blur(2px);
    }

    .top-row {
      display: flex;
      justify-content: space-between;
      width: 100%;
      pointer-events: none;
    }

    .logo {
      font-weight: 600;
      letter-spacing: 3px;
      font-size: 1.2rem;
      text-transform: uppercase;
      background: linear-gradient(135deg, #aaccff, #e0c0ff);
      -webkit-background-clip: text;
      background-clip: text;
      color: transparent;
      filter: drop-shadow(0 4px 6px #00000030);
    }

    .badge {
      background: rgba(20, 30, 50, 0.5);
      backdrop-filter: blur(12px);
      -webkit-backdrop-filter: blur(12px);
      border: 1px solid rgba(120, 180, 255, 0.25);
      border-radius: 60px;
      padding: 0.5rem 1.5rem;
      font-size: 0.9rem;
      font-weight: 400;
      letter-spacing: 1px;
      color: #ccdeff;
      box-shadow: 0 10px 20px -8px rgba(0,0,0,0.4);
      pointer-events: auto;
    }

    .center-message {
      text-align: center;
      pointer-events: none;
      transform: translateY(-10px);
    }

    .planet-name {
      font-size: clamp(3rem, 12vw, 5.5rem);
      font-weight: 800;
      background: linear-gradient(135deg, #fff8e7, #d6e6ff);
      -webkit-background-clip: text;
      background-clip: text;
      color: transparent;
      letter-spacing: 8px;
      margin-bottom: 0.5rem;
      text-transform: uppercase;
      filter: drop-shadow(0 0 30px #3f6ac0);
    }

    .sub {
      font-size: 1rem;
      opacity: 0.8;
      font-weight: 300;
      letter-spacing: 6px;
      word-spacing: 8px;
      color: #b8ceff;
    }

    .bottom-hint {
      font-size: 0.9rem;
      color: rgba(200, 220, 255, 0.8);
      background: rgba(10, 18, 30, 0.3);
      backdrop-filter: blur(8px);
      -webkit-backdrop-filter: blur(8px);
      padding: 0.5rem 2rem;
      border-radius: 40px;
      border: 1px solid rgba(255,255,255,0.08);
      pointer-events: auto;
      transition: opacity 0.3s;
    }

    .bottom-hint i {
      font-style: normal;
      display: inline-block;
      animation: subtlePulse 3s infinite;
    }

    @keyframes subtlePulse {
      0% { opacity: 0.6; }
      50% { opacity: 1; text-shadow: 0 0 8px #7aaaff; }
      100% { opacity: 0.6; }
    }

    /* responsive adjustments */
    @media (max-width: 600px) {
      .info { padding: 1.2rem 1rem; }
      .planet-name { letter-spacing: 4px; }
      .badge { padding: 0.3rem 1rem; font-size: 0.75rem; }
    }

    /* le canvas de three.js est injecté dans #canvas-container */
    canvas {
      display: block;
    }
  </style>
  
  <!-- Three.js (core) -->
  <script type="importmap">
    {
      "imports": {
        "three": "https://unpkg.com/three@0.128.0/build/three.module.js"
      }
    }
  </script>
</head>
<body>
  <div id="canvas-container"></div>

  <!-- overlay moderne / réactif -->
  <div class="info">
    <div class="top-row">
      <span class="logo">◈ COSMOS REACTIVE</span>
      <span class="badge">FULLSCREEN · 3D</span>
    </div>
    <div class="center-message">
      <div class="planet-name">ASTRALIS</div>
      <div class="sub">TURNING · INFINITE</div>
    </div>
    <div class="bottom-hint">
      <i>⚡ rotation fluide · réactive au mouvement</i> &nbsp; | &nbsp; <span style="opacity:0.7;">drag / scroll</span>
    </div>
  </div>

  <script type="module">
    import * as THREE from 'three';
    import { OrbitControls } from 'https://unpkg.com/three@0.128.0/examples/jsm/controls/OrbitControls.js';

    // --- INITIALISATION SCÈNE MODERNE FULL WIDTH / FULL BACKGROUND ---
    const container = document.getElementById('canvas-container');
    
    // Scene avec fond profond (espace)
    const scene = new THREE.Scene();
    scene.background = new THREE.Color('#03050b'); // presque noir, mais très légèrement bleu
    
    // Caméra perspective avec angle large pour effet immersif
    const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
    camera.position.set(0, 1.2, 8);
    
    // Renderer avec antialiasing et alpha (même si fond opaque, pour transparence éventuelle)
    const renderer = new THREE.WebGLRenderer({ antialias: true, alpha: false });
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2)); // netteté sans surcoût
    renderer.shadowMap.enabled = true; // pour les effets de lumière (bien que léger)
    renderer.shadowMap.type = THREE.PCFSoftShadowMap;
    container.appendChild(renderer.domElement);

    // --- CONTRÔLES ORBIT pour une interactivité réactive & moderne ---
    const controls = new OrbitControls(camera, renderer.domElement);
    controls.enableDamping = true;      // mouvement fluide
    controls.dampingFactor = 0.05;
    controls.autoRotate = true;
    controls.autoRotateSpeed = 1.8;     // rotation planétaire continue et lente
    controls.enableZoom = true;
    controls.zoomSpeed = 0.8;
    controls.enablePan = false;         // on garde le focus sur la planète
    controls.maxPolarAngle = Math.PI / 1.8; // empêche de passer sous la planète trop brusquement
    controls.minDistance = 3.5;
    controls.maxDistance = 14.0;
    controls.target.set(0, 0.2, 0);     // légèrement au-dessus du centre pour l'esthétique
    
    // --- LUMIÈRES : atmosphère riche et moderne ---
    
    // Lumière ambiante douce
    const ambientLight = new THREE.AmbientLight(0x404060, 0.45);
    scene.add(ambientLight);
    
    // Lumière principale directionnelle (simule un soleil lointain)
    const sunLight = new THREE.DirectionalLight(0xffeedd, 1.2);
    sunLight.position.set(5, 8, 5);
    sunLight.castShadow = true;
    sunLight.receiveShadow = true;
    sunLight.shadow.mapSize.width = 1024;
    sunLight.shadow.mapSize.height = 1024;
    const d = 8;
    sunLight.shadow.camera.left = -d;
    sunLight.shadow.camera.right = d;
    sunLight.shadow.camera.top = d;
    sunLight.shadow.camera.bottom = -d;
    sunLight.shadow.camera.near = 1;
    sunLight.shadow.camera.far = 25;
    sunLight.shadow.bias = -0.0005;
    scene.add(sunLight);
    
    // Lumières d'appoint colorées pour un rendu "moderne & réactif"
    const fillLight1 = new THREE.PointLight(0x4466ff, 0.8);
    fillLight1.position.set(-3, 2, 4);
    scene.add(fillLight1);
    
    const fillLight2 = new THREE.PointLight(0xff66aa, 0.5);
    fillLight2.position.set(4, 1, -5);
    scene.add(fillLight2);
    
    const backLight = new THREE.PointLight(0x335588, 0.6);
    backLight.position.set(-2, 0.5, -7);
    scene.add(backLight);
    
    // Une lumière douce sous la planète pour accentuer le relief
    const bottomLight = new THREE.PointLight(0x2a3f6e, 0.4);
    bottomLight.position.set(1, -2, 2);
    scene.add(bottomLight);
    
    // --- CRÉATION DE LA PLANÈTE (texture procédurale via canvas, style moderne) ---
    // On génère une texture de planète avec des bandes, des taches, pour un look "gazeuse / tellurique stylisée"
    function createPlanetTexture() {
      const canvas = document.createElement('canvas');
      canvas.width = 1024;
      canvas.height = 512;
      const ctx = canvas.getContext('2d');
      
      // Fond de base : dégradé bleu nuit / violet
      const grad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
      grad.addColorStop(0, '#1a2a4a');
      grad.addColorStop(0.4, '#2e4a6e');
      grad.addColorStop(0.7, '#4a3e6b');
      grad.addColorStop(1, '#1f2a3f');
      ctx.fillStyle = grad;
      ctx.fillRect(0, 0, canvas.width, canvas.height);
      
      // Ajout de bandes nuageuses horizontales (style Jupiter moderne)
      for (let i = 0; i < 40; i++) {
        const y = Math.random() * canvas.height;
        const height = 6 + Math.random() * 30;
        const alpha = 0.12 + Math.random() * 0.25;
        ctx.beginPath();
        const gradient = ctx.createLinearGradient(0, y-5, canvas.width, y+height);
        if (Math.random() > 0.5) {
          gradient.addColorStop(0, `rgba(180, 200, 255, ${alpha})`);
          gradient.addColorStop(0.5, `rgba(220, 180, 255, ${alpha*1.2})`);
          gradient.addColorStop(1, `rgba(140, 180, 240, ${alpha})`);
        } else {
          gradient.addColorStop(0, `rgba(210, 190, 160, ${alpha*0.9})`);
          gradient.addColorStop(0.6, `rgba(140, 170, 210, ${alpha})`);
          gradient.addColorStop(1, `rgba(170, 150, 200, ${alpha})`);
        }
        ctx.fillStyle = gradient;
        ctx.fillRect(0, y, canvas.width, height);
      }
      
      // Ajout de taches / ouragans stylisés
      for (let j = 0; j < 60; j++) {
        const x = Math.random() * canvas.width;
        const y = Math.random() * canvas.height;
        const radius = 15 + Math.random() * 45;
        const grd = ctx.createRadialGradient(x, y, 0, x, y, radius);
        if (Math.random() > 0.6) {
          grd.addColorStop(0, 'rgba(240, 210, 170, 0.25)');
          grd.addColorStop(0.7, 'rgba(120, 100, 160, 0.2)');
        } else {
          grd.addColorStop(0, 'rgba(180, 220, 255, 0.3)');
          grd.addColorStop(0.8, 'rgba(80, 100, 150, 0.15)');
        }
        grd.addColorStop(1, 'transparent');
        ctx.fillStyle = grd;
        ctx.beginPath();
        ctx.arc(x, y, radius, 0, Math.PI*2);
        ctx.fill();
      }
      
      // Effet de brillance aux pôles
      const poleGrad = ctx.createLinearGradient(0, 0, 0, canvas.height*0.2);
      poleGrad.addColorStop(0, 'rgba(200, 230, 255, 0.3)');
      poleGrad.addColorStop(1, 'transparent');
      ctx.fillStyle = poleGrad;
      ctx.fillRect(0, 0, canvas.width, canvas.height*0.2);
      
      const poleGradBottom = ctx.createLinearGradient(0, canvas.height*0.8, 0, canvas.height);
      poleGradBottom.addColorStop(0, 'transparent');
      poleGradBottom.addColorStop(1, 'rgba(190, 180, 240, 0.25)');
      ctx.fillStyle = poleGradBottom;
      ctx.fillRect(0, canvas.height*0.8, canvas.width, canvas.height*0.2);
      
      // Petits détails brillants
      ctx.fillStyle = 'rgba(255, 255, 255, 0.08)';
      for (let k=0; k<200; k++) {
        ctx.beginPath();
        ctx.arc(Math.random()*canvas.width, Math.random()*canvas.height, 1+Math.random()*3, 0, 2*Math.PI);
        ctx.fill();
      }
      
      return new THREE.CanvasTexture(canvas);
    }
    
    const planetTexture = createPlanetTexture();
    planetTexture.wrapS = THREE.RepeatWrapping;
    planetTexture.wrapT = THREE.ClampToEdgeWrapping;
    planetTexture.repeat.set(1, 1);
    
    // Matériau principal de la planète (standard avec rugosité et métal)
    const material = new THREE.MeshStandardMaterial({
      map: planetTexture,
      roughness: 0.45,
      metalness: 0.08,
      bumpMap: planetTexture, // réutilisation pour donner du relief
      bumpScale: 0.25,
      emissive: new THREE.Color(0x111133),
      emissiveIntensity: 0.25,
    });
    
    // Géométrie sphérique haute résolution
    const geometry = new THREE.SphereGeometry(1.8, 64, 64);
    const planet = new THREE.Mesh(geometry, material);
    planet.castShadow = true;
    planet.receiveShadow = true;
    planet.position.y = 0.2;
    scene.add(planet);
    
    // --- ATMOSPHÈRE / GLOW (effet moderne) ---
    const atmosGeometry = new THREE.SphereGeometry(1.85, 64, 64);
    const atmosMaterial = new THREE.MeshPhongMaterial({
      color: 0x88aaff,
      transparent: true,
      opacity: 0.12,
      side: THREE.BackSide, // pour effet de halo
    });
    const atmosphere = new THREE.Mesh(atmosGeometry, atmosMaterial);
    atmosphere.position.y = 0.2;
    scene.add(atmosphere);
    
    // Seconde couche plus large et subtile
    const glowGeometry = new THREE.SphereGeometry(1.95, 48, 48);
    const glowMaterial = new THREE.MeshBasicMaterial({
      color: 0x4466aa,
      transparent: true,
      opacity: 0.05,
      side: THREE.BackSide,
    });
    const glow = new THREE.Mesh(glowGeometry, glowMaterial);
    glow.position.y = 0.2;
    scene.add(glow);
    
    // --- ANNEAU STYLISÉ (moderne, discret, tourne aussi) ---
    const ringGeo = new THREE.TorusGeometry(2.6, 0.08, 32, 200);
    const ringMat = new THREE.MeshStandardMaterial({
      color: 0xc0d0ff,
      emissive: new THREE.Color(0x334466),
      emissiveIntensity: 0.3,
      transparent: true,
      opacity: 0.45,
      side: THREE.DoubleSide,
      roughness: 0.5,
      metalness: 0.1
    });
    const ring = new THREE.Mesh(ringGeo, ringMat);
    ring.rotation.x = Math.PI / 2.4;
    ring.rotation.z = 0.3;
    ring.position.y = 0.2;
    scene.add(ring);
    
    // Second anneau plus fin
    const ring2Geo = new THREE.TorusGeometry(2.9, 0.03, 16, 200);
    const ring2Mat = new THREE.MeshStandardMaterial({
      color: 0xaabce0,
      transparent: true,
      opacity: 0.25,
      side: THREE.DoubleSide,
      emissive: new THREE.Color(0x224466),
      emissiveIntensity: 0.2
    });
    const ring2 = new THREE.Mesh(ring2Geo, ring2Mat);
    ring2.rotation.x = Math.PI / 2.2;
    ring2.rotation.z = -0.2;
    ring2.position.y = 0.2;
    scene.add(ring2);
    
    // --- ÉTOILES (particules réactives en arrière-plan) ---
    const starsGeometry = new THREE.BufferGeometry();
    const starsCount = 4000;
    const starsPositions = new Float32Array(starsCount * 3);
    for (let i = 0; i < starsCount * 3; i += 3) {
      // réparties dans une sphère de rayon 50
      const r = 40 + Math.random() * 60;
      const theta = Math.random() * Math.PI * 2;
      const phi = Math.acos((Math.random() * 2) - 1);
      
      starsPositions[i] = Math.sin(phi) * Math.cos(theta) * r;
      starsPositions[i+1] = Math.sin(phi) * Math.sin(theta) * r;
      starsPositions[i+2] = Math.cos(phi) * r;
    }
    starsGeometry.setAttribute('position', new THREE.BufferAttribute(starsPositions, 3));
    
    // Couleurs variables pour étoiles
    const starsColors = new Float32Array(starsCount * 3);
    for (let i = 0; i < starsCount * 3; i+=3) {
      const tint = Math.random();
      if (tint < 0.6) {
        starsColors[i] = 1.0; starsColors[i+1] = 1.0; starsColors[i+2] = 1.0;
      } else if (tint < 0.8) {
        starsColors[i] = 0.9; starsColors[i+1] = 0.85; starsColors[i+2] = 1.0;
      } else {
        starsColors[i] = 1.0; starsColors[i+1] = 0.8; starsColors[i+2] = 0.7;
      }
    }
    starsGeometry.setAttribute('color', new THREE.BufferAttribute(starsColors, 3));
    
    const starsMaterial = new THREE.PointsMaterial({
      size: 0.15,
      vertexColors: true,
      transparent: true,
      blending: THREE.AdditiveBlending,
      depthWrite: false
    });
    const stars = new THREE.Points(starsGeometry, starsMaterial);
    scene.add(stars);
    
    // Petite nébuleuse lointaine (effet de particules supplémentaires)
    const nebulaGeo = new THREE.BufferGeometry();
    const nebulaCount = 800;
    const nebulaPos = new Float32Array(nebulaCount * 3);
    for (let i=0; i<nebulaCount*3; i+=3) {
      const r = 25 + Math.random() * 40;
      const th = Math.random() * Math.PI*2;
      const ph = Math.acos((Math.random()*2)-1);
      nebulaPos[i] = Math.sin(ph)*Math.cos(th)*r;
      nebulaPos[i+1] = Math.sin(ph)*Math.sin(th)*r*0.6;
      nebulaPos[i+2] = Math.cos(ph)*r;
    }
    nebulaGeo.setAttribute('position', new THREE.BufferAttribute(nebulaPos, 3));
    const nebulaMat = new THREE.PointsMaterial({
      color: 0x5577aa,
      size: 0.3,
      transparent: true,
      opacity: 0.25,
      blending: THREE.AdditiveBlending
    });
    const nebula = new THREE.Points(nebulaGeo, nebulaMat);
    scene.add(nebula);
    
    // --- ANIMATION & RÉACTIVITÉ (responsive + rotation continue) ---
    
    // Rotation automatique déjà activée via OrbitControls.autoRotate
    // On fait tourner les anneaux légèrement pour plus de vie
    // Et les étoiles tournent très lentement
    
    // Gestion du redimensionnement (full width / full background)
    window.addEventListener('resize', onWindowResize, false);
    function onWindowResize() {
      camera.aspect = window.innerWidth / window.innerHeight;
      camera.updateProjectionMatrix();
      renderer.setSize(window.innerWidth, window.innerHeight);
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
    }
    
    // Animation loop
    function animate() {
      requestAnimationFrame(animate);
      
      // Rotation propre des anneaux (indépendante de la caméra)
      ring.rotation.y += 0.0008;
      ring2.rotation.y -= 0.0005;
      
      // Rotation lente de l'atmosphère pour un effet vivant
      atmosphere.rotation.y += 0.0003;
      glow.rotation.y += 0.0002;
      
      // Rotation très lente des étoiles pour une ambiance réactive
      stars.rotation.y += 0.0001;
      nebula.rotation.x += 0.00005;
      
      // Mise à jour des contrôles (damping + autoRotate)
      controls.update();
      
      renderer.render(scene, camera);
    }
    
    animate();
    
    // Petite touche : au survol de la planète (interaction réactive via CSS mais on reste moderne)
    // Le curseur change déjà via OrbitControls.
    
    console.log('✨ Planète réactive · full width background · design moderne');
  </script>
</body>
</html>

Ouvrir cet aperçu dans un nouvel onglet du navigateur

🔗 Ouvrir dans le navigateur