CSS animation day25 となりました。
本日は、3D表現を用いた、Particle をやります。
なお、2D版も作りましたので、よろしければ前回 の記事をご参照ください。
See the Pen Particle Sphere by hiroya iizuka (@hiroyaiizuka) on CodePen.
#2. なぜか?
codrops によると、3D Particle の表現は、ページをローディングする待ち時間のアニメーションに使うと、効果的です。
確かに3D Particleは綺麗ですし、ランダムに動くのを見てても飽きないですし、楽しいですよね。いくらでも待てそうな気がします。
UX を向上させるために、こうした技術は、役に立ちそうですね!
#3. 参考文献
Particle Orb CSS
CSS 3D Particles
#4. 分解してみる
❶.
まずは、マークアップをします。
前回と同様のコードを書きます。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="css/styles.css" />
</head>
<body>
<div class="container">
<div class="particle-wrap"></div>
<div class="particle"></div>
<div class="particle"></div>
・
・
・
× 100
</div>
</body>
</html>
body {
margin: 0px;
padding: 0px;
background: #000;
overflow: hidden;
}
.container {
width: 100%;
height: 100vh;
position: relative;
}
.particle {
background: #fff;
border-radius: 50%;
height: 20px;
width: 20px;
position: absolute;
@for $i from 1 through 100 {
&:nth-child(#{$i}) {
transform: translate(random(100) * 1vw, random(100) * 1vh);
}
}
}
❷. ここから、3D 表現をつけていきたいところですが、知識の復習をしましょう。
CSS で3D 表現をする時に、以下の3つが大事です。
1: transform-style: preserve 3d
2: perspective
3: rotate
transform-style: preserve-3d
transform-style は、要素の子要素を、3D 空間に配置する(preserve-3d)か、平面に配置する(flat)かを決めます。立体的に見せたい要素の親要素に、transform-style を指定しましょう。
perspective
遠近感を出す手法です。値が小さいほど、広角レンズのように歪みが大きくなります。
See the Pen css transform rotate/perspective test by yoichi kobayashi (@ykob) on CodePen.
perspectiveも、立体的に見せたい要素の親要素に、指定しましょう。
rotate
StarWars の以前の記事でrotate Xの解説をしました。また、こちら のQiita 記事も大変わかりやすくまとまっております。
❸.
では、これから 3D を作りますが、ここで質問です!
3D座標空間で、中心から、ある一定距離に、点をランダムに配置すると、どんな形になるでしょうか?
・・・
そうです、球になりますね!
コードを書いて実験しましょう。
body {
margin: 0px;
padding: 0px;
background: #000;
overflow: hidden;
}
.container {
width: 100%;
height: 100vh;
position: relative;
transform-style: preserve-3d;
perspective: 1000px;
}
.particle {
position: absolute;
margin: 50vh 50vw;
width: 10px;
height: 10px;
border-radius: 50%;
background: #fff;
}
@for $i from 1 through 100 {
.particle:nth-child(#{$i}) {
animation: rotate#{$i} 4s infinite;
}
@keyframes rotate#{$i} {
100% {
transform: rotateX((random(360) * 1deg)) rotateY((random(360) * 1deg))
rotateZ((random(360) * 1deg)) translateZ(200px);
}
}
}
球になりました!
ポイントというか、はまったところですが
animation: rotate#{$i}
keyframes rotate#{$i}
というように、
for文の中でアニメーションを設定し、particle要素の一つ一つにアニメーションをつけなければなりません。いつものように、animation: rotate としてしまうと、アニメーションがうまく動かず、3時間くらいハマるので、気をつけましょう。
では、色を変え、keyframes をいじります。
@for $i from 1 through 100 {
.particle:nth-child(#{$i}) {
animation: rotate#{$i} 4s infinite;
background: hsl(random(360), 75%, 75%);
width: random(15) * 1 + px;
height: random(15) * 1 + px;
}
@keyframes rotate#{$i} {
30% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(300px);
}
50% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(100px);
}
70% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(130px);
}
90% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(50px);
}
100% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(600px);
}
}
}
いい感じです。
translateの値をいじると、こういう動きのほか、もっと別の表現もできます。
@keyframes rotate#{$i} {
30% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(300px);
}
50% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translate(300px, 600px);
}
70% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translate(400px, 200px);
}
90% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(50px);
}
100% {
transform: rotateY((random(360) * 1deg)) rotateZ((random(360) * 1deg))
rotateX((random(360) * 1deg)) translateZ(600px);
}
}
様々な表現ができて楽しいですね。
❹.
では最後に、ちょっとおまけです。
下のGIF をご覧ください。
これは、HTMLで入れ子の構造を持った親要素にアニメーションをつけて回転させたものですが、ご覧の通り、入れ子の子要素(赤い点)にもアニメーションが適応されます。
この特性を生かして、球体が、地球のようにぐるぐる回転する表現をつけましょう。
<div class="container">
<div class="wrapper">
<div class="particle"></div>
<div class="particle"></div>
<div class="particle"></div>
・
・
・
× 100
</div>
</div>
.wrapper {
will-change: animation;
animation: moveAround 4s infinite;
transform-style: preserve-3d;
}
@keyframes moveAround {
100% {
transform: rotateY(360deg);
}
}
無事、Particle が、全体的に、横に回転するようになりました。
こういう、綺麗なParticle動画が、CSS だけでできるなんて、素晴らしいですね。
では、また明日〜!