前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Canvas实现的一个壁纸demo

Canvas实现的一个壁纸demo

原创
作者头像
4cos90
修改2021-04-25 10:50:29
3150
修改2021-04-25 10:50:29
举报
文章被收录于专栏:随想随想

实现的效果见我发布的视频

这个壁纸我好像是在csdn里首先看到的 觉得非常有意思,所以自己实现了一个。

先直接上代码吧,直接用原生js实现,因此直接用浏览器打开就可以看到效果,非常的方便。

代码语言:javascript
复制
! function() {

    function SetCanvasArea() {
        CanvasWidth = canvas.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
        CanvasHeight = canvas.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
    }

    function RefreshCanvas() {
        canvas2D.clearRect(0, 0, CanvasWidth, CanvasHeight);
        canvas2D.fillStyle = "#2473ab";
        canvas2D.fillRect(0, 0, CanvasWidth, CanvasHeight);
        canvas2D.fillStyle = "rgb(255,248,220)";
        var AllNodeList = [MouseCoor].concat(NodeList);
        var NodeV, LineWidth, DistanceX, DistanceY, Distance;
        NodeList.forEach(function(NodeI) {
            NodeI.x += NodeI.DX;
            NodeI.y += NodeI.DY;
            NodeI.DX *= (NodeI.x > CanvasWidth || NodeI.x < 0) ? -1 : 1;
            NodeI.DY *= (NodeI.y > CanvasHeight || NodeI.y < 0) ? -1 : 1;

            canvas2D.fillRect(NodeI.x - 0.5, NodeI.y - 0.5, 1, 1);

            for (var v = 0; v < AllNodeList.length; v++) {
                NodeV = AllNodeList[v];
                if (NodeI !== NodeV && null !== NodeV.x && null !== NodeV.y) {
                    DistanceX = NodeI.x - NodeV.x;
                    DistanceY = NodeI.y - NodeV.y;
                    Distance = DistanceX * DistanceX + DistanceY * DistanceY;

                    if (Distance < NodeV.max) {
                        if (NodeV === MouseCoor && Distance >= NodeV.max / 2) {
                            NodeI.x -= 0.03 * DistanceX;
                            NodeI.y -= 0.03 * DistanceY;
                        }
                        canvas2D.strokeStyle = "rgb(255,248,220)";
                        LineWidth = (NodeV.max - Distance) / NodeV.max;
                        canvas2D.beginPath(), canvas2D.lineWidth = LineWidth / 2;
                        canvas2D.moveTo(NodeI.x, NodeI.y), canvas2D.lineTo(NodeV.x, NodeV.y);
                        canvas2D.stroke();
                    }
                }
            }

            AllNodeList.splice(AllNodeList.indexOf(NodeI), 1);

        });
        RequestAnimationFrame(RefreshCanvas);
    }


    var canvas = document.createElement("canvas"),
        canvas2D = canvas.getContext("2d"),
        CanvasWidth,
        CanvasHeight,
        NodeList,
        RequestAnimationFrame = window.requestAnimationFrame,
        RandomNumber = Math.random,
        MouseCoor = { x: null, y: null, max: 20000 };
    canvas.id = "demo";
    canvas.style.cssText = "position:fixed;top:0;left:0;z-index:-1;opacity:0.5";
    canvas2D.fillStyle = "#2473ab";
    canvas2D.fillRect(0, 0, CanvasWidth, CanvasHeight);

    document.getElementsByTagName("body")[0].appendChild(canvas);

    SetCanvasArea();

    window.onresize = SetCanvasArea;

    window.onmousemove = function(i) {
        i = i || window.event;
        MouseCoor.x = i.clientX;
        MouseCoor.y = i.clientY;
    };

    window.onmouseout = function() {
        MouseCoor.x = null;
        MouseCoor.y = null;
    };

    for (NodeList = [], p = 0; 200 > p; p++) {
        var NodeX = RandomNumber() * CanvasWidth,
            NodeY = RandomNumber() * CanvasHeight,
            NodeDX = 2 * RandomNumber() - 1,
            NodeDY = 2 * RandomNumber() - 1;
        NodeList.push({ x: NodeX, y: NodeY, DX: NodeDX, DY: NodeDY, max: 6000 });
    }

    setTimeout(function() {
        RefreshCanvas();
    }, 0);
}();

在html中直接引入即可

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="zh-cn">

<head>
    <meta charset="utf-8">
    <title>demo</title>
    <body>
        <script type="text/javascript" src="./demo.js"></script>
    </body>
</html>

简单解释下代码:

首先我们需要一些在屏幕中漂移的点,如果想要线密集一些也可以把点的数量加多。X,Y表示点的坐标,DX DY表示点的漂移速度,max表示当其他点与该点的距离小于该值时,则与该点连线。

代码语言:javascript
复制
   for (NodeList = [], p = 0; 200 > p; p++) {
        var NodeX = RandomNumber() * CanvasWidth,
            NodeY = RandomNumber() * CanvasHeight,
            NodeDX = 2 * RandomNumber() - 1,
            NodeDY = 2 * RandomNumber() - 1;
        NodeList.push({ x: NodeX, y: NodeY, DX: NodeDX, DY: NodeDY, max: 6000 });
    }

一个坐标对象MouseCoor用于储存鼠标的位置。

RefreshCanvas函数用于实现上面说的连线规则:

遍历所有漂移的点NodeList;

另外注意:当DX,DY碰到边界时,将重置DX,DY的方向,这里为了方便设置为1/-1,如果有强迫症将DX置为-DX效果也是一样的。

代码语言:javascript
复制
NodeI.DX *= (NodeI.x > CanvasWidth || NodeI.x < 0) ? -1 : 1;
NodeI.DY *= (NodeI.y > CanvasHeight || NodeI.y < 0) ? -1 : 1;

与加上鼠标在内的其他点进行连线判定

代码语言:javascript
复制
            for (var v = 0; v < AllNodeList.length; v++) {
                NodeV = AllNodeList[v];
                if (NodeI !== NodeV && null !== NodeV.x && null !== NodeV.y) {
                    DistanceX = NodeI.x - NodeV.x;
                    DistanceY = NodeI.y - NodeV.y;
                    Distance = DistanceX * DistanceX + DistanceY * DistanceY;

                    if (Distance < NodeV.max) {
                        if (NodeV === MouseCoor && Distance >= NodeV.max / 2) {
                            NodeI.x -= 0.03 * DistanceX;
                            NodeI.y -= 0.03 * DistanceY;
                        }
                        canvas2D.strokeStyle = "rgb(255,248,220)";
                        LineWidth = (NodeV.max - Distance) / NodeV.max;
                        canvas2D.beginPath(), canvas2D.lineWidth = LineWidth / 2;
                        canvas2D.moveTo(NodeI.x, NodeI.y), canvas2D.lineTo(NodeV.x, NodeV.y);
                        canvas2D.stroke();
                    }
                }
            }

最后再加上循环

代码语言:javascript
复制
RequestAnimationFrame(RefreshCanvas);

这样一个简单的壁纸demo就完成了,并且效果也非常好,反正我第一次见到还感觉挺好玩的点了半天。

后面我也将这个壁纸移植到了微信小游戏中实现。下次发微信小程序的实现代码。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档