canvas特效一

<!doctype html>
<html>
    <head>
        <meta charset="utf-8">
        <title>demo</title>
        <style>
            html,
            body {
                margin: 0px;
                width: 100%;
                height: 100%;
                overflow: hidden;
                background: #000;
            }
            #canvas {
                position: absolute;
                width: 100%;
                height: 100%;
                top: 0;
                left: 0;
            }
        </style>
    </head>
    <body>
        <audio src="http://183.252.54.29/amobile.music.tc.qq.com/C4000029Lt3K2XVP75.m4a?guid=5877301990&vkey=BAD32E022302E3F9720FA15B179B66628D92DD150D0258DE173C7E210888E9C493B98FB5D6E17D0161DB2A2A3D510E54B6AFA82DAC697EA6&uin=7080&fromtag=66" autoplay="autoplay" loop="loop"></audio>
        <canvas id="canvas"></canvas>
        <script>
            function project3D(x, y, z, vars) {
                var p, d;
                x -= vars.camX;
                y -= vars.camY - 8;
                z -= vars.camZ;
                p = Math.atan2(x, z);
                d = Math.sqrt(x * x + z * z);
                x = Math.sin(p - vars.yaw) * d;
                z = Math.cos(p - vars.yaw) * d;
                p = Math.atan2(y, z);
                d = Math.sqrt(y * y + z * z);
                y = Math.sin(p - vars.pitch) * d;
                z = Math.cos(p - vars.pitch) * d;
                var rx1 = -1000;
                var ry1 = 1;
                var rx2 = 1000;
                var ry2 = 1;
                var rx3 = 0;
                var ry3 = 0;
                var rx4 = x;
                var ry4 = z;
                var uc = (ry4 - ry3) * (rx2 - rx1) - (rx4 - rx3) * (ry2 - ry1);
                var ua = ((rx4 - rx3) * (ry1 - ry3) - (ry4 - ry3) * (rx1 - rx3)) / uc;
                var ub = ((rx2 - rx1) * (ry1 - ry3) - (ry2 - ry1) * (rx1 - rx3)) / uc;
                if(!z) z = 0.000000001;
                if(ua > 0 && ua < 1 && ub > 0 && ub < 1) {
                    return {
                        x: vars.cx + (rx1 + ua * (rx2 - rx1)) * vars.scale,
                        y: vars.cy + y / z * vars.scale,
                        d: (x * x + y * y + z * z)
                    };
                } else {
                    return {
                        d: -1
                    };
                }
            }

            function elevation(x, y, z) {
                var dist = Math.sqrt(x * x + y * y + z * z);
                if(dist && z / dist >= -1 && z / dist <= 1) return Math.acos(z / dist);
                return 0.00000001;
            }

            function rgb(col) {
                col += 0.000001;
                var r = parseInt((0.5 + Math.sin(col) * 0.5) * 16);
                var g = parseInt((0.5 + Math.cos(col) * 0.5) * 16);
                var b = parseInt((0.5 - Math.sin(col) * 0.5) * 16);
                return "#" + r.toString(16) + g.toString(16) + b.toString(16);
            }

            function interpolateColors(RGB1, RGB2, degree) {
                var w2 = degree;
                var w1 = 1 - w2;
                return [w1 * RGB1[0] + w2 * RGB2[0], w1 * RGB1[1] + w2 * RGB2[1], w1 * RGB1[2] + w2 * RGB2[2]];
            }

            function rgbArray(col) {
                col += 0.000001;
                var r = parseInt((0.5 + Math.sin(col) * 0.5) * 256);
                var g = parseInt((0.5 + Math.cos(col) * 0.5) * 256);
                var b = parseInt((0.5 - Math.sin(col) * 0.5) * 256);
                return [r, g, b];
            }

            function colorString(arr) {
                var r = parseInt(arr[0]);
                var g = parseInt(arr[1]);
                var b = parseInt(arr[2]);
                return "#" + ("0" + r.toString(16)).slice(-2) + ("0" + g.toString(16)).slice(-2) + ("0" + b.toString(16)).slice(-2);
            }

            function process(vars) {
                if(vars.points.length < vars.initParticles)
                    for(var i = 0; i < 5; ++i) spawnParticle(vars);
                var p, d, t;

                p = Math.atan2(vars.camX, vars.camZ);
                d = Math.sqrt(vars.camX * vars.camX + vars.camZ * vars.camZ);
                d -= Math.sin(vars.frameNo / 80) / 25;
                t = Math.cos(vars.frameNo / 300) / 165;
                vars.camX = Math.sin(p + t) * d;
                vars.camZ = Math.cos(p + t) * d;
                vars.camY = -Math.sin(vars.frameNo / 220) * 15;
                vars.yaw = Math.PI + p + t;
                vars.pitch = elevation(vars.camX, vars.camZ, vars.camY) - Math.PI / 2;

                var t;
                for(var i = 0; i < vars.points.length; ++i) {

                    x = vars.points[i].x;
                    y = vars.points[i].y;
                    z = vars.points[i].z;
                    d = Math.sqrt(x * x + z * z) / 1.0075;
                    t = .1 / (1 + d * d / 5);
                    p = Math.atan2(x, z) + t;
                    vars.points[i].x = Math.sin(p) * d;
                    vars.points[i].z = Math.cos(p) * d;
                    vars.points[i].y += vars.points[i].vy * t * ((Math.sqrt(vars.distributionRadius) - d) * 2);
                    if(vars.points[i].y > vars.vortexHeight / 2 || d < .25) {
                        vars.points.splice(i, 1);
                        spawnParticle(vars);
                    }
                }
            }
            var stat = 0;

            function drawFloor(vars) {
                var x, y, z, d, point, a;
                for(var i = -25; i <= 25; i += 1) {
                    for(var j = -25; j <= 25; j += 1) {
                        x = i * 2;
                        z = j * 2;
                        y = vars.floor;
                        d = Math.sqrt(x * x + z * z);
                        point = project3D(x, y - d * d / 85, z, vars);
                        if(point.d != -1) {
                            size = 1 + 15000 / (1 + point.d);
                            a = 0.15 - Math.pow(d / 50, 4) * 0.15;
                            if(a > 0) {
                                vars.ctx.fillStyle = colorString(interpolateColors(rgbArray(d / 26 - vars.frameNo / 40), [0, 128, 32], .5 + Math.sin(d / 6 - vars.frameNo / 8) / 2));
                                vars.ctx.globalAlpha = a;
                                vars.ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
                            }
                        }
                    }
                }
                vars.ctx.fillStyle = "#82f";
                for(var i = -25; i <= 25; i += 1) {
                    for(var j = -25; j <= 25; j += 1) {
                        x = i * 2;
                        z = j * 2;
                        y = -vars.floor;
                        d = Math.sqrt(x * x + z * z);
                        point = project3D(x, y + d * d / 85, z, vars);
                        if(point.d != -1) {
                            size = 1 + 15000 / (1 + point.d);
                            a = 0.15 - Math.pow(d / 50, 4) * 0.15;
                            if(a > 0) {
                                vars.ctx.fillStyle = colorString(interpolateColors(rgbArray(-d / 26 - vars.frameNo / 40), [32, 0, 128], .5 + Math.sin(-d / 6 - vars.frameNo / 8) / 2));
                                vars.ctx.globalAlpha = a;
                                vars.ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
                            }
                        }
                    }
                }
            }

            function sortFunction(a, b) {
                return b.dist - a.dist;
            }

            function draw(vars) {
                vars.ctx.globalAlpha = .15;
                vars.ctx.fillStyle = "#000";
                vars.ctx.fillRect(0, 0, canvas.width, canvas.height);

                drawFloor(vars);

                var point, x, y, z, a;
                for(var i = 0; i < vars.points.length; ++i) {
                    x = vars.points[i].x;
                    y = vars.points[i].y;
                    z = vars.points[i].z;
                    point = project3D(x, y, z, vars);
                    if(point.d != -1) {
                        vars.points[i].dist = point.d;
                        size = 1 + vars.points[i].radius / (1 + point.d);
                        d = Math.abs(vars.points[i].y);
                        a = .8 - Math.pow(d / (vars.vortexHeight / 2), 1000) * .8;
                        vars.ctx.globalAlpha = a >= 0 && a <= 1 ? a : 0;
                        vars.ctx.fillStyle = rgb(vars.points[i].color);
                        if(point.x > -1 && point.x < vars.canvas.width && point.y > -1 && point.y < vars.canvas.height) vars.ctx.fillRect(point.x - size / 2, point.y - size / 2, size, size);
                    }
                }
                vars.points.sort(sortFunction);
            }

            function spawnParticle(vars) {
                var p, ls;
                pt = {};
                p = Math.PI * 2 * Math.random();
                ls = Math.sqrt(Math.random() * vars.distributionRadius);
                pt.x = Math.sin(p) * ls;
                pt.y = -vars.vortexHeight / 2;
                pt.vy = vars.initV / 20 + Math.random() * vars.initV;
                pt.z = Math.cos(p) * ls;
                pt.radius = 200 + 800 * Math.random();
                pt.color = pt.radius / 1000 + vars.frameNo / 250;
                vars.points.push(pt);
            }

            function frame(vars) {
                if(vars === undefined) {
                    var vars = {};
                    vars.canvas = document.querySelector("canvas");
                    vars.ctx = vars.canvas.getContext("2d");
                    vars.canvas.width = document.body.clientWidth;
                    vars.canvas.height = document.body.clientHeight;
                    window.addEventListener("resize", function() {
                        vars.canvas.width = document.body.clientWidth;
                        vars.canvas.height = document.body.clientHeight;
                        vars.cx = vars.canvas.width / 2;
                        vars.cy = vars.canvas.height / 2;
                    }, true);
                    vars.frameNo = 0;

                    vars.camX = 0;
                    vars.camY = 0;
                    vars.camZ = -14;
                    vars.pitch = elevation(vars.camX, vars.camZ, vars.camY) - Math.PI / 2;
                    vars.yaw = 0;
                    vars.cx = vars.canvas.width / 2;
                    vars.cy = vars.canvas.height / 2;
                    vars.bounding = 10;
                    vars.scale = 500;
                    vars.floor = 26.5;

                    vars.points = [];
                    vars.initParticles = 700;
                    vars.initV = .01;
                    vars.distributionRadius = 800;
                    vars.vortexHeight = 25;
                }

                vars.frameNo++;
                requestAnimationFrame(function() {
                    frame(vars);
                });

                process(vars);
                draw(vars);
            }
            frame();
        </script>

        <div style="text-align:center;margin:50px 0; font:normal 14px/24px 'MicroSoft YaHei';">
            <p>适用浏览器:360、FireFox、Chrome、Opera、傲游、搜狗、世界之窗. 不支持Safari、IE8及以下浏览器。</p>
        </div>
    </body>
</html>

来源:https://www.bilibili.com/video/av26931969

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

推荐阅读更多精彩内容