美文网首页
收集的两个动画,3d霓虹灯和在3d范围内的运动

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

作者: 眠九 | 来源:发表于2018-01-17 10:35 被阅读0次

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>

相关文章

网友评论

      本文标题:收集的两个动画,3d霓虹灯和在3d范围内的运动

      本文链接:https://www.haomeiwen.com/subject/jdmyoxtx.html