Skip to content

Commit

Permalink
提供将所有图片合并为一张, 同时所有css文件合并为一个文件的功能
Browse files Browse the repository at this point in the history
Signed-off-by: azrael <azrael@imatlas.com>
  • Loading branch information
iazrael committed Sep 10, 2013
1 parent d535cce commit 5e3073e
Show file tree
Hide file tree
Showing 7 changed files with 189 additions and 48 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"author": "azrael <azrael@imatlas.com> (http://imatlas.com/about)",
"name": "ispriter",
"description": "an intelligent merge sprite tool",
"version": "0.2.0",
"version": "0.2.1",
"homepage": "http://imatlas.com/posts/intelligent-merge-css-sprite/",
"repository": {
"type": "git",
Expand Down
3 changes: 2 additions & 1 deletion src/config.example.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"maxSize": 60,//optional 图片容量的最大大小, 单位 KB, 默认 0
"margin": 5,//optional 合成之后, 图片间的空隙, 默认 0
"prefix": "sprite_",//optional
"format": "png"//optional 输出的图片格式
"format": "png",//optional 输出的图片格式
"combine": false//optional 为true时将所有图片合并为一张, 同时所有css文件合并为一个文件
}
}
89 changes: 77 additions & 12 deletions src/ispriter.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ var readConfig = function(config){

config.output.prefix = config.output.prefix || 'sprite_';
config.output.format = config.output.format || 'png';

// console.log(config);
return config;
}
//****************************************************************
Expand Down Expand Up @@ -457,6 +457,7 @@ var drawImageAndPositionBackground = function(styleObjArr, cssFileName){
imageInfo.imageName = imageName;

var image = imageInfo.image;
//对图片进行定位和填充
image.bitblt(imageResult, 0, 0, image.width, image.height,
imageInfo.fit.x, imageInfo.fit.y);
goon();
Expand Down Expand Up @@ -500,11 +501,16 @@ var createPng = function(width, height) {

var getImageName = function(cssFileName, index, total){
// console.log(cssFileName, index, total);
var basename = path.basename(cssFileName);
var extname = path.extname(basename);
var name = basename.replace(extname, '');
var name = '';
if(cssFileName){
var basename = path.basename(cssFileName);
var extname = path.extname(basename);
name = basename.replace(extname, '');
}
if(spriteConfig.output.maxSize && total > 1){
name += '_' + index;
name += (spriteConfig.output.combine ? '' : '_') + index;
}else if(spriteConfig.output.combine){
name = 'all';
}
return spriteConfig.output.imageRoot + spriteConfig.output.prefix +
name + '.' + spriteConfig.output.format;
Expand Down Expand Up @@ -545,23 +551,47 @@ var setPxValue = function(rule, attr, newValue){
// 输出修改后的样式表
//****************************************************************

var writeCssFile = function(spriteObj){
var fileName = spriteConfig.output.cssRoot + spriteObj.fileName;
fileName = path.resolve(fileName);
nf.writeFileSync(fileName, spriteObj.styleSheet.toString());
var writeCssFile = function(spriteObjList){
if(!ztool.isArray(spriteObjList)){
spriteObjList = [spriteObjList];
}
var fileName, spriteObj, cssContentList = [];
for(var i in spriteObjList){
spriteObj = spriteObjList[i];
fileName = spriteConfig.output.cssRoot + spriteObj.fileName;
fileName = path.resolve(fileName);
if(spriteConfig.output.combine){
cssContentList.push(spriteObj.styleSheet.toString());
}else{
nf.writeFileSync(fileName, spriteObj.styleSheet.toString());
}
}
if(spriteConfig.output.combine && cssContentList.length){
fileName = spriteConfig.output.cssRoot + spriteConfig.output.prefix + 'all.css';
fileName = path.resolve(fileName);
nf.writeFileSync(fileName, cssContentList.join(''));
}
}

//****************************************************************
// 主逻辑
//****************************************************************

var onMergeStart = function(){
this.start = +new Date;
}

var onMergeFinish = function(){
console.log('>>all done. time use:', +new Date - this.start, 'ms');
}

/**
* 主逻辑
*/
exports.merge = function(configFile){
onMergeStart();
imageInfoCache = {};
spriteConfig = readConfig(configFile);
var start = +new Date;
// console.log(spriteConfig);
var inputCssRoot = spriteConfig.input.cssRoot;
var fileList = nf.listFilesSync(inputCssRoot, 'css');
Expand All @@ -570,6 +600,7 @@ exports.merge = function(configFile){
return;
}
// console.log(fileList);
var combineStyleObjList = {length: 0 }, combineStyleSheetList = [];
ztool.forEach(fileList, function(i, fileName, next){
var spriteObj = { fileName: fileName }
//解析样式表
Expand All @@ -581,8 +612,25 @@ exports.merge = function(configFile){
//这个 css 没有需要合并的图片
return next();
}
// console.log(styleObjList);

delete styleObjList.length;

if(spriteConfig.output.combine){
// console.log(styleObjList);
combineStyleSheetList.push(spriteObj);
//如果是要合并成一张图片的, 就先把所有图片信息收集起来
var styleObj, existSObj;
for(var url in styleObjList){
styleObj = styleObjList[url];
if(existSObj = combineStyleObjList[url]){
existSObj.cssRules = existSObj.cssRules.concat(styleObj.cssRules);
}else{
combineStyleObjList[url] = styleObj;
}
combineStyleObjList.length++;
}
return next();
}
//读取图片信息(内容, 宽高, 大小)
readImageInfo(styleObjList, function(){
//对图片进行坐标定位
Expand All @@ -597,7 +645,24 @@ exports.merge = function(configFile){
});
},
function(){
console.log('>>all done. time use:', +new Date - start, 'ms');
if(spriteConfig.output.combine && combineStyleObjList.length){
//在这里将所有图片合并
delete combineStyleObjList.length;
//读取图片信息(内容, 宽高, 大小)
readImageInfo(combineStyleObjList, function(){
//对图片进行坐标定位
var styleObjArr = positionImages(combineStyleObjList);

//输出合并的图片 并修改样式表里面的background
drawImageAndPositionBackground(styleObjArr, '');

//输出合并后的样式表
writeCssFile(combineStyleSheetList);
onMergeFinish();
});
}else{
onMergeFinish();
}
});

}
Expand Down
10 changes: 8 additions & 2 deletions test/result.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<title>test</title>
<link href="output/css/style.css" rel="stylesheet">
<link href="sprite_output/css/style.css" rel="stylesheet">
</head>
<body>
<div></div>
Expand All @@ -23,4 +23,10 @@
<div></div>
<div></div>
<div></div>

<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
32 changes: 0 additions & 32 deletions test/result2.html

This file was deleted.

101 changes: 101 additions & 0 deletions test/sprite_output/css/sprite_all.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
body {background: #ddd;}
div {min-height: 10px; border: 1px solid #339; margin: 20px; min-width: 10px;}
div:nth-of-type(8) {width: 20px; height: 20px; background: url(../images/sprite_all.png) -389px -65px;}
div:nth-of-type(9) {width: 79px; height: 18px; background: url(../images/sprite_all.png) -276px -53px;}
div:nth-of-type(10) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -132px;}
div:nth-of-type(11) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -153px;}
div:nth-of-type(12) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -195px;}
div:nth-of-type(13) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -216px;}
div:nth-of-type(14) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -90px;}
div:nth-of-type(15) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -174px;}
div:nth-of-type(16) {width: 38px; height: 38px; background: url(../images/sprite_all.png) 0 -314px;}
div:nth-of-type(17) {width: 13px; height: 11px; background: url(../images/sprite_all.png) -389px -291px;}
div:nth-of-type(18) {width: 46px; height: 44px; background: url(../images/sprite_all.png) 0 -265px;}
div:nth-of-type(20) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -106px;}
div:nth-of-type(21) {width: 15px; height: 12px; background: url(../images/sprite_all.png) -389px -257px;}
div:nth-of-type(22) {width: 81px; height: 38px; background: url(../images/sprite_all.png) -190px -53px;}
div:nth-of-type(23) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -106px -159px;}
div:nth-of-type(1) {width: 12px; height: 12px; background: url(../images/sprite_all.png) -389px -274px;}
div:nth-of-type(2) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -212px;}
div:nth-of-type(3) {width: 43px; height: 43px; background: url(../images/sprite_all.png) -51px -265px;}
div:nth-of-type(4) {width: 79px; height: 18px; background: url(../images/sprite_all.png) -99px -265px;}
div:nth-of-type(5) {width: 15px; height: 15px; background: url(../images/sprite_all.png) -389px -237px;}
div:nth-of-type(11) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -153px;}
div:nth-of-type(12) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -195px;}
div:nth-of-type(13) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -216px;}
div:nth-of-type(14) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -90px;}
div:nth-of-type(15) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -174px;}
div:nth-of-type(16) {width: 38px; height: 38px; background: url(../images/sprite_all.png) 0 -314px;}
div:nth-of-type(17) {width: 13px; height: 11px; background: url(../images/sprite_all.png) -389px -291px;}
div:nth-of-type(20) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -106px;}
div:nth-of-type(21) {width: 15px; height: 12px; background: url(../images/sprite_all.png) -389px -257px;}
div:nth-of-type(22) {width: 81px; height: 38px; background: url(../images/sprite_all.png) -190px -53px;}
div:nth-of-type(23) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -106px -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -53px -212px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) 0 -53px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -95px -53px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -212px -212px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -265px -212px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -106px -212px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -265px -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -212px -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -265px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -159px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -53px -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) 0 -212px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -159px -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) 0 -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -212px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -106px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -53px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) 0 -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -159px -212px;}
body {background: #ddd;}
div {min-height: 10px; border: 1px solid #339; margin: 20px; min-width: 10px;}
div:nth-of-type(1) {width: 12px; height: 12px; background: url(../images/sprite_all.png) -389px -274px;}
div:nth-of-type(2) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -212px;}
div:nth-of-type(3) {width: 43px; height: 43px; background: url(../images/sprite_all.png) -51px -265px;}
div:nth-of-type(4) {width: 79px; height: 18px; background: url(../images/sprite_all.png) -99px -265px;}
div:nth-of-type(5) {width: 15px; height: 15px; background: url(../images/sprite_all.png) -389px -237px;}
div:nth-of-type(11) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -153px;}
div:nth-of-type(12) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -195px;}
div:nth-of-type(13) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -216px;}
div:nth-of-type(14) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -90px;}
div:nth-of-type(15) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -174px;}
div:nth-of-type(16) {width: 38px; height: 38px; background: url(../images/sprite_all.png) 0 -314px;}
div:nth-of-type(17) {width: 13px; height: 11px; background: url(../images/sprite_all.png) -389px -291px;}
div:nth-of-type(18) {width: 46px; height: 44px; background: url(../images/sprite_all.png) 0 -265px;}
div:nth-of-type(19) {width: 384px; height: 48px; background: url(../images/sprite_all.png) 0 0;}
div:nth-of-type(20) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -106px;}
div:nth-of-type(21) {width: 15px; height: 12px; background: url(../images/sprite_all.png) -389px -257px;}
div:nth-of-type(22) {width: 81px; height: 38px; background: url(../images/sprite_all.png) -190px -53px;}
div:nth-of-type(23) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -106px -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) 0 -159px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -212px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -106px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -53px -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) 0 -106px;}
div:nth-of-type(24) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -159px -212px;}
body {background: #ddd;}
div {min-height: 10px; border: 1px solid #339; margin: 20px; min-width: 10px;}
div:nth-of-type(1) {width: 12px; height: 12px; background: url(../images/sprite_all.png) -389px -274px;}
div:nth-of-type(2) {width: 48px; height: 48px; background: url(../images/sprite_all.png) -318px -212px;}
div:nth-of-type(3) {width: 43px; height: 43px; background: url(../images/sprite_all.png) -51px -265px;}
div:nth-of-type(4) {width: 79px; height: 18px; background: url(../images/sprite_all.png) -99px -265px;}
div:nth-of-type(5) {width: 15px; height: 15px; background: url(../images/sprite_all.png) -389px -237px;}
div:nth-of-type(6) {width: 20px; height: 60px; background: url(../images/sprite_all.png) -389px 0;}
div:nth-of-type(7) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -111px;}
div:nth-of-type(8) {width: 20px; height: 20px; background: url(../images/sprite_all.png) -389px -65px;}
div:nth-of-type(9) {width: 79px; height: 18px; background: url(../images/sprite_all.png) -276px -53px;}
div:nth-of-type(10) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -132px;}
div:nth-of-type(11) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -153px;}
div:nth-of-type(12) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -195px;}
div:nth-of-type(13) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -216px;}
div:nth-of-type(14) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -90px;}
div:nth-of-type(15) {width: 16px; height: 16px; background: url(../images/sprite_all.png) -389px -174px;}
div:nth-of-type(16) {width: 38px; height: 38px; background: url(../images/sprite_all.png) 0 -314px;}
div:nth-of-type(17) {width: 13px; height: 11px; background: url(../images/sprite_all.png) -389px -291px;}
Binary file added test/sprite_output/images/sprite_all.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 5e3073e

Please # to comment.