twolfson/layout

Custom Template not working

Closed this issue · 7 comments

Hello,

I'm trying to create a custom template that is left to right, but 2 rows of images tall.

My gulpfile.js:

var gulp = require('gulp');
var spritesmith = require('gulp.spritesmith');
var layout = require('layout');

gulp.task('add-custom-layout', function() {
    spritesmith.layout = layout;
    spritesmith.layout.addAlgorithm('2-row', require('./sprites/algorithms/2-row.js'));
});

gulp.task('sprite-sleeve', function() {
    var spriteData = gulp.src('./sprites/src/sleeve/*.png').pipe(spritesmith({
        imgName: './sprites/generated/sleeve.png',
        cssName: './src/css/filter-panel/sleeve/sleeve-sprite.scss',
        algorithm: '2-row',
        cssSpritesheetName: 'sleeve',
        cssVarMap: function (sprite) {
            sprite.name = 'vs-icon-' + sprite.name;
        },
        cssTemplate: './sprites/icon.scss.handlebars'
    }));
    return spriteData.pipe(gulp.dest('./'));
});

gulp.task('sprite', ['add-custom-layout', 'sprite-sleeve']);
gulp.task('default', ['sprite']);

My custom algorithm 2-row.js is literally just a copy and paste of the left-right algorithm.

The error is on https://github.com/twolfson/layout/blob/master/lib/layout.js line 21. Essentially my algorithm cannot be found.

I tried to debug and find the root cause. It seems like even though i add the algorithm to the layout module imported into my package, that layout doesn't ever get put through to the actual spritesmith code https://github.com/Ensighten/spritesmith/blob/master/src/smith.js::processImages method.

Any ideas on the issue? Any errors in my code? Are there any examples of working custom templates? The documentation was a bit light on this area.

Thank you for your time and really loving spritesmith on the whole!

I'm not sure where you got defining spritesmith.layout from but we don't support that implementation =/

https://github.com/twolfson/gulp.spritesmith/blob/6.2.1/lib/gulp-spritesmith.js

We currently don't have support for adding layout algorithms (nobody has asked before) but we have added support for dynamic functions before with respect to templating so we should be able to do the same for layout.

However, we should be able to get the existing code working without new functionality. Make sure the following are taken care of:

  • layout is declared as a top level dependency in package.json
  • layout and gulp.spritesmith were installed at the same time (this is to guarantee they refer to the same library)
    • Sometimes we might need to run npm dedupe as well
  • Update your code to the following (skips parallel dependency issue that currently exists)
// Load in our dependencies
var gulp = require('gulp');
var spritesmith = require('gulp.spritesmith');
var layout = require('layout');

// Add our new algorithm
layout.addAlgorithm('2-row', require('./sprites/algorithms/2-row.js'));

// Define our spritesmith tasks
gulp.task('sprite-sleeve', function() {
    var spriteData = gulp.src('./sprites/src/sleeve/*.png').pipe(spritesmith({
        imgName: './sprites/generated/sleeve.png',
        cssName: './src/css/filter-panel/sleeve/sleeve-sprite.scss',
        algorithm: '2-row',
        cssSpritesheetName: 'sleeve',
        cssVarMap: function (sprite) {
            sprite.name = 'vs-icon-' + sprite.name;
        },
        cssTemplate: './sprites/icon.scss.handlebars'
    }));
    return spriteData.pipe(gulp.dest('./'));
});

gulp.task('sprite', ['sprite-sleeve']);
gulp.task('default', ['sprite']);

Thanks for the quick response. I had tried your suggested code and that hadn't worked at the time. I should've looked closer at the code i posted and sent you both versions i had tried.

Regardless, it does seem to be a package version issue of some sort as you predicted. I re-installed both layout and gulp.spritesmith and that has fixed the issue! npm dedupe didn't seem to help.

Cool, I'm glad to hear the issue has been resolved. For our reference, what's the purpose of your custom layout?

I wanted more of a grid layout of my images instead of a single row (left-right) or single column (top-bottom). In particular, the top row is the default state of the icons, second row is the selected state, third row is the disabled state (eventually).

Not sure if its possible, but i'll try to make it so the number of rows/columns is configurable.

Ah, k. For what it's worth binary-tree is the closest algorithm to that and should be better performance if you have any non-state based sprites (e.g. it will take up least amount of visual space and thus bytes). Although, it might not be as aesthetically pleasing.

I tried that out just now and that doesn't work very well for my specific use case. Say i have 10 icons. I would want a layout like:

x x x x x
x x x x x

No empty/wasted space.

binary-tree outputs something like:

x x x x
x x x o
x x x o

Which has 2 empty spots. Does that make sense?

Ah, k. I guess it isn't a perfect algorithm (hard problem to solve) =/