Динамический цвет без лишних расчетов

10.06.2008, автор Stormit, рубрики: Flash игры, Все остальное

Не совсем о флэш-играх, но хитрость.

Недавно сделал карту для сайта kartablogov.ru. Она отображает плотность распределения блогов по регионам России. По замыслу автора, регионы на карте должны менять цвет в зависимости от количества блогов. Отлично, цвет в дизайне - сильная штука. Здесь он меняется от зеленого до красного и понять где зарегистрировано больше блогов можно даже без наведения мышки.

Собственно, я столкнулся с проблемой, как расчитать программно промежуточный цвет. То есть, 2 крайних значения у меня есть, а все оттенки между ними должны расчитываться.
Закраска делается функцией Color.setRGB() и ей в качестве параметра нужен цвет в виде 0xFFFFFF. Это хорошо, все привыкли к такому формату, но если записать его в переменную, в таком виде он уже не хранится и при трэйсе выдаст 16777215. Чтобы корректно расчитывать оттенки, цвет нужно разложить на составляющие Red, Green и Blue. И потом по пропорции вычислять для каждой составляющей…

Короче, много работы. Я не спорю, это давно кем-то уже написано и можно найти в сети готовый скрипт. Просто есть еще один интересный способ. Его я и предлагаю:

  1. Создаем символ-контейнер (назовем colorSampler).
  2. В нем создаем клип (назовем s) и анимируем его с эффектом Tint из одного цвета в другой (100 кадров). Фишка в том, что заданный “руками” эффект Tint теперь можно считать программно.
  3. Для этого клипа создается объект Color. И теперь, чтобы получить промежуточный цвет, отправляем символ colorSampler в нужный кадр и считываем его с символа s методом Color.getRGB().

В примере ниже строится произвольный график, где цвет столбиков зависит от их высоты. Символ в нижней части как раз и задает цветовой переход.

Преимущество такого способа перед математическим расчетом в создании цветового перехода любой сложности. Добавлением промежуточных кадров с другими оттенками можно и радугу сделать.

Пока писал пост, подумал что еще проще нарисовать градиент (100 пикселов шириной), сделать из него объект BitmapData и считывать цвет методом getPixel(). Будет наглядней.

Интересно на 17%

(14) Хитрых на тему «Динамический цвет без лишних расчетов»

  1. Aleksandr Kozlovskij

    Пять баллов за решение!!! Красиво:)

  2. Designfreak

    Вот и ещё один повод тебя поблагодарить. Я к сожалению не могу оценить глубинную флэш-хитрость решения, но вот то что вышло — было точным отображением того, что снилось мне. А это бывает очень и очень редко.

  3. Stormit

    Спасибо.
    Приятно когда твои работы нравятся другим

  4. Иван Азаров

    Классная идея. Особенно когда требуется нелинейные переходы.
    Для линейных же, имхо, программный расчет проще и + можно потом использовать в других проектах.

  5. Иван Азаров

    Хочу еще добавить, мне очень нравится твой блог именно за нестандартность идей и решений которые здесь описываются. Так держать!

  6. Катенька

    мда… я бы до такого не додумалась…молодец!

  7. Аккостер

    гуд….. очень наглядно!

  8. yzh44yzh

    Да, действительно интересный вариант.
    Но зря ты не стал вникать в программную реализацию. Тут все очень просто:

    var colorNum:Number = 16777215;
    var colorStr:String = colorNum.toString(16);
    trace(colorStr); // 0xFFFFFF

    var colorStr2:String = “FF0000″;
    var colorNum2:Number = parseInt(colorStr2, 16);

  9. chefil

    Вот еще одно программное решение

    nRed, nGreen, nBlue от 0 до 255;

    setcolor=function(my_mc,nRed,nGreen,nBlue){

    var mc = new Color(my_mc);
    mc.setRGB(nRed<<16 | nGreen<<8 | nBlue);

    }// End of the function

  10. Stormit

    Ну это пол дела, нужно еще для составляющих пропорции вычислить и склеить в результат.
    Кажется я такое решение у Мука видел.

  11. yzh44yzh

    Да, совмем забыл — получить цвет из трех составляющих:

    var r:Number = 255;
    var g:Number = 127;
    var b:Number = 31;
    var clr:Number = r << 16 | g <> 16;
    var g:Number = (clr >> 8) & 255;
    var b:Number= clr & 255;

  12. yzh44yzh

    Сорри, опечатка.
    Короче, вот рабочий код:

    public function get ColorRGB():Object
    {
    return {r: this.curColor >> 16, g: (this.curColor >> 8) & 255, b: this.curColor & 255};
    }

    public function set ColorRGB(color:Object):Void
    {
    this.ColorNum = (color.r << 16 | color.g << 8 | color.b);
    }

  13. Stormit

    Ух ты, через сеттеры - это интересно.

  14. hevac

    Прекрасная находка!

Оставить комментарий