Skip to content

Commit

Permalink
新增demo
Browse files Browse the repository at this point in the history
  • Loading branch information
sunft1996 committed May 22, 2020
1 parent e25c8ef commit a1f4b0c
Show file tree
Hide file tree
Showing 12 changed files with 968 additions and 286 deletions.
183 changes: 183 additions & 0 deletions demo/loaders/sprite-smith-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
const fs = require('fs');
const path = require('path');
const Spritesmith = require('spritesmith');
const { stringifyRequest } = require('loader-utils');
var valueParser = require('postcss-value-parser');

module.exports = function (source) {

let outputName = new Date().getTime() + '_smith.png';
// 清除css中的注释
const cleanSource = source.replace(/\/\*[\w\W]*\*\//g, '')

let imgs = cleanSource.match(/url\(.+_sprite.+\)/g);

const callback = this.async();

imgs = imgs.map(item => path.resolve(this.context, item.replace(/(url\(.)|(.\))/g, '')));

Spritesmith.run({ src: imgs }, async (err, result) => {
if (err) throw err;

// 雪碧图尺寸
const imgInfo = result.properties;

// 子图片的偏移、尺寸信息
const coord = {};

for (key in result.coordinates) {
let newKey = key.match(/\w+_sprite.+/)[0];
coord[newKey] = result.coordinates[key];
delete result.coordinates[key];
}

const emitFile = (name) => {
return new Promise((resolve) => {
fs.mkdir(this.context + '/sprites', { recursive: true }, (err) => {
if (err) {
throw (err);
}
fs.writeFileSync(path.resolve(this.context, 'sprites', name), result.image);
resolve();
});
});
}
// 当前目录生成雪碧图
await emitFile(outputName);

let parsedValue = valueParser(cleanSource);

// 包含所有需要转化的css块
let blocks = {};

// 找到当前css块的范围
function findCurrentDeclare(currentIndex) {
let beginIndex;

let endIndex;

parsedValue.walk(node => {
if (/\{/.test(node.value) && node.sourceIndex < currentIndex) {
beginIndex = node.sourceIndex;
}
if (endIndex === undefined && /\}/.test(node.value) && node.sourceIndex > currentIndex) {
endIndex = node.sourceIndex;
}
});
if (beginIndex === undefined || endIndex === undefined) throw new Error(`css code error!`);
return {
beginIndex,
endIndex,
currentIndex
};
}

parsedValue.walk(node => {
if (node.value === 'url' && /_sprite.+/.test(node.nodes[0].value)) {
blocks[node.sourceIndex] = findCurrentDeclare(node.sourceIndex);
blocks[node.sourceIndex].url = node.nodes[0].value.match(/\w+_sprite.+/)[0];
}
});

// 转换
for (const key in blocks) {
let bgLineStart = 0;
let bgLineEnd = 0;
let bgszLineStart = 0;
let bgszLineEnd = 0;
let width;
let height;
let x;
let y;
let ratio;
const item = blocks[key];
// 找到background所在行
parsedValue.walk(node => {
if (blocks[key].beginIndex <= node.sourceIndex && blocks[key].endIndex >= node.sourceIndex) {
if (bgLineStart !== 0 && bgLineEnd !== 0) return;

if (bgLineStart === 0 && node.value === 'background') {
bgLineStart = node.sourceIndex;
return;
}

if (bgLineStart !== 0 && /;/.test(node.value)) {
bgLineEnd = node.sourceIndex;
return;
}

}
});
// 找到background-size所在行
parsedValue.walk(node => {
if (blocks[key].beginIndex <= node.sourceIndex && blocks[key].endIndex >= node.sourceIndex) {
if (bgszLineStart !== 0 && bgszLineEnd !== 0) return;

if (bgszLineStart === 0 && node.value === 'background-size') {
bgszLineStart = node.sourceIndex;
return;
}

if (bgszLineStart !== 0 && /;/.test(node.value)) {
bgszLineEnd = node.sourceIndex;
return;
}

}
});

// 处理 background-size
parsedValue.walk(node => {
if (bgszLineStart <= node.sourceIndex && bgszLineEnd >= node.sourceIndex) {

// 若background-size只有一个px
if (width === undefined && /px;/.test(node.value)) {
ratio = node.value.match(/\d+/)[0] / coord[item.url].width;
width = imgInfo.width * ratio + 'px ';
height = imgInfo.height * ratio + 'px;';
node.value = width + height;
return;
}
if (width === undefined && /px/.test(node.value)) {
ratio = node.value.match(/\d+/)[0] / coord[item.url].width;
width = imgInfo.width * ratio + 'px';
node.value = width;
return;
}
if (width !== undefined && height === undefined && /px;/.test(node.value)) {
height = imgInfo.height * ratio + 'px;';
node.value = height;
return;
}


}
});
// 处理 background
if (ratio) {
parsedValue.walk(node => {
if (bgLineStart <= node.sourceIndex && bgLineEnd >= node.sourceIndex) {

if (x === undefined && /px/.test(node.value)) {
x = - coord[item.url].x * ratio + Number(node.value.match(/-?\d+/)[0]) + 'px';
node.value = x;
return;
}
if (x !== undefined && y === undefined && /px;/.test(node.value)) {
y = - coord[item.url].y * ratio + Number(node.value.match(/-?\d+/)[0]) + 'px;';
node.value = y;
return;
}
if (x !== undefined && y === undefined && /px/.test(node.value)) {
y = - coord[item.url].y * ratio + Number(node.value.match(/-?\d+/)[0]) + 'px';
node.value = y;
return;
}
}
});
}
}
callback(null, parsedValue.toString().replace(/url\(.+_sprite.+\)/g, `url(${stringifyRequest(this.context, './sprites/' + outputName)})`));
});

}
Binary file added demo/resource/demo1_sprite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/resource/demo2_sprite.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions demo/resource/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!--
* @Descripttion:
* @Author: sunft
* @Date: 2020-05-14 10:52:55
* @LastEditTime: 2020-05-22 14:13:22
-->
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>demo</title>
</head>

<body>
<div id='root'></div>
</body>

</html>
15 changes: 15 additions & 0 deletions demo/resource/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* @Descripttion:
* @Author: sunft
* @Date: 2020-05-14 13:18:03
* @LastEditTime: 2020-05-22 11:35:52
*/
require('./style.css');

document.getElementById('root').innerHTML =
`<h3 class="text_center">this is a demo</h3>
<div class="my_content">
<div class="my_bg_1"></div>
<div class="my_bg_2"></div>
</div>`

Binary file added demo/resource/sprites/1590130839494_smith.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added demo/resource/sprites/1590130873790_smith.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 27 additions & 0 deletions demo/resource/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
.my_bg_1{
height: 100px;
width: 100px;
background: url('./demo1_sprite.png');
background-size: 100px;
border: 1px solid #ddd;
display: inline-block;
}

.my_bg_2{
height: 100px;
width: 100px;
background: url('./demo2_sprite.png') no-repeat -20px -20px;
background-size: 150px;
border: 1px solid #ddd;
display: inline-block;
margin-left: 20px;
}

.my_content{
display: flex;
justify-content: center;
}

.text_center{
text-align: center;
}
54 changes: 54 additions & 0 deletions demo/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* @Descripttion:
* @Author: sunft
* @Date: 2020-03-24 11:19:44
* @LastEditTime: 2020-05-22 14:58:48
*/
const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
index: './resource/index.js',
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
loader: 'file-loader',
options: {
outputPath: 'images',
},
},
{
test: /\.css$/i,
use: [
'style-loader',
'css-loader',
'sprite-smith-loader'
],
},
],
},
resolveLoader: {
// tell webpack where to find modules
modules: ['node_modules', path.join(__dirname, './loaders')],
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new HtmlWebpackPlugin({
template: './resource/index.html',
}),
],
devServer: {
hot: true,
contentBase: './dist',
port: 4000,
https: false,
open: true
},
}
1 change: 0 additions & 1 deletion dist/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ module.exports = function (source) {

}
});
console.log(bgszLineStart, bgszLineEnd, bgLineStart, bgLineEnd)

// 处理 background-size
parsedValue.walk(node => {
Expand Down
Loading

0 comments on commit a1f4b0c

Please sign in to comment.