CSSパラパラアニメのファイルサイズが小さく、効率的な作成方法

CSSパラパラアニメの効率的な作成方法

CSSパラパラアニメにはCSSスプライトとstepsを使用してbackground-positionを指定する…というのは仕事でコーディングしている人にとっては、もはや常識だ。

しかし、ファイルサイズが小さく、効率的に作成する方法についてはあまり知られていない。

この記事ではそれについて説明している。

ファイルにはPNG8かSVGを使用する

CSSパラパラアニメ用の画像にはファイルサイズの小さいPNG8かSVGを使用する。ファイルサイズの大きいJPGやPNG24は基本的に使用しない。

PNGの場合は必ずソフトウェアでPNGを圧縮してファイルサイズを小さくする処理をする。

PNGを圧縮する主なソフトウェア一覧

ちなみにSVGもファイルサイズ軽減のための圧縮が必要。

前述のImageOptimはSVG圧縮(SVGO)が可能だ。

npmが使用可能であればimagemin-pngquantとsvgoをインストールして使う方法もある。

npm i -D imagemin-pngquant svgo

PNGやSVGを圧縮するWebサービスも存在するが処理に時間がかかるため、できれば仕事で使用しないほうが良い。

TinyPNG SVGOMG

ファイルをCSSスプライト用の画像にする

ファイルをCSSスプライト用の画像にする際にPhotoshopなどで1個ずつ並べている人をよく見かけるがImageMagickを使用すればconvertコマンドを実行するだけでCSSスプライト用の画像を作成できる。

ImageMagick installer for Mac OS X

convert -append *.png sprite.png

CSS Sprite用画像

CSSは下記のように記述する。100px*100pxが4枚なのでstepsを4にしてbackground-position-yには-100px*4を指定して4fps(1秒に4フレーム)のアニメーションにしている。

.anime {
  width: 100px;
  height: 100px;
  background: url(sprite.png) no-repeat;
  animation: anime 1s steps(4) infinite;
}

@keyframes anime {
  to {
    background-position-y: -400px;
  }
}

stepsを使用したCSSアニメーションのデメリット

stepsを使用したアニメーションだと、例えば6fpsで1,2,3の画像は1フレーム、4は3フレームの合計6フレームで作成したい場合は4の画像がスプライト画像内に3枚必要になるためファイルサイズが無駄に大きくなってしまう。

このようなケースの場合はstepsを使用せずkeyframesの%を計算して指定して動かす。

steps(4)のアニメーションはkeyframesの%を使用する場合、100%を4で割って1フレームは25%ということになる。

ただし、25% background-position-y: -100px、50% background-position-y: -200pxのように指定してしまうとパラパラアニメにならないため、間に0.001%を加算した25.001% background-position-y: -200pxを入れる必要がある。

.anime2 {
  width: 100px;
  height: 100px;
  background: url(sprite.png) no-repeat;
  animation: anime2 1s infinite;
}

@keyframes anime2 {
  0% { background-position-y: 0; }
  25% { background-position-y: 0; }
  25.001% { background-position-y: -100px; }
  50% { background-position-y: -100px; }
  50.001% { background-position-y: -200px; }
  75% { background-position-y: -200px; }
  75.001% { background-position-y: -300px; }
  100% { background-position-y: -300px; }
}

これを6fpsで1,2,3の画像は1フレーム、4は3フレームの合計6フレームにする場合は100%を6で割って1フレーム16.66%で作成する。

.anime3 {
  width: 100px;
  height: 100px;
  background: url(sprite.png) no-repeat;
  animation: anime3 1s infinite;
}

@keyframes anime3 {
  0% { background-position-y: 0; }
  16.66% { background-position-y: 0; }
  16.661% { background-position-y: -100px; }
  33.32% { background-position-y: -100px; }
  33.321% { background-position-y: -200px; }
  49.98% { background-position-y: -200px; }
  49.981% { background-position-y: -300px; }
  100% { background-position-y: -300px; }
}

SCSSで変数をkeyframesの%の指定は不可

100%を任意の数で割るならSCSSを使用したいところだが、SCSSは変数をkeyframesの%に指定できないため、下記のようなコードはエラーになる。

$pos: -100;
$fps: 6;
$per: $pos / $fps;

@keyframes anime {
  @for $i from 0 through $fps {
    ($per * $i)% { background-position-y: ($pos * $i)px; }
  }
}
カテゴリーcss