JavaScript canvas實(shí)現(xiàn)動態(tài)點(diǎn)線效果
本文實(shí)例為大家分享了JavaScript canvas實(shí)現(xiàn)動態(tài)點(diǎn)線效果的具體代碼,供大家參考,具體內(nèi)容如下
效果預(yù)覽

1.實(shí)現(xiàn)效果
- 畫彩色點(diǎn)
- 相近的點(diǎn)產(chǎn)生連線
- 點(diǎn)線運(yùn)動,遇到邊界反彈
- 選中點(diǎn),可拖動點(diǎn)改變位置*
2.具體實(shí)現(xiàn)
初始化相關(guān)變量
var c = document.getElementById("myCanvas");
//設(shè)置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;
構(gòu)造對象存儲相關(guān)點(diǎn)線數(shù)據(jù)
var PointLine = function(canvas, x, y, r, color) {
this.theCanvas = canvas;
this.x = x;
this.y = y;
this.r = r;
this.color = color; //點(diǎn)顏色
this.speed = 5; //點(diǎn)移動速度
//移動方向
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();
};
//檢查是否出界,若出界就改變?yōu)榉捶较?
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;
};
//移動點(diǎn)
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;
};
畫兩點(diǎn)間連線
//兩點(diǎn)間連線
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();
}
//兩點(diǎn)之間距離
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; //連線的最短距離
//一點(diǎn)與其他點(diǎn)連線
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);
}
}
}
生成隨機(jī)點(diǎn)
//生產(chǎn)隨機(jī)顏色
function randColor() {
return (
"rgb(" +
[
Math.floor(Math.random() * 255),
Math.floor(Math.random() * 255),
Math.floor(Math.random() * 255)
].join(",") +
")"
);
}
//生成隨機(jī)點(diǎn)
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個隨機(jī)點(diǎn)線
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
);
}
開始動畫
//循環(huán)執(zhí)行canvas動畫
function start() {
anim = canvasAnimation()(this.start);
//清空canvas
theCanvas.clearRect(
0,
0,
theCanvas.canvas.width,
theCanvas.canvas.height
);
//畫點(diǎn)線
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();
選中點(diǎn)進(jìn)行拖動
//px坐標(biāo)轉(zhuǎn)canvas坐標(biāo)
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)
};
}
//設(shè)置動作,按下選中點(diǎn)
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;
}
}
};
//移動點(diǎn)
theCanvas.canvas.onmousemove = function(e) {
if (selectPoint) {
var loc = windowToCanvas(theCanvas.canvas, e.clientX, e.clientY);
selectPoint.x = loc.x;
selectPoint.y = loc.y;
}
};
//取消選中點(diǎn)
theCanvas.canvas.onmouseup = function(e) {
selectPoint = null;
};
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
利用JS+Canvas給南方的冬季來一場紛紛揚(yáng)揚(yáng)的大雪
現(xiàn)在冬天下雪已經(jīng)是很常見的事情了,為了應(yīng)景,我們可以為我們的網(wǎng)站增加雪花飄落的效果,這個應(yīng)該還是很不錯的,下面這篇文章主要給大家介紹了關(guān)于利用JS+Canvas給南方的冬季來一場紛紛揚(yáng)揚(yáng)的大雪,需要的朋友可以參考下2022-12-12
Bootstrap組件之下拉菜單,多級菜單及按鈕布局方法實(shí)例
這篇文章主要介紹了Bootstrap組件之下拉菜單,多級菜單及按鈕布局方法,結(jié)合完整實(shí)例形式分析了Bootstrap多級菜單布局相關(guān)樣式功能與具體使用技巧,需要的朋友可以參考下2017-05-05
Javascript中構(gòu)造函數(shù)要注意的一些坑
JavaScript語言是一門面向?qū)ο蟮恼Z言,但JS中并沒有類的概念的。于是JavaScript采用構(gòu)造函數(shù)的方式來模擬類的效果,即我們通過函數(shù)來創(chuàng)建對象。這也證明了函數(shù)在JavaScript中具有非常重要的地位。本文主要介紹了Javascript中構(gòu)造函數(shù)的一些坑,需要的朋友可以參考。2017-01-01
鼠標(biāo)拖拽移動子窗體的JS實(shí)現(xiàn)
這篇文章主要介紹了鼠標(biāo)拖拽移動子窗體的JS實(shí)現(xiàn),需要的朋友可以參考下2014-02-02
web頁面和微信小程序頁面實(shí)現(xiàn)瀑布流效果
這篇文章主要介紹了web頁面和微信小程序頁面實(shí)現(xiàn)瀑布流效果,本文通過實(shí)例代碼圖文介紹,給大家介紹的非常詳細(xì),具有一定的參考借鑒價值 ,需要的朋友可以參考下2018-09-09
Javascript數(shù)組的排序 sort()方法和reverse()方法
JavaScript提供了sort()方法和reverse()方法,使得我們可以簡單的對數(shù)組進(jìn)行排序操作和逆序操作2012-06-06
el-input限制輸入只允許輸入浮點(diǎn)型的解決思路
本文主要是記錄,el-input怎么限制輸入只允許輸入浮點(diǎn)型,注意是輸入的時候限制只允許輸入浮點(diǎn)型,而不是輸入完提交的時候再校驗(yàn)提示,感興趣的朋友跟隨小編一起看看吧2024-03-03
Javascript 拖拽雛形(逐行分析代碼,讓你輕松了拖拽的原理)
這篇文章主要介紹了Javascript 拖拽雛形(逐行分析代碼,讓你輕松了拖拽的原理),需要的朋友可以參考下2015-01-01

