캔버스 기반 배경 이미지

프로그래매틱 방식으로 배경 이미지 애니메이션

배경 이미지에 애니메이션을 적용하는 기본적인 두 가지 방법이 있습니다.

  1. CSS 스프라이트를 사용하여 JS에서 background-position를 업데이트합니다 .
  2. .toDataURL()를 사용한 해킹

첫 번째 방법은 이미지가 미리 있는 경우에 적합하지만, <canvas>와 같이 소스를 프로그래매틱 방식으로 생성해야 하는 경우에는 어떻게 해야 하나요? 1번 문제의 해결 방법은 캔버스에서 .toDataURL()를 사용하고 배경을 생성된 URL로 설정하는 것입니다.

while(1) {
    var url = canvas.toDataURL('image/jpeg');
    el.style.background = 'url(' + url + ')';
}

이 방법에는 두 가지 문제가 있습니다.

  1. data: URL은 결과 이미지에 약 33% 의 크기 오버헤드를 추가합니다.
  2. 많은 양의 DOM 터치 (el.style)

이 두 가지 방법은 모두 비효율적입니다. 항상 부드럽게 작동하는 60fps 웹 앱에는 허용되지 않습니다.

2D 캔버스를 배경으로 사용

배경으로 캔버스 사용 데모
DEMO

캔버스를 배경 소스로 사용할 수 있는 비표준 API가 WebKit에 오래 전부터 있었던 것으로 확인되었습니다. 하지만 안타깝게도 이 기능에 대한 게시된 사양은 없습니다.

먼저 뒤로 탐색 URL을 지정하는 대신 다음을 실행합니다.

.bg {
    background: url(bg.png) no-repeat 50% 50%;
}

-webkit-canvas()를 사용하여 캔버스 컨텍스트에 문자열 식별자를 참조합니다.

.canvas-bg {
    background: -webkit-canvas(animation) no-repeat 50% 50%;
}

다음으로 .getContext()의 특수 버전으로 2D 컨텍스트를 만들어야 합니다.

var ctx = document.getCSSCanvasContext('2d', 'animation', 300, 300);

데이브 하이얏트의 추가 정보:

애니메이션

데모에서 볼 수 있듯이 requestAnimationFrame()를 재사용하여 애니메이션을 구동할 수 있습니다. 이렇게 하면 연결이 완료되면 CSS와 캔버스 요소 간의 연결이 유지되므로 좋습니다. DOM을 조작할 필요가 없습니다.

Chrome에서 데모에 애니메이션이 적용되지 않나요?

Chrome의 현재 안정화 버전 채널 (버전 23)에는 requestAnimationFrame() 애니메이션이 백그라운드를 제대로 업데이트하지 못하도록 하는 crbug.com/161699가 있습니다. 이 문제는 Chrome 25 (현재 Canary)에서 수정되었습니다. 데모도 현재 Safari에서 잘 작동합니다.

실적 이점

여기서는 캔버스에 대해 이야기하고 있습니다. 이제 하드웨어 가속 애니메이션이 완전히 지원됩니다 (적어도 이 기능이 작동하는 브라우저의 경우). 다시 한번 강조하지만 JS에서 DOM을 괴롭힐 필요가 없습니다.

WebGL을 배경으로 사용

잠깐만요. WebGL을 사용하여 CSS 배경을 구동할 수 있다는 뜻인가요? 물론입니다. WebGL은 캔버스의 3D 컨텍스트일 뿐입니다. '2d' 대신 'experimental-webgl'을 바꾸면 됩니다.

var gl = document.getCSSCanvasContext('experimental-webgl', 'animation', 300, 150);

다음은 정점 및 프래그먼트 셰이더를 사용하여 그려진 배경이 있는 div가 포함된 개념 증명입니다. 데모

기타 접근 방식

Mozilla는 오랫동안 -moz-element() (MDN)을 보유하고 있었습니다. 이는 CSS 이미지 값 및 대체 콘텐츠 모듈 4단계 사양의 일부이며 동영상, 캔버스, DOM 콘텐츠 등 임의의 HTML에서 생성된 이미지를 만들 수 있습니다. 그러나 DOM의 스냅샷 이미지에 대한 전체 액세스 권한을 갖는 것은 보안상 문제가 있습니다. 이것이 다른 브라우저에서 이 기능을 채택하지 않은 주된 이유입니다.