问题
网上有很多关于webpack-spritesmith的配置使用方法。但是通过这个插件生成的样式文件是px或rem做图片定位的,这种方式在移动端的使用场景会不再适用。移动端的background-position不同于pc端,这里我们会想办法把像素单位转换成百分比。
开始做
我用的vue-cli@2.x + less项目
1.在webpack.base.conf里引入插件webpack-spritesmith
const spritePlugin = new SpritesmithPlugin({
//设置源icons,即icon的路径,必选项
src: {
cwd: path.resolve(__dirname, '../static/img'),
glob: '*.png'
},
//设置导出的sprite图及对应的样式文件,必选项
target: {
image: path.resolve(__dirname, '../static/sprite/sprite.png'),
css: path.resolve(__dirname, '../static/sprite/sprite.less') //也可以为css, sass文件,需要先安装相关loader
},
//设置sprite.png的引用格式
apiOptions: {
cssImageRef: '/static/sprite/sprite.png' //cssImageRef为必选项
},
//配置spritesmith选项,非必选
spritesmithOptions: {
algorithm: 'top-down'//设置图标的排列方式
}
});
plugins.push(spritePlugin)
- 生成雪碧图和样式文件sprite.less
- 打开sprite.less可以看到有很多图片相关的less变量定义,翻到最后有一个.sprite函数的定义
重点来了
1.修改图中关于background-position的计算方法。
2.然后自定义一个生成background-size的方法
附源码:
/*
* 移动H5 雪碧图sprite.less转换方案, 所有用到雪碧图背景图片的地方都需要在less中调用 .sprite(图片名) 方法
* created by shiningding@tencent.com 2019/01/11;
*/
@star-name: 'star';
@star-x: 0px;
@star-y: 72px;
@star-offset-x: 0px;
@star-offset-y: -72px;
@star-width: 27px;
@star-height: 27px;
@star-total-width: 750px;
@star-total-height: 8863px;
@star-image: '/static/sprite/sprite.png';
@star: 0px 72px 0px -72px 27px 27px 750px 8863px '/static/sprite/sprite.png' 'star';
@welcome-word-name: 'welcome-word';
@welcome-word-x: 0px;
@welcome-word-y: 4125px;
@welcome-word-offset-x: 0px;
@welcome-word-offset-y: -4125px;
@welcome-word-width: 601px;
@welcome-word-height: 501px;
@welcome-word-total-width: 750px;
@welcome-word-total-height: 8863px;
@welcome-word-image: '/static/sprite/sprite.png';
@welcome-word: 0px 4125px 0px -4125px 601px 501px 750px 8863px '/static/sprite/sprite.png' 'welcome-word';
.sprite-width(@sprite) {
width: extract(@sprite, 5);
}
.sprite-height(@sprite) {
height: extract(@sprite, 6);
}
.sprite-position(@sprite) {
@sprite-offset-x: extract(@sprite, 3);
@sprite-offset-y: extract(@sprite, 4);
@sprite-width : extract(@sprite,5)+0.000001; //这个地方需要加一点点,防止计算Position的时候分母为0的情况
@sprite-height : extract(@sprite,6)+0.000001; //这个地方需要加一点点,防止计算Position的时候分母为0的情况
background-position: (@sprite-offset-x/(@spritesheet-width - @sprite-width))*100% -
(@sprite-offset-y/(@spritesheet-height - @sprite-height))*100%; //生成百分比替代像素单位
}
.sprite-image(@sprite) {
@sprite-image: extract(@sprite, 9);
@sprite-image-bare: ~`"@{sprite-image}".slice(1, -1)`;
background-image: url(@sprite-image-bare);
}
.sprite-size(@sprite){
@sprite-width : extract(@sprite,5);
background-size:(@spritesheet-width / @sprite-width) *100%!important; //移动端需要计算特定的百分比size
}
.sprite(@sprite) {
.sprite-image(@sprite);
.sprite-position(@sprite);
.sprite-width(@sprite);
.sprite-height(@sprite);
.sprite-size(@sprite);
}
.sprites(@sprites, @i: 1) when (@i <= length(@sprites)) {
@sprite: extract(@sprites, @i);
@sprite-name: e(extract(@sprite, 10));
.@{sprite-name} {
.sprite(@sprite);
}
.sprites(@sprites, @i + 1);
}
- 替换图片的样式
.i-icon-pic-star{
.sprite(@star);
}
.i-icon-welcome-word{
.sprite(@welcome-word);
}
大功告成,查看效果
图片也正常在移动端里可以显示了。