Flex 4 Горизонтальный ход по круговой траектории для компонента Color Wheel - PullRequest
0 голосов
/ 17 июня 2011

Я пытаюсь создать компонент цветового круга в Flex 4, который позволит мне представлять данные RGB и HSL. Я делаю это с помощью кругового цветового круга, представляющего различные доступные мне оттенки, и прямоугольного градиента в центре того, что будет представлять поля яркости и насыщенности

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

Вот попытка, которую я сделал до сих пор:

<s:Group>
    <s:Ellipse x="7" y="7" width="136" height="136">
        <s:stroke>
            <s:LinearGradientStroke weight="14">
                <s:GradientEntry ratio="0" color="0xFF0000"/>
                <s:GradientEntry ratio="0.1647" color="0xFFFF00"/>
                <s:GradientEntry ratio="0.3294" color="0x00FF00"/>
                <s:GradientEntry ratio="0.4941" color="0x00FFFF"/>
                <s:GradientEntry ratio="0.6588" color="0x0000FF"/>
                <s:GradientEntry ratio="0.3529" color="0xFF00FF"/>
                <s:GradientEntry ratio="1" color="0xFF0000"/>
            </s:LinearGradientStroke>
        </s:stroke>
    </s:Ellipse>
    <s:Rect x="32" y="32" width="86" height="86">
        <s:fill>
            <s:SolidColor/>
        </s:fill>
    </s:Rect>
</s:Group>

Цвета и их соотношения правильно позиционируют нужный мне градиент слева направо, но конечный результат выглядит так:

http://imageshack.us/photo/my-images/10/flexo.png/

Я бы хотел, чтобы изображение выглядело так: (скриншот из Paint Shop Pro 8)

http://imageshack.us/photo/my-images/687/psph.png/

(извините за ссылки, но у меня пока нет 10 представителей, поэтому я не могу публиковать изображения прямо в посте)

(нет, я еще не построил прямоугольный градиент, поскольку его цвета основаны на внешнем кольце ... Я пока не беспокоюсь о прямоугольнике)

1 Ответ

0 голосов
/ 21 июня 2011

Я наконец-то понял это

Сначала я использовал код Райана Тейлора из BoostWorthy.com, который был приведен в этом уроке: http://www.boostworthy.com/blog/?p=200

Проблема этого урока в том, что цветовые диапазоны не позволяют получить все возможные оттенки, доступные для моего цветового круга оттенков, поскольку он использует синусоидальные волны для вычисления углового цвета. Если вы просмотрите статью в Википедии для Hue, вы увидите, что цветовой спектр - это не синусоида, а простая смесь красного, зеленого и синего. Вот график, который наглядно объясняет, о чем я говорю:

http://en.wikipedia.org/wiki/File:HSV-RGB-comparison.svg

Если вы используете вместо этого синусоидальные волны, максимальные значения волн достигаются только один раз каждые 60 градусов ... когда наклон значения цвета должен быть постоянным в течение каждых 60 градусов (то есть в течение одного периода каждого цвета будет иметь максимальное значение 255 или минимальное значение 0 в течение этого периода)

Это было затронуто в постах урока как проблема с его кодом, но никто не опубликовал решение для него ... Вот фактическое решение:

//Define our variables
var nRadians:Number;
var nColor:int = 0;
var nX:Number;
var nY:Number;
var nIX:Number;
var nIY:Number;     
var nR:Number;
var nG:Number;
var nB:Number;
// Calculate the thickness of the lines which draw the colors.
var iThickness:int = 1 + int(nRadius / 50); 

// Loop from '0' to '360' degrees, drawing lines from the center 
// of the wheel outward the length of the specified radius.
for(var i:int = 0; i < 360; i++)
{
    nRadians = i * (Math.PI / 180);

    var offset:Number = i;
    do 
    {
        offset = offset - 60;
    } while (offset >= 60)

    if (offset < 0) offset = offset + 60;

    var greenSlope:String = "up";
    var redSlope:String = "max";
    var blueSlope:String = "min";

    //GREEN-----------------
    if (i >= 60) greenSlope = "max";
    if (i > 180) greenSlope = "down";
    if (i >= 240) greenSlope = "min";
    //RED-------------------
    if (i > 60) redSlope = "down";
    if (i >= 120) redSlope = "min";
    if (i > 240) redSlope = "up";
    if (i >= 300) redSlope = "max";
    //BLUE------------------
    if (i > 120) blueSlope = "up";
    if (i >= 180) blueSlope = "max";
    if (i > 300) blueSlope = "down";

    var colorArr:Array = new Array(blueSlope,greenSlope,redSlope);
    var valueArr:Array = new Array(nB,nG,nR);
    var counter:int = 0;
    var bitRotation:int = 0;

    for each (var color:String in colorArr)
    {
        var value:Number = 0;
        var percentUpOffset:Number = ((100 / 60) * offset) / 100;
        var percentDownOffset:Number = ((100 / 60) * (60 - offset)) / 100;

        if (color == "max")  value = 255;
        if (color == "min")  value = 0;
        if (color == "up")   value = 255 * percentUpOffset;
        if (color == "down") value = 255 * percentDownOffset;

        valueArr[counter] = value << bitRotation;
        if (i == 0) trace(value);

        bitRotation = bitRotation + 8;  
        counter++;
    }

    nR = valueArr[2];
    nG = valueArr[1];
    nB = valueArr[0];

    // OR the individual color channels together.
    nColor = nR | nG | nB;

    // Calculate the coordinate in which the line should be drawn to.
    // (nIX / nIY is the inner start position of the ring
    nX = (nRadius * Math.cos(nRadians)) + DEFAULT_RADIUS;
    nY = (nRadius * Math.sin(nRadians)) + DEFAULT_RADIUS;
    nIX = ((nRadius - nHeight) * Math.cos(nRadians)) + DEFAULT_RADIUS;
    nIY = ((nRadius - nHeight) * Math.sin(nRadians)) + DEFAULT_RADIUS;

    //Draw the line
    var line:Line = new Line();
    var stroke:SolidColorStroke = new SolidColorStroke(nColor,iThickness);
    line.stroke = stroke;
    line.xFrom = nIX;
    line.xTo = nX;
    line.yFrom = nIY;
    line.yTo = nY;

    this.addElement(line);
}
...