雪碧图工具sprity(20151201更新修复了同时合并多张图的bug)

前身是css-sprite,前几天帮新同事搭建环境,意外发现sprity在window下能够安装成功了,同时也发现node版本已经4点几了,本身电脑的版本还停留在0.10,赶忙把本身的node升级到最新版本,win10下,sprity安装成功,可使用。css

在这里介绍下sprity顺便提下本身遇到的问题。node

介绍

sprity,一个模块化的雪碧图生成工具,会根据目录中的图片生成相应的雪碧图和样式文件,支持retina图,能够内嵌base64 编码格式的图,支持不一样的图片格式和有不一样的图片引擎能够选择。git

安装使用

经过npm安装github

npm install sprity --save

也能够全局安装使用web

npm install sprity -g

结合gulp使用,也能够用grunt,这里说下gulp的用法:npm

var gulp = require('gulp');
var gulpif = require('gulp-if');
var sprity = require('sprity');

// 建立sprites任务
gulp.task('sprites', function () {
  return sprity.src({
    src: './src/images/**/*.{png,jpg}', //须要进行合并的图片路径
    style: './sprite.css',              //生成的样式文件名和格式,能够生成scss
    // 还有不少其余参数,如指定模板、图片格式、前缀、名称和图片合并的方向等,具体能够查看sprity的github内容
    processor: 'sass', // 生成的样式格式
  })
  .pipe(gulpif('*.png', gulp.dest('./dist/img/'), gulp.dest('./dist/css/')))
});

配置好options,把图片放进目录中,运行gulp sprites,就能够生成对应的雪碧图和样式文件了。gulp

sprity支持三种图片引擎,sprity-lwip、sprity-canvas和sprity-gm。默认使用的是sprity-lwip,好像lwip须要从新编译node-gyp什么的,因此当时我仍是win7系统的时候,常常会报错,没法编译成功。另两个没试过,不展开说,有兴趣的能够去试着使用下。canvas

模板

sprity采用handlebar来处理模板,已经写好有模板案例能够参考,sprity-csswindows

图片引擎

鉴于sprity-lwip在windows下很难部署,太难安装成功了。因此我尝试了其余的引擎,sprity-canvas也很难安装成功,最后惟有靠sprity-gm了,这个须要依靠GraphicsMagick和Imagemagick,我尝试只安装其中某一个,发现不行,必定得两个都安装。数组

本身搜索引擎找到官网下载,而后安装,重启电脑,对,要重启才有用,否则会报错。

接着安装sprity-gm

npm install sprity-gm

而后在gulp的任务中加上参数配置:

engine: 'gm',
format: 'png', // because sprity name it with uppercase: https://github.com/sprity/sprity/issues/28
'gm-use-imagemagick': true

就能够了。

问题

使用途中,我遇到一个问题没法解决,一个gulp任务里面,我想同时分开生成多张雪碧图,不知道为何生成的图和样式会合并在一块儿。

例如,我这样写:

gulp.task('sprites', function () {
    sprity.src({
        src: '/img/icon/*.png',
        style: '_icon.scss',
        format: 'png',
        orientation: 'left-right',
        template: './sprity-css.hbs',
        processor: 'scss',
        prefix: 'icon',
        name: 'icon'
    })
    .pipe(gulpif('*.png', gulp.dest('/img/'), gulp.dest('/css/')));

    sprity.src({
        src: topicType + '/img/bg/*.png',
        style: '_bg.scss',
        format: 'png',
        orientation: 'left-right',
        template: './sprity-css.hbs',
        processor: 'scss',
        prefix: 'bg',
        name: 'bg'
    })
    .pipe(gulpif('*.png', gulp.dest('/img/'), gulp.dest('/css/')));
});

最后生成两张图片:icon.png和bg.png,两个样式文件:_bg.scss和_icon.scss,这样没错,能够icon的图片和样式里面包含有bg的图片和样式:

_icon.scss:

.bg {
      background-image: url('#{$icon-sprite-path}/bg.png');
    }

  .bg-btn-tg {
    background-position: -526px -196px;
    width: 80px;
    height: 32px;
  }
.icon {
      background-image: url('#{$icon-sprite-path}/icon.png');
    }

  .icon-btn-tg {
    background-position: -510px -280px;
    width: 80px;
    height: 32px;
  }

_bg.scss:

.bg {
      background-image: url('#{$icon-sprite-path}/bg.png');
    }

  .bg-btn-tg {
    background-position: -526px -196px;
    width: 80px;
    height: 32px;
  }

我不肯定是gulp流的问题,仍是模板的问题,由于模板循环的是一个数组来的。
sprity-css.hbs:

{{#each layouts}}
  {{#each sprites}}

    {{#if dpi}}
    @media (-webkit-min-device-pixel-ratio: {{ratio}}), (min-resolution: {{dpi}}dpi) {
    {{/if}}
    .{{cssesc ../classname}} {
      background-image: url('{{escimage url}}');
      {{#if dpi}}
      background-size: {{baseWidth}}px {{baseHeight}}px;
      {{/if}}
    }
    {{#if dpi}}
    }
    {{/if}}
  {{/each}}

  {{#each layout.items}}
  .{{../classname}}-{{meta.name}} {
    background-position: -{{baseDim x}}px -{{baseDim y}}px;
    width: {{baseDim width}}px;
    height: {{baseDim height}}px;
  }
  {{/each}}
{{/each}}

20151201更新
sprity修复了同时合并多张图片会重叠的bug,当时也想过试下能不能修改,然技术太渣,不知道哪里修改。
缘由好像是sprity会从同一个节点处理多个png流,以至默认的layout成为一应俱全的每个png图像,英语太渣。
其实就是把一个变量改下就能够了。如今能够同时合并多张图片了。
修复问题的commit


20160227更新
新的sprity-css.hbs:

{{#each layouts}}
  {{#each layout.items}}
  ${{meta.name}}: -{{x}}px -{{y}}px {{meta.width}}px {{meta.height}}px;
  {{/each}}

  @mixin sprite-width($sprite) {
  width: nth($sprite, 3);
  }

  @mixin sprite-height($sprite) {
  height: nth($sprite, 4);
  }

  @mixin sprite-position($sprite) {
  $sprite-offset-x: nth($sprite, 1) - 4;
  $sprite-offset-y: nth($sprite, 2) - 4;
  background-position: $sprite-offset-x $sprite-offset-y;
  }

  {{#each sprites}}
  @mixin sprite-{{name}}() {
  background-image: url('#{$icon-sprite-path}/{{name}}.png?v=#{$version}');
  }
  {{/each}}

  @mixin sprite($sprite) {
  @include sprite-position($sprite);

  @include sprite-width($sprite);
  @include sprite-height($sprite);

  }

  {{#each sprites}}
  .{{name}} {
    background-repeat: no-repeat;
    overflow: hidden;
    border: none;
    background: url('#{$icon-sprite-path}/{{name}}.png?v=#{$version}');
    @include inline-block();
    vertical-align: middle;
    font-style: normal;
  }
  {{/each}}

  {{#each layout.items}}
  .{{meta.name}} {
    @include sprite(${{meta.name}});
  }
  {{/each}}
{{/each}}
相关文章
相关标签/搜索