1

:記法を使用してパラメーターを提供したくありません。ユーザー フレンドリーではなく、開発者は常にそのことを考えなければならないからです。このトリック~"parameters"を JavaScript 評価で使用して、引数を正しい形式で取得しています。以下の mixin で確認できます。

私は LESS mixin を持っています

.gradient(...) {
    @def = ~`"@{arguments}".replace(/[\[\]]/g,"")`;

    background-color: mix(/* first and last argument color */)
    background-image: linear-gradient(to bottom, @def);
}

グラデーションには複数のカラーストップ定義を含めることができるため、任意の数の引数をサポートするように定義しました。

今。私が取得したいのは、最初と最後のパラメーターの色の定義のみです。問題は、これらがさまざまな方法で提供される可能性があることです。単純なものから複雑なものまで抽出できます。

.gradient(#000, #fff); // easy
.gradient(fade(#000, 50) 25%, #ccc 50%, fade(#fff, 90) 80%); // complicated

質問

  1. @arguments文字列変換に頼らずにから個々の引数にアクセスすることは可能ですか?
  2. 文字列変換を (のように~'"@{arguments}"') 行う必要がある場合、個々のパラメーターを分割して、括弧内のコンマを無視するにはどうすればよいですか (上の複雑な例では、それらをrbga値に変換しています)。
4

2 に答える 2

2

LESS 1.4.0 ソリューション

extract()以下は、新しい機能を利用するため、LESS 1.4.0 (この記事の執筆時点では現在ベータ版) を必要とするソリューションです。また、色は常に各引数の値のセットの最初の値であると想定しています (これは、linear-gradientcss の適切な構文であると私が信じている場合です)。

LESS 1.4.0の関数を使用するextract()ことで、引数を非文字列として渡すことができます。これにより、私たちが議論した他の質問で発生していた文字列から色への変換の問題が軽減されます(ただし、それでも良い質問です)。個々の価値へのアクセスを提供します。

以下

.gradient(...) {

  //setting up your argument definition string
  @def: ~`"@{arguments}".replace(/[\[\]]/g,"")`;

  //getting the number of arguments 
  //(weeding out nested commas in parenthesis to do it)
  @numStops: unit(`"@{arguments}".replace(/\([^)]*\)/g,"").split(',').length`);

  //extracting raw form of first and last arguments
  //which may be more than just a single color
  @rawFirst: extract(@arguments,1);
  @rawLast: extract(@arguments,@numStops);

  //mixins to recursively evaluate the raw arguments down to a color
  .setFirstColor(@color) when (isColor(@color)) {
     @FirstColor: @color;
  }
  .setFirstColor(@color) when not (isColor(@color)) {
     .setFirstColor(extract(@color,1));
  }
  .setLastColor(@color) when (isColor(@color)) {
     @LastColor: @color;
  }
  .setLastColor(@color) when not (isColor(@color)) {
     .setLastColor(extract(@color,1));
  }

  //call mixins to get the first & last color from first & last arguments
  .setFirstColor(@rawFirst);
  .setLastColor(@rawLast);

  //set your css using the extracted and formatted info
  background-color: mix(@FirstColor, @LastColor);
  background-image: linear-gradient(to bottom, @def);
}

.myClass1 {
  .gradient(#000, #fff); 
}

.myClass2 {
  .gradient(fade(#000, 50) 25%, #ccc 50%, fade(#fff, 90) 80%); //complicated
}

CSS出力

.myClass1 {
  background-color: #808080;
  background-image: linear-gradient(to bottom, #000000, #ffffff);
}
.myClass2 {
  background-color: rgba(179, 179, 179, 0.7);
  background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5) 25%, #cccccc 50%, rgba(255, 255, 255, 0.9) 80%);
}
于 2013-03-28T18:56:34.300 に答える
1

このソリューションに関する詳細なブログ投稿は、ここにあります

私自身の質問に答え、実行可能な解決策を提供するには

文字列変換に頼らずにから個々の引数にアクセスすることは可能ですか?@arguments

LESS 1.4 (現在はベータ版) がなければ、文字列変換に頼らずに直接これを実行して実際の引数を取得し、それらを操作することはできないようです。

文字列変換を (のように ~'"@{arguments}"') 行う必要がある場合、個々のパラメーターを分割して、括弧内のコンマを無視するにはどうすればよいですか (上の複雑な例では、それらを rgba 値に変換しています)。

答えは、目的の結果を返す無名関数をすぐに実行することです。質問から例を挙げましょう:

.gradient(fade(#000, 50) 25%, #ccc 50%, fade(#fff, 90) 80%);

mixin 内の最初の行を実行すると、次の@def値が割り当てられます。

@def: "rgba(0, 0, 0, 0.5) 25%, #ccc 50%, rgba(255, 255, 255, 0.9) 80%";

ここで、分割してはならないコンマを置き換える必要があります。そして、それらは括弧内のコンマです。これは、先読み正規表現を使用して非常に簡単に検出できます。したがって、これらのコンマをセミコロンに置き換えてから、残ったコンマで分割します。

val.replace(/,\s+(?=[\d ,.]+\))/gi, ";").split(/,\s*/g)

この文字列の配列または個々のグラデーションパラメーターになります

["rgba(0;0;0;0.5) 25%", "#ccc 50%", "rgba(255;255;255;0.9) 80%"]

これで、操作できるデータができました。オブジェクトではないLESSmix引数を提供することもできないcolorため、手動でミキシングを行う必要があります。

これは.gradient、最初と最後のグラデーション カラーの結果として #xxxxxx を出力する mixin の結果です。

.gradient (...) {
    @all: ~`"@{arguments}".replace(/[\[\]]/g,"")`;
    @mix: ~`(function(a){a=a.replace(/,\s+(?=[\d ,.]+\))/gi,";").split(/,\s*/g);var f=a[0].split(/\s+/g)[0];var l=a.pop().split(/\s+/g)[0];var c=function(c){var r=[];/rgb/i.test(c)&&c.replace(/[\d.]+/g,function(i){r.push(1*i);return"";});/#.{3}$/.test(c)&&c.replace(/[\da-f]/ig,function(i){r.push(parseInt(i+i,16));return"";});/#.{6}/.test(c)&&c.replace(/[\da-f]{2}/ig,function(i){r.push(parseInt(i,16));return"";});if(r.length)return r;return[100,0,0];};var p=function(v){return("0"+v.toString(16)).match(/.{2}$/)[0];};f=c(f);l=c(l);var r={r:((f.shift()+l.shift())/2)|0,g:((f.shift()+l.shift())/2)|0,b:((f.shift()+l.shift())/2)|0};return"#"+p(r.r)+p(r.g)+p(r.b);})("@{arguments}")`;
    background-color: @mix;
    background-image: -webkit-linear-gradient(top, @all);
    background-image: -moz-linear-gradient(top, @all);
    background-image: -o-linear-gradient(top, @all);
    background-image: linear-gradient(to bottom, @all);
}

もちろん、これをさらに複雑にして、すべてのグラデーション カラーの平均を計算することもできますが、私のニーズではこれで十分です。以下は、引数を解析し、グラデーションの最初と最後の色の混合を計算するトリックを実行する関数であり、上部の@mix変数で縮小されます。

(function(args) {
    args = args.replace(/,\s+(?=[\d ,.]+\))/gi, ";").split(/,\s*/g);
    var first = args[0].split(/\s+/g)[0];
    var last = args.pop().split(/\s+/g)[0];

    var calculateValues = function(color) {
        var result = [];
        /rgb/i.test(color) && color.replace(/[\d.]+/g, function(i) {
            result.push(1*i);
            return "";
        });
        /#.{3}$/.test(color) && color.replace(/[\da-f]/ig, function(i) {
            result.push(parseInt(i+i, 16));
            return "";
        });
        /#.{6}/.test(color) && color.replace(/[\da-f]{2}/ig, function(i) {
            result.push(parseInt(i, 16));
            return "";
        });
        if (result.length) return result;
        return [100,0,0];
    };

    var padZero = function(val) {
        return ("0" + val.toString(16)).match(/.{2}$/)[0];
    };

    first = calculateValues(first);
    last = calculateValues(last);

    var result = {
        r: ((first.shift() + last.shift()) / 2) | 0,
        g: ((first.shift() + last.shift()) / 2) | 0,
        b: ((first.shift() + last.shift()) / 2) | 0
    };
    return "#"+ padZero(result.r) + padZero(result.g) + padZero(result.b);
})("@{arguments}")
于 2013-03-29T09:52:32.033 に答える