日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

实现canvas连线

發(fā)布時(shí)間:2025/3/15 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现canvas连线 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

如圖:

簡(jiǎn)單說明下,每個(gè)點(diǎn)都可以連接,但是不能重復(fù)連接同一個(gè)點(diǎn),當(dāng)連接到最后一個(gè)點(diǎn)的時(shí)候,會(huì)自動(dòng)連接第一個(gè)點(diǎn)(首尾相連)。

?

var canvas = document.querySelector('#canvas') var ctx = canvas.getContext('2d')

  

畫點(diǎn)

?

使用數(shù)組保存點(diǎn)的位置,遍歷數(shù)組將點(diǎn)畫出來

1 var points = [{x: 300,y: 98, isConnect: false},{x: 217,y: 264, isConnect: false},{x: 295,y: 359, isConnect: false},{x: 372,y: 508, isConnect: false},{x: 511,y: 385, isConnect: false},{x: 497,y: 203, isConnect: false}] 2 3 function drawPoint () { 4 for (var i = 0, len = points.length; i < len; i++) { 5 ctx.save() 6 ctx.beginPath() 7 ctx.arc(points[i].x, points[i].y, 10, 0, 2 * Math.PI) 8 ctx.fill() 9 ctx.restore() 10 } 11 } View Code

畫線

畫線這部分涉及到交互,所以我們需要添加事件,設(shè)置drawing,當(dāng)點(diǎn)擊的時(shí)候才能開始畫線

1 var mouse = { //用來保存鼠標(biāo)移動(dòng)的位置 2 start: {x: 0, y: 0}, 3 end: {x: 0, y: 0} 4 } 5 var drawing = false; //判斷是否可以畫線 6 function drawLine (pos1, pos2) { 7 ctx.save() 8 ctx.beginPath() 9 ctx.moveTo(pos1.x, pos1.y) 10 ctx.lineTo(pos2.x, pos2.y) 11 ctx.stroke() 12 ctx.closePath() 13 ctx.restore() 14 } 15 16 canvas.addEventListener('mousedown', function(e) { 17 18 mouse.start.x = e.pageX 19 mouse.start.y = e.pageY 20 drawing = true 21 }) 22 23 canvas.addEventListener('mousemove', function(e) { 24 25 mouse.end.x = e.pageX 26 mouse.end.y = e.pageY 27 ctx.clearRect(0, 0, canvas.width, canvas.height) //清除畫布 28 29 if (drawing) { 30 drawLine(mouse.start, mouse.end) 31 } 32 33 })

“吸附”點(diǎn)

我們現(xiàn)在是可以在任意一點(diǎn)開始畫線,但是我們的需求是,靠近某個(gè)點(diǎn)才能開始畫線

怎么判斷靠近某個(gè)點(diǎn)呢?使用勾股定理,計(jì)算兩點(diǎn)的距離(一個(gè)點(diǎn)是原點(diǎn), 另一個(gè)點(diǎn)是鼠標(biāo)位置)小于一個(gè)值(dis)時(shí),我們判定被這個(gè)點(diǎn)“吸附”了,然后開始畫線。

寫一個(gè)方法計(jì)算距離:

1 function distance (pos1, pos2) { 2 return Math.sqrt(Math.pow(pos1.x - pos2.x, 2) + Math.pow(pos1.y - pos2.y, 2)) 3 }

判斷是否被”吸附“, 并且”吸附“過的點(diǎn)不能再連接:

1 function adsorption (mouse) { 2 3 for (var i = 0, len = points.length; i < len; i++) { 4 5 if (!points[i].isConnect && distance(mouse, points[i]) <= dis) { 6 7 points[i].isConnect = true 8 drawing = true 9 10 } 11 12 } 13 } 14 ... 15 //修改下事件 16 // canvas.addEventListener('mousedown', function(e) { 17 18 // mouse.start.x = e.pageX 19 // mouse.start.y = e.pageY 20 21 // }) 22 23 canvas.addEventListener('mousemove', function(e) { 24 25 mouse.end.x = e.pageX 26 mouse.end.y = e.pageY 27 ctx.clearRect(0, 0, canvas.width, canvas.height) 28 adsorption(mouse.end) 29 drawPoint() 30 if (drawing) { 31 drawLine(mouse.start, mouse.end) 32 } 33 34 })

到這里,鼠標(biāo)靠近點(diǎn)的時(shí)候,就可以畫線了,但是并不是我們預(yù)想的那樣,應(yīng)該從點(diǎn)開始畫線

這是因?yàn)樵赿rawLine傳值的是mouse.start,我們只需要把mouse.start換成點(diǎn)的位置就可以了,那么如何換成點(diǎn)的位置呢?

可以用一個(gè)數(shù)組保存連接過的點(diǎn):

1 var savePoints = [] 2 ... 3 //修改adsorption 4 function adsorption (mouse) { 5 6 for (var i = 0, len = points.length; i < len; i++) { 7 8 if (!points[i].isConnect && distance(mouse, points[i]) <= dis) { 9 10 points[i].isConnect = true 11 drawing = true 12 savePoints.push(points[i]) 13 14 } 15 16 } 17 } 18 ... 19 //修改mouse事件 20 canvas.addEventListener('mousemove', function(e) { 21 22 ... 23 if (drawing) { 24 drawLine(savePoints[savePoints.length - 1], mouse.end) 25 } 26 27 })

我們發(fā)現(xiàn)每次靠近一個(gè)點(diǎn)的時(shí)候,都是從這個(gè)點(diǎn)開始連線的,之前連接的線并沒有畫出來,clearRect清除了之前連的線

可以利用保存過的點(diǎn),把之前連過的線畫出來:

1 ... 2 function drawOldLine () { 3 for (var i = 0, len = savePoints.length - 1; i < len; i++) { 4 drawLine(savePoints[i], savePoints[i + 1]) 5 } 6 } 7 ... 8 //修改mousemove事件 9 ... 10 if (_this.drawing) { 11 12 ... 13 drawOldLine() 14 15 }

好了,我們可以看到,每個(gè)點(diǎn)都可以連接,跟我們預(yù)想的一樣,現(xiàn)在就差最后一步了

首尾相連,簡(jiǎn)單的思路就是,保存過的數(shù)組savePoints里的第一個(gè)點(diǎn)和最后一個(gè)點(diǎn)連線:

1 function autoLine () { 2 ctx.clearRect(0, 0, canvas.width, canvas.height) 3 drawOldLine() 4 drawPoint() 5 drawLine(savePoints[savePoints.length - 1], savePoints[0]) 6 drawing = false 7 }

到這里,已經(jīng)完成了連線功能。

大家可以嘗試一下封裝成插件,以后可以方便地使用以及拓展。

?

轉(zhuǎn)載于:https://www.cnblogs.com/Zhongxk/p/10197538.html

總結(jié)

以上是生活随笔為你收集整理的实现canvas连线的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。