Градиент RGB на основе процента загруженного файла

Я работаю над своим первым проектом Flash, и для моего предварительного загрузчика я хотел бы сделать очень простой градиент на основе загруженного процента. Предварительный загрузчик говорит «загружено на 77%...», где число 77 — это динамический текстовый экземпляр с именем «percentLoaded». Я бы хотел, чтобы textColor для процентаLoaded изменялся с градиентом от #000000 до #FFFFFF в оттенках серого.

Поэтому я не могу просто сделать:

percentLoaded.textColor=(currentValue/100)*0xFFFFFF;

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

percentLoaded.text=currentValue.toString();
percentLoaded.textColor=rgb2hex((currentValue/100)*255, (currentValue/100)*255, (currentValue/100)*255);

Где «rgb2hex» — это функция, определенная в классе как таковая:

public function rgb2hex(r:Number, g:Number, b:Number) {
    return '0x'+(r << 16 | g << 8 | b).toString(16).toUpperCase();
}

Однако это не похоже на изменение цвета шрифта. Я импортировал flash.text.TextField и flash.display.MovieClip, но не уверен, что упустил что-то еще. Было бы проще сделать это с конкатенацией строк? Или, может быть, что-то происходит с currentValue/100 и передается как число?

Если интересно, я нашел код для rgb2hex здесь.

Спасибо!


person Rockmaninoff    schedule 21.01.2010    source источник


Ответы (4)


percentLoaded.textColor=(currentValue/100)*0xFFFFFF;

Это близко.

Чтобы получить оттенки серого, вам действительно нужно иметь каждый компонент, но это все равно можно сделать аналогичным вашим способом:

percentLoaded.textColor = uint((currentValue / 100) * 0xFF) * 0x010101;
person LiraNuna    schedule 21.01.2010
comment
Это не работает. попробуйте установить для currentValue значение 1. Вы получите 0x28f5c. вам нужно привести ((currentValue/100) * 0xFF) к int перед умножением на 0x010101. - person Ponkadoodle; 21.01.2010
comment
Правда, я забыл об этом, исправлено; спасибо, что заметили это! На самом деле приведение должно идти по результату деления, потому что это происходит потому, что класс Flash Number является плавающей точкой IEE. Приведение к uint должно решить эту проблему. - person LiraNuna; 21.01.2010
comment
Нет, текущее значение находится в диапазоне 0-100. Если вы произведете преобразование после деления, но до умножения на 0xFF, вы получите 0 или 1. Ему нужны полные оттенки серого, а не только черный/белый. И проблема не возникает из-за неточностей с плавающей запятой. Это потому, что ваш формат (*0x010101) состоит из трех полей (01, 01, 01). Это не ожидание того, что что-то в одной области будет зависеть от другой области. Но использование значения больше 255 позволяет низкому полю влиять на высокое поле, а значение между целыми числами позволяет высокому полю влиять на более низкое. Попробуйте 1.5*0x010101, чтобы понять, что я имею в виду. - person Ponkadoodle; 21.01.2010
comment
Плохо, сегодня слишком много кодил :P - person LiraNuna; 21.01.2010
comment
Спасибо за ответы, всем. Сначала это не сработало, и я не хотел комментировать, потому что не совсем понимал, что происходит. Теперь я это понимаю, и это особенно элегантное решение! РЕДАКТИРОВАТЬ: позже я реализую это в своем коде и отмечу его как ответ, как только буду уверен, что он работает. - person Rockmaninoff; 22.01.2010

Вам повезло, я сделал это совсем недавно в проекте, только с другими цветами. Вот функция, которая возвращает значение цвета между двумя другими цветами в диапазоне от 0 до 1. Я думаю, что код довольно понятен, но дайте мне знать, если у вас возникнут какие-либо проблемы.

private function getBetweenColourByPercent(value:Number = 0.5 /* 0-1 */, highColor:uint = 0xFFFFFF, lowColor:uint = 0x000000):uint {
    var r:uint = highColor >> 16;
    var g:uint = highColor >> 8 & 0xFF;
    var b:uint = highColor & 0xFF;

    r += ((lowColor >> 16) - r) * value;
    g += ((lowColor >> 8 & 0xFF) - g) * value;
    b += ((lowColor & 0xFF) - b) * value;

    return (r << 16 | g << 8 | b);
}

Тайлер.

person Tyler Egeto    schedule 21.01.2010
comment
Спасибо, Тайлер, это действительно может пригодиться в будущем; Например, я мог бы выбрать, чтобы текст предварительного загрузчика менялся между красным и белым. - person Rockmaninoff; 22.01.2010

percentLoaded.textColor = int((currentValue / 100) * 0xFF) * 0x010101;

Приведение к типу int перед умножением на 0x010101 является обязательным. 8-битные значения цвета могут быть только целыми числами от 0 до 255. Если он не находится в этих пределах, умножение на 0x010101 может привести к переполнению чисел из одного цветового компонента (RR,GG,BB) в другой (B->G, G->R). Но они также могут переноситься в другую сторону, если не целое число (R->G, G->B). Я предположил, что currentValue — это любое число от 0 до 100.

Учтите это, с каждой цифрой собственный цветовой компонент (в десятичном виде):

5.0 * 111 = 555 = 5R, 5G, 5B
5.5 * 111 = 610.5 = 6R, 1G, 0.5B
person Ponkadoodle    schedule 21.01.2010

Если это работает для вас

percentLoaded.textColor=(currentValue/100)*0xFFFFFF;

Тогда вы могли бы просто сделать

var percent = currentValue / 100;
percentLoaded.textColor = Math.floor(percent*0xFF) * 0x010101;
person sberry    schedule 21.01.2010
comment
Это не работает. попробуйте установить для currentValue значение 1. Вы получите 0x28f5c. вам нужно привести к int перед умножением на 0x010101. - person Ponkadoodle; 21.01.2010
comment
@wallacoloo: Вы правы, исправлено. - person sberry; 21.01.2010