一个有意思的Canvas绘图
2017-11-26 15:40
260 查看
pre
很久之前朋友给我看过一个网站的背景canvas,感觉有意思,今天正好又看到一个网站用了这个背景,所以我就直接从网页上摘下这段代码来看一下实现原理。效果如下
(为了分析的方便,这里面的线条粗细以及颜色被调整过)
参考网页效果
实际网页效果
源码分析
(源码经过轻微修改,在关键步骤都做了相应的注释)<html> <body> </body> </html> <script color="255,0,0" count="200"> !function() { function A(a, b, c) { return a.getAttribute(b) || c } function F(a) { return document.getElementsByTagName(a); } function D() { var c = F("script"), a = c.length, b = c[a - 1]; return { l: a, z: A(b, "zIndex", -1), o: A(b, "opacity", 0.5), c: A(b, "color", "0,0,0"), n: A(b, "count", 199) } } function E() { x = i.width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; B = i.height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; } function M() { J.clearRect(0, 0, x, B); var c = [I].concat(v);//将当前鼠标位置压入栈中 var b, d, a, g, e, f; v.forEach(function(h) { h.x += h.xa, h.y += h.ya, h.xa *= h.x > x || h.x < 0 ? -1 : 1, h.ya *= h.y > B || h.y < 0 ? -1 : 1, J.fillRect(h.x - 0.5, h.y - 0.5, 1, 1);//以坐标点为中心,绘制一个1*1的矩形区域 for (d = 0; d < c.length; d++) { b = c[d]; if (h !== b && null !== b.x && null !== b.y) { //计算之间的距离,不开根号,节省时间 g = h.x - b.x; e = h.y - b.y; f = g * g + e * e; //纯色填充 f < b.max && (b === I && f >= b.max / 2 && (h.x -= 0.03 * g, h.y -= 0.03 * e), a = (b.max - f) / b.max, J.beginPath(), J.lineWidth = a *4, J.strokeStyle = "rgba(" + w.c + "," + (a + 0.2) + ")", J.moveTo(h.x, h.y), J.lineTo(b.x, b.y), J.stroke()) //变色填充 //linecolor = Math.floor(N()*255)+","+Math.floor(N()*255)+","+Math.floor(N()*255); //f < b.max && (b === I && f >= b.max / 2 && (h.x -= 0.03 * g, h.y -= 0.03 * e), a = (b.max - f) / b.max, J.beginPath(), J.lineWidth = a / 2, J.strokeStyle = "rgba(" + linecolor + "," + (a + 0.2) + ")", J.moveTo(h.x, h.y), J.lineTo(b.x, b.y), J.stroke()) } } c.splice(c.indexOf(h), 1); }), C(M); } var i = document.createElement("canvas"), w = D(),//初始属性 L = "c_n" + w.l, //id J = i.getContext("2d"), x,//可视宽度 B,//可视高度 C = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function(a) { window.setTimeout(a, 1000 / 4) },//获取刷新函数 N = Math.random,//随机函数 I = { x: null, y: null, max: 20000 };//记录窗口位置 //在页面中添加canvas元素 i.id = L; i.style.cssText = "position:fixed;top:0;left:0;z-index:" + w.z + ";opacity:" + w.o; document.body.appendChild(i); //捕获窗口可视区域大小 E(); window.onresize = E; //捕获鼠标位置 window.onmousemove = function(a) { a = a || window.event, I.x = a.clientX, I.y = a.clientY }; window.onmouseout = function() { I.x = null, I.y = null }; //随机产生 w.n个初始点,并且初始化方向 for (var v = [], z = 0; w.n > z; z++) { var G = N() * x, H = N() * B, y = 2 * N() - 1, K = 2 * N() - 1; v.push({ x: G, y: H, xa: y, ya: K, max: 6000 }); } //开启定时刷新 C(M) } (); </script>
post
这样的效果实现起来没有什么困难,主要是存在几个设计上的亮点。鼠标交互
在每一帧刷新的时候,用户的鼠标位置会被传入,然后影响整体绘图,这样的交互对于部分用户来说可能会带来惊喜感,当然不排除因为背景交互而影响内容的呈现的问题,所以在实际应用在一些网站上时,线条的移动速度和刷新率会做权衡吸附效果
设计者在连线的时候没有直接连,他将对应的顶点拉近一个小距离,在用户的视觉上呈现的效果就是吸附了。当然会存在顶点被捕获的问题,最主要体现在鼠标顶点上,如果一个背景上的顶点位于鼠标顶点的捕获范围,同时该顶点有一个逃离鼠标捕获范围的趋势,如果顶点的逃离速度无法克服顶点吸附带来的影响,那么这个顶点就会在边界不停的抖动。当然如果两个运动方向正好想法或者有相对运动的顶点,也可以出现一个顶点被另外一个顶点拉着跑的情况。总体来说,吸附效果增强了交互感。
层次感
如果单纯给运动中的点连线,那么这样的2D效果还不是那么OK,设计者在连线的时候参考点之间的距离为不同的练习赋予不同的线宽,为动画增加了一种层次感。利于是错觉的原理,用户会认为3D中的平面图形处于旋转状态。当然由于线宽的规则不是那么复杂,所以仔细看,还是会存在很多漏洞。post
不得不说,前端的学问很深,难度不仅在技术上。相关文章推荐
- 每天一个JavaScript实例-canvas绘图
- Android 自定义控件-Canvas和Paint绘图详解-手把手带你绘制一个时钟.
- 一个有意思的在线绘图(像Flash) - zas 的flash blog |闪客,RIA - 歪酷博客 Ycool Blog
- canvas绘图详解-06-绘制一个五角星-常用绘图原理
- 开发一个基于Canvas的网页绘图应用程序
- 每日一个js实例15--canvas绘图内容打印
- 一个简单的Canvas绘图的代码
- 有趣的Javascript:只需一个JS让万恶的IE5、IE6、IE7、IE8全都支持H5原生Canvas绘图(有演示demo)
- 一个html5 canvas 绘图框架
- canvas绘制一个五角星-常用绘图原理
- 安卓Canvas绘图之setXfermode一个需要注意的点
- Android 自定义控件-Canvas和Paint绘图详解-手把手带你绘制一个时钟.
- Three.JS学习 7:使用Canvas画一个时钟
- 【一天一个canvas】写文字(十四)
- 一个Vue+Canvas的酷炫后台管理
- AngularJS权威教程 笔记(AngularJS是一个很有意思的库,基于函数形参的依赖注入?酷!还有奇怪的$scope和指令)
- 一个C#三维绘图控件
- 浅谈Canvas的状态绘图
- 一个比较有意思的判断两数大小的方法,不用逻辑比较运算符
- 从ListBox中拖拽一个图片到Canvas上,然后在Canvas上