{ CF }

11 CSS Page Transitions

Triangle Shatter

Delaunay-like triangular fragments fill the viewport then explode outward with random velocities and rotations, revealing the next page. Applied to an aerospace deep-tech site.

CSS + JS MIT licensed

Triangle Shatter the 8th of 11 designs in the 11 CSS Page Transitions collection. The design pairs CSS styling with a small amount of JavaScript for interactivity. Copy the HTML, CSS and JavaScript panels below into your project — the JS is self-contained, has zero dependencies, and is safe to drop into any framework (React, Vue, Svelte, plain HTML). The design honours prefers-reduced-motion and uses real semantic markup, so it ships accessibility-ready out of the box.

Live preview

This is a full-page demo — interact inside the frame above, or open it in the playground for the full-screen experience.

Open in playground

The code

<div id="shatterLayer"></div>

<div class="pages">

  <div class="page active" id="p0">
    <canvas id="starCanvas" class="stars"></canvas>
    <div class="orbit-graphic">
      <div class="orbit-ring or-1"></div>
      <div class="orbit-ring or-2"></div>
      <div class="orbit-ring or-3"></div>
      <div class="orbit-ring or-4"></div>
      <div class="orbit-dot od-1"></div>
      <div class="orbit-dot od-2"></div>
      <div class="orbit-dot od-3"></div>
      <div class="planet"></div>
    </div>
    <div class="p0-content">
      <div class="p0-top">
        <div class="logo">APEX<span>.</span>SYS</div>
        <div class="mission-count">MISSION 047 · ACTIVE</div>
      </div>
      <div class="p0-hero">
        <div class="mission-badge">
          <div class="mission-dot"></div>
          <div class="mission-text">Launch window open · T-minus 48:00:00</div>
        </div>
        <h1 class="p0-title">We build<br>for the <span class="blue">void</span></h1>
        <p class="p0-sub">Autonomous systems for environments that humans cannot reach — built to fail safely, adapt quietly, and outlast everything else we send up there.</p>
        <div class="btn-row">
          <button class="btn-primary" data-next="1">Mission Overview</button>
          <button class="btn-ghost" data-next="3">Join the crew</button>
        </div>
      </div>
      <div class="p0-bottom">
        <div class="p0-stats">
          <div class="stat-item"><div class="stat-num">47</div><div class="stat-lbl">Missions</div></div>
          <div class="stat-item"><div class="stat-num">99.1<span style="font-size:14px">%</span></div><div class="stat-lbl">Success rate</div></div>
          <div class="stat-item"><div class="stat-num">4</div><div class="stat-lbl">Orbiting now</div></div>
        </div>
      </div>
    </div>
  </div>

  <div class="page" id="p1">
    <div class="p1-header">
      <h2 class="p1-title">Core<br><span>Systems</span></h2>
      <div class="p1-index">SYS.001 — SYS.006</div>
    </div>
    <div class="tech-grid">
      <div class="tech-card"><div class="tc-icon">⬡</div><div class="tc-label">SYS.001</div><div class="tc-title">Adaptive GNC</div><div class="tc-body">Guidance, navigation & control that rewrites its own mission parameters in-flight based on sensor confidence intervals.</div></div>
      <div class="tech-card"><div class="tc-icon">◈</div><div class="tc-label">SYS.002</div><div class="tc-title">Fault Mesh</div><div class="tc-body">Distributed fault tolerance across 2,048 redundant compute nodes. No single point of failure. Period.</div></div>
      <div class="tech-card"><div class="tc-icon">▲</div><div class="tc-label">SYS.003</div><div class="tc-title">Thermal Skin</div><div class="tc-body">Ceramic-composite outer layers with embedded heat-pipe lattice rated to 1,650°C continuous exposure.</div></div>
      <div class="tech-card"><div class="tc-icon">◇</div><div class="tc-label">SYS.004</div><div class="tc-title">Deep RF</div><div class="tc-body">X-band + Ka-band comms array with 3.2 Gbit/s downlink. Operates from lunar distance without relay.</div></div>
      <div class="tech-card"><div class="tc-icon">⬟</div><div class="tc-label">SYS.005</div><div class="tc-title">Propulsion AI</div><div class="tc-body">Neural burn optimizer trained on 3M simulated flight paths. Reduces delta-v budget by 18% on average.</div></div>
      <div class="tech-card"><div class="tc-icon">⬢</div><div class="tc-label">SYS.006</div><div class="tc-title">Surface Intel</div><div class="tc-body">Multispectral imaging + LIDAR fusion producing real-time 3D terrain maps at 4mm/pixel resolution.</div></div>
    </div>
  </div>

  <div class="page" id="p2">
    <div class="p2-left">
      <div class="p2-eyebrow">// Mission Architecture</div>
      <h2 class="p2-title">Built to<br>outlast<br>certainty</h2>
      <p class="p2-body">Every system assumes its own failure. Every component assumes its redundant twin will fail first. This is how you build hardware for places no one can go to fix it.</p>
      <div class="timeline">
        <div class="tl-item"><div class="tl-dot"></div><div><div class="tl-text">First autonomous landing: Mare Tranquillitatis basin</div><div class="tl-year">2021</div></div></div>
        <div class="tl-item"><div class="tl-dot"></div><div><div class="tl-text">48-hour continuous ops record — no human input</div><div class="tl-year">2022</div></div></div>
        <div class="tl-item"><div class="tl-dot"></div><div><div class="tl-text">Mission 040: first in-situ resource utilisation test</div><div class="tl-year">2024</div></div></div>
        <div class="tl-item"><div class="tl-dot"></div><div><div class="tl-text">Mission 047: deep polar orbit insertion, active now</div><div class="tl-year">2025</div></div></div>
      </div>
    </div>
    <div class="p2-right">
      <div class="p2-glow"></div>
      <div class="data-readout">
        <div style="font-size:8px;letter-spacing:0.25em;text-transform:uppercase;color:var(--electric);margin-bottom:20px;font-family:'Space Mono',monospace">// LIVE · Mission 047</div>
        <div class="dr-row"><span class="dr-key">ALTITUDE</span><span class="dr-val">847.3 km</span></div>
        <div class="dr-row"><span class="dr-key">INCLINATION</span><span class="dr-val">89.7°</span></div>
        <div class="dr-row"><span class="dr-key">VELOCITY</span><span class="dr-val">7.62 km/s</span></div>
        <div class="dr-row"><span class="dr-key">BATTERY</span><span class="dr-val">98.2%</span></div>
        <div class="dr-row"><span class="dr-key">TEMPERATURE</span><span class="dr-val">-112°C</span></div>
        <div class="dr-row"><span class="dr-key">SIGNAL DELAY</span><span class="dr-val">1.28s</span></div>
        <div class="dr-row"><span class="dr-key">FAULT COUNT</span><span class="dr-val" style="color:#40ff80">0</span></div>
        <div class="dr-row"><span class="dr-key">UPTIME</span><span class="dr-val">14d 08h 33m</span></div>
      </div>
    </div>
  </div>

  <div class="page" id="p3">
    <div class="p3-top">
      <h2 class="p3-title">Join the<br>mission</h2>
      <div class="p3-open">8 open roles · Remote + Berlin</div>
    </div>
    <div class="job-list">
      <div class="job-row"><div class="job-cell"><div class="job-title">Principal GNC Engineer</div><div class="job-sub">Guidance & Navigation · Orbital</div></div><div class="job-cell"><div class="job-dept">Engineering</div></div><div class="job-cell"><div class="job-loc">Berlin / Remote</div></div><div class="job-cell"><button class="apply-btn">Apply</button></div></div>
      <div class="job-row"><div class="job-cell"><div class="job-title">ML Engineer — Flight Systems</div><div class="job-sub">Neural burn optimization</div></div><div class="job-cell"><div class="job-dept">AI / ML</div></div><div class="job-cell"><div class="job-loc">Remote</div></div><div class="job-cell"><button class="apply-btn">Apply</button></div></div>
      <div class="job-row"><div class="job-cell"><div class="job-title">Thermal Systems Lead</div><div class="job-sub">Materials & thermal design</div></div><div class="job-cell"><div class="job-dept">Hardware</div></div><div class="job-cell"><div class="job-loc">Berlin</div></div><div class="job-cell"><button class="apply-btn">Apply</button></div></div>
      <div class="job-row"><div class="job-cell"><div class="job-title">Systems Integration Engineer</div><div class="job-sub">Avionics & software</div></div><div class="job-cell"><div class="job-dept">Systems</div></div><div class="job-cell"><div class="job-loc">Berlin</div></div><div class="job-cell"><button class="apply-btn">Apply</button></div></div>
      <div class="job-row"><div class="job-cell"><div class="job-title">Mission Control Operator</div><div class="job-sub">24/7 ops rotation</div></div><div class="job-cell"><div class="job-dept">Operations</div></div><div class="job-cell"><div class="job-loc">Berlin</div></div><div class="job-cell"><button class="apply-btn">Apply</button></div></div>
    </div>
  </div>

</div>

<div class="sys-nav">
  <button class="sys-btn active" data-i="0">Launch</button>
  <button class="sys-btn" data-i="1">Systems</button>
  <button class="sys-btn" data-i="2">Mission</button>
  <button class="sys-btn" data-i="3">Careers</button>
</div>
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
:root{
  --space:#03040a;
  --deep:#070b18;
  --steel:#8090a8;
  --electric:#2060ff;
  --glow:#4080ff;
  --white:#e8eef8;
  --dim:rgba(232,238,248,0.4);
}
html,body{height:100%;overflow:hidden;background:var(--space);font-family:'Space Grotesk',sans-serif;color:var(--white);}

/* Pages */
.pages{position:fixed;inset:0;}
.page{position:absolute;inset:0;pointer-events:none;visibility:hidden;}
.page.active{pointer-events:auto;visibility:visible;}

/* Shatter layer */
#shatterLayer{
  position:fixed;inset:0;z-index:700;pointer-events:none;overflow:hidden;
}

/* PAGE 0 — LAUNCH */
#p0{
  background:var(--space);
  position:relative;overflow:hidden;
}

.stars{position:absolute;inset:0;pointer-events:none;}

.p0-content{
  position:absolute;inset:0;
  display:flex;flex-direction:column;
  justify-content:space-between;
  padding:60px 80px;
}

.p0-top{
  display:flex;align-items:center;justify-content:space-between;
}

.logo{
  font-family:'Space Mono',monospace;
  font-size:13px;letter-spacing:0.08em;
  color:var(--white);font-weight:700;
}
.logo span{color:var(--electric);}

.mission-count{
  font-family:'Space Mono',monospace;
  font-size:9px;letter-spacing:0.2em;color:var(--steel);
}

.p0-hero{
  display:flex;flex-direction:column;
  max-width:820px;
}

.mission-badge{
  display:inline-flex;align-items:center;gap:8px;
  border:1px solid rgba(32,96,255,0.3);
  padding:6px 16px;
  margin-bottom:32px;
  width:fit-content;
}
.mission-dot{
  width:5px;height:5px;border-radius:50%;
  background:var(--electric);
  box-shadow:0 0 8px var(--electric);
  animation:pulse 1.5s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1);}50%{opacity:0.5;transform:scale(0.8);}}
.mission-text{
  font-family:'Space Mono',monospace;
  font-size:8px;letter-spacing:0.25em;color:rgba(32,96,255,0.8);
}

.p0-title{
  font-size:clamp(52px,8.5vw,120px);
  font-weight:700;line-height:0.92;
  letter-spacing:-0.04em;
  color:var(--white);
  margin-bottom:32px;
}
.p0-title .blue{color:var(--electric);}

.p0-sub{
  font-size:16px;line-height:1.65;
  color:var(--dim);font-weight:300;
  max-width:540px;margin-bottom:48px;
  font-family:'Space Mono',monospace;
  letter-spacing:-0.01em;
}

.btn-row{display:flex;gap:16px;}

.btn-primary{
  padding:16px 40px;
  background:var(--electric);color:var(--white);
  border:none;font-family:'Space Grotesk',sans-serif;
  font-size:12px;font-weight:700;letter-spacing:0.12em;text-transform:uppercase;
  cursor:pointer;
  transition:box-shadow .2s,transform .15s;
  box-shadow:0 0 20px rgba(32,96,255,0.3);
}
.btn-primary:hover{box-shadow:0 0 40px rgba(32,96,255,0.6);transform:translateY(-2px);}

.btn-ghost{
  padding:16px 32px;
  background:transparent;color:var(--steel);
  border:1px solid rgba(128,144,168,0.25);
  font-family:'Space Grotesk',sans-serif;
  font-size:12px;letter-spacing:0.1em;text-transform:uppercase;
  cursor:pointer;
  transition:border-color .2s,color .2s;
}
.btn-ghost:hover{border-color:var(--steel);color:var(--white);}

.p0-bottom{
  display:flex;align-items:flex-end;justify-content:space-between;
}

.p0-stats{display:flex;gap:48px;}
.stat-item{display:flex;flex-direction:column;gap:6px;}
.stat-num{
  font-family:'Space Mono',monospace;
  font-size:28px;font-weight:700;
  color:var(--white);
  text-shadow:0 0 20px rgba(32,96,255,0.3);
}
.stat-lbl{
  font-family:'Space Mono',monospace;
  font-size:8px;letter-spacing:0.2em;text-transform:uppercase;color:var(--steel);
}

/* Orbit graphic */
.orbit-graphic{
  position:absolute;right:80px;top:50%;transform:translateY(-50%);
  width:360px;height:360px;
  pointer-events:none;
}
.orbit-ring{
  position:absolute;border-radius:50%;
  border:1px solid rgba(32,96,255,0.12);
}
.or-1{inset:0;}
.or-2{inset:40px;border-color:rgba(32,96,255,0.08);}
.or-3{inset:80px;border-color:rgba(32,96,255,0.06);}
.or-4{inset:120px;border-color:rgba(32,96,255,0.08);}

.orbit-dot{
  position:absolute;width:6px;height:6px;border-radius:50%;
  background:var(--glow);
  box-shadow:0 0 12px var(--glow);
}
.od-1{top:20px;left:50%;transform:translateX(-50%);}
.od-2{bottom:60px;right:40px;}
.od-3{top:50%;left:10px;transform:translateY(-50%);}

.planet{
  position:absolute;inset:130px;border-radius:50%;
  background:radial-gradient(ellipse at 35% 35%,rgba(32,96,255,0.3),rgba(3,4,10,0.8));
  border:1px solid rgba(32,96,255,0.2);
  box-shadow:0 0 40px rgba(32,96,255,0.1),inset 0 0 40px rgba(32,96,255,0.05);
}

/* PAGE 1 — TECHNOLOGY */
#p1{
  background:var(--deep);
  padding:60px 80px;
  display:flex;flex-direction:column;
  overflow-y:auto;
}

.p1-header{
  display:flex;justify-content:space-between;align-items:flex-start;
  margin-bottom:52px;
}

.p1-title{
  font-size:clamp(36px,5.5vw,72px);
  font-weight:700;letter-spacing:-0.04em;line-height:0.95;
}
.p1-title span{color:var(--electric);}

.p1-index{
  font-family:'Space Mono',monospace;
  font-size:9px;letter-spacing:0.2em;color:var(--steel);
  padding-top:8px;
}

.tech-grid{
  display:grid;grid-template-columns:repeat(3,1fr);gap:2px;
  flex:1;
}

.tech-card{
  background:rgba(255,255,255,0.02);
  border:1px solid rgba(128,144,168,0.08);
  padding:32px;
  transition:background .25s,border-color .25s;
  cursor:pointer;
}
.tech-card:hover{background:rgba(32,96,255,0.04);border-color:rgba(32,96,255,0.2);}

.tc-icon{
  width:40px;height:40px;
  border:1px solid rgba(32,96,255,0.3);
  display:flex;align-items:center;justify-content:center;
  margin-bottom:20px;
  color:var(--electric);font-size:18px;
  position:relative;
}
.tc-icon::before{
  content:'';position:absolute;inset:0;
  background:linear-gradient(135deg,rgba(32,96,255,0.1),transparent);
}

.tc-label{
  font-family:'Space Mono',monospace;
  font-size:8px;letter-spacing:0.2em;text-transform:uppercase;
  color:var(--electric);margin-bottom:12px;
}
.tc-title{
  font-size:18px;font-weight:700;letter-spacing:-0.02em;
  margin-bottom:12px;
}
.tc-body{
  font-size:12px;line-height:1.7;color:var(--dim);
  font-family:'Space Mono',monospace;
  letter-spacing:-0.01em;
}

/* PAGE 2 — MISSION */
#p2{
  background:var(--space);
  display:grid;grid-template-columns:1fr 1fr;
  position:relative;overflow:hidden;
}

.p2-left{
  padding:80px;
  display:flex;flex-direction:column;justify-content:center;
  border-right:1px solid rgba(128,144,168,0.06);
}

.p2-eyebrow{
  font-family:'Space Mono',monospace;
  font-size:8px;letter-spacing:0.3em;text-transform:uppercase;
  color:var(--electric);margin-bottom:28px;
}

.p2-title{
  font-size:clamp(40px,6vw,80px);
  font-weight:700;letter-spacing:-0.04em;line-height:0.95;
  margin-bottom:32px;
}

.p2-body{
  font-family:'Space Mono',monospace;
  font-size:12px;line-height:1.8;color:var(--dim);
  margin-bottom:40px;max-width:440px;
  letter-spacing:-0.01em;
}

.timeline{
  display:flex;flex-direction:column;gap:0;
}
.tl-item{
  display:flex;gap:20px;
  padding:20px 0;
  border-bottom:1px solid rgba(128,144,168,0.06);
  position:relative;
}
.tl-item::before{
  content:'';
  position:absolute;left:8px;top:0;bottom:-1px;width:1px;
  background:linear-gradient(180deg,var(--electric),rgba(32,96,255,0));
}
.tl-dot{
  width:17px;height:17px;flex-shrink:0;
  border:1px solid var(--electric);border-radius:50%;
  background:var(--space);
  display:flex;align-items:center;justify-content:center;
  position:relative;z-index:1;
  margin-top:2px;
}
.tl-dot::after{
  content:'';width:5px;height:5px;border-radius:50%;
  background:var(--electric);
  box-shadow:0 0 6px var(--electric);
}
.tl-text{font-size:12px;color:var(--dim);font-family:'Space Mono',monospace;line-height:1.6;}
.tl-year{font-size:9px;color:var(--electric);letter-spacing:0.1em;margin-top:4px;font-weight:700;}

.p2-right{
  background:var(--deep);
  display:flex;flex-direction:column;justify-content:center;align-items:center;
  padding:80px;
  position:relative;
}

.data-readout{
  font-family:'Space Mono',monospace;
  width:100%;max-width:340px;
}
.dr-row{
  display:flex;justify-content:space-between;align-items:center;
  padding:14px 0;
  border-bottom:1px solid rgba(128,144,168,0.08);
  font-size:11px;
}
.dr-key{color:var(--steel);letter-spacing:0.06em;}
.dr-val{color:var(--electric);font-weight:700;}

.p2-glow{
  position:absolute;inset:0;
  background:radial-gradient(ellipse 40% 40% at 50% 50%,rgba(32,96,255,0.04),transparent);
  pointer-events:none;
}

/* PAGE 3 — CAREERS */
#p3{
  background:var(--deep);
  padding:80px;
  overflow-y:auto;
}

.p3-top{
  display:flex;justify-content:space-between;align-items:flex-end;
  margin-bottom:48px;
}

.p3-title{
  font-size:clamp(40px,6vw,80px);
  font-weight:700;letter-spacing:-0.04em;line-height:0.95;
}

.p3-open{
  font-family:'Space Mono',monospace;
  font-size:9px;letter-spacing:0.2em;color:var(--steel);
}

.job-list{display:flex;flex-direction:column;gap:2px;}

.job-row{
  display:grid;
  grid-template-columns:1fr 160px 120px 80px;
  border:1px solid rgba(128,144,168,0.08);
  align-items:center;
  transition:background .2s,border-color .2s;
  cursor:pointer;
}
.job-row:hover{background:rgba(32,96,255,0.04);border-color:rgba(32,96,255,0.2);}

.job-cell{
  padding:24px;
  border-right:1px solid rgba(128,144,168,0.06);
}
.job-cell:last-child{border-right:none;}

.job-title{
  font-size:15px;font-weight:700;letter-spacing:-0.02em;
  margin-bottom:4px;
}
.job-sub{
  font-family:'Space Mono',monospace;
  font-size:9px;color:var(--steel);letter-spacing:0.08em;
}
.job-dept{
  font-family:'Space Mono',monospace;
  font-size:10px;color:var(--electric);letter-spacing:0.1em;
}
.job-loc{
  font-family:'Space Mono',monospace;
  font-size:10px;color:var(--steel);letter-spacing:0.06em;
}
.apply-btn{
  padding:8px 20px;
  background:var(--electric);color:var(--white);border:none;
  font-family:'Space Grotesk',sans-serif;
  font-size:9px;font-weight:700;letter-spacing:0.12em;text-transform:uppercase;
  cursor:pointer;transition:opacity .2s;
}
.apply-btn:hover{opacity:0.8;}

/* Nav */
.sys-nav{
  position:fixed;top:40px;right:60px;z-index:900;
  display:flex;flex-direction:column;gap:6px;
  align-items:flex-end;
}
.sys-btn{
  font-family:'Space Mono',monospace;
  font-size:8px;letter-spacing:0.2em;text-transform:uppercase;
  color:rgba(128,144,168,0.4);
  background:none;border:none;cursor:pointer;
  display:flex;align-items:center;gap:8px;
  transition:color .2s;
  padding:4px 0;
}
.sys-btn::after{
  content:'';width:16px;height:1px;
  background:rgba(128,144,168,0.3);
  transition:width .3s,background .2s;
}
.sys-btn:hover{color:var(--white);}
.sys-btn:hover::after{width:32px;background:var(--white);}
.sys-btn.active{color:var(--electric);}
.sys-btn.active::after{width:32px;background:var(--electric);}

@media(max-width:768px){
  #p0 .orbit-graphic{display:none;}
  #p2{grid-template-columns:1fr;}
  .p2-right{display:none;}
  #p0 .p0-content,#p1,#p2 .p2-left,#p3{padding:40px 24px;}
  .tech-grid{grid-template-columns:1fr;}
  .job-row{grid-template-columns:1fr 100px;}
  .job-dept,.job-loc{display:none;}
  .sys-nav{top:auto;right:20px;bottom:20px;}
  .p0-stats{gap:24px;}
}
// Starfield
const sc=document.getElementById('starCanvas');
sc.width=window.innerWidth;sc.height=window.innerHeight;
const sx=sc.getContext('2d');
for(let i=0;i<200;i++){
  sx.beginPath();
  sx.arc(Math.random()*sc.width,Math.random()*sc.height,Math.random()*1.2,0,Math.PI*2);
  sx.fillStyle=`rgba(232,238,248,${Math.random()*0.5+0.1})`;
  sx.fill();
}

// Shatter transition
const shatterLayer=document.getElementById('shatterLayer');
const pages=document.querySelectorAll('.page');
const navBtns=document.querySelectorAll('.sys-btn');
let cur=0,busy=false;

function genTriangles(W,H,N){
  const pts=[];
  const cols=Math.ceil(Math.sqrt(N*W/H));
  const rows=Math.ceil(N/cols);
  for(let r=0;r<=rows;r++)
    for(let c=0;c<=cols;c++){
      const x=(c/cols)*W+(Math.random()-0.5)*W/cols*0.8;
      const y=(r/rows)*H+(Math.random()-0.5)*H/rows*0.8;
      pts.push([Math.max(0,Math.min(W,x)),Math.max(0,Math.min(H,y))]);
    }
  const tris=[];
  const cx=cols+1;
  for(let r=0;r<rows;r++)
    for(let c=0;c<cols;c++){
      const a=r*cx+c,b=a+1,d=a+cx,e=d+1;
      if(pts[a]&&pts[b]&&pts[d])tris.push([pts[a],pts[b],pts[d]]);
      if(pts[b]&&pts[e]&&pts[d])tris.push([pts[b],pts[e],pts[d]]);
    }
  return tris;
}

function goTo(n){
  if(busy||n===cur)return;
  busy=true;
  const prev=cur;cur=n;
  navBtns.forEach((b,i)=>b.classList.toggle('active',i===cur));

  const W=window.innerWidth,H=window.innerHeight;
  const tris=genTriangles(W,H,60);
  shatterLayer.innerHTML='';

  tris.forEach(tri=>{
    const pts=tri.map(([x,y])=>`${x}px ${y}px`).join(',');
    const frag=document.createElement('div');
    frag.style.cssText=`
      position:absolute;inset:0;
      clip-path:polygon(${pts});
      background:var(--space);
      opacity:0;
      transition:none;
    `;
    shatterLayer.appendChild(frag);
  });

  const allFrags=Array.from(shatterLayer.children);
  const sorted=allFrags.sort(()=>Math.random()-0.5);

  let covered=false;
  sorted.forEach((frag,i)=>{
    setTimeout(()=>{
      frag.style.transition='opacity 80ms';
      frag.style.opacity='1';
      if(i===Math.floor(sorted.length*0.5)&&!covered){
        covered=true;
        pages[prev].classList.remove('active');
        pages[cur].classList.add('active');
        sorted.forEach((f2,j)=>{
          const angle=Math.random()*Math.PI*2;
          const dist=Math.random()*300+100;
          setTimeout(()=>{
            f2.style.transition=`transform 500ms cubic-bezier(0.4,0,1,0.8),opacity 400ms 100ms`;
            f2.style.transform=`translate(${Math.cos(angle)*dist}px,${Math.sin(angle)*dist}px) rotate(${(Math.random()-0.5)*40}deg)`;
            f2.style.opacity='0';
          },j*8);
        });
      }
    },i*12);
  });

  setTimeout(()=>{
    shatterLayer.innerHTML='';
    busy=false;
  },sorted.length*12+650);
}

navBtns.forEach(b=>b.addEventListener('click',()=>goTo(+b.dataset.i)));
document.querySelectorAll('[data-next]').forEach(b=>b.addEventListener('click',()=>goTo(+b.dataset.next)));

let wt=0;
window.addEventListener('wheel',e=>{
  const now=Date.now();if(now-wt<1200)return;wt=now;
  goTo(Math.max(0,Math.min(3,cur+(e.deltaY>0?1:-1))));
},{passive:true});
document.addEventListener('keydown',e=>{
  if(e.key==='ArrowRight')goTo(Math.min(3,cur+1));
  if(e.key==='ArrowLeft')goTo(Math.max(0,cur-1));
});

Search CodeFronts

Loading…