雪降るアドベントカレンダーを作る
アドベントカレンダーを作る
HTML
カレンダーなのでたくさんの玉が必要です。<template>
を使って玉の雛形を作り、JavaScriptで量産しました。
玉のtemplate
<div id="calendar" class="calendar-container"></div>
<template id="date_cell">
<a href="#">
<div class="date-cell">
<div class="cell-inside">
<div class="cell-door">
<span class="date-number"></span>
<div class="door-nob"></div>
</div>
</div>
</div>
</a>
</template>
JS
このdataにurlを追加することで、日付をクリックすると飛ぶようになります。
const data = [
{url:'#'},
省略
]
data.forEach((elm, index) => {
const clone = date_cell.content.cloneNode(true);
clone.querySelector('.date-number').textContent = index + 1;
clone.querySelector('a').setAttribute("href", elm.url);
calendar.append(clone);
});
CSS
CSSも基本的なものしか使用していないので特に書くこともないのですが、ドアを再現する際にいくつか初め使ったものがあったで書き残しておきます。
transform-origin: left;
transform: perspective(900px) rotateY(-30deg);
transition: all 0.5s ease-in-out;
属性/関数 | 説明 |
---|---|
transform-origin | 座標変換の原点を決めます。今回は扉が開いているように見せたかったので、左を基準に回転させるために使用しました。 |
transform: perspective(900px) | ユーザーと画面までの距離を定義し、3次元であるかのように見せます。これを使う際はtransformの先頭に置く必要があります。 |
transform: rotateY(-30deg) | Y軸で30度回転させます。 |
雪を降らせる
ピュアなHTML/CSS/JSで雪を降らせてみようとしましたが、ほぼSVGです。
HTML
htmlでは、雪を降らせたい要素にcssクラスを与えるだけです。
<body class="snow">
</body>
CSS
CSS Animationを利用して雪が降り続けるようにします。
雪を降らせるCSS.snow {
background-position: 0px 0px;
animation: animatedBackground 15s linear infinite;
}
@keyframes animatedBackground {
100% {
background-position: 0px 100vh;
}
}
JS
雪の結晶となる要素をJavaScriptを使って作ります。
SVGをJavaScriptで生成して、.snow
のbackgroudImage
に設定することで雪を作っています。
雪を作るJS
(() => {
const rndInt = max => Math.floor(Math.random() * max);
let snow_style = "url(\"data:image/svg+xml,\
<svg xmlns='http://www.w3.org/2000/svg'%20\
viewBox='0 0 50 50'>\
<style type='text/css'>\
.st0{opacity:0.7;fill:%23FFFFFF;}\
.st1{opacity:0.3;fill:%23FFFFFF;}\
</style>";
for (let index = 0; index < 100; index++) {
snow_style += `<circle class='st${rndInt(2)}' cx='${rndInt(50)}' cy='${rndInt(50)}' r='${Math.random() * 0.2}'/>`
}
snow_style += "</svg>\")";
document.querySelector(".snow").style.backgroundImage = snow_style;
})();
SVG
svgについては詳しく知らなかったので、ここで少しまとめてます。
<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50'>
<style type='text/css'>
.st0{opacity:0.7;fill:%23FFFFFF;}
.st1{opacity:0.3;fill:%23FFFFFF;}
</style>
<circle class='st${rndInt(2)}' cx='${rndInt(50)}' cy='${rndInt(50)}' r='${Math.random() * 0.2}'/>
...
</svg>
versionについて
ネットで検索すると、version='1.1'
と書いてあるものもありますが、最新版のSVG2ではバージョンの指定は非推奨になっているようです。
xmlnsとは
xmlnsは、xmlの名前空間を設定するものです、
SVGの元となっているXMLにはさまざまな派生言語があり、派生言語によってタグの意味が異なります。
それぞれのタグの名前が衝突しないようにするために、名前空間を設定する必要があります。
styleタグ
HTMLのstyleタグと全く同じように、SVGコンテンツ内に直接スタイルシートを埋め込めます。
circleタグ
クラス属性を持っているので、styleタグないで設定したスタイルを適用することができます。
cx
、cy
、r
はそれぞれ、x座標、y座標、半径です。
今回はJSを使って、ランダムにこれらを設定しました。
成果物
GitHub Pagesに今回作ったものを置きました。
果たしてAdvent Calendarは全て埋まるのか...
Discussion