Motion Lab / Heroes / three scene / playful
// Mechanisme: hero-three-scene-playful import * as THREE from 'https://esm.sh/[email protected]'; const cv = document.querySelector('.three-canvas-playful'); const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; const wrap = cv.parentElement; const r = new THREE.WebGLRenderer({ canvas: cv, antialias: true, alpha: true }); r.setPixelRatio(Math.min(devicePixelRatio, 2)); r.setSize(wrap.clientWidth, wrap.clientHeight); const sc = new THREE.Scene(); const cam = new THREE.PerspectiveCamera(45, wrap.clientWidth / wrap.clientHeight, 0.1, 100); cam.position.z = 3.6; const torus = new THREE.Mesh( new THREE.TorusKnotGeometry(0.75, 0.26, 80, 10), new THREE.MeshStandardMaterial({ color: 0xFF4A1C, roughness: 0.45, metalness: 0.15, flatShading: true }) ); sc.add(torus); sc.add(new THREE.AmbientLight(0xffffff, 0.55)); const dir = new THREE.DirectionalLight(0xffffff, 1.3); dir.position.set(2, 3, 4); sc.add(dir); function tick(t) { torus.rotation.y += 0.018; torus.rotation.x = Math.sin(t * 0.0014) * 0.5; torus.position.y = Math.sin(t * 0.0028) * 0.22; r.render(sc, cam); if (!reduce) requestAnimationFrame(tick); } requestAnimationFrame(tick);
<!-- Skeleton: hero-three-scene-playful -->
<section class="hero-three">
<div class="hero-three__stage">
<canvas class="three-canvas-playful"></canvas>
<h1>Bring it to life.</h1>
</div>
</section> /* Styling: hero-three-scene-playful */
:root { --block-bg:#0E0B12; --block-fg:#F8F5F0; --block-accent:#FF4A1C; }
.hero-three__stage { position: relative; width: 100%; height: 70vh; background:#0E0B12; }
.three-canvas-playful { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }