可以在此处找到有关此解决方案的详细博客文章。
回答我自己的问题并提供可行的解决方案
是否可以在不求助于字符串转换的情况下访问单个参数?@arguments
如果没有 LESS 1.4(目前处于测试阶段),似乎不可能直接执行此操作并获得实际参数,而无需求助于字符串转换然后操作它们。
如果必须进行字符串转换(as ~'"@{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%"]
现在我们有了可以使用的数据。由于也不可能提供mix
不是color
对象的 LESS 参数,我们必须手动进行混合。
这是.gradient
作为第一个和最后一个渐变颜色的结果输出#xxxxxx的结果混合:
.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}")