call less.js function in javascript has different

2019-09-01 01:08发布

问题:

during this question i want to call some less functions such as darken, lighten and spin inside javascript. i did it in node.js like this and it works:

#!/usr/bin/env node
var less = require('less');
var args = process.argv.slice(2);

less.render(".my{ color:lighten("+ args[0]+","+args[1]+"%); }", function (e, css) {
     console.log(css.match(/\#[0-9a-fA-F]+/)[0]);
});

this is output:

$ ./my "#000" 13.5
#222222

but i did in html and less.js file and using solution in this question and made this:

<html>
<head>
    <title></title>
    <script language="JavaScript" src="less-1.7.0.min.js"></script>
    <script language="JavaScript">
        var lessColor = {
            /*
             |--------------------------------------------------------------------------
             | Lighten
             |--------------------------------------------------------------------------
             */
            lighten: function (col, val) {
                col = col.replace(/#/g, '');    //Remove the hash

                var color = new less.tree.Color(col);   //Create a new color object
                var amount = new less.tree.Value(val);      //Create a new amount object
                var newRGB = less.tree.functions.lighten(color, amount); //Get the new color
                var hex = (newRGB.rgb[0] + 256 * newRGB.rgb[1] + 65536 * newRGB.rgb[2]).toString(16);
                hex = hex.split('.', 1);    //Remove everything after the decimal if it exists

                //Add padding to the hex to make it 6 characters
                while (hex.length < 6) {
                    hex = hex + '0';
                }
                hex = '#' + hex;  //Add the hash

                return hex; //return the color
            }
        };
        console.log(lessColor.lighten("#000",13.5));
    </script>
</head>
<body>
</body>
</html>

but different output in console:

i'm pretty sure #222222 is correct result but how can i get this result inside javascript?

回答1:

As can be read from the comments the following code will give you #222222:

   var lessColor = {
        lighten: function (color, amount) {
        color = new (less.tree.Color)(color.substring(1));
        amount = new(less.tree.Dimension)(amount, '%');
        return less.tree.functions.lighten(color, amount).toRGB(); 
        }
    };
    console.log(lessColor.lighten('#000',13.5));

Notice that color.substring(1) just like col.replace(/#/g, ''); removes the starting #. The input of less.tree.Color is the hex color triplet the less parser uses the following code for that conversion:

var rgb;
if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})/))) {
var colorCandidateString = rgb.input.match(/^#([\w]+).*/); // strip colons, brackets, whitespaces and other characters that should not definitely be part of color string
colorCandidateString = colorCandidateString[1];
if (!colorCandidateString.match(/^[A-Fa-f0-9]+$/)) { // verify if candidate consists only of allowed HEX characters
error("Invalid HEX color code");
}
return new(tree.Color)(rgb[1]);
}


回答2:

Correcting the answer from @Bass Jobsen https://stackoverflow.com/a/26811314/3027390

In modern versions of Less there is no more less.tree.functions.lighten.

You should use less.functions.functionRegistry.get('lighten') instead.

That applies to any other Less function (not only color).

So, the updated answer should look like:

var lessColor = {
    lighten: function (color, amount) {
        color = new (less.tree.Color)(color.substring(1));
        amount = new (less.tree.Dimension)(amount, '%');
        func = less.functions.functionRegistry.get('lighten');
        return func(color, amount).toRGB(); 
    }
};

console.log(lessColor.lighten('#000', 13.5)); // => '#222222'