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;
};