How can I use gulp.spritesmith to make multi images
zswxp32 opened this issue · comments
I have used grunt-spritesmith before and find that I can parse a image-config to grunt-spritesmith, it works perfect.
Now I don't know how gulp.spritesmith do with multi image-config, I had tried "merge-stream", but it only works for one of image-config.
Please tell me how to do with this situation, how to correctly return.
Now I use like this and don't know if it's correct...haha
gulp.task('sprite', () => {
console.log('sprite start!');
_.forEach(spriteConfig, (val, key) => {
let spritesmithOptions = {
imgName: key + '.png',
cssName: key + '.less',
padding: 10,
engine: 'pixelsmith',
algorithm: 'binary-tree',
cssOpts: Object.assign(
{
base64: false
},
val.cssOpts
)
}
let spriteData = gulp.src(val.src)
.pipe(spritesmith(spritesmithOptions));
let imgStream = spriteData.img
.pipe(gulp.dest('./image_new/sprite'));
let lessStream = spriteData.css
.pipe(gulp.dest('./less_new/sprite'));
return merge(imgStream, lessStream);
});
});
You were so close to the answer o.o
The issue is Gulp needs some way of knowing a task completes. It has a few mechanisms for this:
- Running task synchronously (return nothing)
- Async callback (ask for
done
as parameter in task) - Stream (return stream so it can listen for
finish
event) - Promise (return promise so it can listen to
error
andthen
actions)
In our scenario, we are dealing with streams so we need to return a stream with all of our items on it. We can merge our merge stream results and return that to get the result:
gulp.task('sprite', () => {
console.log('sprite start!');
// Updated to `_.map` and saved variable
var retStreams = _.map(spriteConfig, (val, key) => {
let spritesmithOptions = {
imgName: key + '.png',
cssName: key + '.less',
padding: 10,
engine: 'pixelsmith',
algorithm: 'binary-tree',
cssOpts: Object.assign(
{
base64: false
},
val.cssOpts
)
}
let spriteData = gulp.src(val.src)
.pipe(spritesmith(spritesmithOptions));
let imgStream = spriteData.img
.pipe(gulp.dest('./image_new/sprite'));
let lessStream = spriteData.css
.pipe(gulp.dest('./less_new/sprite'));
return merge(imgStream, lessStream);
});
// Returned a merge stream of array of streams
return merge(retStreams);
});
merge-stream
doesn't document this well but it supports infinite levels of arrays as a parameters due to its recursion:
https://github.com/grncdr/merge-stream/blob/v1.0.1/index.js#L16-L24
Another option would be to define separate sprite
tasks (e.g. sprite-foo
, sprite-bar
) and define a sprite
task which calls those (i.e. gulp.task('sprite', ['sprite-foo', 'sprite-bar'])
)