Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Images measurements support #54

Merged
merged 6 commits into from
Apr 4, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions Gruntfile.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,15 @@ module.exports = function (grunt) {
icons36: {
src: ['test/out/img/icons36/*.png'],
css: 'test/out/css/icons36.css',
map: 'test/out/img/icons36.png'
map: 'test/out/img/icons36.png',
dimensions: true
},
icons36_scss: {
src: ['test/out/img/icons36/*.png'],
css: 'test/out/scss/icons36.scss',
map: 'test/out/img/icons36_scss.png',
output: 'scss'
output: 'scss',
dimensions: false
},
icons36_sass: {
src: ['test/out/img/icons36/*.png'],
Expand Down
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ jpgmin: {
}
```

If you would like to use lossy compression via `jpegoptim`'s `-m` flag, you can
If you would like to use lossy compression via `jpegoptim`'s `-m` flag, you can
add a `quality` configuration option:

```javascript
Expand Down Expand Up @@ -286,6 +286,46 @@ would generate something like this:

```

##### dimensions

This will add the CSS "width" and "height" properties to the tasks' output. This setting is **false** by default.

For example, the following configuration:

```javascript
sprites: {
icons36: {
src: ['test/out/img/icons36/*.png'],
css: 'test/out/scss/icons36.scss',
map: 'test/out/img/icons36.png',
output: 'scss',
dimensions: true
}
}
```

would generate something like this:

```css
%icons36 {
background: url("../img/icons36.png") no-repeat;
}

%sprite_01 {
@extend %icons36;
width: 32px;
height: 32px;
background-position: 0 0;
}

%sprite_02 {
@extend %icons36;
width: 48px;
height: 48px;
background-position: 0 -32px;
}
```

## Future (TODO)
* Better documentation (Near future!)
* JS only PNG optimizing
Expand All @@ -295,6 +335,10 @@ would generate something like this:

## Release History

### 0.3.4
+ Added width and height properties to the spriter output [@alpadev] (https://github.com/alpadev)
- 85a04f58 Updates the generator functions to adopt the changes introduced to the spriter script. See #52 [@alpadev]
- 6416c26d Rewrote most of it.. to accomplish #52 (also the old code been a lil dirty imo :)) [@alpadev]

### 0.3.3
+ Added Stylus ouput option to sprites task [Thx to @alpadev] (https://github.com/alpadev)
Expand Down
72 changes: 44 additions & 28 deletions lib/phantomspriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,35 +17,51 @@ page.onConsoleMessage = function (msg) {

page.evaluate(function () {
var testdraw = function () {
var maxwidth = 0;
var maxheight = 0;
var allHeight = 0;
var heights = [];
var canvas = null;

for (var i = 0; i < document.images.length; i++) {
maxheight += document.images[i].height;
if (maxwidth < document.images[i].width) {
maxwidth = document.images[i].width;
}
}
maxheight = maxheight + (document.images.length * parseInt(document.getElementById('test').getAttribute('rel'), 10));
// Create canvas element
canvas = document.getElementById('test');
canvas.setAttribute('width', maxwidth);
canvas.setAttribute('height', maxheight);
// Loop through all images
for (var j = 0; j < document.images.length; j++) {
// Insert before the image
var ctx = canvas.getContext('2d');

// Draw image to canvas
var beforeHeight = (j - 1 === -1) ? 0 : document.images[j - 1].height;
allHeight += (beforeHeight + parseInt(canvas.getAttribute('rel'), 10));
heights.push(allHeight);
ctx.drawImage(document.images[j], 0, allHeight);
var images = document.images,
canvas = document.getElementById('test'),
ctx = canvas.getContext('2d'),
spriteCache = document.createElement('canvas'),
cacheCtx = spriteCache.getContext('2d'),
imgHeight = 0,
imgWidth = 0,
imgTotalHeight = 0,
spriteHeight = 0,
spriteWidth = 0,
spacing = parseInt(canvas.getAttribute('rel'), 10) || 0,
meta = { images: [] };

// loop all images
for (var i = 0, l = images.length; i < l; i += 1) {
imgHeight = images[i].height;
imgWidth = images[i].width;
imgTotalHeight = imgHeight + (i === l - 1 ? 0 : spacing);

spriteHeight += imgTotalHeight;
spriteWidth = spriteWidth < imgWidth ? imgWidth : spriteWidth;

// paint to cache
spriteCache.setAttribute('height', spriteHeight);
spriteCache.setAttribute('width', spriteWidth);
cacheCtx.drawImage(canvas, 0, 0);

// draw the real canvas
canvas.setAttribute('height', spriteHeight);
canvas.setAttribute('width', spriteWidth);
ctx.drawImage(spriteCache, 0, 0);
ctx.drawImage(images[i], 0, spriteHeight - imgTotalHeight);

meta.images.push({
height: imgHeight,
width: imgWidth,
totalHeight: imgTotalHeight,
offsetY: spriteHeight - imgTotalHeight
});
}
return JSON.stringify({image: canvas.toDataURL(), heights: heights, maxheight: maxheight}) + '<<<<ENDIMAGE';

meta.maxHeight = spriteHeight;
meta.maxWidth = spriteWidth;

return JSON.stringify({image: canvas.toDataURL(), meta: meta}) + '<<<<ENDIMAGE';
};
setTimeout(function () {
console.log(testdraw());
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "grunt-imagine",
"description": "Grunt tasks for optimizing, inlining & spriting images",
"version": "0.3.3",
"version": "0.3.4",
"homepage": "http://asciidisco.github.com/grunt-imagine/",
"author": {
"name": "asciidisco",
Expand Down
56 changes: 41 additions & 15 deletions tasks/sprites.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ module.exports = function(grunt) {
margin = !_.isUndefined(this.data.margin) ? parseInt(this.data.margin, 10) : 0,
externalData = '',
classPrefix = _.isUndefined(this.data.classPrefix) ? '' : this.data.classPrefix,
output = !_.isUndefined(this.data.output) ? this.data.output.toLowerCase() : "css";
output = !_.isUndefined(this.data.output) ? this.data.output.toLowerCase() : "css",
addSize = !!this.data.dimensions;

// check if the margin setting is a number
if (_.isNaN(margin)) {
Expand Down Expand Up @@ -66,19 +67,31 @@ module.exports = function(grunt) {
});

fileContents += imageClasses + ' {' + '\n' + ' background: url("' + generateBackgroundImagePath() + '") no-repeat;\n' + '}\n\n';
imageData.heights.forEach(function (height, idx) {
fileContents += '.' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') + ' {\n' + ' background-position: 0 ' + -height + ( height === 0 ? "" : 'px') + ';\n' + '}\n\n';
imageData.images.forEach(function (meta, idx) {
fileContents += '.' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') +
' {\n' +
(addSize && ' width: ' + intToPixel(meta.width) + ';\n' || '') +
(addSize && ' height: ' + intToPixel(meta.height) + ';\n' || '') +
' background-position: 0 ' + intToPixel(-meta.offsetY) + ';\n' +
'}\n\n';
});

return fileContents;
}

function generateSASSFile (imageData, images, placeholder, scssSyntax) {
var fileContents = '';
var fileContents = '',
colon = (scssSyntax ? ';' : '') + '\n';

fileContents += "%" + placeholder + (scssSyntax ? ' {' : '') + '\n' + ' background: url("' + generateBackgroundImagePath() + '") no-repeat' + (scssSyntax ? ';\n }' : '') + '\n\n';
imageData.heights.forEach(function (height, idx) {
fileContents += '%' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') + (scssSyntax ? ' {' : '') + '\n @extend ' + '%' + placeholder + (scssSyntax ? ' ;' : '') + '\n' + ' background-position: 0 ' + -height + ( height === 0 ? "" : 'px') + (scssSyntax ? ';\n }' : '') + '\n\n';
imageData.images.forEach(function (meta, idx) {
fileContents += '%' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') +
(scssSyntax ? ' {' : '') + '\n' +
' @extend ' + '%' + placeholder + colon +
(addSize && ' width: ' + intToPixel(meta.width) + colon || '') +
(addSize && ' height: ' + intToPixel(meta.height) + colon || '') +
' background-position: 0 ' + intToPixel(-meta.offsetY) + colon +
(scssSyntax ? '}' : '') + '\n\n';
});

return fileContents;
Expand All @@ -89,8 +102,13 @@ module.exports = function(grunt) {
var fileContents = '';

fileContents += "." + placeholder + ' {\n' + ' background: url("' + generateBackgroundImagePath() + '") no-repeat;\n }' + '\n\n';
imageData.heights.forEach(function (height, idx) {
fileContents += '.' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') + ':extend(.' + placeholder + ') {\n' + ' background-position: 0 ' + -height + ( height === 0 ? "" : 'px') + ';\n' + '}\n\n';
imageData.images.forEach(function (meta, idx) {
fileContents += '.' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') +
':extend(.' + placeholder + ') {\n' +
(addSize && ' width: ' + intToPixel(meta.width) + ';\n' || '') +
(addSize && ' height: ' + intToPixel(meta.height) + ';\n' || '') +
' background-position: 0 ' + intToPixel(-meta.offsetY) + ';\n' +
'}\n\n';
});

return fileContents;
Expand All @@ -100,13 +118,21 @@ module.exports = function(grunt) {
var fileContents = '';

fileContents += '$' + placeholder + '\n background: url("' + generateBackgroundImagePath() + '") no-repeat\n\n';
imageData.heights.forEach(function (height, idx) {
fileContents += '$' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') + '\n @extend $' + placeholder + '\n background-position: 0 ' + ( height > 0 ? -height + 'px' : 0 ) + '\n\n';
imageData.images.forEach(function (meta, idx) {
fileContents += '$' + (classPrefix === '' ? '' : classPrefix + '-') + path.basename(images[idx].file, '.png') +
'\n @extend $' + placeholder +
(addSize && '\n width: ' + intToPixel(meta.width) || '') +
(addSize && '\n height: ' + intToPixel(meta.height) || '') +
'\n background-position: 0 ' + intToPixel(-meta.offsetY) + '\n\n';
});

return fileContents;
}

function intToPixel (int) {
return int !== 0 ? int + 'px' : 0;
}

function runSpriteGenerator (images) {
// spawn a phantom js process
var ps = spawn(binPath, ['--web-security=no', path.resolve(__dirname, '../lib/phantomspriter.js')]);
Expand Down Expand Up @@ -153,19 +179,19 @@ module.exports = function(grunt) {

switch (output){
case "scss":
stylesData = generateSASSFile(incomingData, images, placeHolder, true);
stylesData = generateSASSFile(incomingData.meta, images, placeHolder, true);
break;
case "sass":
stylesData = generateSASSFile(incomingData, images, placeHolder);
stylesData = generateSASSFile(incomingData.meta, images, placeHolder);
break;
case "less":
stylesData = generateLESSFile(incomingData, images, placeHolder);
stylesData = generateLESSFile(incomingData.meta, images, placeHolder);
break;
case "stylus":
stylesData = generateStylusFile(incomingData, images, placeHolder);
stylesData = generateStylusFile(incomingData.meta, images, placeHolder);
break;
default:
stylesData = generateCSSFile(incomingData, images);
stylesData = generateCSSFile(incomingData.meta, images);
break;
}

Expand Down