※注意
この記事で紹介しているのは
gulp-spritesmith
ではなくて
gulp.spritesmith
です。
紛らわしいので、間違えないようにご注意を。
sprite化は面倒くさい
既存のサイトでレスポンス速度向上のために、一部の画像をsprite化する運びになった。
自分で作成するのはだるいし、工数もかかるのでgulpを使って自動化できないかと思って、前に見た記憶を辿りながらたどり着いたのが
gulp.spritesmith
↑これ
sprite化したい画像を特定のディレクトリにポコポコ投げ入れて、taskを回すとsprite画像を作成してくれて、sassとかstylusとかlessとかに変数を吐き出してくれる。
こういう便利なものを作成してくれる人には頭が上がらない。
感謝....圧倒的感謝!
使い方
まずはinstall
$ yarn add gulp.spritesmith -D
taskを追加
gulp.task('sprite', () => {
// pathの設定は適宜変えてくだしあ
const spriteData = gulp.src('/path/to/sprite/*.png') // スプライト化したい画像を入れるディレクトリ
.pipe(spritesmit({
imgName : '/path/to/img/contents-sprite.png', // sprite画像の名前
imgpath : '/path/to/img/contents-sprite.png', // sprite画像のpath
cssName : 'sprite.scss', // スプライト用のcssの名前
cssFormat : 'scss', // ファイルのフォーマット
padding : 5 // 画像のpadding
}));
spriteData.img.pipe(gulp.dest('./dest/path/to/sprite')); // スプライト画像の出力先
spriteData.css.pipe(gulp.dest('./src/path/scss/')); // スプライト用の scss ファイルの出力先
});
実行
実行すると、指定したパスの場所にcontents-sprite.png
っていうsprite化したい画像がひとまとまりになったファイルと、変数が格納されているsprite.scss
っているscssファイルが作成される。
変数名は基本的に画像ファイルの名前に沿って作成される模様。
レスポンシブ対応とか考えてない場合は、そのまま@import
するなりなんなりして、仕様すれば使えるはず。
レスポンシブ対応したい
このままでも仕様は出来るが、当たり前だが画像が等倍で表示されてしまう。
要素の'width'や'height'に対して目一杯画像を広げたいので、それ用のmixinを作成する。
作成される変数の中身はこんな感じ。
$sprite-image-name: 'sprite-image';
$sprite-image-x: 445px;
$sprite-image-y: 45px;
$sprite-image-offset-x: -445px;
$sprite-image-offset-y: -45px;
$sprite-image-width: 10px;
$sprite-image-height: 20px;
$sprite-image-total-width: 459px;
$sprite-image-total-height: 391px;
$sprite-image-image: '/path/to/contents-sprite.png';
$sprite-image: (445px, 45px, -445px, -45px, 10px, 20px, 459px, 391px, '/path/to/contents-sprite.png', 'sprite-image', );
// ~ 中略 ~
@mixin sprite-width($sprite) {
width: nth($sprite, 5);
}
@mixin sprite-height($sprite) {
height: nth($sprite, 6);
}
@mixin sprite-position($sprite) {
$sprite-offset-x: nth($sprite, 3);
$sprite-offset-y: nth($sprite, 4);
background-position: $sprite-offset-x $sprite-offset-y;
}
@mixin sprite-image($sprite) {
$sprite-image: nth($sprite, 9);
background-image: url(#{$sprite-image});
}
@mixin sprite($sprite) {
@include sprite-image($sprite);
@include sprite-position($sprite);
@include sprite-width($sprite);
@include sprite-height($sprite);
}
@mixin sprites($sprites) {
@each $sprite in $sprites {
$sprite-name: nth($sprite, 10);
.#{$sprite-name} {
@include sprite($sprite);
}
}
}
レスポンシブ対応させるためのmixinを作成する
@charset "UTF-8";
// 変数が入っているscssをimport
@mixin sprite-responsive($sprite){
$sheet-w : nth($sprite, 7);
$sheet-h : nth($sprite, 8);
$sprite-w : nth($sprite, 5);
$sprite-h : nth($sprite, 6);
$offset-x : nth($sprite, 1);
$offset-y : nth($sprite, 2);
$bg-path : nth($sprite, 9);
// テキストを隠す
white-space: nowrap;
text-indent: 100%;
overflow: hidden;
font-size: 0;
background-image: url($bg-path);
background-size: ($sheet-w / $sprite-w * 100 + 0%) ($sheet-h / $sprite-h * 100+ 0%);
background-position: ($offset-x / ($sheet-w - $sprite-w) * 100 + 0%) ($offset-y / ($sheet-h - $sprite-h) * 100 + 0%);
&:after{
content: '';
display: block;
padding-top: ($sprite-h / $sprite-w * 100 + 0%);
}
}
nth($sprite, number)
で$sprite
のリストにアクセスしている。
(この機能知らなかった...)
background-image
とかで演算式の後に+ 0%
と記述しているのは単位を%にするため。
(他に良い方法が見つからなかった orz)
で、あとはこのファイルの以下に@include
して書いていく感じ。
i.sprite{
@include sprite-responsive($sprite-image);
display: inline-block;
width: 6px;
height: 12px;
}
これで指定したwidth
とheight
の中にちょうど良く収まってくれる...はず。
修正等があれば、書き直します。