Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【被玩坏的博客园】之canvas装饰博客园侧边栏

【被玩坏的博客园】之canvas装饰博客园侧边栏

作者头像
用户1749219
发布于 2018-07-05 07:48:57
发布于 2018-07-05 07:48:57
88600
代码可运行
举报
运行总次数:0
代码可运行

最近抽空学了学canvas,然后用canvas做了个小球运动的demo,大致的效果如下:

虽然网上已经有很多这样的demo,但是还是想根据自己的思路来写一个,下面先跟大家讲解一下源代码,先看html代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"/>
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
      html, body {
          padding: 0;
          margin: 0;
          width: 100%;
          height: 100%;
      }
      canvas {
        background-image: linear-gradient(-50deg,RGB(255, 106, 100),RGB(71, 0, 182));/*对canvas做背景颜色渐变处理,第一个参数是角度,后面2个是起始颜色,这个我就不细讲了,查查就知道*/
      }
  </style>
</head>
<body>
  <canvas id="canvas">
    
  </canvas>
  <script src="./index.js"></script>
</body>

</html>

html很简单,没啥讲的,就是css那块兼容性你们注意下就好(我懒,没写兼容),再看看canvas的js处理代码,就是上面引入的index.js(讲解都写在注释里了,写的比较基础,方便没多少基础的人看):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
window.onload = function(){// 页面加载完了之后再处理
    var canvas = document.getElementById('canvas');
    var body = document.getElementsByTagName('body')[0];//getElementsByTagName是以标签名获取元素,返回是一个数组,所以用[0]
    canvas.width = body.clientWidth;// 获取body的【客户端宽度】,这个时候body已经加载完成了,页面大小已经形成。
    canvas.height = body.clientHeight;
    var bound = canvas.getBoundingClientRect();// 这个叫做获取边界客户端矩形,可以用来获取canvas的长宽
    var ctx = canvas.getContext('2d');// 获取canvas的上下文环境(可以理解为买下一个画笔)
    var width = bound.width, height = bound.height;
    var circleConfig = {// 配置信息
        ballNums: 300,// 球的数量
        fillColor: 'rgba(255, 255, 255, .5)',// 球的填充颜色
        radius: 1// 球的半径
    };
    var circle = new Circle(circleConfig);// 初始化球
    circle.init();// 初始化
    var zoom=function(e){ // 这个函数是用来缩放球的大小的,简单做了个缩放改变球的效果,目前可能就在chrome下有用
          var e = e || window.event; 
          if (!e.deltaX) {// 缩放的时候这个值是为0或-0的
              if (e.deltaY < 0) {// 小于0好像是放大吧
                if (circleConfig.radius) {
                    circleConfig.radius = null;
                    var circle = new Circle({
                        ballNums: 300,
                        fillColor: 'rgba(255, 255, 255, .5)',
                        // radius: 1
                    });
                    circle.init();
                }
                
              }
              else {
                if (!circleConfig.radius) {
                    circleConfig.radius = 1;
                    var circle = new Circle({
                        ballNums: 300,
                        fillColor: 'rgba(255, 255, 255, .5)',
                        radius: 1
                    });
                    circle.init();
                }
              }
          }
          if(e.wheelDelta && event.ctrlKey){// 禁止网页缩放
               event.returnValue = false
          }else if(e.detail){
              
               event.returnValue = false;
          } 
    }  
    if(document.addEventListener){ 
        document.addEventListener('DOMMouseScroll' , zoom , false); // 兼容火狐
    }
    window.onmousewheel = document.onmousewheel = zoom;// 除火狐之外的浏览器
    function Circle(o) {// 好了,这里才是故事真正开始的地方
        o = o || {};
        this.instance = [];// 可以理解为实例数组,用来存球的
        this.maxLineLength = o.maxLineLength || 100;// 最大线长度,就是2个球在这个距离内会在之间画根线
        function Ball() {
            this.radius = o.radius || (o.MaxRadius || 20) * Math.random();
            this.startDeg = 0;// 开始角度
            this.endDeg = Math.PI * 2;// 终结角度
            this.clockWay = false; // 顺时针还是逆时针
            this.fillColor = o.fillColor || randomColor();// 填充颜色
            this.borderColor = 'transparent';// 球的border设置为透明的不然难看
            this.dirX = 1;// 球的水平方向(控制正反)
            this.dirY = 1;// 如上
            this.speed = o.speed || 1 * Math.random() - 0.3;// 球的移动速度
            this.X = getRandom(width);// 这里是初始化球的起始位置,值是0-width
            this.Y = getRandom(height);
            this.resetDir = function() {// 控制方向
                // X的位置如果小于半径或者大于canvas的宽度-半径就改变方向,Y同理
                if (this.X < this.radius || this.X > width - this.radius) {
                    this.dirX = -this.dirX;
                }
                if (this.Y < this.radius || this.Y > height - this.radius) {
                    this.dirY = -this.dirY;
                }  
            };
            this.init = function() {// 球的初始化
                this.move();
            };
            this.move = function() {// 这个就是移动球,每执行一次就检查方向和改变XY的带系喔啊
                this.resetDir();
                this.X += this.dirX * this.speed;// 移动
                this.Y += this.dirY * this.speed;
            };
            
        }
        this.ball = {

        };
        this.arc = function() {// 画圆函数
            // ctx.translate(this.X, this.Y);
            for (var i = 0; i < this.instance.length; i++) {
                var ball = this.instance[i];// 从实例数组中取出来
                // ctx.save();// 保存状态
                ctx.fillStyle = ball.fillColor;// 球的填充颜色 (准备好填充颜料)
                ctx.strokeStyle = ball.borderColor;// 球的线就是border(理解为准备好颜料)
                ctx.beginPath();// 开始路径,可以理解为拿起画笔
                ctx.arc(ball.X, ball.Y, ball.radius, ball.startDeg, ball.endDeg, this.clockWay);// 画圆
                ctx.fill(); // 填充圆(就相当于给圆上色)
                ctx.closePath();// 放下笔
                // ctx.restore();
                for(var j = i + 1; j < this.instance.length; j++) {
                    var s = Math.pow(ball.X - this.instance[j].X, 2) + Math.pow(ball.Y - this.instance[j].Y, 2);
                        s = Math.sqrt(s);// 获取圆与圆之间的距离,x的平方加y的平方然后开根号,初中数学知识
                    if (s < this.maxLineLength) {// 判断什么时候可以画线
                        ctx.beginPath();
                        ctx.moveTo(ball.X, ball.Y);// 把笔移动到
                        ctx.lineTo(this.instance[j].X, this.instance[j].Y);// 画线到这个位置
                        ctx.strokeStyle = 'rgba(255, 255, 255, ' + (this.maxLineLength - s) / (this.maxLineLength * 1.3)+')';
                        // 上面是调整线的颜色
                        ctx.strokeWidth = 1;// 线宽
                        ctx.stroke();// 画
                        ctx.closePath();
                    }
                }
            }
        };
        this.draw = function() {
            ctx.clearRect(0,0,width,height);// 你要是把这个给注了你会发现不一样的世界
            this.arc();// 执行画圆函数
        };
        this.move = function() {
            for(var i = 0; i < this.instance.length; i++) {
                var ball = this.instance[i];
                ball.init();// 球的初始化函数,其实跟ball.move()是一样的,就是改变球的位置
                
            }
            this.draw();
            requestAnimationFrame(this.move.bind(this));// 这里用bind是强行改变move函数的上下文环境,不然在requestAnimationFrame中的this会变得
            // requestAnimationFrame 请求动画帧,可以理解为控制函数执行的频率(本来这里可以用递归执行,但是递归控制不了频率,会卡死页面的,setTimeout也可以实现类似的效果)
        };
        this.init = function() {
            for(var i = 0; i < o.ballNums; i++) {
                this.instance.push(new Ball()); // 初始化球               
            }
            this.move();
        };
        
    }
    function getRandom(s) {
        return Math.ceil(Math.random() * s);// 获取0 -(s-1)之间的值
    }
    function randomColor() {
        return 'rgba('+getRandom(255)+','+getRandom(255)+','+getRandom(255)+','+Math.random()+')';
    };
  };
  

写完之后,还是想把他应用起来的,所以我就想用来他装饰博客园的侧边栏,所以进到:

把上面的js改了改,插入到博客园页面:

完整代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<script>
var sideBar = document.getElementById('home');
      var canvas = document.createElement('canvas');
      canvas.id = 'canvas';
      sideBar.appendChild(canvas);
window.onload = function(){
    var canvas = document.getElementById('canvas');
    // var body = document.getElementById('home');
    var body = document.getElementsByTagName('html')[0];
    var header = document.getElementById('header');
    canvas.width = header.clientWidth;
    // canvas.height = body.clientHeight;
    canvas.height = window.screen.height;
    var bound = canvas.getBoundingClientRect();
    var ctx = canvas.getContext('2d');
    var width = bound.width, height = bound.height;
    var submit = document.getElementById('btn_comment_submit');
    submit && submit.addEventListener('click', function() {
setTimeout(function() {
body = document.getElementsByTagName('html')[0];
canvas.height = window.screen.height;
var circle = new Circle({
        ballNums: 100,
        fillColor: 'rgba(255, 255, 255, .5)',
radius:1
    });
    circle.init();
},1000);
});
    var circle = new Circle({
        ballNums: 100,
        fillColor: 'rgba(255, 255, 255, .5)',
radius: 1
    });
    circle.init();
    function Circle(o) {
        o = o || {};
        this.instance = [];
        this.maxLineLength = o.maxLineLength || 100;
        function Ball() {
            this.radius = o.radius || (o.MaxRadius || 20) * Math.random();
            this.startDeg = 0;
            this.endDeg = Math.PI * 2;
            this.clockWay = false;
            this.fillColor = o.fillColor || randomColor();
            this.borderColor = 'transparent';
            this.dirX = 1;
            this.dirY = 1;
            this.speed = o.speed || 1 * Math.random() - 0.3;
            this.X = getRandom(width);
            this.Y = getRandom(height);
            this.resetDir = function() {
                if (this.X < this.radius || this.X > width - this.radius) {
                    this.dirX = -this.dirX;
                }
                if (this.Y < this.radius || this.Y > height - this.radius) {
                    this.dirY = -this.dirY;
                }  
            };
            this.init = function() {
                this.move();
            };
            this.move = function() {
                this.resetDir();
                this.X += this.dirX * this.speed;
                this.Y += this.dirY * this.speed;
            };
            
        }
        this.ball = {

        };
        this.arc = function() {
            // ctx.translate(this.X, this.Y);
            for (var i = 0; i < this.instance.length; i++) {
                var ball = this.instance[i];
                ctx.save();
                ctx.fillStyle = ball.fillColor;
                ctx.strokeStyle = ball.borderColor;
                ctx.beginPath();
                ctx.arc(ball.X, ball.Y, ball.radius, ball.startDeg, ball.endDeg, this.clockWay);
                ctx.fill(); 
                ctx.closePath();
                ctx.restore();
                for(var j = i + 1; j < this.instance.length; j++) {
                    var s = Math.pow(ball.X - this.instance[j].X, 2) + Math.pow(ball.Y - this.instance[j].Y, 2);
                        s = Math.sqrt(s);
                    if (s < this.maxLineLength) {
                        ctx.beginPath();
                        ctx.moveTo(ball.X, ball.Y);// 把笔移动到
                        ctx.lineTo(this.instance[j].X, this.instance[j].Y);// 画线到这个位置
                        ctx.strokeStyle = 'rgba(255, 255, 255, ' + (this.maxLineLength - s) / (this.maxLineLength * 1.3)+')';
                        // 上面是调整线的颜色
                        ctx.strokeWidth = 1;// 线宽
                        ctx.stroke();// 画
                        ctx.closePath();
                    }
                }
            }
        };
        this.draw = function() {
            ctx.clearRect(0,0,width,height);
            this.arc();
        };
        this.move = function() {
            for(var i = 0; i < this.instance.length; i++) {
                var ball = this.instance[i];
                ball.init();
                
            }
            this.draw();
            requestAnimationFrame(this.move.bind(this));
        };
        this.init = function() {
            for(var i = 0; i < o.ballNums; i++) {
                this.instance.push(new Ball());                
            }
            this.move();
        };
        
    }
    function getRandom(s) {
        return Math.ceil(Math.random() * s);
    }
    function randomColor() {
        return 'rgba('+getRandom(255)+','+getRandom(255)+','+getRandom(255)+','+Math.random()+')';
    };
  };
  
</script>

然后再调整下CSS代码,就可以达到我博客的左边侧边栏动画效果,如下:

canvas的源代码:https://github.com/lhlybly/canvas-circle,欢迎star

写在这里只是希望更多的人一起来学习,一起享受代码的作用,项目代码中还有很多优化的地方,欢迎大牛拍砖,也希望刚入门的人你呢个看懂,不懂可以留言问我。

PS: 抽空我会优化刚进页面左边白屏的问题 

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-11-18 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【CodeBuddy】三分钟开发一个实用小功能之:弹跳球物理实验
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接: 腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴
Jimaks
2025/05/21
700
【CodeBuddy】三分钟开发一个实用小功能之:弹跳球物理实验
使用canvas实现一个圆球的触壁反弹
HTML <canvas id="canvas" width="500" height="500" style="border: 1px solid #FF0000;"></canvas> JS 1.获取上下文 let canvas = document.getElementById('canvas'); let ctx = canvas.getContext('2d'); 2.实现一个球类 1 class circle { 2 constructor() { 3
李文杨
2018/03/14
8280
canvas动画-跟着鼠标移到的小球 原
小球可以跟着鼠标移到,点击小球时会按既定的坐标移到小球(不再跟着鼠标移到),鼠标移出canvas,此时动画停止,鼠标进入动画时动画开始
tianyawhl
2019/04/04
5030
绚丽烟花:HTML5 Canvas 烟花效果实现(文末附完整代码)
在节日或特殊场合,绚丽的烟花总能带来无尽的欢乐和惊喜。今天,我们将通过 HTML5 Canvas 实现一个绚丽的烟花效果,让你的网页也能绽放出美丽的烟花。
码事漫谈
2025/01/27
9611
绚丽烟花:HTML5 Canvas 烟花效果实现(文末附完整代码)
酷炫一款动态背景(HTML +js canvas)
                                     一款酷炫的前端动态页面     废话不多说 ,分享一款酷炫的页面动态背景 效果见下图。     查看  demo 背景图效果: 实例效果  点击效果: 背景css *{ margin: 0; padding: 0; } #canvas{ position: fixed; background: #ccc; overflow: auto;
Fivecc
2022/11/21
6.7K0
酷炫一款动态背景(HTML +js canvas)
2024年快到了,加个灯笼和飘雪特效吧
可以将代码内容保存到空间里并命名为china-lantern.js然后使用代码调用它,该代码可以放在头部或尾部文件里
林墨白
2024/01/15
2660
2024年快到了,加个灯笼和飘雪特效吧
初识HTML5
客观地讲,没有不好的技术,只有没有用好的技术。JavaScript 的坎坷遭遇让我不禁想起了另一种被人们滥用的技术:Adobe公司研发的 Flash。
林清猫耳
2018/12/04
1.6K0
从MDN上的canvas例子受到的启发
在面对碰撞检测后还有后续动作的情况,必须考虑一下相互纠缠的问题: 如果两个小球被检测到碰撞的时候,而且加上他们的速度下一步还是处于碰撞范围内,就像引力一样无法脱离,无限原地碰撞。这时候,需要其他小球碰撞来解散这种纠缠。有时候,可能3个小球都会一起进入无限纠缠的状态。(判断碰撞-是-速度反方向-远离-判断碰撞-速度反方向-靠近-判断碰撞-是-速度反方向-远离……无限循环)
lhyt
2022/09/21
2460
从MDN上的canvas例子受到的启发
2022跨年烟花——封宿后的去旧年
首先,祝福各位彦祖们,2022快乐,如果没有对象,今年必定脱单!在封宿之余,我做了个跨年烟花来给自己过个年,和彦祖们分享一下,大家先来看一下效果图。
秋名山码神
2022/12/13
5950
2022跨年烟花——封宿后的去旧年
前端如何呼风唤雨
IMWeb前端团队
2017/12/29
9010
前端如何呼风唤雨
Canvas系列(14):实战-小球碰撞
两小球碰撞是Canvas非常经典的案例,他是一个很简单的需求,但做起来却非常复杂。
kai666666
2020/10/19
1.8K0
Canvas系列(14):实战-小球碰撞
WordPress博客网站下雪特效
上班期间也没时间去更新博客,元旦休假的时候就写点内容,分享一段 WordPress 博客网站下雪特效,喜欢的话也可以拿到你的网站去使用。 <script type="text/javascript"> /* 控制下雪 */ function snowFall(snow) { /* 可配置属性 */ snow = snow || {}; this.maxFlake = snow.maxFlake || 200; /* 最多片数 */
沈唁
2018/05/24
9780
HTML5 Canvas炫酷的火焰风暴动画
今天给大家分享一个用Canvas写的火焰风暴动画,实现效果如下: 怎么样,场面是不是很壮观,下面是代码实现,欢迎大家复制粘贴和吐槽。 <!DOCTYPE html> <html lang="zh-cn
越陌度阡
2020/11/26
2.3K0
HTML5 Canvas炫酷的火焰风暴动画
3. 创建游戏界面
进入 /game/templates/multiends 打开 web.html:
浪漫主义狗
2022/11/18
1.5K0
HTML5 canvas鼠标经过星星连线
HTML5 canvas鼠标经过星星连线,鼠标经过星空可将星星一颗颗连成直线,页面背景有变色效果。 完整项目文件(关注后下载免费不需要积分):https://download.csdn.net/download/qq_44273429/13781365
海拥
2021/08/23
2.1K0
两种过年烟花,你喜欢哪一种(HTML+CSS+JS)
🎇两种过年烟花,你喜欢哪一种🎇(HTML+CSS+JS)  目录 🎇两种过年烟花,你喜欢哪一种🎇(HTML+CSS+JS)  效果一 效果二 效果一 <!doctype html> <html> <head> <meta charset="utf-8"> <title>HTML5炫酷喜庆全屏烟花动画特效</title> <style> /* basic styles for black background and crosshair cursor */ body { background: #
红目香薰
2022/11/29
1.1K0
两种过年烟花,你喜欢哪一种(HTML+CSS+JS)
canvas入门笔记(上)
Canvas API 提供了一个通过JavaScript 和 HTML的``元素来绘制图形的方式。它可以用于动画、游戏画面、数据可视化、图片编辑以及实时视频处理等方面。
腿子代码了
2023/12/24
1950
canvas入门笔记(上)
Metaball(元球)效果学习
几年前就在网上曾看见过这种效果,但一直不知道叫什么名字 前一阵无意在9ria(天地会)论坛上看到了一篇专门讲这个的文章:AS3 元球(Metaball),不过有点遗憾的是那篇文章上的代码直接复制下来都
菩提树下的杨过
2018/01/22
2.3K0
Metaball(元球)效果学习
JavaScript动画 —— 弹动动画
缓动和弹动都是那对象从已有位置移动到目标位置的方法。但是缓动是指物体滑动到目标点就停下来;而弹动是指物体来回反弹一段时间后,最终停在目标点的运动。
大师级码师
2021/09/19
1.7K0
HTML之2022新年快乐虎年大吉给对象的不一样礼物
https://github.com/AndersonHJB/YearTiger2022
AI悦创
2021/12/31
4410
HTML之2022新年快乐虎年大吉给对象的不一样礼物
相关推荐
【CodeBuddy】三分钟开发一个实用小功能之:弹跳球物理实验
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验