LoginSignup
17
17

CSS アニメーションでネオンサインの点灯の雰囲気を出してみる

Posted at

SVGのロゴをネオンサインが点灯するようなイメージのアニメーションにできないかと試行錯誤した結果を記事に残しておく。

最終完成バージョン

まずは出来上がりを、Codepen で確認してほしい。Start ボタンを押すと、ロゴが点灯する。
ネオンサインが点灯する雰囲気にみえるとうれしい。
(と言っても、今となってはネオン管っぽいLEDチューブが主流なので、本物のネオン管を見たことがない世代が多いかもしれないが...)

See the Pen Neon Sign by hiroatsu (@scqspcfg-the-solid) on CodePen.

なお、このアニメーションは、地図共有サイト Toboggar のスプラッシュ画面で使用しているものである。

どうやったらネオンサインの点灯のように見えるか

今回の方法がベストだとは思えないし、ベターですらないような気がするが、とりあえず私はこれで納得した。

  • うっすら明るくなったあと短く3回点滅する
  • その後、数度パチっと一瞬消える
  • 点滅の間隔はランダム
  • 時間は全体で2秒前後
  • 影とぼかしで光ってる雰囲気を出す

テクニック

影とぼかし

これは簡単、SVG全体にフィルターを掛ければよい。
drop-shadow CSS関数は、Xのオフセット、Yのオフセット、ぼかし半径、色を指定して影を作る。

svg {
    filter: drop-shadow(0px 3px 10px #71f7ed);
}

アニメーション

点滅はCSSアニメーションで実現する。ロゴ自体はSVGで作成されているが、CSSで操作している。
SVG内でいくつかに分割されたpathに対して、点滅させるためのランダム値を用いて動的に生成される別々の kayframe を設定する。

const title = document.querySelectorAll('svg path');
title.forEach((path) => {
    const keyframe = [];
    /* -----
    ランダムに点滅させるkeyframeを動的に生成する
    ----- */
    animate(path, keyframe);
});

点滅

点滅は単純に opacity の設定で実現できる。
0 から 1 にし、すぐに0に戻せば一瞬光る。アニメーションで0.05秒でoacityを増減させる。

path {
    opacity: 0;
}

よって、アニメーションの keyframe は opacity を0か1に設定しているだけである。

keyframe.push({ opacity: 1, offset: timming });
keyframe.push({ opacity: 0, offset: timming + 0.01 });
keyframe.push({ opacity: 1, offset: timming + 0.02 });

ただ、単純にアニメーションするだけでなく、それっぽくするためにいくつか処理を追加している
冒頭、点滅する前に opacity が 0.2 になるようにうっすら光らせている。
アニメーション全体は2500ミリ秒に設定しているので、平均125ミリ秒かけてうっすら光る。

keyframe.push({ opacity: 0 });
let timming = Math.random() * 0.5;
keyframe.push({ opacity: 0.2, offset: timming });

最初に3回点滅するときには、0.8、0.9、1と段々明るくなるように設定している。

keyframe.push({ opacity: 0.8, offset: timming});
keyframe.push({ opacity: 0, offset: timming + 0.01 });
keyframe.push({ opacity: 0.9, offset: timming + 0.02 });
keyframe.push({ opacity: 0, offset: timming + 0.03 });
keyframe.push({ opacity: 1, offset: timming + 0.04 });

3回点滅したあとランダムに、ときどき点滅するようにする。
offset が 1を超えない範囲でランダムに点滅させるのだが、適当な増分(increase)を設定しているので、段々点滅間隔が長くなるようになっている。
概ね1回か2回点滅するはずである。

let increase = 0;
timming = timming + 0.05 + Math.random() * 0.8;
while (timming < 0.97) {
    keyframe.push({ opacity: 1, offset: timming });
    keyframe.push({ opacity: 0, offset: timming + 0.01 });
    keyframe.push({ opacity: 1, offset: timming + 0.02 });
    timming = timming + 0.05 + Math.random() * (1.1 + increase * 0.1);
    increase = increase + 3;
}

完成ソースはCodepenで確認してほしい。

17
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
17