JavaScriptを使ってアニメーションを作りました。
CanvasとかSVGとかでも良かったのですが、あえてここはDIVだけで作ってみました。
激重です!!
デモページ
Happy Merry Christmas!
ソース
HTML
外部JSを読み込んでいるだけです。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Happy Merry Christmas!</title>
<script src="script.js"></script>
</head>
<body>
</body>
</html>
JavScript
基本関数はスルーします。
- 「ready」はjQueryでいうところの「$(window).ready();」です。
- ループ用の「requestAnimationFrame」
- マウス座標取得「getpos」
関数「snow」に一連の動きを記述していきます。
function snow(){
this.init();
}
HTML読み込み完了後「new snow()」する
ready(function(){
new snow();
});
「prototype」で「snow」関数を拡張していきます。
init
初期設定、リサイズイベント、マウスイベント、ループアニメションをしています。
init:function(){
var me = this;
me.$body = document.getElementsByTagName('body')[0];
me.q = 100;
me.h = 600;
me.mouseX = 0;
me.mouseY = 0;
me.px = me.mouseX;
me.py = me.mouseY;
window.addEventListener('resize',function(){
me.onresize();
});
me.setBody();
me.setFont();
me.$xmas = me.setText();
var loop = function(){
for(var i = 0; i < me.snows.length; i++){
me.snows[i].z += me.snows[i].az;
me.px += (me.mouseX - me.px)/200;
me.py += (me.mouseY - me.py)/200;
var dat = me.threeToTwo(me.snows[i].x + me.px,me.snows[i].y + me.py,me.snows[i].z);
if(me.snows[i].z > me.h){
me.snows[i].z = me.h * -1;
me.snows[i].reset();
}
if(me.snows[i].z < 0){
var alpha = Math.abs(me.snows[i].z)/me.h;
me.snows[i].style.opacity = 1 - alpha;
}else{
me.snows[i].style.opacity = 1;
}
me.snows[i].setPos(dat.x,dat.y,dat.scale);
}
for(var i = 0; i < me.stars.length; i++){
me.stars[i].reset();
}
requestAnimationFrame(loop);
}
me.$body.addEventListener('mousemove',function(e){
var pos = getpos(e);
me.mouseX = (me.midx - pos.x)/10;
me.mouseY = (me.midy - pos.y)/10;
});
setTimeout(function(){
me.onresize();
setTimeout(function(){
me.setStar();
me.setSnow();
requestAnimationFrame(loop);
me.$body.style.opacity = 1;
},100);
},100);
},
setText
「Happy Merry Christmas!」のテキストを生成しています。
setText:function(){
var me = this;
var $text = document.createElement('div');
$text.style.color = '#ffff00';
$text.style.fontSize = '60px';
$text.style.fontFamily = "'Playball', cursive";
$text.style.position = 'absolute';
$text.style.left = '50%';
$text.style.top = '50%';
$text.style.transform = 'translate(-50%,-50%)';
$text.style.background = '-webkit-linear-gradient(0deg, #40E0D0, #FF8C00, #FF0080)';
$text.style.webkitBackgroundClip = 'text';
$text.style.webkitTextFillColor = 'transparent';
var newtext = document.createTextNode('Happy Merry Christmas!');
$text.appendChild(newtext);
me.$body.appendChild($text);
return $text;
},
setSnow
雪を「me.q」個生成して配列「me.snows」に入れています。
生成部分は「me.createSnow()」
setSnow:function(){
var me = this;
me.snows = [];
for(var i = 0; i < me.q; i++){
var $snow = me.createSnow();
me.snows.push($snow);
me.$body.appendChild($snow);
}
},
setStar
星を「me.q」個生成して配列「me.stars」に入れています。
生成部分は「me.createStar()」
setStar:function(){
var me = this;
me.stars = [];
for(var i = 0; i < me.q; i++){
var $star = me.createStar();
me.stars.push($star);
me.$body.appendChild($star);
}
},
createSnow
雪の生成と雪を動かす関数を設定しています。
「div.left」「div.top」「¥div.scale」はあまりにも重くて「transform」に変更してので使用しないですね・・・
createSnow:function(){
var me = this;
var $div = document.createElement('div');
$div.reset = function(){
var size = Math.random() * 35 + 5;
$div.style.width = size + 'px';
$div.style.height = size + 'px';
$div.style.borderRadius = '50%';
$div.style.position = 'absolute';
$div.x = Math.random() * 800 - 400;
$div.y = Math.random() * 800 - 400;
$div.az = Math.random() * 22 + 3;
};
$div.z = Math.random() * 1200 - 600;
$div.style.backgroundColor = '#ffffff';
$div.style.filter = 'blur(4px)';
$div.setPos = function(x,y,scale){
this.style.transform = 'translate(' + x + 'px,' + y +'px) scale('+ scale +')';
};
$div.left = function(num){
this.style.left = num + 'px';
};
$div.top = function(num){
this.style.top = num + 'px';
};
$div.scale = function(num){
this.style.transform = 'scale('+ num +')';
};
$div.reset();
return $div;
},
createStar
星の生成と星を動かす関数を設定しています。
createStar:function(){
var me = this;
var $div = document.createElement('div');
$div.style.width = '3px';
$div.style.height = '3px';
$div.style.position = 'absolute';
$div.style.left = '0px';
$div.style.top = '0px';
$div.style.zIndex = -1;
$div.reset = function(){
$div.style.backgroundColor = 'rgb(' + Math.round(Math.random()*255) +',' + Math.round(Math.random()*255)+',' + Math.round(Math.random()*255) +')';
};
var x = Math.random() * window.innerWidth;
var y = Math.random() * window.innerHeight;
$div.style.borderRadius = '50%';
$div.style.transform = 'translate('+ x +'px,'+ y +'px)';
$div.reset();
return $div;
},
threeToTwo
3次元座標を2次元座標に変換しています。
threeToTwo:function(xpoz,ypoz,zpoz){
var me = this;
_x = (me.h * xpoz)/(me.h - zpoz) + me.midx;
xx = (me.h * (xpoz+100))/(me.h - zpoz) + me.midx;
_y = (me.h * ypoz)/(me.h - zpoz) + me.midy;
sl = xx-_x;
return {
x : _x,
y : _y,
scale : sl/100,
}
},
setBody
背景の設定とフェードインの準備をしています。
setBody:function(){
var me = this;
me.$body.style.backgroundColor = '#001122';
me.$body.style.margin = 0;
me.$body.style.padding = 0;
me.$body.style.position = 'absolute';
me.$body.style.top = 0;
me.$body.style.bottom = 0;
me.$body.style.left = 0;
me.$body.style.right = 0;
me.$body.style.overflow = 'hidden';
me.$body.style.transition = 'all 1500ms 0s ease';
me.$body.style.opacity = 0;
},
setFont
GoogleのWebフォントの読み込み
setFont:function(){
var me = this;
var $link = document.createElement('link');
$link.setAttribute('href','https://fonts.googleapis.com/css?family=Playball&display=swap');
$link.setAttribute('rel','stylesheet');
me.$body.appendChild($link);
},
onresize
リサイズされて時にブラウザの中心座標をもとめる
onresize:function(){
var me = this;
me.midx = window.innerWidth/2;
me.midy = window.innerHeight/2;
}
解説
簡単に言うと3次元座標で動かした雪を2次元座標に変換して配置しています。
Flash時代によく使っていた、3次元座標ー>2次元座標をJavaScriptで使ってみたかったというだけの記事でした。
ネイティブで書いたので、スタイルの設定はめんどくさかったです。
最後に
ふあふあな雪に大の字に寝て星空を見ていると癒やされますよね。。。
そんな感じのアニメーションです。
みなさんはどんなクリスマスを過ごすのでしょうか?
また、今年一年はどんな年でしたか?
来年もみなさんにとって良い年でありますように。。。
Happy Merry Christmas! and Happy New Year!