diff --git a/package.json b/package.json index b9e06d9..ca061e0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "azrael (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", diff --git a/src/config.example.json b/src/config.example.json index 090e502..cdb4457 100644 --- a/src/config.example.json +++ b/src/config.example.json @@ -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文件合并为一个文件 } } \ No newline at end of file diff --git a/src/ispriter.js b/src/ispriter.js index ac0eaef..ab71644 100644 --- a/src/ispriter.js +++ b/src/ispriter.js @@ -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; } //**************************************************************** @@ -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(); @@ -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; @@ -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'); @@ -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 } //解析样式表 @@ -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(){ //对图片进行坐标定位 @@ -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(); + } }); } diff --git a/test/result.html b/test/result.html index 60c2d30..e356d9e 100644 --- a/test/result.html +++ b/test/result.html @@ -3,7 +3,7 @@ test - +
@@ -23,4 +23,10 @@
- +
+
+
+
+
+
+
diff --git a/test/result2.html b/test/result2.html deleted file mode 100644 index e356d9e..0000000 --- a/test/result2.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - test - - - -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/test/sprite_output/css/sprite_all.css b/test/sprite_output/css/sprite_all.css new file mode 100644 index 0000000..474a9b8 --- /dev/null +++ b/test/sprite_output/css/sprite_all.css @@ -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;} diff --git a/test/sprite_output/images/sprite_all.png b/test/sprite_output/images/sprite_all.png new file mode 100644 index 0000000..a49a304 Binary files /dev/null and b/test/sprite_output/images/sprite_all.png differ