Download index.html from sm08th/bootle: direct link, hf CLI and curl.
- Browser
- Download file 25.1 kB
-
https://huggingface.co/spaces/sm08th/bootle/resolve/main/index.html
- Command line
-
hf download hf://spaces/sm08th/bootle/index.html
-
curl -L -o index.html https://huggingface.co/spaces/sm08th/bootle/resolve/main/index.html
25.1 kB
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Présentation Cinématique de Bouteille 3D</title> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/build/three.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/three@0.132.2/examples/js/loaders/GLTFLoader.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/gsap@3.11.4/dist/gsap.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/gsap@3.11.4/dist/ScrollTrigger.min.js"></script> | |
| <script src="https://cdn.jsdelivr.net/npm/aos@2.3.4/dist/aos.js"></script> | |
| <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Bebas+Neue&display=swap" rel="stylesheet"> | |
| <style> | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Orbitron', sans-serif; | |
| background: linear-gradient(135deg, #0f0c29, #302b63, #24243e); | |
| color: white; | |
| overflow-x: hidden; | |
| position: relative; | |
| } | |
| body::before { | |
| content: ''; | |
| position: absolute; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100%; | |
| background: | |
| radial-gradient(circle at 20% 30%, rgba(255,0,150,0.1) 0%, transparent 30%), | |
| radial-gradient(circle at 80% 70%, rgba(0,200,255,0.1) 0%, transparent 30%); | |
| z-index: 0; | |
| animation: pulse 15s infinite alternate; | |
| } | |
| @keyframes pulse { | |
| 0% { opacity: 0.5; } | |
| 100% { opacity: 1; } | |
| } | |
| #canvas-container { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| height: 100vh; | |
| z-index: 1; | |
| pointer-events: none; | |
| } | |
| .scene { | |
| min-height: 100vh; | |
| width: 100%; | |
| position: relative; | |
| z-index: 2; | |
| display: flex; | |
| flex-direction: column; | |
| justify-content: center; | |
| padding: 0 10%; | |
| opacity: 0; | |
| transition: opacity 0.5s; | |
| } | |
| .scene.active { | |
| opacity: 1; | |
| } | |
| h1 { | |
| font-family: 'Bebas Neue', sans-serif; | |
| font-size: 5rem; | |
| margin-bottom: 2rem; | |
| text-transform: uppercase; | |
| letter-spacing: 3px; | |
| } | |
| p { | |
| font-size: 1.2rem; | |
| max-width: 600px; | |
| line-height: 1.6; | |
| margin-bottom: 2rem; | |
| } | |
| .info-card { | |
| background: rgba(17, 17, 17, 0.8); | |
| border-radius: 10px; | |
| padding: 2rem; | |
| max-width: 400px; | |
| backdrop-filter: blur(10px); | |
| border: 1px solid rgba(255, 255, 255, 0.1); | |
| transform: translateY(50px); | |
| opacity: 0; | |
| transition: all 0.5s; | |
| } | |
| .info-card.visible { | |
| transform: translateY(0); | |
| opacity: 1; | |
| } | |
| .cta-button { | |
| background: linear-gradient(45deg, #ff3366, #ba2650); | |
| color: white; | |
| border: none; | |
| padding: 15px 40px; | |
| font-size: 1.2rem; | |
| border-radius: 30px; | |
| cursor: pointer; | |
| font-family: 'Orbitron', sans-serif; | |
| text-transform: uppercase; | |
| letter-spacing: 2px; | |
| transition: all 0.3s; | |
| margin-top: 2rem; | |
| } | |
| .cta-button:hover { | |
| transform: translateY(-3px); | |
| box-shadow: 0 10px 20px rgba(255, 51, 102, 0.3); | |
| } | |
| /* Header Styles */ | |
| header { | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 100%; | |
| display: flex; | |
| justify-content: space-between; | |
| padding: 1.5rem 2rem; | |
| z-index: 100; | |
| } | |
| .nav-title { | |
| transform: translateX(-100%); | |
| opacity: 0; | |
| transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); | |
| } | |
| .nav-title.visible { | |
| transform: translateX(0); | |
| opacity: 1; | |
| } | |
| .nav-toggle { | |
| display: none; | |
| flex-direction: column; | |
| justify-content: space-between; | |
| width: 30px; | |
| height: 21px; | |
| cursor: pointer; | |
| z-index: 101; | |
| transform: translateX(100%); | |
| opacity: 0; | |
| transition: all 0.5s cubic-bezier(0.68, -0.55, 0.265, 1.55); | |
| } | |
| .nav-toggle.visible { | |
| transform: translateX(0); | |
| opacity: 1; | |
| } | |
| .nav-toggle span { | |
| display: block; | |
| height: 3px; | |
| width: 100%; | |
| background: white; | |
| transition: all 0.3s; | |
| } | |
| .main-nav { | |
| transform: translateX(-100%); | |
| position: fixed; | |
| top: 0; | |
| left: 0; | |
| width: 300px; | |
| height: 100vh; | |
| background: rgba(0, 0, 0, 0.9); | |
| padding: 6rem 2rem; | |
| transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0); | |
| z-index: 99; | |
| } | |
| .main-nav.active { | |
| transform: translateX(0); | |
| } | |
| .nav-title { | |
| font-family: 'Bebas Neue', sans-serif; | |
| font-size: 2rem; | |
| margin-bottom: 2rem; | |
| color: white; | |
| } | |
| .main-nav ul { | |
| list-style: none; | |
| } | |
| .main-nav li { | |
| margin-bottom: 1.5rem; | |
| } | |
| .main-nav a { | |
| color: white; | |
| text-decoration: none; | |
| font-size: 1.2rem; | |
| transition: color 0.3s; | |
| } | |
| .main-nav a:hover { | |
| color: #ff3366; | |
| } | |
| .user-nav { | |
| transform: translateX(100%); | |
| position: fixed; | |
| top: 0; | |
| right: 0; | |
| width: 200px; | |
| height: 100vh; | |
| background: rgba(0, 0, 0, 0.9); | |
| padding: 6rem 2rem; | |
| transition: transform 0.5s cubic-bezier(0.77, 0.2, 0.05, 1.0); | |
| z-index: 99; | |
| } | |
| .user-nav.active { | |
| transform: translateX(0); | |
| } | |
| .user-nav a { | |
| display: block; | |
| color: white; | |
| text-decoration: none; | |
| font-size: 1.2rem; | |
| margin-bottom: 1.5rem; | |
| transition: color 0.3s; | |
| } | |
| .user-nav a:hover { | |
| color: #ff3366; | |
| } | |
| @media (max-width: 768px) { | |
| h1 { | |
| font-size: 3rem; | |
| } | |
| p { | |
| font-size: 1rem; | |
| } | |
| .info-card { | |
| padding: 1.5rem; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <header> | |
| <h2 class="nav-title">Bouteille 3D</h2> | |
| <div class="nav-toggle"> | |
| <span></span> | |
| <span></span> | |
| <span></span> | |
| </div> | |
| <nav class="main-nav"> | |
| <ul> | |
| <li><a href="#">Accueil</a></li> | |
| <li><a href="#">Fonctionnalités</a></li> | |
| <li><a href="#">Technologie</a></li> | |
| <li><a href="#">Contact</a></li> | |
| </ul> | |
| </nav> | |
| <div class="user-nav"> | |
| <a href="#">Connexion</a> | |
| <a href="#">Inscription</a> | |
| </div> | |
| </header> | |
| <div id="canvas-container"></div> | |
| <section class="scene" id="scene1"> | |
| <div class="info-card"> | |
| <h1>L'Élégance Redéfinie</h1> | |
| <p>Découvrez notre nouvelle bouteille révolutionnaire, conçue pour capturer la lumière et l'attention.</p> | |
| </div> | |
| </section> | |
| <section class="scene" id="scene2"> | |
| <div class="info-card"> | |
| <h1>Design Ergonomique</h1> | |
| <p>Une forme étudiée pour un confort inégalé, avec des courbes qui épousent parfaitement votre main.</p> | |
| </div> | |
| </section> | |
| <section class="scene" id="scene3"> | |
| <div class="info-card"> | |
| <h1>Précision Technique</h1> | |
| <p>Chaque détail est pensé pour optimiser l'expérience utilisateur, de l'ouverture à la fermeture.</p> | |
| </div> | |
| </section> | |
| <section class="scene" id="scene4"> | |
| <div class="info-card"> | |
| <h1>Système d'Ouverture</h1> | |
| <p>Notre mécanisme breveté offre une ouverture fluide et sécurisée en un seul geste.</p> | |
| </div> | |
| </section> | |
| <section class="scene" id="scene5"> | |
| <div class="info-card"> | |
| <h1>Technologie Intérieure</h1> | |
| <p>Un système de conservation révolutionnaire maintient la qualité du contenu comme jamais auparavant.</p> | |
| </div> | |
| </section> | |
| <section class="scene" id="scene6"> | |
| <div class="info-card"> | |
| <h1>Disponible Maintenant</h1> | |
| <p>Commandez dès aujourd'hui et faites l'expérience de l'innovation dans votre quotidien.</p> | |
| <button class="cta-button">Découvrir</button> | |
| </div> | |
| </section> | |
| <script> | |
| // Initialisation Three.js | |
| let scene, camera, renderer, bottle, mixer, particles, particlePositions, particleSystem; | |
| const particleCount = 1000; | |
| // Logo position definitions | |
| const logos = { | |
| default: Array(particleCount).fill().map(() => { | |
| const radius = 3 + Math.random() * 2; | |
| const theta = Math.random() * Math.PI * 2; | |
| const phi = Math.random() * Math.PI; | |
| return new THREE.Vector3( | |
| radius * Math.sin(phi) * Math.cos(theta), | |
| radius * Math.cos(phi), | |
| radius * Math.sin(phi) * Math.sin(theta) | |
| ); | |
| }), | |
| logo1: Array(particleCount).fill().map(() => { | |
| // Heart shape | |
| const t = Math.random() * Math.PI * 2; | |
| const x = 2.5 * Math.pow(Math.sin(t), 3); | |
| const y = 2 * Math.cos(t) - 0.8 * Math.cos(2*t) - 0.2 * Math.cos(3*t) - 0.1 * Math.cos(4*t); | |
| const z = (Math.random() - 0.5) * 0.5; | |
| return new THREE.Vector3(x, y, z); | |
| }), | |
| logo2: Array(particleCount).fill().map(() => { | |
| // Spiral | |
| const t = Math.random() * Math.PI * 8; | |
| const r = 0.5 + Math.random() * 0.5; | |
| return new THREE.Vector3( | |
| r * Math.cos(t), | |
| t / 8 - 2, | |
| r * Math.sin(t) | |
| ); | |
| }), | |
| logo3: Array(particleCount).fill().map(() => { | |
| // Sphere | |
| const radius = 2; | |
| const theta = Math.random() * Math.PI * 2; | |
| const phi = Math.random() * Math.PI; | |
| return new THREE.Vector3( | |
| radius * Math.sin(phi) * Math.cos(theta), | |
| radius * Math.cos(phi), | |
| radius * Math.sin(phi) * Math.sin(theta) | |
| ); | |
| }), | |
| logo4: Array(particleCount).fill().map(() => { | |
| // Cube | |
| const size = 2; | |
| return new THREE.Vector3( | |
| (Math.random() - 0.5) * size, | |
| (Math.random() - 0.5) * size, | |
| (Math.random() - 0.5) * size | |
| ); | |
| }), | |
| logo5: Array(particleCount).fill().map(() => { | |
| // Text "3D" | |
| const x = (Math.random() - 0.5) * 4; | |
| const y = (Math.random() - 0.5) * 2; | |
| let z = (Math.random() - 0.5) * 0.5; | |
| if (Math.abs(x) < 1 && Math.abs(y) < 0.8) { | |
| z = (Math.random() - 0.5) * 2; | |
| } | |
| return new THREE.Vector3(x, y, z); | |
| }) | |
| }; | |
| function initThreeJS() { | |
| // Création de la scène | |
| scene = new THREE.Scene(); | |
| scene.background = new THREE.Color(0x000000); | |
| // Create particle system | |
| const particleGeometry = new THREE.BufferGeometry(); | |
| particlePositions = new Float32Array(particleCount * 3); | |
| // Initialize with default positions | |
| for (let i = 0; i < particleCount; i++) { | |
| const pos = logos.default[i]; | |
| particlePositions[i * 3] = pos.x; | |
| particlePositions[i * 3 + 1] = pos.y; | |
| particlePositions[i * 3 + 2] = pos.z; | |
| } | |
| particleGeometry.setAttribute('position', new THREE.BufferAttribute(particlePositions, 3)); | |
| // Create particle material with neon effect | |
| const particleMaterial = new THREE.PointsMaterial({ | |
| color: 0x00ffff, | |
| size: 0.03, | |
| sizeAttenuation: true, | |
| transparent: true, | |
| opacity: 0.9, | |
| blending: THREE.AdditiveBlending, | |
| alphaMap: createStarAlphaMap(), | |
| map: createStarTexture(), | |
| emissive: 0x00ffff, | |
| emissiveIntensity: 1.5, | |
| fog: true | |
| }); | |
| // Create star-shaped texture | |
| function createStarTexture() { | |
| const canvas = document.createElement('canvas'); | |
| canvas.width = canvas.height = 64; | |
| const ctx = canvas.getContext('2d'); | |
| // Draw neon star shape | |
| ctx.beginPath(); | |
| ctx.arc(32, 32, 28, 0, Math.PI * 2); | |
| ctx.fillStyle = 'rgba(0, 255, 255, 0.95)'; | |
| ctx.fill(); | |
| // Add neon glow effect | |
| const gradient = ctx.createRadialGradient(32, 32, 0, 32, 32, 28); | |
| gradient.addColorStop(0, 'rgba(0, 255, 255, 1)'); | |
| gradient.addColorStop(0.5, 'rgba(0, 200, 255, 0.8)'); | |
| gradient.addColorStop(0.8, 'rgba(0, 150, 255, 0.3)'); | |
| gradient.addColorStop(1, 'rgba(0, 100, 255, 0)'); | |
| ctx.fillStyle = gradient; | |
| ctx.fillRect(0, 0, 64, 64); | |
| // Add outer glow | |
| const outerGlow = ctx.createRadialGradient(32, 32, 20, 32, 32, 32); | |
| outerGlow.addColorStop(0, 'rgba(0, 200, 255, 0.5)'); | |
| outerGlow.addColorStop(1, 'rgba(0, 100, 200, 0)'); | |
| ctx.fillStyle = outerGlow; | |
| ctx.fillRect(0, 0, 64, 64); | |
| const texture = new THREE.CanvasTexture(canvas); | |
| return texture; | |
| } | |
| function createStarAlphaMap() { | |
| const canvas = document.createElement('canvas'); | |
| canvas.width = canvas.height = 64; | |
| const ctx = canvas.getContext('2d'); | |
| // Create alpha map for smooth edges | |
| const gradient = ctx.createRadialGradient(32, 32, 0, 32, 32, 24); | |
| gradient.addColorStop(0, 'rgba(255, 255, 255, 1)'); | |
| gradient.addColorStop(1, 'rgba(255, 255, 255, 0)'); | |
| ctx.fillStyle = gradient; | |
| ctx.fillRect(0, 0, 64, 64); | |
| const texture = new THREE.CanvasTexture(canvas); | |
| return texture; | |
| } | |
| // Create particle system | |
| particleSystem = new THREE.Points(particleGeometry, particleMaterial); | |
| scene.add(particleSystem); | |
| // Configuration de la caméra | |
| camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); | |
| camera.position.z = 5; | |
| // Configuration du rendu | |
| renderer = new THREE.WebGLRenderer({ antialias: true }); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| renderer.setPixelRatio(window.devicePixelRatio); | |
| document.getElementById('canvas-container').appendChild(renderer.domElement); | |
| // Ajout de lumières | |
| const ambientLight = new THREE.AmbientLight(0x333333); | |
| scene.add(ambientLight); | |
| const directionalLight = new THREE.DirectionalLight(0xffeecc, 0.4); | |
| directionalLight.position.set(1, 1, 1); | |
| scene.add(directionalLight); | |
| const pointLight = new THREE.PointLight(0x4488ff, 0.8, 15); | |
| pointLight.position.set(2, 2, 2); | |
| scene.add(pointLight); | |
| const fillLight = new THREE.HemisphereLight(0x446688, 0x223344, 0.2); | |
| scene.add(fillLight); | |
| // Création d'une bouteille temporaire (en attendant le modèle GLB) | |
| createTemporaryBottle(); | |
| // Gestion du redimensionnement | |
| window.addEventListener('resize', onWindowResize); | |
| } | |
| function createTemporaryBottle() { | |
| // Géométrie temporaire pour la démo | |
| const geometry = new THREE.CylinderGeometry(0.5, 0.3, 1.5, 64); | |
| const material = new THREE.MeshPhongMaterial({ | |
| color: 0x00ffff, | |
| transparent: true, | |
| opacity: 0.9, | |
| shininess: 100, | |
| specular: 0xffffff, | |
| emissive: 0x006666, | |
| emissiveIntensity: 0.3 | |
| }); | |
| bottle = new THREE.Mesh(geometry, material); | |
| scene.add(bottle); | |
| // Animation du bouchon (sera remplacé par le modèle GLB) | |
| const capGeometry = new THREE.CylinderGeometry(0.2, 0.2, 0.2, 32); | |
| const capMaterial = new THREE.MeshPhongMaterial({ | |
| color: 0xdddddd, | |
| shininess: 30, | |
| specular: 0x222222 | |
| }); | |
| const cap = new THREE.Mesh(capGeometry, capMaterial); | |
| cap.position.y = 0.85; | |
| bottle.add(cap); | |
| } | |
| function onWindowResize() { | |
| camera.aspect = window.innerWidth / window.innerHeight; | |
| camera.updateProjectionMatrix(); | |
| renderer.setSize(window.innerWidth, window.innerHeight); | |
| } | |
| // Animation | |
| function animate() { | |
| requestAnimationFrame(animate); | |
| if (bottle) { | |
| bottle.rotation.y += 0.005; | |
| } | |
| // Rotate particles slowly around Y axis | |
| if (particleSystem) { | |
| particleSystem.rotation.y += 0.001; | |
| } | |
| renderer.render(scene, camera); | |
| } | |
| // Initialisation des animations GSAP | |
| function initAnimations() { | |
| // Configuration des scènes | |
| const scenes = document.querySelectorAll('.scene'); | |
| scenes.forEach((scene, index) => { | |
| ScrollTrigger.create({ | |
| trigger: scene, | |
| start: "top center", | |
| end: "bottom center", | |
| onEnter: () => { | |
| scenes.forEach(s => s.classList.remove('active')); | |
| scene.classList.add('active'); | |
| // Morph particles to current logo shape | |
| const logoKey = `logo${index + 1}`; | |
| if (logos[logoKey] && particleSystem) { | |
| const positions = particleSystem.geometry.attributes.position.array; | |
| const targetPositions = logos[logoKey]; | |
| // Animate each particle to its target position | |
| for (let i = 0; i < particleCount; i++) { | |
| const target = targetPositions[i]; | |
| gsap.to(positions, { | |
| [i * 3]: target.x, | |
| [i * 3 + 1]: target.y, | |
| [i * 3 + 2]: target.z, | |
| duration: 2, | |
| ease: "power2.out", | |
| onUpdate: () => { | |
| particleSystem.geometry.attributes.position.needsUpdate = true; | |
| } | |
| }); | |
| } | |
| } | |
| // Animation spécifique à chaque scène | |
| switch(index) { | |
| case 0: // Apparition | |
| gsap.to(bottle.material, { opacity: 1, duration: 1 }); | |
| gsap.to(camera.position, { z: 5, duration: 1 }); | |
| break; | |
| case 1: // Rotation | |
| gsap.to(bottle.rotation, { y: Math.PI * 2, duration: 5 }); | |
| break; | |
| case 2: // Zoom avant | |
| gsap.to(camera.position, { z: 2, duration: 1 }); | |
| break; | |
| case 3: // Ouverture du bouchon | |
| if (bottle.children.length > 0) { | |
| gsap.to(bottle.children[0].position, { y: 1.2, duration: 0.5 }); | |
| } | |
| break; | |
| case 4: // Vue intérieure | |
| gsap.to(bottle.material, { opacity: 0.5, duration: 0.5 }); | |
| break; | |
| case 5: // Zoom arrière | |
| gsap.to(camera.position, { z: 5, duration: 1 }); | |
| gsap.to(bottle.material, { opacity: 1, duration: 1 }); | |
| if (bottle.children.length > 0) { | |
| gsap.to(bottle.children[0].position, { y: 0.85, duration: 0.5 }); | |
| } | |
| break; | |
| } | |
| }, | |
| onEnterBack: () => { | |
| scenes.forEach(s => s.classList.remove('active')); | |
| scene.classList.add('active'); | |
| } | |
| }); | |
| }); | |
| // Animation des cartes d'information | |
| gsap.utils.toArray('.info-card').forEach((card, i) => { | |
| ScrollTrigger.create({ | |
| trigger: card, | |
| start: "top 80%", | |
| onEnter: () => card.classList.add('visible'), | |
| onLeaveBack: () => card.classList.remove('visible') | |
| }); | |
| }); | |
| } | |
| // Initialisation AOS | |
| function initAOS() { | |
| AOS.init({ | |
| duration: 800, | |
| easing: 'ease-in-out', | |
| once: false, | |
| mirror: true | |
| }); | |
| } | |
| // Gestion du header | |
| document.querySelector('.nav-toggle').addEventListener('click', function() { | |
| this.classList.toggle('active'); | |
| document.querySelector('.main-nav').classList.toggle('active'); | |
| document.querySelector('.user-nav').classList.toggle('active'); | |
| }); | |
| // Initialisation au chargement | |
| window.addEventListener('DOMContentLoaded', () => { | |
| initThreeJS(); | |
| animate(); | |
| initAnimations(); | |
| initAOS(); | |
| // Animation d'apparition du header | |
| setTimeout(() => { | |
| document.querySelector('.nav-title').classList.add('visible'); | |
| document.querySelector('.nav-toggle').classList.add('visible'); | |
| }, 500); | |
| }); | |
| </script> | |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=sm08th/bootle" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> | |
| </html> |