Git Product home page Git Product logo

gulp-svgstore's Introduction

gulp-svgstore Build Status

Combine svg files into one with <symbol> elements. Read more about this in CSS Tricks article.

If you need similar plugin for grunt, I encourage you to check grunt-svgstore.

Options:

The following options are set automatically based on file data:

  • id attribute of the <symbol> element is set to the name of corresponding file;
  • result filename is the name of base directory of the first file.

If your workflow is different, please use gulp-rename to rename sources or result.

The only available option is:

  • inlineSvg — output only <svg> element without <?xml ?> and DOCTYPE to use inline, default: false.

Install

npm install gulp-svgstore --save-dev

Usage

The following script will combine all svg sources into single svg file with <symbol> elements. The name of result svg is the base directory name of the first file src.svg.

Additionally pass through gulp-svgmin to minify svg and ensure unique ids.

const gulp = require('gulp');
const svgstore = require('gulp-svgstore');
const svgmin = require('gulp-svgmin');
const path = require('path');

gulp.task('svgstore', () => {
    return gulp
        .src('test/src/*.svg')
        .pipe(svgmin((file) => {
            const prefix = path.basename(file.relative, path.extname(file.relative));
            return {
                plugins: [{
                    cleanupIDs: {
                        prefix: prefix + '-',
                        minify: true
                    }
                }]
            }
        }))
        .pipe(svgstore())
        .pipe(gulp.dest('test/dest'));
});

Inlining svgstore result into html body

To inline combined svg into html body I suggest using gulp-inject. The following gulp task will inject svg into

In your html file (using sr-only from html5-boilerplate to fix the gradients):

<div class="sr-only">
  <!-- inject:svg --><!-- endinject -->
</div>

In your gulp tasks:

const gulp = require('gulp');
const svgstore = require('gulp-svgstore');
const inject = require('gulp-inject');

gulp.task('svgstore', () => {
    const svgs = gulp
        .src('test/src/*.svg')
        .pipe(svgstore({ inlineSvg: true }));

    function fileContents (filePath, file) {
        return file.contents.toString();
    }

    return gulp
        .src('test/src/inline-svg.html')
        .pipe(inject(svgs, { transform: fileContents }))
        .pipe(gulp.dest('test/dest'));
});

Generating id attributes

Id of symbol element is calculated from file name. You cannot pass files with the same name, because id should be unique.

If you need to add prefix to each id, please use gulp-rename:

const gulp = require('gulp');
const rename = require('gulp-rename');
const svgstore = require('gulp-svgstore');

gulp.task('default', () => {
    return gulp
        .src('src/svg/**/*.svg', { base: 'src/svg' })
        .pipe(rename({prefix: 'icon-'}))
        .pipe(svgstore())
        .pipe(gulp.dest('dest'));
});

If you need to have nested directories that may have files with the same name, please use gulp-rename. The following example will concatenate relative path with the name of the file, e.g. src/svg/one/two/three/circle.svg becomes one-two-three-circle.

const gulp = require('gulp');
const path = require('path');
const rename = require('gulp-rename');
const svgstore = require('gulp-svgstore');

gulp.task('default', () => {
    return gulp
        .src('src/svg/**/*.svg', { base: 'src/svg' })
        .pipe(rename((file) => {
            const name = file.dirname.split(path.sep);
            name.push(file.basename);
            file.basename = name.join('-');
        }))
        .pipe(svgstore())
        .pipe(gulp.dest('dest'));
});

Using svg as external file

There is a problem with <use xlink:href="external.svg#icon-name"> in Internet Explorer, so you should either inline everything into body with a simple script like this or polyfill with svg4everybody.

PNG sprite fallback for unsupported browsers

gulp-svgfallback is a gulp plugin that generates png sprite and css file with background offsets from svg sources. Please check it and leave feedback.

Transform svg sources or combined svg

To transform either svg sources or combined svg you may pipe your files through gulp-cheerio.

Transform svg sources

An example below removes all fill attributes from svg sources before combining them. Please note that you have to set xmlMode: true to parse svgs as xml file.

const gulp = require('gulp');
const svgstore = require('gulp-svgstore');
const cheerio = require('gulp-cheerio');

gulp.task('svgstore', () => {
    return gulp
        .src('test/src/*.svg')
        .pipe(cheerio({
            run: ($) => {
                $('[fill]').removeAttr('fill');
            },
            parserOptions: { xmlMode: true }
        }))
        .pipe(svgstore({ inlineSvg: true }))
        .pipe(gulp.dest('test/dest'));
});

Transform combined svg

The following example sets style="display:none" on the combined svg: (beware if you use gradients and masks, display:none breaks those and just show nothing, best method is to use the method show above )

const gulp = require('gulp');
const svgstore = require('gulp-svgstore');
const cheerio = require('gulp-cheerio');

gulp.task('svgstore', () => {
    return gulp
        .src('test/src/*.svg')
        .pipe(svgstore({ inlineSvg: true }))
        .pipe(cheerio({
            run: ($) => {
                $('svg').attr('style', 'display:none');
            },
            parserOptions: { xmlMode: true }
        }))
        .pipe(gulp.dest('test/dest'));
});

Extracting metadata from combined svg

You can extract data with cheerio.

The following example extracts viewBox and id from each symbol in combined svg.

const gulp = require('gulp');
const Vinyl = require('vinyl');
const svgstore = require('gulp-svgstore');
const through2 = require('through2');
const cheerio = require('cheerio');

gulp.task('metadata', () => {
    return gulp
        .src('test/src/*.svg')
        .pipe(svgstore())
        .pipe(through2.obj(function (file, encoding, cb) {
            const $ = cheerio.load(file.contents.toString(), {xmlMode: true});
            const data = $('svg > symbol').map(() => {
                return {
                    name: $(this).attr('id'),
                    viewBox: $(this).attr('viewBox')
                };
            }).get();
            const jsonFile = new Vinyl({
                path: 'metadata.json',
                contents: Buffer.from(JSON.stringify(data))
            });
            this.push(jsonFile);
            this.push(file);
            cb();
        }))
        .pipe(gulp.dest('test/dest'));
});

Possible rendering issues with Clipping Paths in SVG

If you're running into issues with SVGs not rendering correctly in some browsers (see issue #47), the issue might be that clipping paths might not have been properly intersected in the SVG file. There are currently three ways of fixing this issue:

Correcting the Clipping Path in the SVG

If you have the source file, simply converting the clipping path to a nice coded shape will fix this issue. Select the object, open up the Pathfinder panel, and click the Intersect icon.

Editing the SVG Code

If you don't have the source file or an SVG Editor (Adobe Illustrator etc.), you can manually edit the SVG code in the file. Wrapping the <clipPath> into a <defs> will fix this issue. Here's an example:

<defs>
    <path d="M28.4 30.5l5.3 5c0-.1 7-6.9 7-6.9l-4-6.8-8.3 8.7z" id="a"/>
</defs>
<clipPath id="b"><use overflow="visible" xlink:href="#a"/></clipPath>

Becomes:

<defs>
    <path d="M28.4 30.5l5.3 5c0-.1 7-6.9 7-6.9l-4-6.8-8.3 8.7z" id="a"/>
    <clipPath id="b"><use overflow="visible" xlink:href="#a"/></clipPath>
</defs>

Or you can go further and reduce the size by removing the <use> element, like this:

<defs>
    <clipPath id="b"><path d="M28.4 30.5l5.3 5c0-.1 7-6.9 7-6.9l-4-6.8-8.3 8.7z"/></clipPath>
</defs>

Using gulp-cheerio to automate this

Another possible solution would be to write a transformation with gulp-cheerio. Check this issue #98 for the instructions.

Changelog

  • 9.0.0

  • 8.0.0

    • Update dependencies
    • Drop support for node < 10
  • 7.0.1

    • Include xmlns:xlink in svg definition #96
  • 7.0.0

    • Stop using deprecated new Buffer() api
    • Drop support for node 0.12
  • 6.1.1

    • Removed dependency on gulp-util to support gulp 4
  • 6.1.0

    • Copy preserveAspectRatio attribute from source svg to to symbol #76
  • 6.0.0

    • Removed cache of the cheerio object #61
  • 5.0.5

    • Correctly set namespaces of the combined svg
  • 5.0.4

    • Skip null and invalid files
  • 5.0.3

    • Updated readme with a way to ensure unique ids
  • 5.0.2

    • Updated direct dependencies
  • 5.0.1

    • Removed cheerio from devDependencies #34
  • 5.0.0

    • Removed prefix and fileName options
  • 4.0.3

    • Ensure unique file names
    • Improved readme with gulp-rename usage to generate id for nested directories
  • 4.0.1

    • Added cheerio to devDependencies
  • 4.0.0

    • Removed transformSvg, pipe files through gulp-cheerio instead.
    • Made cheerio 0.* a peer dependency, allows to choose what version to use.
    • Uses file.cheerio if cached in gulp file object and also sets it for the combined svg.
    • Improved readme.
  • 3.0.0

    • Used cheerio instead of libxmljs (changes transformSvg syntax)
  • 2.0.0

    • Added check for inputs before generating SVG.
  • 1.0.1

    • Added check for missing viewBox in original svg.
  • 1.0.0

    • Initial release.

gulp-svgstore's People

Contributors

bruha avatar firefoxic avatar ghetolay avatar jimmymultani avatar matthewnessworthy avatar mrflix avatar pastjean avatar petermac- avatar petrux99 avatar seierstad avatar tomasklaen avatar trysound avatar w0rm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gulp-svgstore's Issues

Extract transformSvg

Hey,

did you already extract the transformSvg method to a different gulp plugin?
There is one plugin to edit svgs, but I think it mostly handles fonts https://www.npmjs.com/package/gulp-svgedit/.

I think it would be awesome if you would extract your part to a gulp-svg-edit plugin which just takes one more multiple svgs and does something on them.

This means you could plug it into the flow before the svgstore fires and change something for all seperate icons (like add an attribute, etc.) and you could also use it afterwards to do something like the display:none; stuff when wanting to inline it.

Sadly I have not enough knowledge of gulp to send a PR.

TypeError: Cannot call method 'value' of null

Getting this, and cannot run gulp now:

/Applications/XAMPP/xamppfiles/htdocs/proj/wp-content/themes/proj/node_modules/gulp-svgstore/index.js:34 var viewBoxAttr = xmlDoc.root().attr('viewBox').value() ^ TypeError: Cannot call method 'value' of null at Transform.transform [as _transform] (/Applications/XAMPP/xamppfiles/htdocs/proj/wp-content/themes/proj/node_modules/gulp-svgstore/index.js:34:55) at Transform._read (/Applications/XAMPP/xamppfiles/htdocs/proj/wp-content/themes/proj/node_modules/gulp-svgstore/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:184:10) at Transform._write (/Applications/XAMPP/xamppfiles/htdocs/proj/wp-content/themes/proj/node_modules/gulp-svgstore/node_modules/through2/node_modules/readable-stream/lib/_stream_transform.js:172:12) at doWrite (/Applications/XAMPP/xamppfiles/htdocs/proj/wp-content/themes/proj/node_modules/gulp-svgstore/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:238:10) at writeOrBuffer (/Applications/XAMPP/xamppfiles/htdocs/proj/wp-content/themes/proj/node_modules/gulp-svgstore/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:228:5) at Transform.Writable.write (/Applications/XAMPP/xamppfiles/htdocs/proj/wp-content/themes/proj/node_modules/gulp-svgstore/node_modules/through2/node_modules/readable-stream/lib/_stream_writable.js:195:11) at write (_stream_readable.js:601:24) at flow (_stream_readable.js:610:7) at Transform.pipeOnReadable (_stream_readable.js:642:5) at Transform.emit (events.js:92:17)

Need to add new attribute to generated Symbol

Using this plugin, I am able to generated svg's inside <symbol> element. I have a requirement where I need to add a attribute to these generated <symbol> elements.

I tried the following, which isn't working:

        .pipe(svgstore())
        .pipe(through2.obj(function (file, encoding, cb) {
            var $ = file.cheerio;
            $('svg > symbol').each(function(index, element){
                element.attribs['preserveAspectRatio'] = 'xMinYMid';
            })
        }))
        // Store the generated svg sprite in "site/assets/images/" folder
        .pipe(gulp.dest('site/assets/images/'));

In the above excerpt code, I am trying to add preserveAspectRatio attribute to generated symbol elements. (this isn't working)

Please help.

Remove attributes

Great plugin, would really like to be able to remove fill="#abc123" from svg. Can do this with the grunt plugin with cleanup: ['fill']

Add prefix option

Hi,

Thanks for your great plugin!

I'd like to have a prefix on all my id. Is this possible ?

Thanks!

TypeError: $svg.contents is not a function

Hi,

Today we realised our Gulp SVG task was failing, seemingly due to some issue with gulp-svgstore. How long this has been happening we can't say, but there was a time it was working. Could it be an issue with the latest version of Node?

We get the following error:

/Applications/MAMP/htdocs/raggededge/wp-content/themes/raggededge/node_modules/gulp-svgstore/index.js:111
$symbol.append($svg.contents())
^

TypeError: $svg.contents is not a function
at Transform.transform as _transform
at Transform._read (_stream_transform.js:167:10)
at Transform._write (_stream_transform.js:155:12)
at doWrite (_stream_writable.js:292:12)
at writeOrBuffer (_stream_writable.js:278:5)
at Transform.Writable.write (_stream_writable.js:207:11)
at Transform.ondata (_stream_readable.js:529:20)
at emitOne (events.js:90:13)
at Transform.emit (events.js:182:7)
at readableAddChunk (_stream_readable.js:147:16)

Our task looks like:

'use strict';

module.exports = function(gulp, plugins) {

    return function() {

        gulp.src('src/svg/*.svg')

            .pipe(plugins.svgmin({
                plugins: [
                    {
                        removeViewBox: false
                    }
                ]
            }))
            .pipe(plugins.svgstore())
            .pipe(plugins.rename('sprite.svg'))
            .pipe(gulp.dest('dist/svg/'))
            .pipe(plugins.browserSync.reload({
                stream: true
            }));

    };

};

This task hasn't changed and the plugin versions have not changed either:

"gulp-svgstore": "^5.0.5"

Our Node version is:

node/5.6.0

Although we're using gulp-svgmin, removing this still shows the error, so we're pretty confident the issue lies with gulp-svgstore.

Any help would be greatly appreciated!

Thanks,
Michael

SVG viewbox metadata

In order to use the output correctly for SVG's that have variable widths, you need to include the viewBox in the HTML:

<svg viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg">
  <use xlink:href="#icon-close"></use>
</svg>

What do you think about this plugin writing icons.json or similar, with name: viewbox pairs, so that downstream tools or a server can have access to the correct viewBox value for each icon.

Feature parity with the Grunt version

First, thanks for the time you put into this.

I was wondering if there are plans to eventually have some sort of feature parity between gulp-svgstore and grunt-svgstore?

The Grunt plugin has made a long way, and many of its current features seem to be missing from the Gulp version, which is a shame.

Copy sprites svg's attributes into symbols

So following the pull request about namespace, I think we should add the ability to copy some/all attributes from the different sprites into final symbols.

First I think namespace should be left apart and so none of the following will apply to namespace attribute.

Using a option seems the best and most flexible way to handle it for most case.
We could set an option copyAttr and cover theses values :

  • false or null (default) : Behave like now, no attributes are copied except viewBox
  • true : Copy all attributes
  • array (white-list) : Copy attributes whose names are included in the array.
  • function(AttrName, AttrValue, symbolId) : Function is called for each attribute of each sprite and return true or false.

Now I don't know what to do about viewBox in the case of an array : Should it be included on the array or should it be implicitly considered into the white-list and always copied.
IMHO it should be treated as any other attribute and then should be part of the array.

The last form using callback is handy because you can create a map to keep track of viewBox values while returning false so it won't be copied.
Here is a snippet :

var map = {};
gulp.src('...')
.svgstore({
    copyAttr: function(name, value, id){
        if(name == 'viewBox'){
           map[id] = value
           return false;
        }
        return true;
    }
})

//inject/update html file with the map

Should this package be split in two?

I realised that the code in index.js is almost entirely usable without gulp, so I was wondering if it would make sense to split into a svgstore package and a gulp-svgstore wrapper, so people (like me!) can use the svgstore sans-gulp?

Thanks!

Generates SVG file even if source is empty/null

This may be by design, but currently gulp-svgstore will generate an empty SVG file if the gulp.src(path.to.svg.directory) returns an empty directory or no files.

<svg xmlns="http://www.w3.org/2000/svg">

Any consideration to generating nothing in a situation like this?

I can see why you might want to return an empty file. If, for example, you're injecting the file dynamically into an HTML document, a null file would break other Gulp tasks. Perhaps this is best as an optional setting?

Pure JS API

I'd love this functionality as a pure JS api rather than being married to gulp. I haven't found a suitable alternative. Before forking this and building a new module myself I thought I'd ask if there were already plans for this or if there was a known alternative that isn't tied to another build tool (grunt, broccoli, cli, etc.).

Ideally something like this:

var mergedSvgFile = svgstore(listOfSvgStringsOrBuffers, options);

inlineSvg option should also strip out xmlns attributes

In addition to removing the <xml> and <!DOCTYPE> stuff, I think inlineSvg = true should also remove the xmlns and xmlns:xlink attributes from the <svg> itself.

This article from David Sleight makes two points about this:

  • IE8 chokes when an inlineSvg has the xmlns attribute
  • there is no functional reason to use either the xmlns or the xmlns:xlink attribute in HTML5

It would be possible to use transformSvg() for this, but since there's a custom option already available for inlineSvg it seems like it should be bundled there.

Note: This doesn't really apply to the process of generating the sprite sheet. But I have a separate gulp process that moves all vectors from src to dist in case I need to use them individually. But in either case, the xmlns attributes are useless in the output files.

Conflicting gradient ids after merge?

I have two SVGs. Each one had linearGradients defined. The first one has it like this:

<linearGradient id="SVGID_3_" gradientUnits .... etc

and the second one has a linear gradient with the same id:

<linearGradient id="SVGID_3_" x1="29.6744" y1="50.....

So now, after svgstore combined my SVGs, I have two different linear gradients with the same IDs. That means there are conflicts and the gradients get used on the wrong svg sprites.

How do I avoid this? I'm working with SVGs that are generated by Adobe Illustrator. It pretty much chooses it's own naming convention for the gradient ids for each separate SVG. It's no wonder they aren't unique to each other.

Short of manually changing the IDs, what is the best approach to solving this? Surely I'm not the first person to come across this issue right?

Removing doctype from generated sprite sheet

Hi,

Just wondering if there's a way to remove the doctype and xml header from the main generated sprite sheet?

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

Add npm installation instruction

I was missing a simple npm install instruction which is kind of established for gulp/grunt plugins.

So I guess putting something like this in the README.md would be helpful to gulp/grunt newcomers:

npm install gulp-svgstore --save-dev

Symbols are empty after gulp-remember has populated it's cache

I'm currently utilizing gulp-cached and gulp-remember to make my build more incremental.
Unfortunately gulp-svgstore is broken in conjunction with gulp-remember.

I tracked the issue down, to the following lines of code:

  1. gulp-svgstore adds a JSDOM cheerio property to the current file, but only if it does not exist already.
    file.cheerio
  2. This SVG document is cached in $svg $svg
  3. At the end the whole contens of the $svgvariable is appended to the current SVG symbol $symbol.
    This step removes all children of $svgand hence also of file.cheerio, which causes empty <symbol> tags in my sprite after gulp-cached and gulp-remember have done their magic (e.g. after a watch has triggered).

Suggested Fix 1

Cleanup file.cheerio reference in stream._transform function:

delete file.cheerio; 

Suggested Fix 2

Just clone the entire svg before appending it to a symbol. This way the cache stays untouched.

Quick fix utilizing gulp-intercept

gulp.src('src/icons/*.svg')
    .pipe($.cached('sprites:svg'))
    .pipe($.svgmin(function (file) {
        var prefix = path.basename(file.relative, path.extname(file.relative));
        return {
            plugins: [{
                cleanupIDs: {
                    prefix: prefix + '-',
                    minify: config.minifySVG
                }
            }]
        }
    }))
    .pipe($.remember('sprites:svg'))
    .pipe($.intercept(function(file) {
        // this is IMPORTANT!!!!
        // gulp-svgstore adds cheerio property to file, but does not clean up
        // hence this breaks gulp-remember, who remembers an empty cheerio instance.
        delete file.cheerio;
        return file;
    }))
    .pipe($.svgstore())
    .pipe(gulp.dest('dest/icons'))
``

Blank visual output

I'm trying out the plugin by just using the "times" icon from FontAwesome. My task is as follows (more or less, removed variables for paths):

import gulp from 'gulp';
import svgstore from 'gulp-svgstore';

gulp.task('icons', () => {
    return gulp.src('icons/times.svg')
        .pipe(svgstore())
        .pipe(gulp.dest('icons/output'));
});

The output SVG file is as follows:

<?xml version="1.0" encoding="UTF-8"?><!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"><symbol id="times" viewBox="0 0 1792 1792"><path d="M1490 1322q0 40-28 68l-136 136q-28 28-68 28t-68-28l-294-294-294 294q-28 28-68 28t-68-28l-136-136q-28-28-28-68t28-68l294-294-294-294q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 294 294-294q28-28 68-28t68 28l136 136q28 28 28 68t-28 68l-294 294 294 294q28 28 28 68z"/></symbol></svg>

Great. I now load it in Illustrator (or in a page, whatever) and I see nothing. There is nothing in the SVG file visually, try to select all in Illustrator and it selects nothing.

What am I missing in this equation?

defs inside symbols like lineargradient and mask arent recognized by IE/Firefox (works in chrome)

If you have an svg icon like this:

<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 446.9 512" >
    <defs>
<linearGradient id="grad" gradientUnits="userSpaceOnUse" x1="-49.1313" y1="-138.4424" x2="-48.4011" y2="-138.4424" gradientTransform="matrix(4.282765e-14 699.4286 -612 3.747418e-14 -84503.2812 34364.4883)">
    <stop  offset="0" style="stop-color:#F7931E"/>
    <stop  offset="1" style="stop-color:#F2693E"/>
</linearGradient>
  </defs>
<polygon style="fill:url(#grad)" points="446.9,256 0,512 0,0 "/>
</svg>

the generated svg :

<svg xmlns="http://www.w3.org/2000/svg"><symbol id="logo" viewBox="0 0 446.9 512">
    <defs>
        <linearGradient id="a" gradientUnits="userSpaceOnUse" x1="-49.131" y1="-138.442" x2="-48.401" y2="-138.442" gradientTransform="matrix(0 699.429 -612 0 -84503.281 34364.488)">
            <stop offset="0" stop-color="#F7931E"/>
            <stop offset="1" stop-color="#F2693E"/>
        </linearGradient>
    </defs>
    <path fill="url(#a)" d="M446.9 256L0 512V0z"/>
</symbol>
</svg

the gradient wont show in ie and firefox

even worst if the svg (or any wrapping div) are set to display none it wont work ( another problem tough)

Structuring SVG files

Having a little bit of trouble with creating separate files. If I have a directory structured as such:

social/
    twitter.svg
    github.svg
devices/
    phone.svg
    tablet.svg
    desktop.svg

Any thoughts on how I structure my "src" so that it would output the following files:

social.svg
devices.svg

Option to switch between <symbol> and <g>

An option switch so we could choose between transforming files into <symbol> or <g>.

<symbol> is awesome for icons, but doesn't work for CSS backgrounds. <g> is awesome for CSS backgrounds.

In other words, this doesn't work with <symbol>, but does with <g>:

.foo {
  background: url('images.svg#bar');
}

Output symbols only

I was wondering if there is anyway to just output everything as <symbols> (like already happens), but without the <svg> wrapper and initial <defs><style> etc?

Documentation for transforms

I want to create inline svg with the display property set to none. I cannot find how the transform functions should be incorporated into gulps pipe structure.

I tried the following but no luck

gulp.task('svg', function () {
    var svgs = gulp.src(['app/resources/*.svg', '!app/resources/lines.svg'])
        .pipe(svgmin())
        .pipe(svgstore({inlineSvg: true}))
        .pipe(function transformSvg (svg, cb) {
            svg.attr({ style: 'display:none' })
            cb(null)
        })

    return gulp.src('app/index.html')
        .pipe(inject(svgs, { transform: fileContents }))
        .pipe(gulp.dest('www/'));
}); 

duplicate xmlns:link attributes

version 5.0.5 is adding the xmlns:link attribute twice to our combined svg file.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">

version 5.0.4 works fine.

Remove transformSvg

I consider completely removing transformSvg from gulp-svgstore, and suggest to use gulp-cheerio.

Also, it would be great if gulp-cheerio cached parsed xml in file objects, so it could be reused in other gulp plugins. For this I have created this issue.

svgstore ignores `base` gulp.SRC option

Given this pipeline:

gulp.src('foo/**/*.svg', { base: '.' })
  .pipe(svgstore())
  .pipe(gulp.dest('.'))

the plugin should output to foo, as do all plugins I tried (e.g. uglify); svgstore save its output on foo parent directory, instead.

Files

/
|--> gulpfile.js
|--> foo/
     |--> *.svg

Fails to install

the new version of gulp-svgstore fails to install (on OS X 10.9) because it fails to run the install script for libxml

Rendering issue with gradients on browsers?

I'm having a bit of an issue when it comes to rendering SVGs with gradients associated with them, using svgstore. If I place the SVG as an image it, looks fine. Using svgstore however causes this weird behaviour in the gradients.

svg-issue

As you can see on Chrome, it renders correctly. However the results on IE11 and FireFox greatly differ...

I've wrapped the <svg> around with a <div>, and styled:

.svg-hide {
    width: 0;
    height: 0;
    overflow: hidden;
}

I'm calling symbols like this:

<svg class="icon icon__plane"><use xlink:href="#icon__plane" /></svg>

Gulpfile:

// svgstore
gulp.task('svgstore', function () {
    return gulp
        .src(options.paths.images + 'svg/*.svg')
        .pipe(svgmin(function (file) {
            var prefix = path.basename(file.relative, path.extname(file.relative));
            return {
                plugins: [{
                    cleanupIDs: {
                        prefix: prefix + '--',
                        minify: true
                    }
                }]
            };
        }))
        .pipe(svgstore({ inlineSvg: true }))
        // .pipe(svgstore())
        .pipe(rename('sprite.svg.twig'))
        .pipe(gulp.dest(options.paths.html + 'Default/partial/'));
});

Any help on this issue would be greatly appreciated. Thanks.

Using SVGO options

I'd like to have the output XML pretty printed by using SVGO's pretty option. Is it currently possible to do that with gulp-svgstore?

Remove prefix and fileName

Prefix can be added with gulp-rename.

Filename can be guessed from the directory name of the first svg file.
If its not a good convention, then one might rename using gulp-rename.

Styling issue in chrome

Hi, love this thing. thanks for all the great work. I am having trouble styling the svg in chrome. It's basically just ignoring the styles i declare. Works in firefox, but not chrome. Any ideas?

Here's what I'm using to render

<svg class="site-header__icon">
   <use class="icon-search" xlink:href="#icon-search" />
</svg>

Here's my scss

.site-header__icon { //This is the svg tag
   height: 18px;
   width: 18px;
   g, path {
      stroke: #fff;
   }
}

Issue with SVG from Sketch

Hi there,

I'm working on a design that was created in Sketch. For some reason that I don't understand, the SVG don't render as expected after using this plugin. See what I'm talking about:

Before & After screenshot

image

Base SVG:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="96px" height="96px" viewBox="0 0 96 96" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
    <!-- Generator: bin/sketchtool 1.4 (305) - http://www.bohemiancoding.com/sketch -->
    <title>icon-work</title>
    <desc>Created with bin/sketchtool.</desc>
    <defs>
        <filter x="-50%" y="-50%" width="200%" height="200%" filterUnits="objectBoundingBox" id="filter-1">
            <feOffset dx="0" dy="2" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
            <feGaussianBlur stdDeviation="4" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
            <feColorMatrix values="0 0 0 0 0   0 0 0 0 0   0 0 0 0 0  0 0 0 0.35 0" in="shadowBlurOuter1" type="matrix" result="shadowMatrixOuter1"></feColorMatrix>
            <feMerge>
                <feMergeNode in="shadowMatrixOuter1"></feMergeNode>
                <feMergeNode in="SourceGraphic"></feMergeNode>
            </feMerge>
        </filter>
    </defs>
    <g id="Home" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
        <g id="Home---Web" sketch:type="MSArtboardGroup" transform="translate(-672.000000, -3252.000000)">
            <g id="icon-work" sketch:type="MSLayerGroup" transform="translate(680.000000, 3258.000000)">
                <circle id="Oval-72-Copy-20" stroke="#756196" fill="#44355C" filter="url(#filter-1)" sketch:type="MSShapeGroup" cx="40" cy="40" r="40"></circle>
                <path d="M37.0000085,41 L23,41 L23,36.5 C23,34.0147186 25.0124601,32 27.4973899,32 L33,32 L33,31 C33,29.3431458 34.3423789,28 36.0033512,28 L43.9966488,28 C45.6553538,28 47,29.3465171 47,31 L47,32 L47,32 L52.5026101,32 C54.9864499,32 57,34.0197757 57,36.5 L57,41 L42.9999917,41 C42.9999972,41.0019723 43,41.0039453 43,41.0059191 L43,43.9940809 C43,45.1019194 42.1017394,46 41.0020869,46 L38.9979131,46 C37.8944962,46 37,45.1134452 37,43.9940809 L37,41.0059191 C37,41.0039454 37.0000029,41.0019723 37.0000085,41 L37.0000085,41 Z M36,44 L24,44 L24,53.002848 C24,54.6583772 25.3413998,56 26.9961002,56 L53.0038998,56 C54.6657405,56 56,54.6581293 56,53.002848 L56,44 L44,44 C44,45.6568542 42.6609799,47 40.9983345,47 L39.0016655,47 C37.3438914,47 36,45.6534829 36,44 Z M45,32 L45,31.0093689 C45,30.4433532 44.5543453,30 44.0046024,30 L35.9953976,30 C35.4556644,30 35,30.4519098 35,31.0093689 L35,32 L45,32 Z M38,40.9998075 C38,40.4476291 38.4433532,40 39.0093689,40 L40.9906311,40 C41.5480902,40 42,40.4437166 42,40.9998075 L42,44.0001925 C42,44.5523709 41.5566468,45 40.9906311,45 L39.0093689,45 C38.4519098,45 38,44.5562834 38,44.0001925 L38,40.9998075 Z" id="Rectangle-343" fill="#9E91B2" sketch:type="MSShapeGroup"></path>
            </g>
        </g>
    </g>
</svg>

Generated symbol

<symbol id="icon-work" viewBox="0 0 96 96"><title>icon-work</title><g transform="translate(8 6)" fill="none" fill-rule="evenodd"><circle stroke="#756196" fill="#44355C" filter="url(#filter-1)" cx="40" cy="40" r="40"/><path d="M37 41H23v-4.5c0-2.485 2.012-4.5 4.497-4.5H33v-1c0-1.657 1.342-3 3.003-3h7.994C45.655 28 47 29.347 47 31v1h5.503C54.986 32 57 34.02 57 36.5V41H43V43.994C43 45.102 42.102 46 41.002 46h-2.004C37.894 46 37 45.113 37 43.994v-2.988V41zm-1 3H24v9.003C24 54.658 25.34 56 26.996 56h26.008C54.666 56 56 54.658 56 53.003V44H44c0 1.657-1.34 3-3.002 3h-1.996C37.344 47 36 45.653 36 44zm9-12v-.99c0-.567-.446-1.01-.995-1.01h-8.01c-.54 0-.995.452-.995 1.01V32h10zm-7 9c0-.552.443-1 1.01-1h1.98c.558 0 1.01.444 1.01 1v3c0 .552-.443 1-1.01 1h-1.98c-.558 0-1.01-.444-1.01-1v-3z" fill="#9E91B2"/></g></symbol>

From what I have researched, this could be linked: FWeinb/grunt-svgstore#25 but I'm not sure.

Please tell me whether this is a known issue and if there's a work around.

Thanks

does not work properly with null files

version "gulp-svgstore": "~5.0.3"

error:
file.cheerio = cheerio.load(file.contents.toString(), { xmlMode: true })
TypeError: Cannot call method 'toString' of null

quick fix:
add

    if (file.isNull()) {
      return cb(null, file);
    }

before

    if (!file.cheerio) {
      file.cheerio = cheerio.load(file.contents.toString(), { xmlMode: true })
    }

Reinstate prefix and filename options

It would be good to use the folder/filenames as defaults but also have the option to prefix and change the output filename.

This seems like a step backwards.

repaint logo in sprite

I use you plugin without any setting.
I put two logo in directory:
one_logo_s2.svg
two_logo-s2.svg
And when i use your plugin, first logo repaint at color of second logo. And second logo i see normal.
Text of both logo in right color. But background of main part of first logo is wrong.
I put another few another logo. Only one logo have his color.
If i remove second logo from directory. Another logo use background color from the first logo. And etc...
Maybe something with svg?
Can you help me? What I do wrong?

Create multiple files

For now svgstore takes a bunch of files as input and output a single merged file.

What about generating multiple output file ?

I'm thinking about 2 simple way of doing it :

  1. With some option like recurse:true we would expect a 2 level folder hierarchy like that :
    .
    ├── theme1
    │   ├── sprite1.svg
    │   ├── sprite2.svg
    │   ├── ....
    ├── theme2
    │   ├── sprite1.svg
    │   ├── sprite2.svg
    │   ├── ....
    ├── ....

=> theme1.svg, theme2.svg

So each folder represent an output and its content the input.

  1. Through a callback function that would match each input file to an output file. If function returns same value for multiple files they'll be merged into the same output. The return value could be the output filename or filepath.

Of course both solution may coexist, actually 1) would just be some alias to define the callback function of 2).

Gradients not rendering

Hey,

Been testing out gulp-svgstore for my new site. I have got it working on quite a few SVG's and it's great.

However, any svg's that contain gradients do not render them. On;y the solid fill areas show up. I have read everything I can find to locate a solution but can't seem to get anything to work. I tried moving a linearGradient blog out of the and this allows it to display in Firefox but still nothing in Chrome.

I also have a lot of SVG's and quite a few have a lot of gradients so it's a big issue for me here. Is there a solution to this and if so, is there an automated way that can be done as part of the gulp workflow and svgstore task?

Change path id's to classes

Hey, I'm pretty new to all this but is there a way to run through and change any the id's on paths to classes?

Or is this a job for svgmin?

Reconsider xml library

I've chosen libxmljs but just found this fork by @lemming that replaces it with cheerio.

Unfortunately changes by @lemming cannot be merged because they contain code style changes. Does anybody know what are benefits of this? Is it because of better performance or because its easier to install cheerio than libxmljs?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.