Skip to content
This repository has been archived by the owner on Jan 20, 2019. It is now read-only.

Possible SCSS integrations / invert filter error? #3

Open
erwstout opened this issue Apr 25, 2016 · 7 comments
Open

Possible SCSS integrations / invert filter error? #3

erwstout opened this issue Apr 25, 2016 · 7 comments

Comments

@erwstout
Copy link

Hello there!

Have you given any thought to making a scss version? It would be a little bit easier in some builds instead of using the default CSS. Usually when I come across something where only .css is available I will just copy and paste the css into a new file for my build. When I did that with svg-awesome, I actually got a compile error:

Message:
    assets/scss/plugins/_svg-awesome.scss
Error: required parameter $color is missing in call to Function invert
        on line 7 of assets/scss/plugins/_svg-awesome.scss
>> .fa.fa-white{-webkit-filter:brightness(0) invert();

And it led me down the path of looking at what parameters the invert() function takes.

From W3 Schools on invert():

0% (0) is default and represents the original image.
100% will make the image completely inverted.

Shouldn't the invert be passed a property? Or is it possibly just throwing an error since it is being compiled, but css on its own invert() would work?

Thanks!

@mgwalker
Copy link
Owner

That's a good idea!

I think you're right on the money about invert(). If you can import it as plain CSS, that should help (e.g., @import 'svg-awesome-color'; - you'd need to leave off the .css extension: sass/libsass#754).

Having a Sass version does sound good, though. Maybe I could wrap it up into mixins too to reduce the total deliverable size. Thanks for the idea! And if you have time and effort, pull requests are welcome. (I'm not sure when I'll have time to get to it, but open issues bug me so I'll keep this open as motivation. 😛)

@erwstout
Copy link
Author

Yeah I forked it and planned to take a look this week sometime and see what I come up with, if I understand correctly it's just node scripts right?

Sent from my iPhone

On Apr 25, 2016, at 4:50 PM, Greg Walker notifications@github.com wrote:

That's a good idea!

I think you're right on the money about invert(). If you can import it as plain CSS, that should help (e.g., @import 'svg-awesome-color'; - you'd need to leave off the .css extension: sass/libsass#754).

Having a Sass version does sound good, though. Maybe I could wrap it up into mixins too to reduce the total deliverable size. Thanks for the idea! And if you have time and effort, pull requests are welcome. (I'm not sure when I'll have time to get to it, but open issues bug me so I'll keep this open as motivation. 😛)


You are receiving this because you authored the thread.
Reply to this email directly or view it on GitHub

@erwstout
Copy link
Author

So I tried to dive in a bit this morning to see what I can do on the scss side, but my build keeps throwing an error. Am I missing a dependency?

ReferenceError: reject is not defined
    at /Volumes/Storage/GIT/svg-awesome/build/generate-css.js:31:6
    at fs.js:1196:7
    at FSReqWrap.oncomplete (fs.js:82:15)

I tried installing and requiring Promise but that doesn't seem to work either. Any thoughts?

@mgwalker
Copy link
Owner

That's just a straight-up bug... I've fixed it in master. (See fe175f1)

This is what I get for not writing tests. 😄

@erwstout
Copy link
Author

Haha, I feel ya. Perfect thanks.

@erwstout
Copy link
Author

Still tinkering a bit, I have it outputting scss files instead of css, but the glyphs dont seem to be outputting at all.. Here is what my build version of svg-awesome-bw.scss is so far:

.fa{display:inline-block;width:1em;height:1em;background-size:contain;}
.fa-lg{width:1.33333em;height:1.33333em;}
.fa-2x{width:2em;height:2em;}
.fa-3x{width:3em;height:3em;}
.fa-4x{width:4em;height:4em;}
.fa-5x{width:5em;height:5em;}
.fa.fa-white{-webkit-filter:brightness(0) invert();-moz-filter:brightness(0) invert();-ms-filter:brightness(0) invert();filter:brightness(0) invert();}
.fa.fa-black{-webkit-filter:brightness(0);-moz-filter:brightness(0);-ms-filter:brightness(0);filter:brightness(0);}

And get-fa-glpyh-vectors.js ( hey a typo! :-) - left in tact for now ) largely unchanged but with some updated paths:

"use strict";

const fs = require("fs");

function getSVG(range, path) {
    const width = range.x.max - range.x.min;
    const height = range.y.max - range.y.min;
    return `<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" viewBox="${range.x.min} ${range.y.min} ${width} ${height}" width="${width}" height="${height}"><path transform="scale(1,-1) translate(0, ${-height - (2 * range.y.min)})" stroke="red" fill="red" ${path} /></svg>`;
}

function updateRange(range, x, y) {
    if(x > range.x.max) {
        range.x.max = x;
    }
    if(x < range.x.min) {
        range.x.min = x;
    }
    if(y > range.y.max) {
        range.y.max = y;
    }
    if(y < range.y.min) {
        range.y.min = y;
    }
}

function getArgRegexString(numArgs) {
    let argsRegex = " *";
    for(let i = 0; i < numArgs; i++) {
        if(i > 0) {
            if(i % 2 === 0) {
                argsRegex += ",?";
            }
            argsRegex += " +";
        }
        argsRegex += "(-?[0-9.]+)";
    }
    return argsRegex;
}

function getArguments(str, numArgs) {
    if(Number.isNaN(Number(numArgs))) {
        numArgs = 0;
    }

    const args = [ ];
    const match = (new RegExp(getArgRegexString(numArgs))).exec(str);
    if(match) {
        for(let i = 0; i < numArgs; i++) {
            args.push(Number(match[i + 1]));
        }
    }
    return args;
}

function stripCommandWithArguments(str, numArgs) {
    if(Number.isNaN(Number(numArgs))) {
        numArgs = 1;
    }

    return str.replace(new RegExp(`^[A-Za-z]${getArgRegexString(numArgs)}`), "").trim();
}

module.exports = function(glyphs) {
    return new Promise((resolve, reject) => {
        fs.exists("../node_modules/font-awesome/fonts/fontawesome-webfont.svg", exists => {
            if(!exists) {
                return reject(new Error("No font-awesome SVG font found"));
            }

            fs.readFile("../node_modules/font-awesome/fonts/fontawesome-webfont.svg", { encoding: "utf-8" }, (err, font) => {
                if(err) {
                    return reject(new Error(err));
                }

                const writePromises = [ ];

                for(let glyph of glyphs) {
                    const regex = new RegExp("<glyph unicode=\"&#x" + glyph.unicode.replace("\\", "") + ";\" ([^>]*)?/>", "g");
                    const match = regex.exec(font);
                    let correctedPath = "";

                    if(match) {
                        let range = {
                            x: { min: +Infinity, max: -Infinity },
                            y: { min: +Infinity, max: -Infinity }
                        };

                        let position = { x: 0, y: 0 };
                        let path = /d="([^"]*)"/.exec(match)[1].trim();

                        while(path) {
                            let lastLength = path.length;
                            let command = path[0];
                            let args = [ ];

                            if(command.toLowerCase() !== "z") {
                                switch(command) {
                                    case "M":
                                    case "L":
                                    case "T":
                                        args = getArguments(path, 2);
                                        position.x = args[0];
                                        position.y = args[1];
                                        path = stripCommandWithArguments(path, 2);
                                        break;

                                    case "m":
                                    case "l":
                                    case "t":
                                        args = getArguments(path, 2);
                                        position.x += args[0];
                                        position.y += args[1];
                                        path = stripCommandWithArguments(path, 2);
                                        break;

                                    case "V":
                                        args = getArguments(path, 1);
                                        position.y = args[0];
                                        path = stripCommandWithArguments(path, 1);
                                        break;

                                    case "v":
                                        args = getArguments(path, 1);
                                        position.y += args[0];
                                        path = stripCommandWithArguments(path, 1);
                                        break;

                                    case "H":
                                        args = getArguments(path, 1);
                                        position.x = args[0];
                                        path = stripCommandWithArguments(path, 1);
                                        break;

                                    case "h":
                                        args = getArguments(path, 1);
                                        position.x += args[0];
                                        path = stripCommandWithArguments(path, 1);
                                        break;

                                    case "C":
                                        args = getArguments(path, 6);
                                        updateRange(range, args[0], args[1]);
                                        updateRange(range, args[2], args[3]);
                                        position.x = args[4];
                                        position.y = args[5];
                                        path = stripCommandWithArguments(path, 6);
                                        break;

                                    case "c":
                                        args = getArguments(path, 6);
                                        updateRange(range, position.x + args[0], position.y + args[1]);
                                        updateRange(range, position.x + args[2], position.y + args[3]);
                                        position.x += args[4];
                                        position.y += args[5];
                                        path = stripCommandWithArguments(path, 6);
                                        break;

                                    case "S":
                                    case "Q":
                                        args = getArguments(path, 4);
                                        updateRange(range, args[0], args[1]);
                                        position.x = args[2];
                                        position.y = args[3];
                                        path = stripCommandWithArguments(path, 4);
                                        break;

                                    case "s":
                                    case "q":
                                        args = getArguments(path, 4);
                                        updateRange(range, position.x + args[0], position.y + args[1]);
                                        position.x += args[2];
                                        position.y += args[3];
                                        path = stripCommandWithArguments(path, 4);
                                        break;

                                    default:
                                        console.log(`UNKNOWN COMMAND: ${command}`);
                                        break;
                                }

                                updateRange(range, position.x, position.y);
                                //console.log(`${command} | ${args}`);
                            }
                            else {
                                path = stripCommandWithArguments(path, 0);
                            }

                            correctedPath += `${command}`;
                            for(let i = 0; i < args.length; i++) {
                                if(i > 0) {
                                    correctedPath += " ";
                                }
                                correctedPath += `${args[i]}`;
                            }

                            if(lastLength == path.length) {
                                console.log("Didn't remove anything else from the path...");
                                console.log(path);
                                break;
                            }
                        }

                        let width = range.x.max - range.x.min;
                        let height = range.y.max - range.y.min;

                        if(height > width) {
                            const deltaX = (height - width) / 2.0;
                            range.x.max += deltaX;
                            range.x.min -= deltaX;
                        } else {
                            const deltaY = (width - height) / 2.0;
                            range.y.max += deltaY;
                            range.y.min -= deltaY;
                        }

                        writePromises.push(new Promise(resolve => {
                            fs.writeFile(`svgs/${glyph.name}.svg`, getSVG(range, `d="${correctedPath}"`), (err) => {
                                resolve();
                            });
                        }));
                    }
                }

                Promise.all(writePromises).then(() => resolve(glyphs));
            });
        });
    });
};

Any thought as to why the no output?

@mgwalker
Copy link
Owner

From the path changes, it looks like you're running from inside the build directory. If that's the case, you'll also need to update paths in get-fa-glyphs.js too. There's an npm script you can run instead if you'd like (npm run build) but you may have to fiddle with that too to get it to build from a base SCSS.

Thanks for digging into this!

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants