Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

ペンデュラムウェーブ

 どうも!LSSです!!

 

なにげなくYouTubeを見ていて、興味深いものを見つけました。

「ペンデュラムウェーブ」という、複数の振り子についた玉を揺らすと…それぞれの振り子は普通に揺れているだけなのに、全体で見ると一列だったものが二列、三列…と連なって動いているように見えるものです。

 

2020年7月頃(去年ですね)にバズったそうですが、自分は今さら知りましたw

 

 

ペンデュラムウェーブ(動画)


www.youtube.com

バズった動画はこれとは別のものだそうですが、自分が最初に見たのはこちら!

振り子運動は紐の長さによって往復速度が変化しますが、その紐の長さをある規則に応じて決める事で、こうした不思議な動きになるみたいですね。

 

 

ペンデュラムウェーブ(CSS

というわけで、このブログらしくCSSでの再現を試みてみましたw

 

                          

 

いくらか試行錯誤しましたが、結局はこんな形に。

4つごとにボールに色をつけてみました^^

 

 

コード

<style>
@keyframes pdwa{
0%{top:0px;}
100%{top:100px;}
}
.pdw{position:relative;height:120px;}
.pdws{
position:relative;
animation:pdwa linear infinite alternate;
display:inline-block;
width:12px;height:12px;
}
.pdws:nth-child(4n+1){background-image:radial-gradient(circle at 50% 50%,#ff666640 0%,#ff6666ff 50%,#ff666600 51%);}
.pdws:nth-child(4n+2){background-image:radial-gradient(circle at 50% 50%,#6666ff40 0%,#6666ffff 50%,#6666ff00 51%);}
.pdws:nth-child(4n+3){background-image:radial-gradient(circle at 50% 50%,#aaaa6640 0%,#aaaa66ff 50%,#aaaa6600 51%);}
.pdws:nth-child(4n){background-image:radial-gradient(circle at 50% 50%,#66ff6640 0%,#66ff66ff 50%,#66ff6600 51%);}
.pdws:nth-child(1){animation-duration:calc(30s / 11);}
.pdws:nth-child(2){animation-duration:calc(30s / 12);}
.pdws:nth-child(3){animation-duration:calc(30s / 13);}
.pdws:nth-child(4){animation-duration:calc(30s / 14);}
.pdws:nth-child(5){animation-duration:calc(30s / 15);}
.pdws:nth-child(6){animation-duration:calc(30s / 16);}
.pdws:nth-child(7){animation-duration:calc(30s / 17);}
.pdws:nth-child(8){animation-duration:calc(30s / 18);}
.pdws:nth-child(9){animation-duration:calc(30s / 19);}
.pdws:nth-child(10){animation-duration:calc(30s / 20);}
.pdws:nth-child(11){animation-duration:calc(30s / 21);}
.pdws:nth-child(12){animation-duration:calc(30s / 22);}
.pdws:nth-child(13){animation-duration:calc(30s / 23);}
.pdws:nth-child(14){animation-duration:calc(30s / 24);}
.pdws:nth-child(15){animation-duration:calc(30s / 25);}
.pdws:nth-child(16){animation-duration:calc(30s / 26);}
.pdws:nth-child(17){animation-duration:calc(30s / 27);}
.pdws:nth-child(18){animation-duration:calc(30s / 28);}
.pdws:nth-child(19){animation-duration:calc(30s / 29);}
.pdws:nth-child(20){animation-duration:calc(30s / 30);}
.pdws:nth-child(21){animation-duration:calc(30s / 31);}
.pdws:nth-child(22){animation-duration:calc(30s / 32);}
.pdws:nth-child(23){animation-duration:calc(30s / 33);}
.pdws:nth-child(24){animation-duration:calc(30s / 34);}
.pdws:nth-child(25){animation-duration:calc(30s / 35);}
.pdws:nth-child(26){animation-duration:calc(30s / 36);}
</style>
<div class="pdw">
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
<span class="pdws">&nbsp;</span>
</div>

 

 

長いけど実は単純なコードです

ちょっと欲張って、玉を26個並べてみたので少々コードが長くなっていますが、そのほとんどの部分は単純なコピペだったりします。

 

まず、<style>内の、
.pdws:nth-child(1){animation-duration:calc(30s / 11);}
ペンデュラムウェーブの肝となるのは、この最後の11という数値。
これが次の行では、
.pdws:nth-child(2){animation-duration:calc(30s / 12);}
と、nth-childの( )内の数値と併せて+1しています。

 

これを26個分、用意しているコードという事になります。

 

次に、そのCSSによって装飾される26個の玉となる要素ですが、
<span class="pdws">&nbsp;</span>
をひたすらコピペで26個並べています。

(この「&nbsp;」の部分は、はてなブログのHTML編集画面では一度プレビューしてから戻ると「背景ピンクの赤点」に変更されます。)

 

 

今回使ったCSSセレクタ.pdws:nth-child(1)」は「pdwsというクラス名を持つ要素が並んでいる(兄弟要素)うち、1つめのものに対して」という意味になります。

 

animation-duration:calc(30s / 11);」のanimation-durationはキーフレームアニメーションの再生にかける時間を指定し、例えば「animation-duration:5s;」だと「5秒かけて再生」という意味になりますが、今回は再生時間を「calc(30s / 11)」という変わった指定方法で指定しています。

 

calcは、CSSで値を指定する時に「( )の内容を計算した結果」を値に出来る、CSSに計算機能をもたらしたもので、「calc(30s / 11)」は「30秒を11で割る」事を意味します。

この割り算は「30秒に11回再生されるような秒数」を算出する計算です。

 

そして、今回のキーフレームは
@keyframes pdwa{
0%{top:0px;}
100%{top:100px;}
}
と「上からの位置を0pxあけた状態→100pxあけた状態」に変化させる単純なもので、それを「animation:pdwa linear infinite alternate;」のalternate指定で「再生後に逆再生する」と指定しているので、上下の往復運動になるんですね。

※ちなみに、前述の「再生にかける時間」は片道分の時間で、alternateによる往復は倍の時間かかるという事になります。

 

もうひとつのnth-childの使い方。

.pdws:nth-child(4n+1){中略;}
.pdws:nth-child(4n+2){中略;}
.pdws:nth-child(4n+3){中略;}
.pdws:nth-child(4n){中略;}

のように並んでいる箇所があります。

ここが「4つごとに玉の色を指定している」部分です。

nth-childは「要素が並んでいる(兄弟要素)うち、〇つめのものに対して」という指定ですが、この「4n+1」のように「n」を入れると、「4の倍数+1つめ」という指定方法になります。

すると「4n+1」は「1つめ、5つめ、9つめ…」という事になり、「4n+2」は「2つめ、6つめ、10番目…」という事になるので、4つ毎になる指定をかける事になるんですね。

 

 

あとがき

「ペンデュラムウェーブ」は「周期となる時間内の繰り返し回数を+1、+2、+3…と順に増やしたものを並べる」というルールだけで、あのような動きになるのが…分かってみた上でも、やはり不思議ですね。

CSSのような、コンピュータの計算じゃなく、現実の振り子で動いているのを見るとなおさら不思議感があります。

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^