JavaScript canvas實(shí)現(xiàn)動(dòng)態(tài)點(diǎn)線效果
本文實(shí)例為大家分享了JavaScript canvas實(shí)現(xiàn)動(dòng)態(tài)點(diǎn)線效果的具體代碼,供大家參考,具體內(nèi)容如下
效果預(yù)覽
1.實(shí)現(xiàn)效果
- 畫彩色點(diǎn)
- 相近的點(diǎn)產(chǎn)生連線
- 點(diǎn)線運(yùn)動(dòng),遇到邊界反彈
- 選中點(diǎn),可拖動(dòng)點(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 = []; //存儲(chǔ)points var anim = null; var selectPoint = null;
構(gòu)造對(duì)象存儲(chǔ)相關(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)移動(dòng)速度 //移動(dòng)方向 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; }; //移動(dòng)點(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個(gè)隨機(jī)點(diǎn)線 for (var i = 0; i < 100; i++) { pointList.push(createPoint()); }
兼容瀏覽器canvas動(dòng)畫幀
//啟用動(dòng)畫 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); } ); } //取消動(dòng)畫 function canvasCancleAnim() { return ( window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.mosCancelAnimationFrame || window.clearTimeout ); }
開始動(dòng)畫
//循環(huán)執(zhí)行canvas動(dòng)畫 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(); } } //開始動(dòng)畫 start();
選中點(diǎn)進(jìn)行拖動(dòng)
//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è)置動(dòng)作,按下選中點(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; } } }; //移動(dòng)點(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)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
javascript KeyDown、KeyPress和KeyUp事件的區(qū)別與聯(lián)系
KeyDown、KeyPress和KeyUp事件的區(qū)別與聯(lián)系,以后就可以根據(jù)需求來選擇使用。2009-12-12layui?框架的upload上傳文件的data參數(shù)傳到后端的方法
這篇文章主要介紹了layui框架的upload上傳文件的data參數(shù)傳到后端的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧2023-11-11JavaScript代碼實(shí)現(xiàn)簡單日歷效果
這篇文章主要為大家詳細(xì)介紹了JavaScript代碼實(shí)現(xiàn)簡單日歷效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-04-04