mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 14:17:22 +01:00
Move sprites task to gulp
This commit is contained in:
73
Gruntfile.js
73
Gruntfile.js
@@ -2,57 +2,6 @@
|
|||||||
var _ = require('lodash');
|
var _ = require('lodash');
|
||||||
module.exports = function(grunt) {
|
module.exports = function(grunt) {
|
||||||
|
|
||||||
// Ported from shared
|
|
||||||
// So this sucks. Mobile Safari can't render image files > 1024x1024*3, so we have to break it down to multiple
|
|
||||||
// files in this hack approach. See https://github.com/Ensighten/grunt-spritesmith/issues/67#issuecomment-34786248
|
|
||||||
var images = grunt.file.expand('common/img/sprites/spritesmith/**/*.png');
|
|
||||||
// var totalDims = {width:0,height:0};
|
|
||||||
// _.each(images, function(img){
|
|
||||||
// var dims = sizeOf(img);
|
|
||||||
// if(!dims.width || !dims.height) console.log(dims);
|
|
||||||
// totalDims.width += dims.width;
|
|
||||||
// totalDims.height += dims.height;
|
|
||||||
// })
|
|
||||||
var COUNT = 7;//Math.ceil( (totalDims.width * totalDims.height) / (1024*1024*3) );
|
|
||||||
//console.log({totalDims:totalDims,COUNT:COUNT});
|
|
||||||
|
|
||||||
var sprite = {};
|
|
||||||
_.times(COUNT, function(i){
|
|
||||||
var sliced = images.slice(i * (images.length/COUNT), (i+1) * images.length/COUNT)
|
|
||||||
sprite[''+i] = {
|
|
||||||
src: sliced,
|
|
||||||
dest: 'common/dist/sprites/spritesmith'+i+'.png',
|
|
||||||
destCss: 'common/dist/sprites/spritesmith'+i+'.css',
|
|
||||||
engine: 'phantomjssmith',
|
|
||||||
algorithm: 'binary-tree',
|
|
||||||
padding:1,
|
|
||||||
cssTemplate: 'common/css/css.template.mustache',
|
|
||||||
cssVarMap: function (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: "" + 60 + "px",
|
|
||||||
height: "" + 60 + "px"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (~sprite.name.indexOf('shirt'))
|
|
||||||
sprite.custom.px.offset_y = "-" + (sprite.y + 30) + "px"; // even more for shirts
|
|
||||||
}
|
|
||||||
/*,cssOpts: {
|
|
||||||
cssClass: function (item) {
|
|
||||||
return '.' + item.name; //'.sprite-' + item.name;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
// Project configuration.
|
// Project configuration.
|
||||||
grunt.initConfig({
|
grunt.initConfig({
|
||||||
pkg: grunt.file.readJSON('package.json'),
|
pkg: grunt.file.readJSON('package.json'),
|
||||||
@@ -69,24 +18,7 @@ module.exports = function(grunt) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
clean: {
|
clean: {
|
||||||
build: ['website/build'],
|
build: ['website/build']
|
||||||
sprite: ['common/dist/sprites']
|
|
||||||
},
|
|
||||||
|
|
||||||
sprite: sprite,
|
|
||||||
|
|
||||||
imagemin: {
|
|
||||||
spritesmith: {
|
|
||||||
options: {
|
|
||||||
optimizationLevel: 7
|
|
||||||
},
|
|
||||||
files: [{
|
|
||||||
expand: true,
|
|
||||||
flatten: true,
|
|
||||||
src: ["common/dist/sprites/*.png"],
|
|
||||||
dest: "common/dist/sprites/"
|
|
||||||
}]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
cssmin: {
|
cssmin: {
|
||||||
@@ -200,7 +132,6 @@ module.exports = function(grunt) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Register tasks.
|
// Register tasks.
|
||||||
grunt.registerTask('compile:sprites', ['clean:sprite', 'sprite', 'imagemin', 'cssmin']);
|
|
||||||
grunt.registerTask('build:prod', ['loadManifestFiles', 'clean:build', 'browserify', 'uglify', 'stylus', 'cssmin', 'copy:build', 'hashres']);
|
grunt.registerTask('build:prod', ['loadManifestFiles', 'clean:build', 'browserify', 'uglify', 'stylus', 'cssmin', 'copy:build', 'hashres']);
|
||||||
grunt.registerTask('build:dev', ['browserify', 'stylus']);
|
grunt.registerTask('build:dev', ['browserify', 'stylus']);
|
||||||
grunt.registerTask('build:test', ['test:prepare:translations', 'build:dev']);
|
grunt.registerTask('build:test', ['test:prepare:translations', 'build:dev']);
|
||||||
@@ -222,8 +153,6 @@ module.exports = function(grunt) {
|
|||||||
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
grunt.loadNpmTasks('grunt-contrib-cssmin');
|
||||||
grunt.loadNpmTasks('grunt-contrib-copy');
|
grunt.loadNpmTasks('grunt-contrib-copy');
|
||||||
grunt.loadNpmTasks('grunt-contrib-watch');
|
grunt.loadNpmTasks('grunt-contrib-watch');
|
||||||
grunt.loadNpmTasks('grunt-spritesmith');
|
|
||||||
grunt.loadNpmTasks('grunt-contrib-imagemin');
|
|
||||||
grunt.loadNpmTasks('grunt-hashres');
|
grunt.loadNpmTasks('grunt-hashres');
|
||||||
grunt.loadNpmTasks('grunt-karma');
|
grunt.loadNpmTasks('grunt-karma');
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,6 @@
|
|||||||
"grunt-contrib-watch": "~0.6.1",
|
"grunt-contrib-watch": "~0.6.1",
|
||||||
"grunt-hashres": "~0.4.1",
|
"grunt-hashres": "~0.4.1",
|
||||||
"grunt-karma": "~0.6.2",
|
"grunt-karma": "~0.6.2",
|
||||||
"grunt-spritesmith": "~3.5.0",
|
|
||||||
"gulp": "^3.9.0",
|
"gulp": "^3.9.0",
|
||||||
"gulp-grunt": "^0.5.2",
|
"gulp-grunt": "^0.5.2",
|
||||||
"icalendar": "lefnire/node-icalendar#e06da0e55901f0ba940dfadc42c158ed0b1fead9",
|
"icalendar": "lefnire/node-icalendar#e06da0e55901f0ba940dfadc42c158ed0b1fead9",
|
||||||
@@ -82,6 +81,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "gulp test",
|
"test": "gulp test",
|
||||||
"start": "gulp run:dev",
|
"start": "gulp run:dev",
|
||||||
|
"sprites": "gulp sprites:compile",
|
||||||
"postinstall": "bower --config.interactive=false install -f; gulp build;",
|
"postinstall": "bower --config.interactive=false install -f; gulp build;",
|
||||||
"coverage": "COVERAGE=true mocha --require register-handlers.js --reporter html-cov > coverage.html; open coverage.html"
|
"coverage": "COVERAGE=true mocha --require register-handlers.js --reporter html-cov > coverage.html; open coverage.html"
|
||||||
},
|
},
|
||||||
@@ -94,8 +94,10 @@
|
|||||||
"event-stream": "^3.2.2",
|
"event-stream": "^3.2.2",
|
||||||
"expect.js": "~0.2.0",
|
"expect.js": "~0.2.0",
|
||||||
"glob": "^4.3.5",
|
"glob": "^4.3.5",
|
||||||
"grunt-contrib-imagemin": "^0.9.4",
|
"gulp-clean": "^0.3.1",
|
||||||
|
"gulp-imagemin": "^2.3.0",
|
||||||
"gulp-nodemon": "^2.0.4",
|
"gulp-nodemon": "^2.0.4",
|
||||||
|
"gulp.spritesmith": "^4.1.0",
|
||||||
"istanbul": "^0.3.14",
|
"istanbul": "^0.3.14",
|
||||||
"karma": "~0.10.2",
|
"karma": "~0.10.2",
|
||||||
"karma-chai-plugins": "~0.1.0",
|
"karma-chai-plugins": "~0.1.0",
|
||||||
@@ -112,12 +114,11 @@
|
|||||||
"karma-requirejs": "~0.2.0",
|
"karma-requirejs": "~0.2.0",
|
||||||
"karma-script-launcher": "~0.1.0",
|
"karma-script-launcher": "~0.1.0",
|
||||||
"lcov-result-merger": "^1.0.2",
|
"lcov-result-merger": "^1.0.2",
|
||||||
|
"merge-stream": "^1.0.0",
|
||||||
"mocha": "~1.12.1",
|
"mocha": "~1.12.1",
|
||||||
"mongoskin": "~0.6.1",
|
"mongoskin": "~0.6.1",
|
||||||
"phantomjssmith": "~0.5.4",
|
|
||||||
"protractor": "~2.0.0",
|
"protractor": "~2.0.0",
|
||||||
"rewire": "^2.3.3",
|
"rewire": "^2.3.3",
|
||||||
"rimraf": "^2.2.8",
|
|
||||||
"shelljs": "^0.4.0",
|
"shelljs": "^0.4.0",
|
||||||
"sinon": "1.15.4",
|
"sinon": "1.15.4",
|
||||||
"sinon-chai": "^2.7.0",
|
"sinon-chai": "^2.7.0",
|
||||||
|
|||||||
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
|
||||||
|
}
|
||||||
@@ -71,8 +71,8 @@ apt-get install -qq nodejs
|
|||||||
|
|
||||||
cd /vagrant
|
cd /vagrant
|
||||||
|
|
||||||
echo Installing grunt/bower...
|
echo Installing gulp/bower...
|
||||||
npm install -g grunt-cli bower phantomjs
|
npm install -g gulp grunt-cli bower
|
||||||
|
|
||||||
echo Installing Habitica
|
echo Installing Habitica
|
||||||
npm install --no-bin-link
|
npm install --no-bin-link
|
||||||
|
|||||||
Reference in New Issue
Block a user