GODRICH
#css애니메이션#버튼#로딩#전환효과#스크롤#대시보드#실전ui#디자인트렌드

스티커 효과 9종 — 흰 테두리부터 홀로그램 스윕까지

스티커 효과 아홉 가지 중 하나는 흰 테두리와 그림자만으로 다이컷 스티커처럼 보이게 하고, 하나는 마우스를 올리면 표면 위로 무지개빛이 각도 따라 쓸고 지나가며, 하나는 커서를 따라 살짝 기울어져 진짜 스티커를 만지는 느낌을 냅니다.

어떤 이벤트를 듣는지 늘어놓아 보면 손끝 동작이 갈립니다. 01은 pointerenter·pointerleave와 focus·blur를 함께 들어 커서가 카드에 들고 날 때만 반응하고, 02·06은 진입 판정을 pointerenter 대신 pointermove로 바꿔 커서가 표면 위 어디에 있는지까지 매 프레임 추적하며, 03은 focus·blur 없이 pointermove·pointerleave 두 가지만 들어 색 전환에만 집중하고, 04·05·07·09는 click 하나로 상태를 뒤집으며, 08은 pointerdown·pointermove·pointerup·pointercancel에 keydown까지 더해 아홉 개 중 가장 많은 이벤트를 듣습니다. 스티커를 실제로 만질 때 손끝이 하는 동작(올리기·누르기·끌기·떼기)을 한 편에 모아 서로 비교하도록 순서를 짰습니다.

자동 재생 · 눌러서 해당 항목으로 · 전부 한 zip

아홉 개의 해부 — 계산 한 겹이 어디서 도는가

번호 이름 누적면적 강도_평균 움직인프레임
01 흰 테두리 다이컷 스티커 카드 7.18% 100.8 15/23
02 모서리부터 벗겨지는 스티커 0.11% 71.9 22/23
03 각도 따라 도는 홀로그램 스티커 14.42% 24.9 23/23
04 마스킹 테이프로 붙인 스티커 10.05% 78.3 20/23
05 폴더 탭 모양 스티커 1.11% 127.5 15/23
06 커서를 따라 기울어지는 스티커 5.16% 57.7 23/23
07 랜덤 각도로 흩뿌려진 스티커 무더기 18.39% 101.0 17/23
08 드래그해서 붙이는 스티커 21.61% 128.2 16/23
09 인쇄 절단선이 보이는 스티커 시트 8.43% 72.3 23/23

화면이 가장 많이 바뀌는 항목은 08로, 스티커를 놓을 때마다 격자 전체가 다시 그려져 누적면적이 21.61%까지 오릅니다. 반대로 02는 커서가 모서리 근처에 있을 때만 삼각형 하나가 작게 벗겨져 0.11%로 가장 작습니다. 프레임 사이 픽셀 변화의 세기(강도_평균)는 08이 128.2로 가장 세고 — 05도 127.5로 근접하지만 08 하나만 최고로 꼽습니다 — 03이 24.9로 가장 약한데, 03은 hue·sweep이 부드러운 그라디언트 색 전환이라 그렇고 08은 놓는 순간 그림자와 회전이 한꺼번에 바뀌기 때문입니다. 23개 구간 중 실제로 픽셀이 움직인 구간은 03·06·09가 23/23으로 가장 촘촘하고 — 홀로그램 스윕과 기울기, 절단선 행진이 매 프레임 값을 갱신하기 때문입니다 — 01·05는 15/23으로 가장 뜸한데 진행률이 목표에 도달한 뒤에는 그림자와 탭 너비가 멈춰 있기 때문입니다.

포인터 벡터를 각도로 바꾼다 — 02·03·06

02는 카드 모서리를 기준점으로 삼아 커서까지의 dx·dy를 atan2에 넣어 벗겨지는 방향각을 구하고, 03은 같은 atan2 결과에 이동 속도(px/ms)를 곱해 홀로그램 스윕 각도와 색상 회전 속도를 동시에 정합니다. 06은 atan2 없이 카드 중심 기준 좌표를 -1..1로 정규화한 값에 MAX_TILT 상수를 곱해 rotateX·rotateY 각도를 만드는데, 방향을 구하는 계산식은 다르지만 셋 다 포인터 좌표가 곧 회전이나 그라디언트 각도라는 점이 같습니다. 포인터 좌표계의 정확한 정의는 MDN Pointer_events 문서에 나와 있습니다.

인덱스·씨앗값으로 각도를 만든다 — 04·07

04는 tapeAngle(i)가 인덱스 i에 TAPE_ANGLE_STEP을 곱하고 홀짝 인덱스마다 부호를 뒤집어 두 테이프가 서로 다른 방향으로 기울게 하고, 07은 같은 인덱스 자리에 사인 함수 기반 해시(hash(seed))를 넣어 규칙적인 증가 대신 뒤섞인 듯한 각도를 뽑습니다. 이름에 random이 들어 있지만 07은 Math.random을 전혀 쓰지 않는 결정적 산란이라, 같은 seed면 새로고침해도 늘 같은 배치가 나옵니다.

진행률·경과 시간을 산술식에 넣는다 — 01·09

01은 카드가 들리는 진행률 t(0~1)에 레이어 인덱스 i를 곱해 shadowFor(t)가 5겹의 오프셋·블러·알파를 한 번에 계산하고, 09는 타임스탬프에 MARCH_SPEED를 곱한 값을 점선 마디 길이로 나눈 나머지(모듈로)를 매 프레임 strokeDashoffset에 넣어 절단선이 끊김 없이 도는 것처럼 보이게 합니다. 둘 다 픽셀 좌표를 직접 계산하지 않고, 진행률이나 시간이라는 숫자 하나를 산술식에 통과시켜 그림을 만듭니다.

실측·좌표를 그대로 옮긴다 — 05·08

05는 canvas의 measureText()로 라벨 글자의 실제 폭을 재 그 값을 clip-path의 드러나는 폭으로 바로 옮기고, 08은 포인터가 놓인 좌표를 snap()이 격자 칸 크기로 나눠 반올림해 가장 가까운 칸 중심으로 되돌립니다. 05는 콘텐츠 크기를, 08은 콘텐츠 위치를 실측·반올림해 그대로 되먹인다는 점이 같습니다.

패턴별 코드

01흰 테두리 다이컷 스티커 카드

커서를 올리면(pointerenter) shadowFor(t)가 진행률 t에 맞춰 5겹의 그림자를 offset·blur·alpha 모두 산술로 늘리고, 뗄 때(pointerleave)는 같은 함수가 역방향으로 줄어들며 원래 자리로 돌아갑니다. 포트폴리오 이미지 꾸미기나 SNS 피드형 카드에서 이미지 하나를 실제 스티커처럼 보이게 할 때 씁니다.

  function shadowFor(t) {
    var parts = [];
    for (var i = 1; i <= LIFT_LAYERS; i++) {
      var off = (LAYER_OFFSET * i * t).toFixed(2);
      var blur = (LAYER_BLUR * i * t + 2).toFixed(2);
      var alpha = Math.max(0, LAYER_ALPHA_BASE - LAYER_ALPHA_STEP * i) * t;
      parts.push('0 ' + off + 'px ' + blur + 'px rgba(10,8,14,' + alpha.toFixed(3) + ')');
    }
    return parts.join(', ');
  }
흰 테두리 다이컷 스티커 카드
새 창에서 열기

01 · 흰 테두리 다이컷 스티커 카드 — 측정 누적면적 7.179% · 움직인 프레임 15/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

box-shadowclip-pathpointerenter

02모서리부터 벗겨지는 스티커

카드 위에서 커서를 움직이면(pointermove) 모서리 기준점까지의 거리와 각도를 hypot·atan2로 구해 가까울수록 크게 벗겨지는 삼각형을 clip-path로 그립니다(133의 홀로그램 배지 필+스윕 조합과 다른 시연 — 여긴 벗겨지는 각도 자체가 커서 위치를 따라간다). 쿠폰·배지 카드를 강조하거나 갤러리 썸네일에 호기심을 주는 용도에 맞습니다.

  function applyFromPoint(px, py) {
    var r = card.getBoundingClientRect();
    var pivotX = r.right, pivotY = r.top;
    var dx = pivotX - px, dy = py - pivotY;
    var distance = Math.hypot(dx, dy);
    var amt = Math.max(0, Math.min(1, 1 - distance / PEEL_REACH));
    targetSize = amt * PEEL_CORNER_SIZE;
    targetDeg = (Math.atan2(dy, dx) * 180 / Math.PI + 360) % 360;
  }
모서리부터 벗겨지는 스티커
새 창에서 열기

02 · 모서리부터 벗겨지는 스티커 — 측정 누적면적 0.108% · 움직인 프레임 22/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

clip-pathatan2pointermove

03각도 따라 도는 홀로그램 스티커

커서가 표면 위를 지나가는 속도(px/ms)를 재 그 값에 비례해 무지개 빛의 색상(hue)과 스윕 위치를 동시에 돌리고, 이동 방향은 atan2로 구해 스윕이 흐르는 기준각을 정합니다(133의 정적 카드·배지 홀로그램 세트와 다른 시연 — 여긴 포인터 이동량이 빛의 이동 속도를 직접 정한다). conic-gradient로 그린 무지개 막은 mix-blend-mode:color-dodge로 아래 카드 색과 섞여 실제 홀로그램 필름처럼 밝은 부분만 더 밝게 도드라지고, 한정판 카드나 홀로그램 스티커 느낌의 굿즈 목업 미리보기에서 손에 들고 기울이는 인상을 낼 때 씁니다.

  function applyMove(x, y, now) {
    if (lastX !== null) {
      var dt = Math.max(now - lastTime, 1);
      var dx = x - lastX, dy = y - lastY;
      var speed = Math.hypot(dx, dy) / dt; // px/ms
      hue = (hue + speed * HUE_SPEED * (dt / 1000)) % 360;
      sweepPos = (sweepPos + speed * SWEEP_SPEED * (dt / 1000)) % 200;
      sweepAngleTarget = 90 + (Math.atan2(dy, dx) * 180 / Math.PI) % HOLO_SWEEP_ANGLE_RANGE;
    }
    lastX = x; lastY = y; lastTime = now;
  }
각도 따라 도는 홀로그램 스티커
새 창에서 열기

03 · 각도 따라 도는 홀로그램 스티커 — 측정 누적면적 14.422% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

conic-gradientmix-blend-modeatan2

04마스킹 테이프로 붙인 스티커

클릭할 때마다(click) tapeAngle(i)가 인덱스에 상수를 곱해 두 테이프 조각의 기울기를 정하고, 떼는 동안에는 그중 하나가 TAPE_STRETCH만큼 더 기울어지며 스크랩북 페이지를 손으로 뜯는 듯한 순간을 만듭니다. 다이어리나 무드보드 스타일 섹션에서 카드가 손으로 고정된 느낌을 낼 때 맞습니다.

  function tapeAngle(i) {
    var sign = i % 2 === 0 ? -1 : 1;
    return sign * (TAPE_BASE_ANGLE + TAPE_ANGLE_STEP * i);
  }
  var baseAngleA = tapeAngle(1);
  var baseAngleB = tapeAngle(2);
  tapeB.style.transform = 'rotate(' + baseAngleB + 'deg)';

  var target = 0; // 0 = 붙어 있음, 1 = 한쪽이 떼어짐
  var shown = 0;
  var pinned = true;
마스킹 테이프로 붙인 스티커
새 창에서 열기

04 · 마스킹 테이프로 붙인 스티커 — 측정 누적면적 10.047% · 움직인 프레임 20/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

box-shadowtransform-originrequestAnimationFrame

05폴더 탭 모양 스티커

라벨을 클릭하면(click) measureWidth()가 canvas로 그 글자의 실제 폭을 재 탭이 딱 그 크기로 넓어지도록 clip-path의 드러나는 폭을 옮기고, 상자 크기 자체는 레이아웃 재계산 없이 최대치로 고정해 둡니다. 카테고리 태그나 파일함 UI 장식에서 이름표 길이가 저마다 다른 탭을 만들 때 씁니다.

  // 라벨 글자 폭을 canvas 로 실측해 탭이 그 글자에 딱 맞는 폭을 갖게 한다 — 폭은 미리 정한 값이
  // 아니라 매번 실제로 잰 값이다. 실제 상자 너비(width)는 최대치로 고정해 두고 clip-path 로만
  // 드러내는 폭을 바꿔 레이아웃 재계산 없이(transform·opacity 규칙과 같은 취지) 늘고 준다.
  function measureWidth(text) {
    ctx.font = '600 13px -apple-system, "Segoe UI", "Noto Sans KR", sans-serif';
    var w = ctx.measureText(text).width;
    return Math.max(TAB_MIN, Math.min(TAB_MAX, w + TAB_PADDING));
  }
폴더 탭 모양 스티커
새 창에서 열기

05 · 폴더 탭 모양 스티커 — 측정 누적면적 1.111% · 움직인 프레임 15/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

clip-pathmeasureText--tab-w

06커서를 따라 기울어지는 스티커

포인터가 카드 위 어디에 있는지를 중심 기준 -1..1로 정규화해 rotateX·rotateY 각도로 바꾸고, 표면 위 하이라이트도 같은 좌표를 따라 이동해 두께가 있는 것처럼 보입니다. 제품 카드나 굿즈 프리뷰에서 입체감을 주고 싶을 때 맞습니다.

  // 포인터 좌표를 카드 중심 기준 -1..1 로 정규화한 뒤 그 값에 MAX_TILT 를 곱해 회전각을 얻는다.
  // 세로 이동은 rotateX 를, 가로 이동은 rotateY 를 반대 부호로 결정한다(위로 밀면 뒤로 젖혀짐).
  function applyFromPoint(px, py) {
    var rect = zone.getBoundingClientRect();
    var nx = ((px - rect.left) / rect.width) * 2 - 1;
    var ny = ((py - rect.top) / rect.height) * 2 - 1;
    nx = Math.max(-1, Math.min(1, nx));
    ny = Math.max(-1, Math.min(1, ny));
    targetRY = nx * MAX_TILT;
    targetRX = -ny * MAX_TILT;
    targetGX = 50 + nx * GLARE_RANGE;
    targetGY = 50 + ny * GLARE_RANGE;
  }
커서를 따라 기울어지는 스티커
새 창에서 열기

06 · 커서를 따라 기울어지는 스티커 — 측정 누적면적 5.158% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

rotateXrotateYperspective

07랜덤 각도로 흩뿌려진 스티커 무더기

클릭하면(click) hash(seed)가 사인 함수로 0~1 사이 소수부를 뽑아 회전각과 위치 오프셋을 정하는데, 이름에 random이 있어도 Math.random은 전혀 쓰지 않는 결정적 산란이라 같은 seed에서는 새로고침해도 항상 같은 배치가 나옵니다. 노트북 스티커 무드보드나 랜딩 히어로 장식에서 흩어진 듯하지만 재현 가능한 배치가 필요할 때 씁니다.

  // deterministic scatter (seeded, no Math.random) — 사인 해시로 씨앗값 하나에서 항상 같은
  // 소수부를 뽑는다. seed 가 같으면 언제 호출해도 같은 결과가 나오는 결정적 함수다.
  function hash(seed) {
    var v = Math.sin(seed * 12.9898 + 78.233) * 43758.5453;
    return v - Math.floor(v);
  }

  function layoutFor(seed) {
    var h1 = hash(seed);
    var h2 = hash(seed + 100);
    var h3 = hash(seed + 200);
    return {
      rot: (h1 * 2 - 1) * SCATTER_ROTATE_RANGE,
      dx: (h2 * 2 - 1) * SCATTER_POS_RANGE,
      dy: (h3 * 2 - 1) * SCATTER_POS_RANGE
    };
  }
랜덤 각도로 흩뿌려진 스티커 무더기
새 창에서 열기

07 · 랜덤 각도로 흩뿌려진 스티커 무더기 — 측정 누적면적 18.395% · 움직인 프레임 17/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

Math.sinbox-shadowrequestAnimationFrame

08드래그해서 붙이는 스티커

스티커를 누르면(pointerdown) setPointerCapture()로 포인터를 붙잡고, 움직이는 동안(pointermove) 좌표를 계속 추적하다 놓으면(pointerup) snap()이 그 좌표를 가장 가까운 격자 칸 중심으로 반올림해 그 자리에 고정합니다. 커스텀 무드보드 메이커나 꾸미기 위젯에서 자유롭게 배치하되 자리는 깔끔하게 정렬하고 싶을 때 맞습니다.

  function snap(px, py) {
    var col = Math.max(0, Math.min(1, Math.round((px - GRID / 2) / GRID)));
    var row = Math.max(0, Math.min(1, Math.round((py - GRID / 2) / GRID)));
    return { x: col * GRID + GRID / 2, y: row * GRID + GRID / 2 };
  }

  chip.addEventListener('pointerdown', function (e) {
    human();
    dragging = true;
    chip.setPointerCapture(e.pointerId);
  });
  chip.addEventListener('pointermove', function (e) {
    if (!dragging) return;
    var rect = board.getBoundingClientRect();
    var px = Math.max(0, Math.min(BOARD_W, e.clientX - rect.left));
    var py = Math.max(0, Math.min(BOARD_H, e.clientY - rect.top));
    target = snap(px, py);
  });
드래그해서 붙이는 스티커
새 창에서 열기

08 · 드래그해서 붙이는 스티커 — 측정 누적면적 21.61% · 움직인 프레임 16/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

setPointerCapturetouch-actionMath.round

09인쇄 절단선이 보이는 스티커 시트

낱장을 클릭하면(click) aria-pressed가 바뀌며 그 스티커만 살짝 앞으로 떨어져 나오고, 격자 전체에 그려진 점선은 타임스탬프에 MARCH_SPEED를 곱한 값을 strokeDashoffset에 모듈로 연산으로 되먹여 끊김 없이 행진합니다. 스티커 팩 랜딩이나 다운로드 미리보기에서 인쇄 절단선 자체를 시각적 장치로 쓰고 싶을 때 맞습니다.

  // 점선 마디 길이(PATTERN)에 대해 경과 시간을 곱한 오프셋을 모듈로 연산으로 되감아, 끊김 없이
  // 도는 재단선(stroke-dashoffset)을 만든다 — 실제 인쇄 재단선의 "개미 행진" 표시와 같은 계산.
  function loop(ts) {
    if (!last) last = ts;
    last = ts;
    if (isDemo && !reduce) autoAdvance(ts);
    if (!reduce) {
      var offset = (ts * MARCH_SPEED / 1000) % PATTERN;
      rects.forEach(function (r) { r.style.strokeDashoffset = (-offset).toFixed(2); });
    }
    requestAnimationFrame(loop);
  }
인쇄 절단선이 보이는 스티커 시트
새 창에서 열기

09 · 인쇄 절단선이 보이는 스티커 시트 — 측정 누적면적 8.425% · 움직인 프레임 23/23GODRICH 원작 · zip 에 SCSS·React 포함 · 비밀번호 보기

strokeDasharraystrokeDashoffsetaria-pressed

값이 UI를 바꾸는 곳 — 각도·크기·타이밍·순서

모바일 화면처럼 폭이 좁아지면 스티커 애니메이션 상수 하나가 전체 인상을 바꿉니다. 01은 LIFT_LAYERS와 LAYER_OFFSET이 그림자가 몇 겹까지 얼마나 멀리 퍼지는지를, 02는 PEEL_CORNER_SIZE가 최대로 벗겨졌을 때 드러나는 삼각형의 크기를, 03은 HOLO_SWEEP_ANGLE_RANGE가 스윕이 흐르는 기준각의 폭을, 04는 TAPE_ANGLE_STEP이 두 테이프 사이 기울기 차이를, 05는 TAB_MIN·TAB_MAX가 탭이 줄어들고 늘어나는 한계를, 06은 MAX_TILT가 최대로 기울어지는 각도를, 07은 SCATTER_ROTATE_RANGE가 스티커 무더기의 흩어진 정도를, 08은 GRID가 격자 칸의 크기를, 09는 MARCH_SPEED가 점선이 도는 속도를 그대로 결정합니다.

이웃 가지

모서리를 파고들어 각도를 계산하는 방식은 CSS 홀로그램 카드 효과 9가지 — 스티커·뱃지·티켓의 정적 카드·배지 세트와 이 편의 02·03이 같은 재질(홀로그램·벗겨짐)을 다루지만, 그 편은 카드 자체가 고정된 배지·티켓 형태인 반면 이 편은 커서 위치와 속도가 각도·색상을 직접 구동한다는 점이 갈립니다. 캐릭터 일러스트가 아니라 스티커라는 오브제 자체의 재질과 움직임에 집중하는 접근은 귀여운 캐릭터 애니메이션 9종 — 일러스트 캐릭터 CSS 모음과 대비되고, 종이 질감으로 오려 붙인 레이아웃을 만드는 발상은 종이 질감 디자인 랜딩 키트, 오려 붙인 섹션 9개의 섹션 단위 오려내기와 이 편의 04·09가 조각 하나를 오려 붙이거나 잘라낸다는 점에서 이어지지만, 이 편은 시트 전체가 아니라 스티커 한 장 단위로 동작합니다.

어디서 깨지는가 — 접근성·reduced-motion·키보드

아홉 개를 실제 프로젝트에 그대로 붙여 확인하고 싶다면 다운로드 zip 비밀번호 dkbn5f83 로 vanilla·react 코드와 prompt.md를 함께 풀어볼 수 있습니다.

06의 applyFromPoint 함수는 포인터가 움직일 때마다 zone 요소의 위치와 크기를 새로 조회해 좌표를 정규화합니다. 이 계산이 성립하려면 rotateX·rotateY 회전은 반드시 바깥쪽 zone이 아니라 안쪽 card에만 걸려 있어야 합니다 — 회전을 zone 자체에 걸면 다음 조회 때 회전이 반영된 크기값이 돌아와 nx·ny 계산이 프레임마다 어긋나고, 기울기가 한 값에 안정되지 못한 채 떨립니다.

reduced-motion 아래 남는 것

아홉 항목 모두 .is-demo가 붙어 있고 prefers-reduced-motion:reduce가 아닐 때만 자동 시연(autoAdvance)이 돌며, 처음 상호작용하는 순간 human()이 .is-demo를 떼어 자동 재생을 끕니다. reduce일 때는 아홉 개 전부 LERP_RATE 보간을 건너뛰고 목표값으로 즉시 스냅하는데, 03은 한발 더 나아가 hue·sweepPos 값 자체를 0으로 고정해 색상 회전을 멈추고, 09는 strokeDashoffset 갱신 자체를 멈춰 절단선이 도는 것을 완전히 끕니다. 아홉 개 style.scss 모두 reduced-motion 블록에서 트리거 요소의 transition을 별도로 꺼둡니다.

키보드·스크린리더로 확인할 것

01·02·03·06·08은 각각 aria-label로 무엇이 어떻게 움직이는지 문장으로 설명해 스크린리더가 시각 효과 없이도 상태를 알 수 있게 하고, 04는 버튼 텍스트("테이프 한쪽 떼기")가 접근성 이름을 대신하며 aria-pressed로 지금 떼어졌는지를, 09는 각 낱장에 붙은 aria-label과 aria-pressed로 몇 번째 스티커가 오려졌는지를 함께 전달합니다. 08은 pointerdown·move·up 드래그와 별개로 화살표 키(keydown)가 같은 target 좌표를 직접 정해, 마우스 없이도 네 칸 격자 전체를 오갈 수 있습니다.

변형 세 가지와 접근성

이름 값 느낌
홀로그램 스윕 각도 범위 넓히기 03 HOLO_SWEEP_ANGLE_RANGE 45deg → 90deg 빛줄기가 흐르는 기준각이 넓어져, 포인터를 살짝만 움직여도 스윕이 대각선을 크게 가로지르며 방향이 확 꺾인다 — 45deg 대비 반응이 과장돼 보인다
벗겨지는 모서리 크기 키우기 02 PEEL_CORNER_SIZE 24px → 44px 최대로 벗겨졌을 때 드러나는 삼각형이 거의 두 배로 커져, 숨어 있던 뒷면 색이 코너 장식이 아니라 카드 내용의 일부처럼 눈에 띈다 — 은은한 힌트에서 뚜렷한 폭로로 바뀐다
랜덤 스캐터 각도 폭 줄이기 07 SCATTER_ROTATE_RANGE 30deg → 10deg 같은 해시값이라도 회전 폭이 좁아져 스티커들이 거의 나란히 놓인 것처럼 정돈돼 보인다 — 아무렇게나 던져둔 무더기에서 살짝만 어긋난 진열대 느낌으로 바뀐다

세 변형 모두 값만 바뀔 뿐 aria-label·aria-pressed 같은 접근성 속성은 그대로 남아, 03의 스윕 각도가 넓어지거나 02의 벗겨지는 삼각형이 커지거나 07의 회전 폭이 좁아져도 스크린리더가 읽는 정보는 달라지지 않습니다.

FAQ

이 스티커 디자인들은 실제 이미지 없이 그림만 CSS로 그린 건가요?

네, 아홉 개 전부 외부 이미지나 브랜드 로고 없이 SVG·CSS 도형만으로 그렸기 때문에 <img> 태그나 원격 이미지 주소가 하나도 없습니다.

애니메이션 캐릭터 스티커처럼 그림 자체를 바꿔서 써도 되나요?

네, 아홉 개 모두 흰 테두리·클립패스·홀로그램 같은 효과가 감싸는 방식이라 안쪽 도형만 원하는 그림으로 바꾸면 되고, 회전·벗겨짐·타이밍을 계산하는 JS는 손댈 필요가 없습니다.

드래그해서 붙이는 스티커는 터치 기기에서도 되나요?

네, pointerdown·pointermove·pointerup·pointercancel은 마우스·펜·터치를 하나로 묶는 Pointer Events라 그대로 동작하고, touch-action:none을 걸어 두어 드래그 중에 화면이 함께 스크롤되는 충돌도 막아 둡니다.

압축 비밀번호를 입력하세요

비밀번호는 이 글 본문 안에 있습니다. 읽다 보면 나옵니다.