mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 06:07:21 +01:00
Move sprites task to gulp
This commit is contained in:
128
tasks/gulp-sprites.js
Normal file
128
tasks/gulp-sprites.js
Normal file
@@ -0,0 +1,128 @@
|
||||
import gulp from 'gulp';
|
||||
import imagemin from 'gulp-imagemin';
|
||||
import spritesmith from 'gulp.spritesmith';
|
||||
import clean from 'gulp-clean';
|
||||
import sizeOf from 'image-size';
|
||||
import merge from 'merge-stream';
|
||||
import {sync} from 'glob';
|
||||
import {times, each} from 'lodash';
|
||||
|
||||
const SPRITES_SRC = sync('common/img/sprites/spritesmith/**/*.png');
|
||||
const DIST_PATH = 'common/dist/sprites/';
|
||||
|
||||
// https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248
|
||||
const MAX_SPRITESHEET_SIZE = 1024 * 1024 * 3;
|
||||
const SPRITESHEET_COUNT = _calculateNumberOfSpritesheets();
|
||||
const NUMBER_OF_SPRITES_PER_SHEET = SPRITES_SRC.length / SPRITESHEET_COUNT;
|
||||
|
||||
let spritesTasks = ['sprites:clean'];
|
||||
|
||||
times(SPRITESHEET_COUNT, (i) => {
|
||||
let slicedSrc = _getSliceSrc(i);
|
||||
|
||||
let taskName = `sprites:${i}`;
|
||||
spritesTasks.push(taskName);
|
||||
|
||||
gulp.task(taskName, () => {
|
||||
let spriteData = gulp.src(slicedSrc)
|
||||
.pipe(spritesmith({
|
||||
imgName: `spritesmith${i}.png`,
|
||||
cssName: `spritesmith${i}.css`,
|
||||
algorithm: 'binary-tree',
|
||||
padding:1,
|
||||
cssTemplate: 'common/css/css.template.mustache',
|
||||
cssVarMap: _cssVarMap
|
||||
}));
|
||||
|
||||
let imgStream = spriteData.img
|
||||
.pipe(imagemin())
|
||||
.pipe(gulp.dest(DIST_PATH));
|
||||
|
||||
let cssStream = spriteData.css
|
||||
.pipe(gulp.dest(DIST_PATH));
|
||||
|
||||
return merge(imgStream, cssStream);
|
||||
});
|
||||
});
|
||||
|
||||
gulp.task('sprites:clean', (done) => {
|
||||
gulp.src(`${DIST_PATH}spritesmith*`)
|
||||
.pipe(clean());
|
||||
|
||||
done();
|
||||
});
|
||||
|
||||
gulp.task('sprites:checkCompiledDimensions', () => {
|
||||
console.log('Verifiying that images do not exceed max dimensions');
|
||||
|
||||
let numberOfSheetsThatAreTooBig = 0;
|
||||
|
||||
times(SPRITESHEET_COUNT, (i) => {
|
||||
let fileName = `spritesmith${i}.png`;
|
||||
let spritesheetPath = `${DIST_PATH}${fileName}`
|
||||
let spriteSize = _calculateImgDimensions(spritesheetPath);
|
||||
|
||||
|
||||
if (spriteSize > MAX_SPRITESHEET_SIZE) {
|
||||
numberOfSheetsThatAreTooBig++;
|
||||
console.error(`WARNING: ${fileName} is too big - ${spriteSize} > ${MAX_SPRITESHEET_SIZE}`);
|
||||
}
|
||||
});
|
||||
|
||||
if (numberOfSheetsThatAreTooBig > 0) {
|
||||
console.error(`${numberOfSheetsThatAreTooBig} sheets are too big :(`);
|
||||
console.error('Mobile Safari may be unhappy with you');
|
||||
}
|
||||
});
|
||||
|
||||
gulp.task('sprites:compile', spritesTasks, () => {
|
||||
gulp.run('sprites:checkCompiledDimensions');
|
||||
});
|
||||
|
||||
function _getSliceSrc(num) {
|
||||
let start = num * NUMBER_OF_SPRITES_PER_SHEET;
|
||||
let end = (num + 1) * NUMBER_OF_SPRITES_PER_SHEET;
|
||||
let src = SPRITES_SRC.slice(start, end)
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
function _calculateNumberOfSpritesheets() {
|
||||
let totalPixels = 0;
|
||||
|
||||
each(SPRITES_SRC, function(img){
|
||||
totalPixels += _calculateImgDimensions(img);
|
||||
});
|
||||
|
||||
let numberOfSpriteSheets = Math.ceil(totalPixels / MAX_SPRITESHEET_SIZE);
|
||||
|
||||
return numberOfSpriteSheets;
|
||||
}
|
||||
|
||||
function _calculateImgDimensions(img) {
|
||||
let dims = sizeOf(img);
|
||||
|
||||
if(!dims.width || !dims.height) console.error('MISSING DIMENSIONS:', dims);
|
||||
|
||||
let totalPixelSize = dims.width * dims.height;
|
||||
|
||||
return totalPixelSize;
|
||||
}
|
||||
|
||||
function _cssVarMap(sprite) {
|
||||
// For hair, skins, beards, etc. we want to output a '.customize-options.WHATEVER' class, which works as a
|
||||
// 60x60 image pointing at the proper part of the 90x90 sprite.
|
||||
// We set up the custom info here, and the template makes use of it.
|
||||
if (sprite.name.match(/hair|skin|beard|mustach|shirt|flower|^headAccessory_special_\w+Ears/) || sprite.name=='head_0') {
|
||||
sprite.custom = {
|
||||
px: {
|
||||
offset_x: `-${ sprite.x + 25 }px`,
|
||||
offset_y: `-${ sprite.y + 15 }px`,
|
||||
width: '60px',
|
||||
height: '60px'
|
||||
}
|
||||
}
|
||||
}
|
||||
if (~sprite.name.indexOf('shirt'))
|
||||
sprite.custom.px.offset_y = `-${ sprite.y + 30 }px`; // even more for shirts
|
||||
}
|
||||
Reference in New Issue
Block a user