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> | <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