guido
Version:
基于webpack4的一键式开发工具,集成handlebars、雪碧图、SVG Sprite、自定义资源注入等方式
109 lines (91 loc) • 3.06 kB
JavaScript
;
const path = require('path');
const postcss = require('postcss');
const paths = require('../config/paths');
const RE_SPRITES_FILTER = /\.(jpe?g|png|gif)\?__sprite$/;
const RE_SPRITES_RETINA = new RegExp('@(\\d+)x\\.(jpe?g|png|gif)$', 'i');
/**
* 过滤一些不需要合并的图片,返回值是一个promise,默认有一个exist的filter
* @param image
* @returns {*}
*/
function spritesFilterBy(image) {
if (RE_SPRITES_FILTER.test(image.originalUrl)) {
return Promise.resolve();
}
return Promise.reject();
}
function spritesGroupBy(regPath, image) {
let groups = regPath.exec(image.url);
let groupName = groups && groups.length > 1 ? groups[1] : '';
image.retina = true;
image.ratio = 1;
let ratio = RE_SPRITES_RETINA.exec(image.url);
if (ratio) {
ratio = ratio[1];
while (ratio > 10) {
ratio = ratio / 10;
}
image.ratio = ratio;
image.groups = image.groups.filter(function (group) {
return ('@' + ratio + 'x') !== group;
});
groupName += '@' + ratio + 'x';
}
return Promise.resolve(groupName);
}
function spritesOnUpdateRule(rule, comment, image) {
let retina = image.retina;
let ratio = image.ratio;
let coords = image.coords;
let spriteUrl = image.spriteUrl;
let spriteWidth = image.spriteWidth;
let spriteHeight = image.spriteHeight;
let posX = -1 * Math.abs(coords.x / ratio);
let posY = -1 * Math.abs(coords.y / ratio);
let sizeX = spriteWidth / ratio;
let sizeY = spriteHeight / ratio;
let backgroundImageDecl = postcss.decl({
prop: 'background-image',
value: 'url(' + spriteUrl + '?__url)'
});
if (retina && ratio > 1) {
let backgroundSizeDecl = postcss.decl({
prop: 'background-size',
value: sizeX + 'px ' + sizeY + 'px'
});
rule.insertAfter(comment, backgroundSizeDecl);
rule.insertAfter(comment, backgroundImageDecl);
} else {
let backgroundPositionDecl = postcss.decl({
prop: 'background-position',
value: [
posX ? posX + 'px' : posX,
posY ? posY + 'px' : posY
].join(' ')
});
rule.insertAfter(comment, backgroundPositionDecl);
rule.insertAfter(comment, backgroundImageDecl);
['width', 'height'].forEach(function (prop) {
rule.insertAfter(rule.last, postcss.decl({
prop: prop,
value: image.coords[prop] + 'px'
}));
});
}
}
function spritesOnSaveSpritesheet(opts, spritesheet) {
let file = ['sprite'];
if (spritesheet.groups.length) {
let groupsStr = spritesheet.groups.join('-');
groupsStr && file.push('-' + groupsStr);
}
file.push('.' + spritesheet.extension);
return path.join(paths.appCache, file.join(''));
}
module.exports = {
spritesFilterBy,
spritesGroupBy,
spritesOnUpdateRule,
spritesOnSaveSpritesheet
};