JavaScript canvas实现动态点线效果
更新时间:2021年08月17日 09:51:37 作者:xiaolidan00
这篇文章主要为大家详细介绍了JavaScript canvas实现动态点线效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
本文实例为大家分享了JavaScript canvas实现动态点线效果的具体代码,供大家参考,具体内容如下
效果预览
1.实现效果
- 画彩色点
- 相近的点产生连线
- 点线运动,遇到边界反弹
- 选中点,可拖动点改变位置*
2.具体实现
初始化相关变量
var c = document.getElementById("myCanvas"); //设置canvas大小 c.height = document.body.offsetHeight; c.width = document.body.offsetWidth; //canvas跟随窗口大小 window.onresize = function() { c.height = document.body.offsetHeight; c.width = document.body.offsetWidth; }; var theCanvas = c.getContext("2d"); var pointList = []; //存储points var anim = null; var selectPoint = null;
构造对象存储相关点线数据
var PointLine = function(canvas, x, y, r, color) { this.theCanvas = canvas; this.x = x; this.y = y; this.r = r; this.color = color; //点颜色 this.speed = 5; //点移动速度 //移动方向 this.direction = parseInt(Math.random() * 1000) % 4; //0 -x 1 x 2-y 3 y this.drawPoint = function() { this.theCanvas.beginPath(); this.theCanvas.fillStyle = this.color; this.theCanvas.arc(this.x, this.y, this.r, 0, 360); this.theCanvas.fill(); }; //检查是否出界,若出界就改变为反方向 this.checkX = function(x) { if (x - this.r <= 0) { this.x = this.r; this.direction = 1; } else if (x + this.r >= this.theCanvas.canvas.width) { this.x = this.theCanvas.canvas.width - this.r; this.direction = 0; } else this.x = x; }; this.checkY = function(y) { if (y - this.r <= 0) { this.y = this.r; this.direction = 3; } else if (y + this.r >= this.theCanvas.canvas.height) { this.y = this.theCanvas.canvas.height - this.r; this.direction = 2; } else this.y = y; }; //移动点 this.movePoints = function() { if (this.direction == 0) { this.checkX(this.x - parseInt(Math.random() * this.speed)); } else if (this.direction == 1) { this.checkX(this.x + parseInt(Math.random() * this.speed)); } else if (this.direction == 2) { this.checkY(this.y - parseInt(Math.random() * this.speed)); } else if (this.direction == 3) { this.checkY(this.y + parseInt(Math.random() * this.speed)); } }; return this; };
画两点间连线
//两点间连线 function drawLine(start, end) { theCanvas.strokeStyle = "rgba(204,204,204,0.5)"; theCanvas.beginPath(); theCanvas.moveTo(start.x, start.y); theCanvas.lineTo(end.x, end.y); theCanvas.stroke(); } //两点之间距离 function getDistance(p1, p2) { return Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2); } var minDistance = parseInt(0.1 * theCanvas.canvas.height); minDistance = minDistance * minDistance; //连线的最短距离 //一点与其他点连线 function drawLinkLine(p1) { for (var j = 0; j < pointList.length; j++) { var p2 = pointList[j]; if (p2.x == p1.x && p2.y == p1.y) continue; var line = getDistance(p1, p2); if (line < minDistance && line > 0) { drawLine(p1, p2); } } }
生成随机点
//生产随机颜色 function randColor() { return ( "rgb(" + [ Math.floor(Math.random() * 255), Math.floor(Math.random() * 255), Math.floor(Math.random() * 255) ].join(",") + ")" ); } //生成随机点 function createPoint() { var x = parseInt(Math.random() * theCanvas.canvas.width); var y = parseInt(Math.random() * theCanvas.canvas.height); var r = 5 + parseInt(Math.random() * 20); if (x - r < 0) x = r; else if (x + r > theCanvas.canvas.width) x = theCanvas.canvas.width - r; if (y - r < 0) x = r; else if (y + r > theCanvas.canvas.height) y = theCanvas.canvas.height - r; return new PointLine(theCanvas, x, y, r, randColor()); } //生成100个随机点线 for (var i = 0; i < 100; i++) { pointList.push(createPoint()); }
兼容浏览器canvas动画帧
//启用动画 function canvasAnimation() { return ( window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame || function(callback, element) { var self = this, start, finish; window.setTimeout(function() { start = +new Date(); callback(start); finish = +new Date(); self.timeout = 1000 / 60 - (finish - start); }, self.timeout); } ); } //取消动画 function canvasCancleAnim() { return ( window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.mosCancelAnimationFrame || window.clearTimeout ); }
开始动画
//循环执行canvas动画 function start() { anim = canvasAnimation()(this.start); //清空canvas theCanvas.clearRect( 0, 0, theCanvas.canvas.width, theCanvas.canvas.height ); //画点线 for (var i = 0; i < this.pointList.length; i++) { var p = pointList[i]; drawLinkLine(p); p.drawPoint(); if (selectPoint && selectPoint == p) continue; p.movePoints(); } } //开始动画 start();
选中点进行拖动
//px坐标转canvas坐标 function windowToCanvas(canvas, x, y) { var bbox = canvas.getBoundingClientRect(); return { x: x - bbox.left * (canvas.width / bbox.width), y: y - bbox.top * (canvas.height / bbox.height) }; } //设置动作,按下选中点 theCanvas.canvas.onmousedown = function(e) { var loc = windowToCanvas(theCanvas.canvas, e.clientX, e.clientY); for (var i = 0; i < pointList.length; i++) { var p = pointList[i]; if (getDistance(p, loc)<100) { selectPoint = p; break; } } }; //移动点 theCanvas.canvas.onmousemove = function(e) { if (selectPoint) { var loc = windowToCanvas(theCanvas.canvas, e.clientX, e.clientY); selectPoint.x = loc.x; selectPoint.y = loc.y; } }; //取消选中点 theCanvas.canvas.onmouseup = function(e) { selectPoint = null; };
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
您可能感兴趣的文章:
相关文章
javascript KeyDown、KeyPress和KeyUp事件的区别与联系
KeyDown、KeyPress和KeyUp事件的区别与联系,以后就可以根据需求来选择使用。2009-12-12layui 框架的upload上传文件的data参数传到后端的方法
这篇文章主要介绍了layui框架的upload上传文件的data参数传到后端的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧2023-11-11
最新评论