Динамическая анимация изменения оттенка на изображении холста

Я все еще относительно новичок в работе с тегом canvas. Что я сделал до сих пор, так это нарисовал изображение на холсте. Моя цель — создать фальшивую анимацию дня/ночи, которая повторяется многократно.

Я исчерпал довольно много разных способов (фильтры SVG, CSS3 и т. д.) и думаю, что манипулирование пикселями холста — лучший способ в моем случае. Я пытаюсь:

  1. Перебрать все пиксели изображения
  2. Выберите определенную цветовую гамму
  3. Настроить на новый цвет
  4. Обновите холст

Вот код, который у меня есть до сих пор:

function gameLoop(){
        requestAnimationFrame(gameLoop);        

        ////////////////////////////////////////////////////////////////
        // LOOP PIXEL DATA - PIXEL'S RGBA IS STORED IN SEQUENTIAL ARRAYS
        ////////////////////////////////////////////////////////////////
        for(var i=0; i<data.length; i+=4){
            red=data[i+0];
            green=data[i+1];
            blue=data[i+2];
            alpha=data[i+3];

            // GET HUE BY CONVERTING TO HSL
            var hsl=rgbToHsl(red, green, blue);
            var hue=hsl.h*360;

            // CHANGE SET COLORRANGE TO NEW COLORSHIFT
            if(hue>colorRangeStart && hue<colorRangeEnd){
                var newRgb=hslToRgb(hsl.h+colorShift, hsl.s, hsl.l);
                data[i+0]=newRgb.r;
                data[i+1]=newRgb.g;
                data[i+2]=newRgb.b;
                data[i+3]=255;
            };
        };

        // UPDATE CANVAS
        ctx.putImageData(imgData, 0, 0);        
    };

Код работает и выбирает диапазоны оттенков и сдвигает их один раз, но невероятно тормозит. Размеры холста примерно 500x1024.

Мои вопросы:

  1. Можно ли улучшить производительность?
  2. Есть ли лучший способ выполнить заданную анимацию смены оттенка?

Спасибо!


person Aaron    schedule 12.11.2014    source источник


Ответы (1)


Это сложно сделать в режиме реального времени, используя высококачественное преобразование HSL. Было ли это сделано, поэтому я придумал квантовый подход, который позволяет вам делать это в реальном времени.

Вы можете найти решение здесь (под лицензией GPL3.0):
https://github.com/epistemex/FastHSL2RGB

Пример использования можно найти здесь (лицензия MIT), вкл. демо:
https://github.com/epistemex/HueWheel

Извиняюсь за ссылку на мои собственные решения здесь, но внутренняя работа (как сделать) слишком обширна, чтобы представить ее в простой форме здесь, и оба они могут использоваться для чего угодно.

Ключевые моменты в любом случае:

  • Квантизируйте диапазон, который вы хотите использовать (не используйте полные 360 градусов и не используйте плавающие точки для легкости и т. д.)
  • Кэшировать значения в 3D-массиве (первоначальная настройка с использованием веб-воркеров или использование приблизительных значений)
  • Квантуйте входные значения, чтобы они соответствовали диапазону внутреннего трехмерного массива.
  • Обработайте растровое изображение, используя эти значения

Он не точен, но достаточно хорош для анимации (или превью, для чего я его и написал).

Существуют и другие методы, такие как предварительное кэширование полностью обработанного растрового изображения для ключевых позиций, а затем вместо этого интерполяция цветов между ними. Это, конечно, требует гораздо больше памяти, но это быстрый способ.

Надеюсь это поможет!

person Community    schedule 12.11.2014
comment
Спасибо! Это выглядит очень многообещающе — попробуйте прямо сейчас. :D - person Aaron; 12.11.2014
comment
Отличная работа - именно то, что мне было нужно и имеет смысл! Спасибо! - person Aaron; 12.11.2014