雪碧圖工具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}}
相關文章
相關標籤/搜索