Motion Lab / Galleries / spline embedded / minimal
// Mechanisme: gallery-spline-embedded-minimal
// Techniek #43 — Spline 3D scene embed via <spline-viewer> web component.
//
// 1) Laad de viewer (eenmalig, met expliciete versie):
// <script type="module" src="https://unpkg.com/@splinetool/viewer@1.9.48/build/spline-viewer.js"></script>
//
// 2) Plaats het element en vul JOUW eigen scene-URL in via het url-attribuut.
// Een Spline scene-URL eindigt doorgaans op .splinecode, bv:
// https://prod.spline.design/<scene-id>/scene.splinecode
// <spline-viewer url="https://prod.spline.design/XXXX/scene.splinecode"></spline-viewer>
//
// 3) Reduced motion: als de bezoeker prefers-reduced-motion: reduce heeft,
// laten we de viewer weg en tonen we de CSS-only fallback (radial-gradient sphere).
//
// 4) Fallback (geen scene-URL): zonder url-attribuut blijft de CSS-radial gradient
// sphere zichtbaar als statische placeholder. Geen JS nodig.
import gsap from 'https://esm.sh/gsap@3.12.5';
const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
const stage = document.querySelector('.spline-stage');
if(stage && !reduce){
gsap.from(stage, {autoAlpha:0, y:24, duration:1.0, ease:'power2.out'});
gsap.from(stage.querySelectorAll('[data-fade]'), {autoAlpha:0, y:12, duration:1.0, ease:'power2.out', stagger:0.06, delay:0.1});
} <!-- Skeleton: gallery-spline-embedded-minimal -->
<!-- Laad viewer eenmalig per pagina: -->
<script type="module" src="https://unpkg.com/@splinetool/viewer@1.9.48/build/spline-viewer.js"></script>
<section class="spline-stage">
<p data-fade>Motion Lab / Galleries / spline embedded / minimal</p>
<div class="spline-frame">
<!-- Vul je eigen scene-URL in (eindigt op .splinecode). Zonder url valt het terug op de CSS sphere. -->
<spline-viewer url=""></spline-viewer>
<div class="spline-fallback" aria-hidden="true"></div>
</div>
<h2 data-fade>Stillness, rendered in three dimensions.</h2>
</section> /* Styling: gallery-spline-embedded-minimal */
:root {
--block-bg: #F4F1EB;
--block-fg: #0A0A0A;
}
.spline-stage{background:var(--block-bg);color:var(--block-fg);}
.spline-frame{position:relative;aspect-ratio:16/10;overflow:hidden;}
.spline-frame spline-viewer{position:absolute;inset:0;width:100%;height:100%;}
.spline-fallback{
position:absolute;inset:0;
background: radial-gradient(circle at 50% 50%, rgba(10,10,10,.55) 0%, rgba(10,10,10,.18) 28%, rgba(10,10,10,0) 55%);
pointer-events:none;
}
@media (prefers-reduced-motion: reduce){
.spline-frame spline-viewer{display:none;}
}