このソリューションに関する詳細なブログ投稿は、ここにあります。
私自身の質問に答え、実行可能な解決策を提供するには
文字列変換に頼らずにから個々の引数にアクセスすることは可能ですか?@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}")