0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

image.png

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!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?