一、什么是雪碧图?

CSS雪碧 即CSS Sprite,也有人叫它CSS精灵,是一种CSS图像合并技术,该方法是将小图标和背景图像合并到一张图片上,然后利用css的背景定位来显示需要显示的图片部分。

二:为什么要用雪碧图

结合我们公司的需求来说,因为有很多组件,每个组件下有大概50张图片,每张图片是一个请求,也就是发了300多个请求,这样是很可怕的,所以为了优化性能,减少http请求,决定采用雪碧图的形式。

雪碧图是将你想要的很多张图片整理成一张图片,然后通过background-*来进行图片识别和定位来达到之前的效果。

三:如何使用雪碧图

雪碧图在之前有很多方式,如ps之类,现在最佳的方案还是在webpack-spritesmith

我其实对webpack并不是很了解,我现在列出使用方法和我在使用webpack时候遇到的问题。

1.安装

执行命令行:npm install --save-dev webpack-spritesmith

2.在webpack.config.js中写入

 var path = require(\'path\')

 var SpritesmithPlugin = require(\'webpack-spritesmith\')

 //自定义样式
 var templateFunction = function (data) {
  var shared = \'.ico { background-size: TWpx THpx }\'
    .replace(\'TW\', data.sprites[0].total_width / 2)
    .replace(\'TH\', data.sprites[0].total_height / 2)

  var perSprite = data.sprites.map(function (sprite) {
    return \'&.element-N {\\n width: Wpx;\\n height: Hpx;\\n background-position: Xpx Ypx;\\n}\'
      .replace(\'N\', sprite.name)
      .replace(\'W\', sprite.width / 2)
      .replace(\'H\', sprite.height / 2)
      .replace(\'X\', sprite.offset_x / 2)
      .replace(\'Y\', sprite.offset_y / 2)
      .replace(\'TW\', sprite.total_width / 2)
      .replace(\'TH\', sprite.total_height / 2)
  }).join(\'\\n\')

  return shared + \'\\n\' + perSprite
 }

 module.exports = {
   ...
   module: {
     rules: [
       {test: /\\.styl$/, use: [
         \'style-loader\',
         \'css-loader\',
         \'stylus-loader\'
       ]},
       {test: /\\.png$/, use: [
         \'file-loader?name=i/[hash].[ext]\'
       ]}
     ]
   },
   resolve: {
     modules: [\'node_modules\', \'spritesmith-generated\']
   },
   plugins: [
     new SpritesmithPlugin({
       src: { //引入路径
         cwd: path.resolve(__dirname, \'src/images/ios/\'),
         glob: \'*.png\'
       },
       target: { //输出路径
         image: path.resolve(__dirname, \'src/spritesmith-generated/ios.png\'),
         css: [
          [path.resolve(__dirname, \'src/spritesmith-generated/sprite-1.css\'), {
            format: \'function_ d_template\'
          }],
          [path.resolve(__dirname, \'src/spritesmith-generated/sprite-2.css\'), {
            format: \'handlebars_ d_template\'
          }]
         ]
       },
       customTemplates: {
        \'function_ d_template\': templateFunction, //自定义输出什么样的css样式
       },
       apiOptions: {
         cssImageRef: \'ios.png\'
       }
     })
   ]
 }

3.根据地址更改后执行命令

wbpack

其实这样已经满足了大部分需求,根据需要将你所在的输入和输出地址进行更改即可,可以设置自己想要设置的的css(style-components、styl等),然后直接复制在自己的项目css文件,很有灵活性。

四:需要注意的点

我有的时候指定不同文件下的图片合成一张雪碧图,那该如何呢

例如我的需求是:

  • resources
    • ios
      • images
    • ant
      • images
    • ios
      • images
  • ...

翻译: resources下有几个文件夹(ios、ant、ios),相对应下面images文件夹放着各自对应的图片。

需要注意下,它是支持glob的

src: { 
 //引入路径
 cwd: path.resolve(__dirname, \'src/images/ios/\'),
 glob: \'*.png\' //这里进行更改
},

这里可以参考在这里根据需求进行设置:http://www.globtester.com/

把glob改成

@(wechat|element|ios)/images/*.png

效果

五:更深层次的需求

我其实是想在各自的文件夹下的图片,生成各自文件夹下的雪碧图和css,那该如何实现呢,我写了一部分,还没有写完,感觉遇到了技术难点,我呈现出代码,会继续优化来实现

var path = require(\'path\')
var SpritesmithPlugin = require(\'webpack-spritesmith\')

var platforms = [\'android\', \'ant\', \'element\', \'ios\', \'wechat\']//, \'windows\']

// var url = \'ant\'
const TARGET = process.env.TARGET

console.log({ TARGET })

module.exports = [TARGET].map(l => {
 console.log(l)
 const url = l

 const fn = (data) => {
  console.log(url)
  var shared = \'background-size: TWpx THpx\\n\'
    .replace(\'TW\', data.sprites[0].total_width / 2)
    .replace(\'TH\', data.sprites[0].total_height / 2)

  var perSprite = data.sprites.map(function (sprite) {
    return `&.${url}-N {\\n width: Wpx;\\n height: Hpx;\\n background-position: Xpx Ypx;\\n}\\n`
      .replace(\'N\', sprite.name)
      .replace(\'W\', sprite.width / 2)
      .replace(\'H\', sprite.height / 2)
      .replace(\'X\', sprite.offset_x / 2)
      .replace(\'Y\', sprite.offset_y / 2)
      .replace(\'TW\', sprite.total_width / 2)
      .replace(\'TH\', sprite.total_height / 2)
  }).join(\'\\n\')

  return shared + \'\\n\' + perSprite
 }

 return {
  module: {
    rules: [
      {test: /\\.styl$/, use: [
        \'style-loader\',
        \'css-loader\',
        \'stylus-loader\'
      ]},
      {test: /\\.png$/, use: [
        \'file-loader?name=i/[hash].[ext]\'
      ]}
    ]
  },
  entry: {
   [url]: path.join(__dirname, url),
  },
  output: {
   path: path.join(__dirname, \'../parsed/\', url),
   filename: \'[name].css\'
  },
  resolve: {
    modules: [\'node_modules\', \'spritesmith-generated\']
  },
  plugins: [
    new SpritesmithPlugin({
      src: {
        cwd: path.resolve(__dirname, \'images/\'+url+\'/\'),
        glob: \'*.png\' // \'@(android|ant|element|ios|wechat|windows)/*.png\'
      },
      target: {
        image: path.resolve(__dirname, \'../parsed/\'+url+\'/\'+url+\'.png\'),
        css: [
          [path.resolve(__dirname, \'../parsed/\'+url+\'/\'+url+\'.css\'), {
            format: \'function_ d_template\'
          }]
        ]
      },
      customTemplates: {
        \'function_ d_template\': fn
      }
    })
  ]
 }
})

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

收藏 打印