2

タイトルが悪くて申し訳ありません(必要に応じて編集してください)が、このリクエストの入れ方がわかりません。物事をもう少しよく説明する Photoshop の画像を添付しました。

要求自体は非常に単純です。10.0 から 0.0 までの数値範囲があります。10 は色 #00ff00 (濃い緑) を表し、0.0 は色 #ff0000 (濃い赤) を表します。

ここで、数値 10.0 を渡すと #00ff00 が出力されます。8.2 のようなものを指定すると、#00cc33 のようなものが出力されるため、フローティング グラデーションがずっと下にあるが、常に #00ff00 からオレンジ #ff9900 を越えて #ff0000 までフロートします (真ん中のオレンジも省略できます)。

それは私が欲しいものです

4

5 に答える 5

4

1 つの方法は、色を円のセグメントのように考えてから、Math.cosまたはを利用することですMath.sin

function toColour(x) {
    var pad = function (x) {
        x = x.toString(16);
        if (x.length === 1) {
            return '0' + x;
        }
        return x;
    }, r, g, b;
    r = ~~(255 * Math.cos(Math.PI * x / 20)); // cos(0) = 1, cos(π/2) = 0
    g = ~~(255 * Math.sin(Math.PI * x / 20)); // sin(0) = 0, sin(π/2) = 1
    b = 0;
    return '#' + pad(r) + pad(g) + pad(b);
}

// test the gradient produced
for (var i = 0; i <= 10; ++i) {
    document.body.appendChild(
        document.createElement('div')
    ).setAttribute('style', 'width: 400px;height: 5px;background: '+toColour(i)+';');
}

テスト結果については、このフィドルを参照してください ( MikeMに感謝)

于 2013-01-27T20:10:51.807 に答える
3

楽しみのためだけに:

function toHex( n ) {
    var r = 255 - ( n / 10 * 255 | 0 ); 
        g = n / 10 * 255 | 0;  

    return '#' + 
        ( r ? ( r = r.toString(16), r.length == 2 ? r : '0' + r ) : '00' ) +
        ( g ? ( g = g.toString(16), g.length == 2 ? g : '0' + g ) : '00' ) + '00'
}

ここでそれを参照してください(その価値について):http://jsfiddle.net/xD6Uf/

アップデート

Samuel Edwin WardによるHSLの使用に触発された次の関数は、BrianGrinsteadhslToRgbのMITライセンスのtinycolor.jsから採用されています。

注:この関数は、完成品またはグッドプラクティスを表すことを目的としたものではなく、概念実証のみを目的としています。境界チェックはなく、読みやすさへの譲歩はほとんどありません。

nは0〜10の値であり、startはそれぞれ0〜360の色相値です。実験する色相、彩度、明度の値を選択するには、Mother-effinghsl を参照してください。middleend

function toHex( n ) {
    var r, g, b, p, q,
        start = 0,          // 0 - 360 (red 0)
        middle = 36,        // 0 - 360 (orange 36, use 0 or null for no middle)
        end = 120,          // 0 - 360 (green 120)
        saturation = 1,     // 0 - 1
        lightness = 0.5,    // 0 - 1
        hue = ( middle ?
            n > 5 ? ( n -= 5, n / 5 * ( end - middle ) ) + middle :
                ( n / 5 * ( middle - start ) ) + start :
                    ( n / 10 * ( end - start ) ) + start ) / 360;

    function hue2hex( p, q, h ){
        if ( h < 0 ) h++;
        else if ( h > 1 ) h--;
        h = ( h < 1/6 ? p + ( q - p ) * 6 * h : h < 1/2 ? q :
            h < 2/3 ? p + ( q - p ) * ( 2/3 - h ) * 6 : p ) * 255 | 0;
        return h ? ( h = h.toString(16), h.length > 1 ? h : '0' + h ) : '00';
    }

    if ( saturation === 0 ) {
        n = lightness * 255 | 0;
        r = g = b = n ?
            ( n = n.toString(16), n.length > 1 ? n : '0' + n ) : '00'; 
    } else {
        q = lightness < 0.5 ? lightness * ( 1 + saturation ) :
            lightness + saturation - lightness * saturation;
        p = 2 * lightness - q;
        r = hue2hex( p, q, hue + 1/3 );
        g = hue2hex( p, q, hue );
        b = hue2hex( p, q, hue - 1/3 );
    }

    return '#' + r + g + b;
}

toHex(0);    // "#ff0000"
toHex(5);    // "#ff9900"
toHex(10);   // "#00ff00"

jsfiddle

于 2013-01-27T19:56:38.107 に答える
3

色の間を補間したいようです。

色の値を数値として取得し、それらの間で補間を行うこともできますが、結果は非常に奇妙になると思います.

色を RGB から別の色空間に変換し、色相コンポーネントをスケーリングすることをお勧めします。CSS3 はそのスペースでの色の指定をサポートしているため、HSL は適切な選択です。

カラースケールのイメージ

両方のアプローチのコードをjsfiddle に置きました。

これらは重要な部分です:

/* numeric interpolation */
for (var value = 0; value < 10; value += 10/40) {
    var color = (10-value)/10*(0xff0000-0xff00)+(0x00ff00),
        hex = Math.floor(color).toString(16);

    while (hex.length < 6) {
        hex = "0" + hex;
    }

    /* hex now holds the hex code */
  }

/* hue interpolation */

for (var value = 0; value < 10; value += 10/40) {
    var hue = value/10*120, /* red is 0; green is 120 */
        color = 'hsl(' + hue + ', 100%, 50%)';

    /* hsl now holds the hsl color specification */
}

必要に応じて、私が使用した単純な線形式 (x は入力スケール、y は出力スケール) よりも優れた方法で値を補間することができます。

y = (x - minX) / (maxX - minX) * (maxY-minY) + minY
于 2013-01-27T20:02:38.750 に答える
1

つまり、基本的に、2つの変数を持つ16進数の範囲があります。

var startHex = "0x00ff00";
var endHex = "0xff0000"
int startInt = parseInt(startHex, 16);
int endInt = parseInt(endHex, 16);
int newInt = startInt + (endInt-startInt)/100 * floatValue; // floatValue is number between 10.0 and 0.0
var newHex = newDec.ToString(16);

私はあなたが開始と終了の間に可能な100の増分を意図したと仮定しています。これはもっときれいに行うことができますが、説明のために私はそれをすべて分解しました。実際には、これを1〜2行で記述します。

于 2013-01-27T19:50:10.013 に答える
0

ブラウザのレンダリング エンジンに依存したい場合は、HTML5 のキャンバスとcreateLinearGradient. このアプローチの利点の 1 つは、カラー ストップを使用できることです (ただし、必要に応じて数学的に行うこともできます)。

var canvas = document.createElement('canvas'),
    context = canvas.getContext('2d');

canvas.height = 100; canvas.width = 1;

var gradient = context.createLinearGradient(0,0,0,100);

// color stops
gradient.addColorStop(0, '#00ff00');
gradient.addColorStop(0.5, '#ff9900');
gradient.addColorStop(1, '#ff0000');

context.fillStyle = gradient;
context.fillRect(0,0,1,100);

var point = 10.0,
    colorData = context.getImageData(0, parseInt(point*canvas.height*.1, 10), 1, 1).data;

// rgba ( colorData[0], colorData[1], colorData[2], colorData[3] )

colorData[0](赤)、colorData[1](青)、 (緑)の色の正確な rgba 座標を見つけて、colorData[2]それらを 16 進数値に簡単に変換できます。

このソリューションを使用する場合はpoint、0 ~ 9.9 の範囲の数値に設定してください。

于 2013-01-27T20:13:21.340 に答える