html
<div class="tree root">
<div>
<div>
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>
</div>
<div>
<div>
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>
<div >
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
<div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
<div>
<div>
<div></div>
<div></div>
</div>
<div>
<div></div>
<div></div>
</div>
</div>
</div>
</div>
</div>
</div>
CSS
.tree{
position: fixed;
bottom: 0;
left: 50%;
width: 3px;
height: 100px;
background-color: #8A5533;
transform: translate(-50%,0);
}
/* 枝 */
.tree div{
position: absolute;
bottom: 90%;
left: 50%;
width: 100%;
height: 65%;
border-radius: 100% 100% 0 0;
background-color: #8A5533;
animation: grow 3s linear forwards;
}
.tree div:nth-child(odd){
transform-origin: right bottom;
transform: translateX(-50%) rotate(-25deg) skewY(-10deg);
}
.tree div:nth-child(even){
transform-origin: left bottom;
transform: translateX(-50%) rotate(25deg) skewY(5deg);
}
.tree div:empty{
box-shadow: 0 10px 2px 0 hotpink inset;
}
/* 花 */
.tree div:empty:after{
content: "";
position: absolute;
bottom: 95%;
left: 50%;
width: 25px;
height: 25px;
border-radius: 100%;
background-color: transparent;
box-shadow: none;
transform: translateX(-50%);
z-index: 1;
animation: flowering 3s 3s linear forwards;
}
@keyframes grow{
from{
height: 0;
}
to{
height: 95%;
}
}
@keyframes flowering{
to{
background-color: pink;
box-shadow: 0 25px 50px 2px mistyrose;
}
}
仕組み
'枝が、2本の枝をつくる' '作られた枝も2本の枝をつくる'
開花アニメーション
枝の先端に花をつける必要があるので :empty
を利用します
:empty
は 空の要素のみを指定できるセレクタ
サンプルでは 空の要素 == 子要素を持たない要素
です。
これで先端だけに花をつけることができます。
JS 再帰関数を使ってHTMLを作成
root要素はあらかじめ用意しておきます
<div class="tree"></div>
var root = document.querySelector('.tree');
// 引数: 階層,要素
fractal(5,root);
function fractal(hierarchyCnt,node) {
if(hierarchyCnt <= 0) return;
var e1 = document.createElement('div');
var e2 = document.createElement('div');
node.appendChild(e1);
node.appendChild(e2);
fractal(hierarchyCnt - 1,e1);
fractal(hierarchyCnt - 1,e2);
}