fis-spriter-csssprites
Advanced tools
Comparing version 0.0.4 to 0.0.5
12
index.js
@@ -7,13 +7,15 @@ /** | ||
var cssParser = require('./libs/cssParser.js'); | ||
var imgGen = require('./libs/imageGenerate.js'); | ||
var imgGen = require('./libs/image.js'); | ||
module.exports = function(ret, conf, settings, opt) { | ||
//文件属性中useSprite == true的css做图片合并 | ||
fis.util.map(ret.src, function(subpath, file) { | ||
if (file.rExt == '.css' && file.useSprite) { | ||
process(file, ret, conf, settings, opt); | ||
process(file, ret, settings, opt); | ||
} | ||
}); | ||
//打包后的css文件做图片合并 | ||
fis.util.map(ret.pkg, function (subpath, file) { | ||
if (file.rExt == '.css') { | ||
process(file, ret, conf, settings, opt); | ||
process(file, ret, settings, opt); | ||
} | ||
@@ -23,7 +25,7 @@ }); | ||
function process(file, ret, conf, settings, opt) { | ||
function process(file, ret, settings, opt) { | ||
var res = cssParser(file.getContent()); | ||
content = res.content; | ||
if (res.map && res.map.length > 0) { | ||
var css = imgGen(file, res.map, ret, conf, settings, opt); | ||
var css = imgGen(file, res.map, ret, settings, opt); | ||
content = content + css; | ||
@@ -30,0 +32,0 @@ } |
@@ -15,3 +15,3 @@ /* | ||
, __image_url_re = /url\s*\(\s*("(?:[^\\"\r\n\f]|\\[\s\S])*"|'(?:[^\\'\n\r\f]|\\[\s\S])*'|[^)}]+)\s*\)/i | ||
, __support_position_re = /(0|(?:-)?\d+px)\s*(0|(?:-)?\d+px)/i | ||
, __support_position_re = /(0|[+-]?(?:\d*\.|)\d+px|left|right)\s*(0|[+-]?(?:\d*\.|)\d+px|top)/i | ||
, __repeat_re = /\brepeat-(x|y)/i | ||
@@ -21,9 +21,36 @@ , __sprites_re = /\?__sprite/i | ||
, __sprites_hook_rd = '>>>'; | ||
self._id = id; | ||
self._image = ''; | ||
//selectors | ||
self.id = id; | ||
//use image url | ||
self.image = ''; | ||
self.repeat = false; | ||
self._position = [0, 0]; | ||
self._repeat = false; | ||
//image has __sprite query ? | ||
self._is_sprites = false; | ||
//x,y,z | ||
self._direct = 'z'; | ||
//left or right | ||
self._type = null; | ||
self._have_position = false; | ||
/** | ||
* get position | ||
* @param res | ||
* @private | ||
*/ | ||
function _get_position(res) { | ||
if (!res[1] || !res[2]) { | ||
return; | ||
} | ||
self._have_position = true; | ||
if (['left', 'right'].indexOf(res[1]) != -1) { | ||
self._type = res[1]; | ||
self._position[0] = res[1]; | ||
} else { | ||
self._position[0] = parseFloat(res[1]); | ||
} | ||
self._position[1] = res[2] === 'top' ? 0 : parseFloat(res[2]); | ||
} | ||
self._css = css.replace(__background_re, | ||
@@ -38,3 +65,3 @@ function(m, image, position, repeat) { | ||
info = _.query(info.rest); | ||
self._image = info.rest; | ||
self.image = info.rest; | ||
if (info.query && __sprites_re.test(info.query)) { | ||
@@ -47,3 +74,3 @@ self._is_sprites = true; | ||
if (res) { | ||
self._repeat = true; | ||
self.repeat = res[1].trim(); | ||
self._direct = res[1].trim() | ||
@@ -54,5 +81,3 @@ } | ||
if (res) { | ||
self._have_position = true; | ||
self._position[0] = parseFloat(res[1]); | ||
self._position[1] = parseFloat(res[2]); | ||
_get_position(res); | ||
} | ||
@@ -64,5 +89,3 @@ } | ||
if (res) { | ||
self._have_position = true; | ||
self._position[0] = parseFloat(res[1]); | ||
self._position[1] = parseFloat(res[2]); | ||
_get_position(res); | ||
} | ||
@@ -73,3 +96,3 @@ } | ||
if (res) { | ||
self._repeat = true; | ||
self.repeat = res[1].trim(); | ||
self._direct = res[1]; | ||
@@ -83,16 +106,23 @@ } | ||
getId: function() { | ||
return this._id; | ||
return this.id; | ||
}, | ||
getImageUrl: function() { | ||
return this._image; | ||
return this.image; | ||
}, | ||
getCss: function() { | ||
var __sprites_hook_re = /<<<[\s\S]*?>>>/ | ||
var __sprites_hook_re = /<<<[\s\S]*?>>>/g | ||
, ret = this._css; | ||
//if use sprites, replace background-image + background-position to space; | ||
if (this.isSprites()) { | ||
ret = ret.replace(__sprites_hook_re, ''); | ||
if (this.getRepeat()) { | ||
ret += 'background-repeat: repeat-' + this.getRepeat(); | ||
ret = ret.replace(__sprites_hook_re, '').trim(); | ||
//压缩会去掉最后一个;所以最前面加一个; | ||
var pre_pad = ''; | ||
if (ret.length > 0 && ret.charAt(ret.length - 1) != ';') { | ||
pre_pad = ';'; | ||
} | ||
if (this.repeat) { | ||
ret += pre_pad + 'background-repeat: repeat-' + this.repeat; | ||
} else { | ||
ret += pre_pad + 'background-repeat: no-repeat;'; | ||
} | ||
} | ||
@@ -104,4 +134,6 @@ return ret; | ||
}, | ||
getRepeat: function() { | ||
return this._repeat; | ||
getType: function() { | ||
//return this._type; | ||
//测试 | ||
return 'left'; | ||
}, | ||
@@ -128,2 +160,2 @@ getDirect: function() { | ||
} | ||
}; | ||
}; |
@@ -7,10 +7,273 @@ /* | ||
'use strict'; | ||
var image = require('node-images'); | ||
var pngcrush = require('node-pngcrush'); | ||
var Image = require('node-images'); | ||
var PngCrush = require('node-pngcrush'); | ||
var exports = module.exports = function() { | ||
module.exports = function(file, list, ret, settings, opt) { | ||
var gen = new Generator(file, list, ret, settings, opt); | ||
return gen.css; | ||
}; | ||
exports.getCss = function() { | ||
function Generator(file, list, ret, settings, opt) { | ||
settings.margin = settings.margin ? parseFloat(settings.margin) : '0'; | ||
this.file = file; | ||
this.ret = ret; | ||
this.settings = settings; | ||
this.opt = opt; | ||
this.css = ''; | ||
}; | ||
var list_x = []; | ||
var list_y = []; | ||
var list_z = []; | ||
fis.util.map(list, function (k, bg) { | ||
if (bg.getDirect() === 'x') { | ||
list_x.push(bg); | ||
} else if (bg.getDirect() === 'y') { | ||
list_y.push(bg); | ||
} else if (bg.getDirect() === 'z') { | ||
list_z.push(bg); | ||
} | ||
}); | ||
this.fill(list_x, 'x'); | ||
this.fill(list_y, 'y'); | ||
this.zFill(list_z); | ||
} | ||
Generator.prototype = { | ||
getImage: function(release) { | ||
var i; | ||
for (i in this.ret.src) { | ||
if (this.ret.src.hasOwnProperty(i) | ||
&& this.ret.src[i].getUrl(this.opt.hash, this.opt.domain) == release) { | ||
return this.ret.src[i]; | ||
} | ||
} | ||
return false; | ||
}, | ||
after: function (image, arr_selector, direct) { | ||
var ext = '_' + direct + '.png'; | ||
var image_file = fis.file.wrap(this.file.realpathNoExt + ext); | ||
if (this.opt.optimize) { | ||
var compress_conf = fis.config.get('settings.optimizer.pngcrush') || {}; | ||
image_file.setContent( | ||
PngCrush.option(compress_conf) | ||
.compress(image.encode('png')) | ||
); | ||
} else { | ||
image_file.setContent(image.encode('png')); | ||
} | ||
image_file.compiled = true; | ||
this.ret.pkg[this.file.subpathNoExt + ext] = image_file; | ||
this.css += arr_selector.join(',') | ||
+ '{background-image: url(' + image_file.getUrl(this.opt.hash, this.opt.domain) + ')}'; | ||
}, | ||
z_pack: require('./pack.js'), | ||
fill: function(list, direct) { | ||
if (list.length == 0) { | ||
return; | ||
} | ||
var max = 0, | ||
images = [], | ||
//宽度或者高的和 | ||
total = 0, | ||
parsed = [], | ||
i, k, j, len, count, op_max; | ||
for (i = 0, k = -1, len = list.length; i < len; i++) { | ||
if (parsed.indexOf(list[i].getImageUrl()) == -1) { | ||
var image_info = this.getImage(list[i].getImageUrl()); | ||
if (!image_info) { | ||
continue; | ||
} | ||
parsed.push(list[i].getImageUrl()); | ||
k++; | ||
var img = Image(image_info.getContent()); | ||
var size = img.size(); | ||
images[k] = { | ||
cls: [], | ||
image: img, | ||
width: size.width, | ||
height: size.height | ||
}; | ||
images[k].cls.push({ | ||
selector: list[i].getId(), | ||
position:list[i].getPosition() | ||
}); | ||
//如果是repeat-x的,记录最大宽度;如果是repeat-y的,记录最大高度 | ||
op_max = (direct == 'x') ? size.width : size.height; | ||
if (op_max > max) { | ||
max = op_max; | ||
} | ||
//如果是repeat-x的,计算高度和;如果是repeat-y的,计算宽度和 | ||
total += (direct == 'x' ? size.height : size.width) + this.settings.margin; | ||
} else { | ||
images[k].cls.push({ | ||
selector: list[i].getId(), | ||
position: list[i].getPosition() | ||
}); | ||
} | ||
} | ||
//减掉多加的一次margin | ||
total -= this.settings.margin; | ||
var height = direct == 'x' ? total : max; | ||
var width = direct == 'x' ? max : total; | ||
var image = Image(width, height); | ||
var x = 0, y = 0, cls = []; | ||
for (i = 0, len = images.length; i < len; i++) { | ||
image.draw(images[i].image, x, y); | ||
if (direct == 'y' && images[i].height < max) { | ||
//如果高度小于最大高度,则在Y轴平铺当前图 | ||
for (k = 0, count = max / images[i].height; k < count; k++) { | ||
image.draw(images[i].image, x, images[i].height * (k + 1)); | ||
} | ||
} else if (direct == 'x' && images[i].width < max) { | ||
//如果宽度小于最大宽度,则在X轴方向平铺当前图 | ||
for (k = 0, count = max / images[i].width; k < count; k++) { | ||
image.draw(images[i].image, images[i].width * (k + 1), y); | ||
} | ||
} | ||
for (k = 0, count = images[i].cls.length; k < count; k++) { | ||
this.css += images[i].cls[k].selector + '{background-position:' | ||
+ (images[i].cls[k].position[0] + -x) + 'px ' | ||
+ (images[i].cls[k].position[1] + -y) + 'px}'; | ||
cls.push(images[i].cls[k].selector); | ||
} | ||
if (direct == 'x') { | ||
y += images[i].height + this.settings.margin; | ||
} else { | ||
x += images[i].width + this.settings.margin; | ||
} | ||
} | ||
this.after(image, cls, direct); | ||
}, | ||
zFill: function(list) { | ||
if (list.length == 0) { | ||
return; | ||
} | ||
var i, k, k0, length, images = [[], []], parsed = [], max = [0, 0], total = [0, 0]; | ||
for (i = 0, k = [-1, -1], length = list.length; i < length; i++) { | ||
if (parsed.indexOf(list[i].getImageUrl()) == -1) { | ||
parsed.push(list[i].getImageUrl()); | ||
var item = list[i]; | ||
var image_info = this.getImage(item.getImageUrl()); | ||
if (!image_info) { | ||
continue; | ||
} | ||
var img = Image(image_info.getContent()); | ||
var size = img.size(); | ||
if (item.getType() == 'left') { | ||
k0 = 0; | ||
//计算最大宽度 | ||
if (size.width > max[k0]) { | ||
max[k0] = size.width; | ||
} | ||
total[k0] += size.height + this.settings.margin; | ||
} else { | ||
k0 = 1; | ||
} | ||
k[k0] ++; | ||
images[k0][k[k0]] = { | ||
cls: [], | ||
image: img, | ||
w: size.width + this.settings.margin, | ||
h: size.height + this.settings.margin | ||
}; | ||
if (k0 == 0) { | ||
//left合并为一竖行,不需要在宽度上加margin | ||
images[k0][k[k0]].w -= this.settings.margin; | ||
} | ||
images[k0][k[k0]].cls.push({ | ||
selector: list[i].getId(), | ||
position:list[i].getPosition() | ||
}); | ||
} else { | ||
if (item.getType() == 'left') { | ||
k0 = 0; | ||
} else { | ||
k0 = 1; | ||
} | ||
images[k0][k[k0]].cls.push({ | ||
selector: list[i].getId(), | ||
position:list[i].getPosition() | ||
}); | ||
} | ||
} | ||
var left = 0, zero = 1; | ||
if (images[zero].length == 0 | ||
&& images[left].length == 0) { | ||
return; | ||
} | ||
if (images[zero]) { | ||
var zero_root; | ||
//高度从大到小排序 | ||
images[zero].sort(function(a, b) { | ||
return -(a.h - b.h); | ||
}); | ||
this.z_pack.fit(images[zero]); | ||
zero_root = this.z_pack.getRoot(); | ||
max[zero] = zero_root.w; | ||
total[zero] = zero_root.h; | ||
} | ||
var height = 0; | ||
for (i = 0, length = total.length; i < length; i++) { | ||
if (total[i] > height) { | ||
height = total[i]; | ||
} | ||
} | ||
//减掉多加了一次的margin | ||
height = height - this.settings.margin; | ||
//@TODO zero为混排,混排暂时不启动,都使用竖排,需要再做实验调整 | ||
//left, zero | ||
//zero | left | ||
var image = Image(max[left] + max[zero], height) | ||
, x = 0 | ||
, y = 0 | ||
, j = 0 | ||
, cls = [] | ||
, count = 0 | ||
, current; | ||
if (images[zero]) { | ||
for (i = 0, length = images[zero].length; i < length; i++) { | ||
current = images[zero][i]; | ||
x = current.fit.x; | ||
y = current.fit.y; | ||
image.draw(Image(current.image), x, y); | ||
for (j = 0, count = current.cls.length; j < count; j++) { | ||
this.css += current.cls[j].selector + '{background-position:' | ||
+ (current.cls[j].position[0] + -x)+ 'px ' | ||
+ (current.cls[j].position[1] + -y) + 'px}'; | ||
cls.push(current.cls[j].selector); | ||
} | ||
} | ||
} | ||
if (images[left]) { | ||
y = 0; | ||
for (i = 0, length = images[left].length; i < length; i++) { | ||
current = images[left][i]; | ||
x = max[zero] + max[left] - current.w; | ||
image.draw(Image(current.image), x, y); | ||
for (j = 0, count = current.cls.length; j < count; j++) { | ||
var x_cur; | ||
if (current.cls[j].position[0] == 'right') { | ||
x_cur = 'right '; | ||
} else if (current.cls[j].position[0] == 'left') { | ||
x_cur = -x + 'px '; | ||
} else { | ||
x_cur = (-x + current.cls[j].position[0]) + 'px '; | ||
} | ||
this.css += current.cls[j].selector + '{background-position:' | ||
+ x_cur | ||
+ (current.cls[j].position[1] + -y) + 'px}'; | ||
cls.push(current.cls[j].selector); | ||
} | ||
y += current.h; | ||
} | ||
} | ||
this.after(image, cls, 'z'); | ||
} | ||
}; |
{ | ||
"name": "fis-spriter-csssprites", | ||
"version": "0.0.4", | ||
"version": "0.0.5", | ||
"description": "基于fis的csssprite,支持repeat-x,repeat-x,background-position", | ||
@@ -17,3 +17,4 @@ "main": "index.js", | ||
"dependencies": { | ||
"node-images": "1.5.1" | ||
"node-images": "1.5.1", | ||
"node-pngcrush": "0.0.7" | ||
}, | ||
@@ -20,0 +21,0 @@ "keywords": [ |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
21715
549
2
8
1
+ Addednode-pngcrush@0.0.7
+ Addednode-pngcrush@0.0.7(transitive)