不知各位是否还有用雪碧图这种东西~听说过时了?哈哈哈,不管,我还是要记录下。
因为我最近用上了,所以学习了使用 webpack-spritesmith
自动生成雪碧图。
需求
项目中有很多图标,或相近的按钮等,不能使用iconfont或者svg代替,因此只能从设计稿上切图后引入。
但是,每个图标都单独引入,就会使加载图片时http的请求次数增加,可能造成加载速度慢等问题。
因此,我决定使用雪碧图。
自动生成雪碧图
- 安装
npm i webpack-spritesmith
- 引入使用
// webpack文件
/*
* 引入webpack-spritesmith
**/
const fs = require('fs');
const SpritesmithPlugin = require('webpack-spritesmith');
/*
* 自定义spritesmith规则 - spritesmith默认单位为 px, 但是我需要使用rem, 所以自定义规则,将单位改为 rem
**/
var templateFunction = function (data) {
var getRem = function(val) {
// 修改时要同时修改 _px2rem.scss 中的$rem
const base = 75;
return parseInt(val)/base + 'rem'
}
// 生成sprites.scss文件时的格式
var perSprite = data.sprites.map(function (sprite) {
return `@mixin sprites-${sprite.name} {
background-image: url(${data.sprites[0].image});
background-size: ${getRem(data.spritesheet.width)} ${getRem(data.spritesheet.height)};
width: ${getRem(sprite.width)};
height: ${getRem(sprite.height)};
background-position: ${getRem(sprite.offset_x)} ${getRem(sprite.offset_y)};
}`
}).join('\n');
return perSprite;
}
/*
* 因为想要生成多个不同类型的sprites,正常需要几个就配置几个 new SpritesmithPlugin() 即可。但是为了方便,这里做了遍历实现一次性配置,使得每一次只需要添加图片文件,就可以自动生成,不需要再进行其他配置。
**/
const spritesmithTasks = []
const spritesImg = {}
const spritesScss = []
// 下面需要注意路径是 ./src/assets/sprites 还是 ../src/assets/sprites/${dirname},如果报错,可以一个个打印看看,配置正确的路径
fs.readdirSync('./src/assets/sprites').map(dirname => {
if (fs.statSync(`./src/assets/sprites/${dirname}`).isDirectory()) {
spritesmithTasks.push(
new SpritesmithPlugin({
src: {
// 需要生成雪碧图的文件夹
cwd: path.resolve(__dirname, `../src/assets/sprites/${dirname}`),
glob: '*.png'
},
target: {
// 雪碧图生成后的图片路径
image: path.resolve(__dirname, `../src/assets/sprites/${dirname}.png`),
css: [
// 雪碧图生成后对应的css文件
[path.resolve(__dirname, `../src/assets/sprites/_${dirname}.scss`), {
// 引用自己的模板
format: 'function_based_template'
}]
]
},
// 自定义css处理模板
customTemplates: {
'function_based_template': templateFunction,
},
// 样式文件中调用雪碧图地址写法
apiOptions: {
cssImageRef: `~${dirname}.sprites.png`
},
spritesmithOptions: {
algorithm: 'binary-tree',
padding: 10 // 雪碧图中每个图标的间距
}
})
),
// 设置生成的雪碧图路径别名,与前面的new SpritesmithPlugin 中的apiOptions.cssImageRef 相对应
spritesImg[`~${dirname}.sprites.png`] = path.resolve(
__dirname,
`../src/assets/sprites/${dirname}.png`,
),
// 在后面的rules中需要全局引入生成的_${dirname}.scss也就是 spritesScss文件。
spritesScss.push(
`./src/assets/sprites/_${dirname}.scss`
)
}
})
const baseResolve = {
...spritesImg, // 设置生成的雪碧图路径别名
'@': path.resolve(__dirname, './src'),
};
module.exports = {
resolve: {
alias: {
...baseResolve,
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
}
},
module: {
rules: [
{
test: /\.scss$/,
exclude: [/node_modules/],
use: [
require.resolve('style-loader'),
{
loader: 'sass-resources-loader',
options: {
resources: [
...spritesScss, // 全局引入生成的_${dirname}.scss
]
},
},
},
],
}
],
},
],
},
plugins: [
...spritesmithTasks // 遍历的new SpritesmithPlugin()
],
};
为了方便理解,上面将webpack配置中的其他配置删除,只留下关于spritesmith
的配置信息。
配置完成后,在对应的文件夹中添加需要生成雪碧图的图片。如我上面配置的是 /src/assets/sprites/${dirname}
, 此时我需要生成一个 button
的雪碧图,那么就在/src/assets/sprites
文件中创建 button
目录,然后将图片都导入其中。
运行项目!
当当当~你会发现/src/assets/sprites
目录下增加了一个 button.png
和 _button.scss
.
button.png
就是生成的雪碧图
_button.scss
就是雪碧图中每个图标的css, 如下所示
@mixin sprites-btn_get_lottery_hover {
background-image: url(~button.sprites.png);
background-size: 11.88rem 11.626666666666667rem;
width: 3.8133333333333335rem;
height: 1.36rem;
background-position: -3.9466666666666668rem -6.64rem;
}
@mixin sprites-btn_get_lottery {
background-image: url(~button.sprites.png);
background-size: 11.88rem 11.626666666666667rem;
width: 3.8133333333333335rem;
height: 1.36rem;
background-position: 0rem -6.64rem;
}
此时,在其他css中引入图标时只需
.test {
@include sprites-btn_get_lottery
}
知识点
使用雪碧图的好处, 参考 雪碧图有什么用
- 减少加载图片时对网页的请求次数
- 提高页面的加载速度
- 减少鼠标hover的bug:IE6不会主动预加载鼠标滑过即a:hover中的背景图片,所以,如果使用多张图片,鼠标滑过会出现闪白的现象。使用CSS雪碧,由于一张图片即可,所以不会出现这种现象。(没遇到过所以没有太明白~)
疑惑
- 使用雪碧图有什么弊端,在pc端或移动端中。
感谢
作为菜鸟,基本都靠百度,哈哈哈,下面是参考的文章,感谢感谢~
-
自定义 sprites css 规则 参考 使用webpack-spritesmith生成雪碧图
-
关于遍历也是参考来的,但是我再找找不到那个网页了,😭,后面再补上吧~
以上,仅作为菜糯糯的笔记。