Каков наиболее эффективный способ исчезновения пропущенных кадров на холсте при анимации на нем? - PullRequest
0 голосов
/ 27 сентября 2018

Я создаю нечто похожее на визуализатор, используя HTML Canvas.После прорисовки каждого кадра я хотел бы взять текущие данные холста и затемнить их.

Я нашел несколько способов получить этот эффект:

  1. Рисование полупрозрачной рамки цвета фона на всем холсте.На самом деле содержимое не исчезает, поэтому все, что находится за холстом, скрывается.Это достаточно быстро, и тот факт, что это можно сделать, доказывает, что браузеры способны выполнять все необходимые вычисления.

  2. Использование canvas.getImageData (), манипулирование данными изображения, а затем использованиеcanvas.putImageData () для его повторного применения.Делать это супер неэффективно, помещая тонны логики в js.Слишком медленно для любого реального использования.

  3. Использование canvas.toDataUrl () для создания изображения (png / jpg) и использование ctx.globalOpacity для перерисовки этого изображения с некоторой прозрачностью.Шаги, предпринимаемые при преобразовании данных холста в изображение и обратно, очень дороги (сжатие, заголовки и т. Д.).Слишком медленно для любого реального использования.

Как я могу затушевывать свои пропущенные кадры на холсте, анимируя новые кадры поверх?

Я проверил это:

Canvas Fade Out Particles - очень похожая проблема, ответ предлагает неприменимое решение моей проблемы (использование спрайтов и перерисовка всего холста)

FadeIn FadeOut на холсте Html5 - вопрос касается затухания / уменьшения изображения на холсте, а не самого содержимого холста.

РЕДАКТИРОВАТЬ: я думаю, что, возможно, нашел решение: https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing

1 Ответ

0 голосов
/ 27 сентября 2018

Композиция сделала свое дело.Вот этап затухания:

// painter = canvas.getContext("2d")
painter.save();
painter.globalAlpha = 1;
painter.globalCompositeOperation = "destination-in";
const fadeOutAmount = 0.99;
painter.fillStyle = "rgba(0, 0, 0, fadeOutAmount)";
painter.fillRect(0, 0, canvas.width, canvas.height);
painter.restore();

При использовании составного режима «приемник» для рисования фигур новая непрозрачность фигур применяется к фону.

https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing

Пример ( также на CodePen ):

const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
canvas.width = 300;
canvas.height = 300;

ctx.fillStyle = "rgb(250, 0, 0)";
// rectangle is filled with solid red
ctx.fillRect(50, 50, 100, 100);

ctx.globalCompositeOperation = "destination-in";
ctx.fillStyle = "rgba(250, 250, 250, 0.5)";
ctx.fillRect(75, 75, 100, 100);
// after the line above, only the part where the two squares show is overlappped, and it only has the opacity of the latter square.  Doing this many frames in a row fully fades out the background.
ctx.globalCompositeOperation = "source-over"

document.getElementById("test").appendChild(canvas);
<div id="test"></div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...