Prerender on canvas 2D

от автора

В попытках оптимизировать 2D анимацию созданную в canvas, был найден один интересный вариант.

hero image

Предварительная визуализация — prerender.

"А что если записать все кадры заранее и показать их после окончания анимации?" — подумали мы с товарищем и вот что получилось на следующий день.

Live demo

amedomary.ru/prerender-canvas

Code v1.0

Сама страница есть на Github.

Логика очень проста и реализуется в 2 шага:

Шаг 1 — Сохраняем каждый кадр нашей анимации в массив изображений

Шаг 1 — javascript код

  function renderLoop() {     draw();      // create prerender images     canvasPrerender.toBlob(blob => {       const reader = new FileReader();       reader.readAsDataURL(blob);        reader.onload = function() {         const image = document.createElement("img");         image.src = reader.result;         prerenderArr.push(image);       };     });      if (prerenderIsCompleted) {       requestAnimationFrame(renderLoop);     } else {       requestAnimationFrame(drawPreImg);     }   }

Шаг 2 — После окончания — рисуем анимацию из уже готовых изображений

Шаг 2 — javascript код

  function drawPreImg() {     ctx.clearRect(0, 0, canvas.width, canvas.height);     ctx.drawImage(prerenderArr[i], 0, 0);      requestAnimationFrame(drawPreImg);   }

Весь код целиком

Analytic

Конкретные значения индивидуальны и зависят от мощности машины. Я тестирую на macbook 13 2019 года.

Давайте посмотрим на код и затраты ресурсов в том числе и временных.

FPS

Fps "до" равен частоте кадров если бы мы запустили анимацию сразу без предварительной отрисовки.

Fps "до" запуска анимации (prerender): 14-22
Fps "после" (сама анимация): 58-60

fps counter

На скриншоте выше используется более сложное изображение, чем в live demo.

Время

Prerender — 9 секунд
Сама анимация — 3 секунды
Общее — 12 секунд (так же на live demo)

CPU / Performance

Как видно из скриншота ниже — наш процессор страдает только на этапе prerender’а. Нарисовать уже готовые изображения не составляет труда.

Производительность — скриншот

performance

Память

Для небольшой анимации как у нас всё это дело занимает:
~ 432 / 2 = 200 кадров
~ 25 мб

performance

Conclusion

Если у вас есть возможность подождать, прежде чем показать анимацию пользователю и она не будет съедать Гигабайты памяти — попробуйте сделать что то подобное.

P.S.

Если у вас есть идеи по повышению производительности данного подхода — пишите 🙂

ссылка на оригинал статьи https://habr.com/ru/post/489602/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *