tl;dr(Too Long, Don't Read)
- HTML/CSSを使って、Webブラウザに流れ星を流してみました
- 成果物は以下の通りです
- ソースコードはこちらから確認できます
- 主に以下の4点のCSSの機能を用いて流れ星を実装しました
-
CSS Animation
/keyframes
で「流れ星の動き」を表現 -
linear-gradient
を使って、「流れ星のしっぽ」を表現 -
opacity
で「流れ星が消える様」を表現 -
transform: rotate
を使って「流れる向き」を表現
-
はじめに
趣味で宇宙開発を行う団体「リーマンサット・プロジェクト」がお送りする新春アドベントカレンダーです。私はRSP-01という超小型人工衛星の、地上局運用システムの開発を担当しています。
今回は、Webブラウザに流れ星を流したかったので、HTML,CSSの基本的な技術を用いて流れ星を表現してみました。
流れ星とは?
流れ星を見たことがないという人は、Youtubeに動画が投稿されているので、見て頂くと良いと思います。
また「流れ星って何が流れているの?星なの?」など、流れ星が流れる仕組みを知りたい方は、以下のサイトが参考になります。
方針
- HTML, CSS JavaScriptを使って表現する
実装
実装に関して、主に以下の4点を説明します。
- CSSアニメーションを使って、流れ星の動きを表現する
-
linear-gradient
を使って、流れ星のしっぽを表現する -
opacity
を使って消える動きを表現 -
transform: rotate
を使って流れる向きを表現
1. CSSアニメーションを使って、流れ星の動きを表現する
まず、流れ星の動きを表現します。そのために、CSSアニメーションを利用します。
CSSアニメーションとは、CSSの記述だけで、HTML要素に動き(アニメーション)を持たせる機能です。
今回はCSSアニメーションの中で、CSS Animation
を使ったアニメーションを利用して、流れ星の動きを表現してみます。
まずは、簡単に白い線を引くアニメーションを作ってみます。実際のコードは以下の通りです。
<div class="star"></div>
.star {
height: 0;
width: 2px;
background: white;
animation-name: shooting;
animation-duration: 0.8s;
animation-timing-function: linear;
}
@keyframes shooting {
0% {
height: 0;
}
100% {
height: 80px;
}
}
上のコードをWebに表示すると以下のようなアニメーションが実行されます。
今回のポイントとしてはCSS Animation
の設定項目と、keyframes
です。
CSS Animation
ではいろいろな設定項目があるのですが、今回はanimation-name
とanimation-duration
, そしてanimation-timing-function
の3つです。
-
animation-name
-
keyframes
の名前を指定します。
-
-
animation-duration
- 指定されたアニメーションの開始から終了までの時間
- 今回は
0.8s=0.8秒
かけてアニメーションを実行します
-
animation-timing-function
- アニメーションの進行方法
- 今回は指定したアニメーションの各ステップを等しいスピードで進める
linear
を指定
次にkeyframes
は実際のアニメーションの動きを指定します。0%
が開始時のスタイル、100%
が終了時のスタイルを指定することで、開始から終了までの動きを表現できます。今回はheight
を0px -> 80px
になるような指定をしています。
2. linear-gradient
を使って、流れ星のしっぽを表現する
先ほどのCSSアニメーションで流れ星の流れを表現できました。ただ、これでは単なる白い棒が伸びているだけで、流れ星とは呼べません。
流れ星といったら、流れに沿って見えてくるしっぽの部分が必要です。
この流れ星の尻尾を表現するためにlinear-gradientを利用します。
linear-gradient
とは色の指定方法の1つですが、その特徴は色を連続的に変えて濃淡を表現できる点です。このlinear-gradient
を使って、流れ星の尻尾を表現すると、以下のようになります。
.star {
height: 0;
width: 2px;
- background: white;
+ background: linear-gradient(transparent, rgb(255, 255, 255));
animation-name: shooting;
animation-duration: 0.8s;
animation-timing-function: linear;
}
@keyframes shooting {
0% {
height: 0;
}
100% {
height: 80px;
}
}
上述のコードをWeb上で確認すると以下のように表現されます。流れ星の先から尻尾までに濃淡が表現されており、流れ星ぽく見えるかと思います。
-
linear-gradient
の解説ですが、今回は2つの色(透明:transparent
, 色:rgb(255, 255, 255)
)を指定してます。これによって、透明→白への濃淡が表現できました。
{
background: linear-gradient(transparent, rgb(255, 255, 255));
}
3. opacity
を使って消える動きを表現
だんだん流れ星っぽくなってきました。
次は、流れ星が消える表現を追加します。現状は、一瞬で消える動きになっていますが、フワッと消える動きにしてみたいと思います。
そのためにopacity
を使います。opacity
は透明度を表すCSSです。では、フワッと消える表現をopacity
を使って表現すると以下のようになります。
.star {
height: 0;
width: 2px;
background: linear-gradient(transparent, rgb(255, 255, 255));
animation-name: shooting;
animation-duration: 0.8s;
animation-timing-function: linear;
}
@keyframes shooting {
0% {
height: 0;
+ opacity: 50%;
}
+
+ 50% {
+ height: 60px;
+ opacity: 100%;
+ }
100% {
height: 80px;
+ opacity: 0;
}
}
変更した点は2つです。
1つ目はkeyframes
に50%のステップを追加。そして、2つ目はopacity
を使い、keyframes
の50%をピークに透明度の上下を追加しました。
これにより流れ星が流れるに従って色が濃くなり、ピークを過ぎるとだんだん薄くなりながら消えていく表現ができました。
以下が、実際の表示です。
4. transform: rotate
を使って流れる向きを表現
最後に、流れ星の流れる向きを変えられるようにします。
現状は上から下へしか流れません。この流れる向きをtrasnform: rotate
を使って変えられるようにします。
transfrom rotateは、指定の要素の向きを回転させるCSSです。
要素の向きを回転させることで流れ星の流れる向きを変えてしまおうというのが、今回の実装の意図です。実際のコードが以下の通りです。
<div class="star-box">
<div class="star">
</div>
+
+.star-box {
+ height: 100px;
+ width: 100px;
+ transform: rotateZ(45deg);
+}
.star {
height: 0;
width: 2px;
background: linear-gradient(transparent, rgb(255, 255, 255));
animation-name: shooting;
animation-duration: 0.8s;
animation-timing-function: linear;
}
今回はstar-box
という流れ星要素の上に新しく要素を追加しています。また、その要素にtransform: rotation
を指定しています。
ポイントとしてはtransform: rotation
を流れ星の要素(star
)ではなく、一つ上の要素(star-box
)に指定する点です。transform: rotation
を流れ星の要素(star
)に指定すると、CSSアニメーションによって自身の大きさが変化するにつれて全体の位置が動いてしまいます。先ほどは上から下へ流れるため高さしか変化しませんでしたが、向きを変化させることで横幅も変化してしまうことが位置がずれの原因です。
そのため、一つ上に縦横の長さを固定した要素(star-box
)を作り、それを回転させることで、上述の位置ズレを回避しています。
上述のコードをWeb上で確認すると、以下のようになります。
完成
上述のコードで流れ星は完成です。
実際の成果物はnetlifyにデプロイしました。
実際のソースコードでは、ボタンを用意し、流れ星が流れる頻度を変えられるボタンを追加しています。また、ランダムに流れ星の表示位置を計算しています。表示位置については、流れ星が中心から同心円状に流れるように計算しています。これについては今回は説明を割愛します。
詰まった点
今回のコードは、当初はnuxt.jsで実装していました(以下、該当のリポジトリ)
- https://github.com/Ushinji/shooting_star_simulator
ただ、SSGでビルドしてnetlifyにデプロイすると、css animationがうまく機能しなかったので断念しました。
おわりに
今回はCSSアニメーションを使って流れ星をWeb上に表現する実装を説明しました。
実際の流れ星はもっと綺麗なので(笑)、流れ星に興味を持った方は、実際に流星群の時期に夜空を見上げてもらえればと思います。以下に、日本での流星群の時期の一覧が紹介されているWebサイトを記載しておきます。
最後に
明日は @ukisoft さんの「firebase storage のサイズが大きくなったのでオラったらやらかしちゃった話」です。
また、リーマンサット・プロジェクトは「普通の人が集まって宇宙開発しよう」を合言葉に活動をしている民間団体です。
興味を持たれた方は https://www.rymansat.com/join からお気軽にどうぞ。