投稿日:2020年3月3日
前回の桜の花びらが舞うアニメーション と同じように、DOM操作でCSSを書き換え、雪を降らせてみました。
8個の雪の結晶の画像をランダムに降らすように設定してあります。
雪の結晶はemStudio(エムスタジオ)さまから使わせていただきました。
結晶の画像の種類、サイズ、ぼかし、透明度、速度を乱数で設定し、フワフワと舞う雰囲気を表現しました。
今回はコメント付きのソースコードを掲載しておきます。
HTML
<div id="main__container"></div>
CSS
#main__container {
width: 100%;
/* ▼背景のグラデーション */
background: -webkit-linear-gradient(top,
#00004b 0%,
#00004b 30%,
#ffffff 100%);
/* ▼横並びにする */
display: flex;
/* ▼幅いっぱいに均等配置 */
justify-content: space-between;
}
JavaScript
// ▼アニメーション関数
function crystalLOfSnowAnime(target, YPixel) {
const containerWidth = $(target).width(); //背景の幅
const containerHeight = containerWidth * YPixel; //背景の高さ
$(target).css('height', containerHeight + 'px'); //背景の高さ
const styleTag = $("style"); //styleを取得
// ▼snow回転 keyframes アニメーション
const snowAnime = [
"from {-webkit-transform:rotate3d(1,,1,0deg);}25%{transform:rotate3d(1,1,1,90deg);}50%{transform:rotate3d(1,1,1,180deg);}75%{transform:rotate3d(1,1,1,270deg);}to{transform:rotate3d(1,1,1,360deg);}"
];
// ▼styleタグの最初にkeyframeアニメーションを追加
styleTag.prepend("@keyframes snowAnime{" + snowAnime.join(" ") + "}");
// ▼結晶の数分繰り返す
for (i = 1; i <= 8; i++) { // imgタグ作成
const img = $("<img>");
img // imgタグに属性追加
.attr({
class: "snow",
style: "position:relative; top:-100px;"
})
.appendTo(target); // snowプロパティ関数実行
randomValue(img);
}
// ▼snowプロパティ関数
function randomValue(ele) {
const snowArray = [
"xxxx01.png",
"xxxx02.png",
"xxxx03.png",
"xxxx04.png",
"xxxx05.png",
"xxxx06.png",
"xxxx07.png",
"xxxx08.png"
]; // 画像の配列。xxxxは任意画像名
// ▼配列から画像をランダムに取得
const randomSnowSelect = snowArray[Math.floor(Math.random() * snowArray.length)];
// ▼1か-1の配列
const multiArray = [1, -1];
// ▼結晶の数分、1か-1を取得。※後ほど乗算して左右方向を決定する
const randomMulti = multiArray[Math.floor(Math.random() * multiArray.length)];
const largeSize = 45; //雪の結晶の最大サイズ
const objSize = randomNum(largeSize, 10), //サイズ値。45〜10pxでランダムに算出
XSpeedNum = randomFloatNum(0.7, 0.3), //Xの移動量。0.7〜0.3でランダムに算出
YSpeedNum = randomFloatNum(2, 0.6); //Y座標の移動量。2〜0.6でランダムに算出
// ▼画像のディレクトリ。xxxxは任意ディレクトリ名
const imgDir = "https://xxxx.net/xxxx/xxxx/xxxx/images/xxxx/";
ele.attr("src", imgDir + randomSnowSelect); // 画像読み込み
ele.attr('src', imgDir + randomSnowSelect); //画像読み込み
ele.css({
width: objSize + "px", //幅
height: objSize + "px", //高さ
margin: (largeSize - objSize) / 2 + "px", //マージン ※サイズ値の最大値から算出
src: "images/" + randomSnowSelect, // 画像読み込み
filter: blur(randomFloatNum(3, 0) + "px"), //ボカシ量。3〜0でランダムに算出
opacity: randomFloatNum(1, 0.4).toFixed(1), //透明度。1〜0.4でランダムに算出
animation: "snowAnime " + randomNum(10, 5) + "s linear 0s infinite" //結晶の回転アニメーション
});
let YNum = -largeSize, // Y座標の開始位置
XNum = 0;
// ▼アニメーションの繰り返し関数
(function animeLoop() {
const requestAnime = window.requestAnimationFrame(animeLoop);
XNum += XSpeedNum; // 左右方向の移動量
YNum += YSpeedNum; // 下方向の移動量
ele.css({
top: YNum + "px",
left: XNum * randomMulti + "px"
});
// ▼Y座標がコンテナの高さを越えたらアニメーションをキャンセル
if (YNum >= containerHeight) {
window.cancelAnimationFrame(requestAnime);
return randomValue(ele);
}
})();
}
}
// ▼ランダムな整数を取得する関数
function randomNum(max, min) {
const ranNum = Math.floor(Math.random() * (max + 1 - min) + min);
return ranNum;
}
// ▼ランダム値取得関数 小数点第1位
function randomFloatNum(max, min) {
const ranFlortNum = Math.random() * (max - min) + min;
return ranFlortNum;
}
※今回もrequestAnimationFrame
を使ってますが、PCに不可がかかるかも知れません。
低スペックのPCだと動作がぎこちなくなると思います。
パソコンが破損するとは思いませんが、何か問題が生じても責任は負い兼ねますのでご了承ください。
関連記事
]