JavaScript canvas實現(xiàn)動態(tài)點線效果
更新時間:2021年08月17日 09:51:37 作者:xiaolidan00
這篇文章主要為大家詳細(xì)介紹了JavaScript canvas實現(xiàn)動態(tài)點線效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
本文實例為大家分享了JavaScript canvas實現(xiàn)動態(tài)點線效果的具體代碼,供大家參考,具體內(nèi)容如下
效果預(yù)覽
1.實現(xiàn)效果
- 畫彩色點
- 相近的點產(chǎn)生連線
- 點線運動,遇到邊界反彈
- 選中點,可拖動點改變位置*
2.具體實現(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)點線數(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; //點顏色 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(); }; //檢查是否出界,若出界就改變?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; }; //移動點 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); } } }
生成隨機點
//生產(chǎn)隨機顏色 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 ); }
開始動畫
//循環(huán)執(zhí)行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();
選中點進(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è)置動作,按下選中點 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; };
以上就是本文的全部內(nèi)容,希望對大家的學(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ì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2023-11-11