PDA

Просмотр полной версии : Динамическое создание оттенков


Haiat
29.07.2008, 19:41
Добрый вечер!
Есть вертикальное меню состоящие из пунктов меню. Концепция дизайна предусматривает градиент от темно-серого до светло-серого(вертикально сверху-вниз) наложенный на меню. В фотошопе это реализовано просто. Все пункты меню объединены в один слой, и в стилях наложен градиент.

Во флэше как я думаю всё гораздо сложнее))

Задача стоит такая что какое бы оно по высоте не было, верхний цвет у верхнего пункта, нижний цвет у нижнего.

Есть конечно вариант сделать прямоугольник с таким же градиентом, растянуть его под высоту меню. Сделать маску пунктами меню. А потом кнопки сверху сделать невидимыми.
Но согласитесь это грязно и неправильно.

Поэтому я подумал сделать по-другому, зная верхний и нижний цвет, а также количество пунктов меню. Этот цвет разложить на составляющие. Количество какого то цвета разделить на количество пунктов. И просто снова собирать этот цвет для каждого пункта.
Но не совсем понимаю как это реализовать.

Прошу Вас помочь, либо направить на верное русло.

Спасибо

silin
30.07.2008, 00:20
если речь об оттенках серого, то все просто:
var depth:Number = 64;//0..255
var grayColor:Number = depth << 16 | depth << 8 | depth;

Haiat
30.07.2008, 00:52
Спасибо что откликнулись.
Не совсем разбираюсь в битах.
А как это привязать к мувику?и как определит у конкретного цвета, количество серого?или это для каждого цвета?то есть для люього цвета можно прибавить от 0 до 255 серого,так?

Wolsh
30.07.2008, 02:19
Haiat, привет!) Серый цвет, как ты понимаешь, это когда красная, синяя и зеленая составляющие равны. silin дал код, который собирает 16-ричное число из трех одинаковых составляющих. Яркость полученного серого будет зависеть от величины depth, которая может быть в пределах от 0 (черный - rgb 0,0,0) до 255 (белый rgb 255,255,255). Т.е. тебе просто надо для каждого пункта вычислить depth (промежуток от самого темного в градиенте до самого светлого поделить на количество пунктов) и собрать этой формулой цвет для каждого пункта)).
Скажем у тебя самый светлый 200,200,200 а самый темный 100,100,100, и всего 5 пунктов в меню.
Шаг составляет 100/4 = 25. Значит цвета получаем из depth=100, 125, 150, 175, 200

crazyone
30.07.2008, 02:52
Разделяете 255 на количество ваших пунктов меню. Или даже плюс один. Т.е. если у вас 5 пунктов, вам нужно 255/6. И дальше рисуете градиент в каждом из ваших пунктов меню с нужными значениями.

Есть еще такая радость:
Number.prototype.HEXtoRGB = function() {
return {rb:this >> 16, gb:(this >> 8) & 0xff, bb:this & 0xff};
};
Color.prototype.blendRGB = function(c1, c2, t) {
if (arguments.length == 2) {
t = c2;
c2 = this.getRGB();
}
if (t<-1) {
t = -1;
} else if (t>1) {
t = 1;
}
if (t<0) {
t = 1+t;
}
c1 = c1.HEXtoRGB();
c2 = c2.HEXtoRGB();
var ct = (c1.rb+(c2.rb-c1.rb)*t) << 16 | (c1.gb+(c2.gb-c1.gb)*t) << 8 | (c1.bb+(c2.bb-c1.bb)*t);
this.setRGB(ct);
return ct;
};


Теперь у класса Color есть метод blendRGB, который позволяет смешивать два цвета в заданной пропорции.

Дальше просто:

import flash.geom.Matrix;

var topcolor=0xcccccc;
var bottomcolor=0x333333;
var itemarr=Array(btn1,btn2,btn3,btn4,btn5);
c=new Color();
var startcolor=topcolor;
for(var i=0;i<itemarr.length;i++){
endcolor=c.blendRGB(topcolor,bottomcolor,i/(itemarr.length-1));
drawGradient(itemarr[i],startcolor,endcolor);
startcolor=endcolor;
}

function drawGradient(mc,sc,ec){
var bbox=mc.getBounds();
var gmtrx:Matrix=new Matrix();
gmtrx.createGradientBox(bbox["xMax"]-bbox["xMin"],bbox["yMax"]-bbox["yMin"],Math.PI/2);
mc.beginGradientFill("linear",[sc,ec],[100,100],[0,255],gmtrx);
mc.moveTo(bbox["xMin"],bbox["yMin"]);
mc.lineTo(bbox["xMax"],bbox["yMin"]);
mc.lineTo(bbox["xMax"],bbox["yMax"]);
mc.lineTo(bbox["xMin"],bbox["yMax"]);
mc.lineTo(bbox["xMin"],bbox["yMin"]);
mc.endFill();
}


Я не уверен, что вам нужны квадратные кнопки. Хотя и это можно пофиксить.
Удачи вам.

Хотя я бы делал именно тем вариантом, который вы назвали грязным и неправильным.

Wolsh
30.07.2008, 03:42
примерчик