收集的两个动画,3d霓虹灯和在3d范围内的运动

3D霓虹灯效果:


image.png
<style>
        body {
            background-color: #080c11;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
        canvas {
            left: 50%;
            position: absolute;
            top: 50%;
            transform: translate(-50%, -50%);
        }
    </style>
<canvas id='canv'></canvas>
<script>
    window.requestAnimFrame = (function() {
        return window.requestAnimationFrame ||
                window.webkitRequestAnimationFrame ||
                window.mozRequestAnimationFrame ||
                window.oRequestAnimationFrame ||
                window.msRequestAnimationFrame ||
                function(callback) {
                    window.setTimeout(callback, 1000 / 60);
                };
    })();
    var $;
    var rad = 0;
    var num = 700;
    var size = 15;
    var len = 0;
    var arr = [];
    var midX;
    var midY;
    var msX = 0;
    var msY = 0;
    var w;
    var h;
    window.onload = function() {
        var c = document.getElementById("canv");
        w = c.width = window.innerWidth;
        h = c.height = window.innerHeight;
        $ = c.getContext("2d");
        midX = c.width / 2;
        midY = c.height / 2;
        rad = c.height;
        for (var i = 0; i < num; i++) {
            arr[i] = new Part();
        }
        $.fillStyle = "hsla(217, 35%, 15%, 1)";
        $.fillRect(0, 0, c.width, c.height);
        len = h / 2;
//        window.addEventListener("mousemove", msmv, false);
//        window.addEventListener("touchmove", tcmv, false);
        window.addEventListener('load', resize);
        window.addEventListener('resize', resize, false);
        window.requestAnimFrame(setInterval(go, 45));
    };
    function resize() {
        c.width = w = window.innerWidth;
        c.height = h = window.innerHeight;
        c.style.position = 'absolute';
        c.style.left = (window.innerWidth - w) *
                .01 + 'px';
        c.style.top = (window.innerHeight - h) *
                .01 + 'px';
    }
    function msmv(e) {
        var rect = e.target.getBoundingClientRect();
        msX = e.clientX - rect.left;
        msY = e.clientY - rect.top;
    }
    function tcmv(e) {
        var rect = e.target.getBoundingClientRect();
        msX = e.touches[0].pageX - rect.left;
        msY = e.touches[0].pageY - rect.top;
    }
    function disp(p1, p2) {
        return (p2.z - p1.z);
    }
    function go() {
        $.globalCompositeOperation = 'source-over';
        $.fillStyle = "hsla(217, 35%, 5%, .8)";
        $.fillRect(0, 0, w, h);
        $.globalCompositeOperation = 'lighter';
        arr.sort(disp);
        for (var i = 0; i < num; i++) {
            arr[i].upd();
            arr[i].draw();
        }
    }

    var rndCol = function() {
        var r = Math.floor(Math.random() * 180);
        var g = Math.floor(Math.random() * 60);
        var b = Math.floor(Math.random() * 100);
        return "rgb(" + r + "," + g + "," + b + ")";
    }
    var Part = function() {
        this.x = 0;
        this.y = 0;
        this.z = 0;
        this.vx = 0;
        this.vy = 0;
        this.dx = Math.random() * Math.PI;
        this.dy = 0;
        this.phi = Math.random() * Math.PI * 2;
        this.t = Math.random() * Math.PI;
        if (Math.random() < 0.5) {
            this.col = rndCol();
            this.dir = 1;
        } else {
            this.col = rndCol();
            this.dir = -1;
        }
    };
    Part.prototype.draw = function() {
        var s = this.scale();
        var x = w / 2 + this.x * s;
        var y = h / 2 + this.y * s;
        $.fillStyle = this.col;
        if (this.z > -rad / 2) {
            $.beginPath();
            $.arc(x, y, Math.ceil(size * s), 0, Math.PI * 2, false);
            $.fill();
        }
    };
    Part.prototype.scale = function() {
        return (len / (len + this.z));
    };
    Part.prototype.upd = function() {
        var m = (w / 2 - msX) / w / 10;
        this.phi += (this.dy + m) * this.dir;
        this.t = this.dx;
        this.x = rad * Math.sin(this.t) * Math.cos(this.phi);
        this.y = rad * Math.cos(this.t);
        this.z = rad * Math.sin(this.t) * Math.sin(this.phi) +
                rad / 2 * (h / 1.2 - msY) / h * 4;
    }
</script>

小球在3D范围内运动:


image.png
<style>
    canvas {
        position: absolute;
        top: 0;
        left: 0;
    }
</style>
<canvas id="c"></canvas>
<script>
    /*Javascript代码片段*/
    var w = c.width = window.innerWidth,
            h = c.height = window.innerHeight,
            ctx = c.getContext('2d'),

            balls = [],
            tick = 0,

            fl = 260, // focal length
            bd = 300, // boundaries
            vp = {      // vanis point
                x: w / 2,
                y: h / 2
            },

            pts = [ // bounding box wireframe
                dimensionize(-bd,-bd,0),
                dimensionize(-bd,bd,0),
                dimensionize(bd,bd,0),
                dimensionize(bd,-bd,0),
                dimensionize(bd,-bd,bd*2),
                dimensionize(bd,bd,bd*2),
                dimensionize(-bd,bd,bd*2),
                dimensionize(-bd,-bd,bd*2)

            ]

    for (var i = 0; i < 50; ++i)
        balls.push({
            x: Math.random() * bd*2 - bd,
            y: Math.random() * bd*2 - bd,
            z: Math.random() * bd*2,
            vx: 5 * ( Math.random() - .5 ),
            vy: 5 * ( Math.random() - .5 ),
            vz: 5 * ( Math.random() - .5 ),
            s: Math.random() * 2 + 20
        });

    function anim(){

        window.requestAnimationFrame( anim );

        ++tick;

        ctx.fillStyle = 'black';
        ctx.fillRect( 0, 0, w, h );

        ctx.strokeStyle = 'white';
        for( var i = 0; i < 5; i+=4 ){
            ctx.beginPath();
            ctx.moveTo( pts[i].x, pts[i].y );
            ctx.lineTo( pts[i+1].x, pts[i+1].y );
            ctx.lineTo( pts[i+2].x, pts[i+2].y );
            ctx.lineTo( pts[i+3].x, pts[i+3].y );
            ctx.closePath();
            ctx.stroke();
        }
        for( var i = 0; i < 4; ++i ){
            ctx.beginPath();
            ctx.moveTo( pts[i].x, pts[i].y );
            ctx.lineTo( pts[7-i].x, pts[7-i].y );
            ctx.stroke();
        }


        balls.map( function( ball ){

            ball.x += ball.vx;
            ball.y += ball.vy; //+=.1; uncomment for gravity ;)
            ball.z += ball.vz;

            if( ball.x - ball.s < -bd ){
                ball.vx *= -1;
                ball.x = -bd + ball.s;
            } else if( ball.x + ball.s > bd ){
                ball.vx *= -1;
                ball.x = bd - ball.s;
            }
            if( ball.y - ball.s < -bd ){
                ball.vy *= -1;
                ball.y = -bd + ball.s;
            } else if( ball.y + ball.s > bd ){
                ball.vy *= -1;
                ball.y = bd - ball.s;
            }
            if( ball.z - ball.s < 0 ){
                ball.vz *= -1;
                ball.z = ball.s;
            } else if( ball.z + ball.s > bd*2 ){
                ball.vz *= -1;
                ball.z = bd*2 - ball.s;
            }
        });

        balls.sort( function( a, b ){ return b.z - a.z } );

        balls.map( function( ball ){

            var p = dimensionize( ball.x, ball.y, ball.z );
            p.s *= ball.s;

            ctx.fillStyle = 'hsl(hue,80%,50%)'.replace( 'hue', ( ball.x+ball.y+ball.z ) / 4 + tick );
            ctx.beginPath();
            ctx.arc( p.x, p.y, p.s, 0, Math.PI * 2 );
            ctx.fill();
        })
    }
    anim();

    function dimensionize( x, y, z ){

        var scale = fl / ( fl + z );
        return {
            x: vp.x + x * scale,
            y: vp.y + y * scale,
            s: scale
        };
    }
</script>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,539评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,594评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,871评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,963评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,984评论 6 393
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,763评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,468评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,357评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,850评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,002评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,144评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,823评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,483评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,026评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,150评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,415评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,092评论 2 355

推荐阅读更多精彩内容