gulp.spritesmithでretina対応した時のメモ


images/sprite-masterフォルダには通常サイズの.pngとretinaサイズの-2x.pngを格納しておく。
※このサンプルではhoge.pnghoge-2x.pngfuga.pngfuga-2x.pngを格納

gulpfile.coffee
gulp = require 'gulp'
spritesmith = require 'gulp.spritesmith'

gulp.task 'sprite', ->
  spriteData = gulp.src 'images/sprite-master/*.png'
  .pipe spritesmith
    imgName: 'sprite.png'
    imgPath: 'images/sprite.png'
    cssName: '_sprite.styl'
    padding: 10
    retinaSrcFilter: 'images/sprite-master/*-2x.png'
    retinaImgName: 'sprite-2x.png'
    retinaImgPath: 'images/sprite-2x.png'

  spriteData.img
    .pipe(gulp.dest('images/'))

  spriteData.css
    .pipe(gulp.dest('stylus/'))

上記の設定でタスクを実行すると
imagesフォルダにsprite.pngsprite-2x.png
stylusフォルダに_sprite.stylが出来上がる。

_sprite.styl
/*
Stylus variables are information about icon's compiled state, stored under its original file name

.icon-home {
  width: $icon_home_width;
}

The large array-like variables contain all information about a single icon
$icon_home = x y offset_x offset_y width height total_width total_height image_path;

At the bottom of this section, we provide information about the spritesheet itself
$spritesheet = width height image $spritesheet_sprites;
*/
$icon_fuga_name = 'icon-fuga';
$icon_fuga_x = 60px;
$icon_fuga_y = 0px;
$icon_fuga_offset_x = -60px;
$icon_fuga_offset_y = 0px;
$icon_fuga_width = 50px;
$icon_fuga_height = 44px;
$icon_fuga_total_width = 110px;
$icon_fuga_total_height = 50px;
$icon_fuga_image = 'images/sprite.png';
$icon_fuga = 60px 0px -60px 0px 50px 44px 110px 50px 'images/sprite.png' 'icon-fuga';
$icon_hoge_name = 'icon-hoge';
$icon_hoge_x = 0px;
$icon_hoge_y = 0px;
$icon_hoge_offset_x = 0px;
$icon_hoge_offset_y = 0px;
$icon_hoge_width = 50px;
$icon_hoge_height = 50px;
$icon_hoge_total_width = 110px;
$icon_hoge_total_height = 50px;
$icon_hoge_image = 'images/sprite.png';
$icon_hoge = 0px 0px 0px 0px 50px 50px 110px 50px 'images/sprite.png' 'icon-hoge';
$icon_fuga_2x_name = 'icon-fuga-2x';
$icon_fuga_2x_x = 120px;
$icon_fuga_2x_y = 0px;
$icon_fuga_2x_offset_x = -120px;
$icon_fuga_2x_offset_y = 0px;
$icon_fuga_2x_width = 100px;
$icon_fuga_2x_height = 88px;
$icon_fuga_2x_total_width = 220px;
$icon_fuga_2x_total_height = 100px;
$icon_fuga_2x_image = 'images/sprite-2x.png';
$icon_fuga_2x = 120px 0px -120px 0px 100px 88px 220px 100px 'images/sprite-2x.png' 'icon-fuga-2x';
$icon_hoge_2x_name = 'icon-hoge-2x';
$icon_hoge_2x_x = 0px;
$icon_hoge_2x_y = 0px;
$icon_hoge_2x_offset_x = 0px;
$icon_hoge_2x_offset_y = 0px;
$icon_hoge_2x_width = 100px;
$icon_hoge_2x_height = 100px;
$icon_hoge_2x_total_width = 220px;
$icon_hoge_2x_total_height = 100px;
$icon_hoge_2x_image = 'images/sprite-2x.png';
$icon_hoge_2x = 0px 0px 0px 0px 100px 100px 220px 100px 'images/sprite-2x.png' 'icon-hoge-2x';
$spritesheet_width = 110px;
$spritesheet_height = 50px;
$spritesheet_image = 'images/sprite.png';
$spritesheet_sprites = $icon_fuga $icon_hoge;
$spritesheet = 110px 50px 'images/sprite.png' $spritesheet_sprites;
$retina_spritesheet_width = 220px;
$retina_spritesheet_height = 100px;
$retina_spritesheet_image = 'images/sprite-2x.png';
$retina_spritesheet_sprites = $icon_fuga_2x $icon_hoge_2x;
$retina_spritesheet = 220px 100px 'images/sprite-2x.png' $retina_spritesheet_sprites;

/*
These "retina group" variables are mappings for the naming and pairing of normal and retina sprites.

The list formatted variables are intended for mixins like `retinaSprite` and `retinaSprites`.
*/
$icon_fuga_group_name = 'icon-fuga';
$icon_fuga_group = 'icon-fuga' $icon_fuga $icon_fuga_2x;
$icon_hoge_group_name = 'icon-hoge';
$icon_hoge_group = 'icon-hoge' $icon_hoge $icon_hoge_2x;
$retina_groups = $icon_fuga_group $icon_hoge_group;

/*
The provided mixins are intended to be used with the array-like variables

.icon-home {
  spriteWidth($icon_home)
}

.icon-email {
  sprite($icon_email)
}
*/
spriteWidth($sprite) {
  width: $sprite[4];
}

spriteHeight($sprite) {
  height: $sprite[5];
}

spritePosition($sprite) {
  background-position: $sprite[2] $sprite[3];
}

spriteImage($sprite) {
  background-image: url($sprite[8]);
}

sprite($sprite) {
  spriteImage($sprite)
  spritePosition($sprite)
  spriteWidth($sprite)
  spriteHeight($sprite)
}

/*
The `retinaSprite` mixin sets up rules and a media query for a sprite/retina sprite.
  It should be used with a "retina group" variable.

The media query is from CSS Tricks: https://css-tricks.com/snippets/css/retina-display-media-query/

$icon_home_group = 'icon-home' $icon_home $icon_home_2x;

.icon-home {
  retinaSprite($icon_home_group)
}
*/
spriteBackgroundSize($sprite) {
  background-size: $sprite[6] $sprite[7];
}

retinaSprite($retina_group) {
  $normal_sprite = $retina_group[1];
  $retina_sprite = $retina_group[2];
  sprite($normal_sprite)

  @media (-webkit-min-device-pixel-ratio: 2),
         (min-resolution: 192dpi) {
    spriteImage($retina_sprite)
    spriteBackgroundSize($normal_sprite)
  }
}

/*
The `sprites` mixin generates identical output to the CSS template
  but can be overridden inside of Stylus

This must be run when you have at least 2 sprites.
  If run with a single sprite, then there will be reference errors.

sprites($spritesheet_sprites);
*/
sprites($sprites) {
  for $sprite in $sprites {
    $sprite_name = $sprite[9];
    .{$sprite_name} {
      sprite($sprite);
    }
  }
}

/*
The `retinaSprites` mixin generates a CSS rule and media query for retina groups
  This yields the same output as CSS retina template but can be overridden in Stylus

retinaSprites($retina_groups);
*/
retinaSprites($retina_groups) {
  for $retina_group in $retina_groups {
    $sprite_name = $retina_group[0];
    .{$sprite_name} {
      retinaSprite($retina_group);
    }
  }
}

使用するときは下記の用にする

style.styl
.hoge
    retinaSprite($icon_hoge_group)

.fuga
    retinaSprite($icon_fuga_group)

出力結果

style.css
.hoge {
  background-image: url("images/sprite.png");
  background-position: 0px 0px;
  width: 50px;
  height: 50px;
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .hoge {
    background-image: url("images/sprite-2x.png");
    background-size: 110px 50px;
  }
}
.fuga {
  background-image: url("images/sprite.png");
  background-position: -60px 0px;
  width: 50px;
  height: 44px;
}
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
  .fuga {
    background-image: url("images/sprite-2x.png");
    background-size: 110px 50px;
  }
}

これでretina対応できた。