Screen Shake

화면 흔들림 (스크린 셰이크)

A brief, decaying camera jolt on big impacts — hits, explosions — that sells the sense of physical force.

Also known as: 카메라 셰이크Camera shake트라우마 셰이크
···
html
<div class="ssouter"><div class="ssworld" id="world"><div class="ssgrid"></div><div class="sshero"></div><div class="sstarget" id="tgt"></div></div><div class="ssflash" id="flash"></div></div>
css
.ssouter{position:relative;width:100%;height:100%;overflow:hidden;background:var(--bg);box-shadow:inset 0 0 clamp(20px,8vmin,60px) color-mix(in srgb,var(--fg) 12%,transparent)}
.ssworld{position:absolute;inset:-8%;display:grid;place-items:center}
.ssgrid{position:absolute;inset:0;background-image:linear-gradient(var(--line) 1px,transparent 1px),linear-gradient(90deg,var(--line) 1px,transparent 1px);background-size:13% 13%;opacity:.6}
.sshero{position:absolute;left:34%;top:50%;width:clamp(24px,13vmin,44px);height:clamp(24px,13vmin,44px);margin-top:-22px;border-radius:7px;background:var(--accent);box-shadow:0 6px 14px color-mix(in srgb,var(--accent) 40%,transparent)}
.sstarget{position:absolute;left:62%;top:50%;width:clamp(30px,16vmin,54px);height:clamp(30px,16vmin,54px);margin-top:-27px;border-radius:8px;background:var(--surface);border:3px solid var(--line)}
.ssflash{position:absolute;inset:0;background:var(--fg);opacity:0;pointer-events:none}
js
const world=document.getElementById('world');
const tgt=document.getElementById('tgt');
const flash=document.getElementById('flash');
let trauma=0, t=0;
function loop(){
  t+=1;
  if(trauma>0) trauma=Math.max(0, trauma-0.045);
  const s=trauma*trauma;
  const ox=(Math.sin(t*1.7)+Math.sin(t*3.1+1))*10*s;
  const oy=(Math.sin(t*2.3+2)+Math.sin(t*4.1))*7*s;
  const rot=(Math.sin(t*2.7))*6*s;
  world.style.transform='translate('+ox+'px,'+oy+'px) rotate('+rot+'deg)';
  requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
function hit(){
  trauma=1;
  flash.style.transition='none'; flash.style.opacity='0.5';
  requestAnimationFrame(function(){ flash.style.transition='opacity .3s ease-out'; flash.style.opacity='0'; });
  tgt.style.transition='transform .08s ease-out';
  tgt.style.transform='translateX(10px) scale(0.9)';
  setTimeout(function(){ tgt.style.transform='translateX(0) scale(1)'; }, 100);
}
setInterval(hit, 1300);
setTimeout(hit, 500);

Rather than shaking the camera by a flat random amount, a common technique tracks a "trauma" value from 0 to 1 and makes shake intensity proportional to trauma squared. An impact raises trauma; every frame it decays by a fixed amount, and the current value drives the offset and rotation — harder hits shake harder, and it settles quickly as trauma drains.

Squaring matters because it keeps small hits nearly still while shake ramps up sharply as trauma accumulates — a linear curve leaves a constant low-level jitter that gets annoying. Building the offset from layered sine waves (or Perlin noise) instead of pure randomness makes the shake read as organic rather than jittery.

Shake the screen too hard or too often and UI text becomes unreadable, and it can trigger motion sickness. Capping the maximum offset, and clamping trauma at its ceiling (usually 1) so repeated hits don't stack forever, keeps it usable.

When to use

Reserve it for rare, high-impact moments — big hits, explosions, boss entrances. Shaking on every step or basic attack tires players out fast.