颜色从蓝色跳到紫罗兰

时间:2014-11-04 15:23:37

标签: javascript math colors

我正在实施彩色屏幕保护程序。有一个颜色范围和一个滑块。

颜色在(HSB)。有6种颜色。

blue (230, S,B)
green (130, S,B)
yellow (55, S,B)
orange (40, S,B)
red (0(or 360), S,B)
violette (315, S,B)

滑块值从0到14.9

blue 0 - 2.9 green
green 3 - 5.9 yellow
yellow 6 - 8.9 orange
orange 9 - 11.9 red
red 12 - 14.9 violette

如果使用滑块值并且旧的slidervalue和新滑块值之间的差值小于2.9,则实际色调将通过减去0.5来改变。

现在如果差异大于2.9那么必须有一个跳跃。这样可以正常工作,直到滑块值小于12.在值12处,颜色从0变为360,我的代码不再起作用。

// this works fine
if (lastSlide < 12) {
            // jump statement
            if (Math.abs(Math.round(top.fillColor.hue - value)) > 41){
                var fillColor = Math.round((Math.abs((value-top.fillColor.hue))/1.05) + Math.min(value, Math.round(top.fillColor.hue)));
                if (fillColor < 0) fillColor = adjustValue(fillColor);
                top.fillColor.hue = fillColor;
            }
            else if (Math.abs(Math.round(top.fillColor.hue - value)) < 41 && top.counter_dsg < 20){
                top.fillColor.hue-= 0.5; 
                top.counter_dsg+=0.5;
            }
            else if (Math.abs(Math.round(top.fillColor.hue - setValue())) < 41 && top.counter_dsg > 19){
                top.fillColor.hue+= 0.5; 
                top.counter_dsg+=0.5;
            }
            else top.fillColor.hue -= 0.5;
            if (top.counter_dsg > 39) top.counter_dsg = 0;
        }
// this not
else {
    // jump statement
    if (Math.abs(Math.round(top.fillColor.hue - value)) > 41){
        var fillColor = Math.round((Math.abs((value-top.fillColor.hue))/1.05) - Math.min(value, Math.round(top.fillColor.hue)));
        if (fillColor < 0) fillColor = adjustValue(fillColor);
        top.fillColor.hue = fillColor;
    }
    else if (Math.abs(Math.round(value - top.fillColor.hue)) < 41 && top.counter_dsg < 20){
        top.fillColor.hue-= 0.5;
        top.counter_dsg+=0.5;
    }
    else if (Math.abs(Math.round(value - top.fillColor.hue)) < 41 && top.counter_dsg > 19){
        top.fillColor.hue+= 0.5; 
        top.counter_dsg+=0.5;
    }
    else top.fillColor.hue -= 0.5;
    if (top.counter_dsg > 39) top.counter_dsg = 0;
}

编辑:

好吧,让我们说屏幕上有一个画布,我想用滑块改变画布的颜色。如果未使用滑块,则画布的实际颜色为swining(+ 10hue,-10hue)。

例如

画布的颜色是蓝色(230色调,s,b),我没有使用滑块,所以画布的颜色通过添加0,5(计数器计数:20次)来改变,在那之后0, 5将从颜色变为反色,直到计数器达到40然后计数器设置为0.因此颜色在(220色调,s,b)和(240色,s,b)之间徘徊

现在,如果我使用滑块(slidersteps = 0.1),颜色将更改为新值。

在示例中 我正在使用滑块,滑块值为2,9,然后颜色变为绿色,通过减去0.5色调。步骤看起来像(230h,s,b),(229.5h,s,b),......,(130h,s,b)。如果达到(130h,s,b),颜色就会开始摆动。

此外,如果新的滑块值比旧的滑块大得多,则必须更快地从旧颜色更改为新颜色。

示例 滑块值= 11.9,最后一个滑块值= 2,9,它们之间的差值为9.因此,如果差值较大,那么2.9我希望从绿色变为红色。所以我决定使用这个公式得到下一个值(旧值 - 新值)/ 1.05 + Min [旧值,新值] 步骤看起来像(130h,s,b),(123h,s,b),...,(0h,s,b)

这个工作正常,直到从红色变为紫色,因为红色的值为0,而下一个的值是360到325紫色。所以我很困惑如何使用此值更改获得与上述相同的步骤

EDIT2:

1.) yes its the actual hue
2.) my fault...it's always setValue() - i have declare it above in this ways value = setValue() to use it once time and didn't change it everywhere 
3.) value = setValue() -> the Hue calculated by the slider
4.) yes
5.) yes

2 个答案:

答案 0 :(得分:1)

我希望我能正确回答,但我并不确定理解你要做的事情。如果我理解,你想对颜色变化有一些过渡效果,对吗?

我提出了一种完全不同的方法,更多的是数学&#34;,流利。让我们假设您希望在1秒内实现颜色转换,无论从旧颜色到新颜色的跳跃有多大。你只需确定一个&#34;过渡向量&#34;,这将是最短的:如果标度从0变为360,则向量为:(540 + new - old)%360 - 180。 / p>

为什么? &#34;天真&#34;矢量只是(新旧)。通过添加360然后模数360,我们确保我们有一个正数。通过以模数加入180(540 = 180 + 360),然后移除180 AFTER模数,我们确保我们有一个范围内的数字[-180,180] =&gt;这就是我们想要获得最短路径的方式。

例如,使用以下公式:

  • 如果old = 5,则new = 10 =&gt;向量是+5
  • 如果old = 350,则new = 10 =&gt;向量是+20
  • 如果old = 350,则new = 340 =&gt;矢量是-10

然后,一旦您计算了该向量,您只需将其应用于每个时间帧的颜色值,再乘以时间因子。例如:

var v = (540 + newColor - oldColor) % 360 - 180;
var currentColor = oldColor;
var delta = 200; // milliseconds
var timeElapsed = 0;
var timeFrame = 1000; // 1s
var hInt = setInterval(function() {
    if (timeElapsed >= timeFrame) {
       clearInterval(hInt);
       currentColor = newColor;
    } else {
       timeElapsed += delta;
       currentColor += v * delta / timeFrame;
    }
}, delta);

&#34; currentColor&#34;随着时间的推移会给你正确的颜色。

答案 1 :(得分:1)

在最短路径上从一种颜色到另一种颜色 Joel 的答案很好,我无法做到更好。所以我提出了另一种方法,尽可能接近你已经拥有的代码,因为你说第一部分工作正常。

在函数setValue()中,beforelast行是else c = 360 - m * 15;。将其更改为:

else c = m * -15;

现在当sliderValue从12变为15时,该函数会从0返回负色调到-45。这样你就可以将'jump'从0移到315并在sliderValue增加时(和相反的方向)不断减小值。从现在开始,价值可以是&lt; 0每次为画布设置值时都使用adjustValue()adjustValue()在内部检查< 0,因此您无需额外检查)。 然后,您发布的所有代码都可能如下所示:

var cur = top.fillColor.hue;
if (cur > 300) cur -= 360;
var dif = cur - setValue();
if (Math.abs(dif) > 41) cur -= Math.round(dif / 1.05);
else {
    cur += top.counter_dsg < 20 ? -0.5 : 0.5; 
    top.counter_dsg += 0.5
}
if (top.counter_dsg > 39) top.counter_dsg = 0;
top.fillColor.hue = adjustValue(cur);