canvas+js实现荧光字符效果

一个小玩意,代码来源于网络。

效果图如下

 

代码如下

<html>
<head>
<style>
* {
        margin: 0;
        padding: 0;
    }
 
    html,
    body {
        height: 100%;
        position: relative;
        width: 100%;
    }
 
    body {
        background: #eee;
    }
 
    canvas {
        background: white;
        display: block;
    }
 
    #c {
        left: 50%;
        position: absolute;
        top: 50%;
        transform: translate(-50%, -50%);
    }
</style>
<script>
;(function(main) {
        var args = {};
        window.onload = function() {
            main(args);
        };
    })(function(args) {
 
        'use strict';
 
        var Box = function(x, y, w, h, s) {
            this.x = x;
            this.y = y;
            this.w = w;
            this.h = h;
            this.s = s;
            this.a = Math.random() * Math.PI * 2;
            this.hue = Math.random() * 360;
        };
 
        Box.prototype = {
            constructor: Box,
            update: function() {
                this.a += Math.random() * 0.5 - 0.25;
                this.x += Math.cos(this.a) * this.s;
                this.y += Math.sin(this.a) * this.s;
                this.hue += 5;
                if(this.x > WIDTH) this.x = 0;
                else if(this.x < 0) this.x = WIDTH;
                if(this.y > HEIGHT) this.y = 0;
                else if(this.y < 0) this.y = HEIGHT;
            },
            render: function(ctx) {
                ctx.save();
                ctx.fillStyle = 'hsla(' + this.hue + ', 100%, 50%, 1)';
                ctx.translate(this.x, this.y);
                ctx.rotate(this.a);
                ctx.fillRect(-this.w, -this.h / 2, this.w, this.h);
                ctx.restore();
            }
        };
 
        var Circle = function(x, y, tx, ty, r) {
            this.x = x;
            this.y = y;
            this.ox = x;
            this.oy = y;
            this.tx = tx;
            this.ty = ty;
            this.lx = x;
            this.ly = y;
            this.r = r;
            this.br = r;
            this.a = Math.random() * Math.PI * 2;
            this.sx = Math.random() * 0.5;
            this.sy = Math.random() * 0.5;
            this.o = Math.random() * 1;
            this.delay = Math.random() * 200;
            this.delayCtr = 0;
            this.hue = Math.random() * 360;
        };
 
        Circle.prototype = {
            constructor: Circle,
            update: function() {
 
                if(this.delayCtr < this.delay) {
                    this.delayCtr++;
                    return;
                }
 
                this.hue += 1;
                this.a += 0.1;
 
                this.lx = this.x;
                this.ly = this.y;
 
                if(!clickToggle) {
                    this.x += (this.tx - this.x) * this.sx;
                    this.y += (this.ty - this.y) * this.sy;                
                } else {
                    this.x += (this.ox - this.x) * this.sx;
                    this.y += (this.oy - this.y) * this.sy;                                    
                }
 
 
                this.r = this.br + Math.cos(this.a) * (this.br * 0.5);
            },
            render: function(ctx) {
 
                ctx.save();
                ctx.globalAlpha = this.o;
                ctx.fillStyle = 'hsla(' + this.hue + ', 100%, 50%, 1)';
                ctx.translate(this.x, this.y);
                ctx.beginPath();
                ctx.arc(0, 0, this.r, 0, Math.PI * 2);
                ctx.fill();
                ctx.restore();
 
                if(clickToggle) {
                    ctx.save();
                    ctx.strokeStyle = 'hsla(' + this.hue + ', 100%, 50%, 1)';
                    ctx.beginPath();
                    ctx.moveTo(this.lx, this.ly);
                    ctx.lineTo(this.x, this.y);
                    ctx.stroke();
                    ctx.restore();                 
                }
 
 
            }
        };
 
        var txtCanvas = document.createElement('canvas');
        var txtCtx = txtCanvas.getContext('2d');
 
        var c = document.getElementById('c');
        var ctx = c.getContext('2d');
 
        var WIDTH = c.width = window.innerWidth;
        var HEIGHT = c.height = window.innerHeight;
        var imgData = null;
        var idx = null;
        var skip = 4;
        var circles = [];
        var circle = null;
        var a = null;
        var clickToggle = false;
        var boxList = [];
        var box = null;
 
        txtCanvas.width = WIDTH;
        txtCanvas.height = HEIGHT;
 
        txtCtx.font = 'bold 70px Sans-serif';
        txtCtx.textAlign = 'center';
        txtCtx.baseline = 'middle';
        txtCtx.fillText('I   L O V E   U', WIDTH / 2, HEIGHT / 2);
 
        ctx.font = 'bold 12px Monospace';
        ctx.textAlign = 'center';
        ctx.baseline = 'middle';
 
        imgData = txtCtx.getImageData(0, 0, WIDTH, HEIGHT).data;
 
        for(var y = 0; y < HEIGHT; y += skip) {
            for(var x = 0; x < WIDTH; x += skip) {
                idx = (x + y * WIDTH) * 4 - 1;
                if(imgData[idx] > 0) {
                    a = Math.PI * 2 * Math.random();
                    circle = new Circle(
                        WIDTH / 2 + Math.cos(a) * WIDTH,
                        HEIGHT / 2 + Math.sin(a) * WIDTH,
                        x,
                        y,
                        Math.random() * 4
                    );
                    circles.push(circle);
                }
            }
        }
 
        for(var b = 0; b < 10; b++) {
            box = new Box(
                    WIDTH * Math.random(),
                    HEIGHT * Math.random(),
                    5,
                    2,
                    5 + Math.random() * 5
                );
            boxList.push(box);
        }
 
 
        c.addEventListener('click', function(e) {
            clickToggle = !clickToggle;
        });
 
        requestAnimationFrame(function loop() {
            requestAnimationFrame(loop);
 
            ctx.globalCompositeOperation = 'source-over';
            ctx.fillStyle = 'rgba(0, 0, 0, 0.5)';
            ctx.fillRect(0, 0, WIDTH, HEIGHT);
 
            ctx.fillStyle = 'white';
            ctx.fillText('CLICK TO TOGGLE', WIDTH / 2, HEIGHT / 2 + 100);                  
 
            ctx.globalCompositeOperation = 'lighter';
 
            for(var i = 0, len = circles.length; i < len; i++) {
                circle = circles[i];
                circle.update();
                circle.render(ctx);
            }
 
            for(var j = 0; j < boxList.length; j++) {
                box = boxList[j];
                box.update();
                box.render(ctx);
            }
 
        });
 
 
    });
</script>
</head>
<body>
<canvas id="c"></canvas>
</body>
</html>

  可直接复制代码保存为html文件,打开查看效果

posted @   YangJavaer  阅读(927)  评论(0编辑  收藏  举报
编辑推荐:
· 大模型 Token 究竟是啥:图解大模型Token
· 35岁程序员的中年求职记:四次碰壁后的深度反思
· 继承的思维:从思维模式到架构设计的深度解析
· 如何在 .NET 中 使用 ANTLR4
· 后端思维之高并发处理方案
阅读排行:
· BotSharp 5.0 MCP:迈向更开放的AI Agent框架
· 分享 3 款基于 .NET 开源且免费的远程桌面工具
· 在线聊天系统中的多窗口数据同步技术解密
· 5. RabbitMQ 消息队列中 Exchanges(交换机) 的详细说明
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(5)
点击右上角即可分享
微信分享提示