js+canvas實(shí)現(xiàn)可自動吸附閉合的鼠標(biāo)繪制多邊形
本文實(shí)例為大家分享了js+canvas實(shí)現(xiàn)鼠標(biāo)繪制多邊形的具體代碼,可自動吸附閉合,供大家參考,具體內(nèi)容如下
效果圖:
完整代碼:(記得引入jQuery)
<!DOCTYPE html> <html lang="en"> <head> ? ? <meta charset="UTF-8"> ? ? <title>canvas繪制多邊形</title> ? ? <script src="jQuery.js"></script> </head> <body> <style> ? ? canvas { ? ? ? ? border: 1px solid #333; ? ? ? ? display: block; ? ? } ? ? input { ? ? ? ? width: 100px; ? ? ? ? margin-left: 200px; ? ? ? ? margin-top: 650px; ? ? } ? ? #canvas{ ? ? ? ? position: absolute; ? ? ? ? left: 0; ? ? ? ? top: 0; ? ? ? ? z-index: 1; ? ? ? ? cursor: crosshair; ? ? } ? ? #canvasSave{ ? ? ? ? position: absolute; ? ? ? ? left: 0; ? ? ? ? top: 0; ? ? } </style> <!--用來和鼠標(biāo)進(jìn)行交互操作的canvas--> <canvas id="canvas" width="1000px" height="600px"></canvas> <!--存儲已生成的點(diǎn)線,避免被清空--> <canvas id="canvasSave" width="1000px" height="600px"></canvas> <input id="deleteCanvas" type="button" value="清空選區(qū)"> <script> ? ? var can = document.getElementById("canvas"); ? ? var ctx = can.getContext('2d'); ? ? var canSave = document.getElementById("canvasSave"); ? ? var ctxSave = canSave.getContext('2d'); ? ? var pointX, pointY; ? ? var pointArr = [];//存放坐標(biāo)的數(shù)組 ? ? ctx.strokeStyle = 'rgba(102,168,255,1)';//線條顏色 ? ? ctx.lineWidth = 4;//線條粗細(xì) ? ? ctxSave.strokeStyle = 'rgba(102,168,255,1)';//線條顏色 ? ? ctxSave.lineWidth = 4;//線條粗細(xì) ? ? var oIndex = -1;//判斷鼠標(biāo)是否移動到起始點(diǎn)處,-1為否,1為是 ? ? /*點(diǎn)擊畫點(diǎn)*/ ? ? $(can).click(function (e) { ? ? ? ? if (e.offsetX || e.layerX) { ? ? ? ? ? ? pointX = e.offsetX == undefined ? e.layerX : e.offsetX; ? ? ? ? ? ? pointY = e.offsetY == undefined ? e.layerY : e.offsetY; ? ? ? ? ? ? var piX,piY; ? ? ? ? ? ? if(oIndex > 0 && pointArr.length > 0){ ? ? ? ? ? ? ? ? piX = pointArr[0].x; ? ? ? ? ? ? ? ? piY = pointArr[0].y; ? ? ? ? ? ? ? ? //畫點(diǎn) ? ? ? ? ? ? ? ? makearc(ctx, piX, piY, GetRandomNum(2, 2), 0, 180, 'rgba(102,168,255,1)'); ? ? ? ? ? ? ? ? pointArr.push({x: piX, y: piY}); ? ? ? ? ? ? ? ? canvasSave(pointArr);//保存點(diǎn)線同步到另一個canvas ? ? ? ? ? ? ? ? saveCanvas();//生成畫布 ? ? ? ? ? ? }else { ? ? ? ? ? ? ? ? piX = pointX; ? ? ? ? ? ? ? ? piY = pointY; ? ? ? ? ? ? ? ? makearc(ctx, piX, piY, GetRandomNum(2, 2), 0, 180, 'rgba(102,168,255,1)'); ? ? ? ? ? ? ? ? pointArr.push({x: piX, y: piY}); ? ? ? ? ? ? ? ? canvasSave(pointArr);//保存點(diǎn)線同步到另一個canvas ? ? ? ? ? ? } ? ? ? ? } ? ? }); ? ? /* ?*/ ? ? $(can).mousemove(function (e) { ? ? ? ? if (e.offsetX || e.layerX) { ? ? ? ? ? ? pointX = e.offsetX == undefined ? e.layerX : e.offsetX; ? ? ? ? ? ? pointY = e.offsetY == undefined ? e.layerY : e.offsetY; ? ? ? ? ? ? var piX,piY; ? ? ? ? ? ? /*清空畫布*/ ? ? ? ? ? ? ctx.clearRect(0, 0, can.width, can.height); ? ? ? ? ? ? /*鼠標(biāo)下跟隨的圓點(diǎn)*/ ? ? ? ? ? ? makearc(ctx, pointX, pointY, GetRandomNum(4, 4), 0, 180, 'rgba(102,168,255,1)'); ? ? ? ? ? ? if (pointArr.length > 0) { ? ? ? ? ? ? ? ? if((pointX > pointArr[0].x-15 && pointX < pointArr[0].x+15) && (pointY > pointArr[0].y-15 && pointY < pointArr[0].y+15)){ ? ? ? ? ? ? ? ? ? ? if(pointArr.length>1){ ? ? ? ? ? ? ? ? ? ? ? ? piX = pointArr[0].x; ? ? ? ? ? ? ? ? ? ? ? ? piY = pointArr[0].y; ? ? ? ? ? ? ? ? ? ? ? ? ctx.clearRect(0, 0, can.width, can.height); ? ? ? ? ? ? ? ? ? ? ? ? makearc(ctx, piX, piY, GetRandomNum(4, 4), 0, 180, 'rgba(102,168,255,1)'); ? ? ? ? ? ? ? ? ? ? ? ? oIndex = 1; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }else { ? ? ? ? ? ? ? ? ? ? piX = pointX; ? ? ? ? ? ? ? ? ? ? piY = pointY; ? ? ? ? ? ? ? ? ? ? oIndex = -1; ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? /*開始繪制*/ ? ? ? ? ? ? ? ? ctx.beginPath(); ? ? ? ? ? ? ? ? ctx.moveTo (pointArr[0].x, pointArr[0].y); ? ? ? ? ? ? ? ? if (pointArr.length > 1){ ? ? ? ? ? ? ? ? ? ? for (var i = 1; i < pointArr.length; i++){ ? ? ? ? ? ? ? ? ? ? ? ? ctx.lineTo(pointArr[i].x, pointArr[i].y); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ctx.lineTo(piX, piY); ? ? ? ? ? ? ? ? ctx.fillStyle = 'rgba(161,195,255,1)';//填充顏色 ? ? ? ? ? ? ? ? ctx.fill();//填充 ? ? ? ? ? ? ? ? ctx.stroke();//繪制 ? ? ? ? ? ? } ? ? ? ? } ? ? }); ? ? // 存儲已生成的點(diǎn)線 ? ? function canvasSave(pointArr){ ? ? ? ? ctxSave.clearRect(0, 0, ctxSave.width, ctxSave.height); ? ? ? ? ctxSave.beginPath(); ? ? ? ? if (pointArr.length > 1){ ? ? ? ? ? ? ctxSave.moveTo (pointArr[0].x, pointArr[0].y); ? ? ? ? ? ? for (var i = 1; i < pointArr.length; i++){ ? ? ? ? ? ? ? ? ctxSave.lineTo(pointArr[i].x, pointArr[i].y); ? ? ? ? ? ? ? ? ctxSave.fillStyle = 'rgba(161,195,255,1)';//填充顏色 ? ? ? ? ? ? ? ? //ctxSave.fill(); ? ? ? ? ? ? ? ? ctxSave.stroke();//繪制 ? ? ? ? ? ? } ? ? ? ? ? ? ctxSave.closePath(); ? ? ? ? } ? ? } ? ? /*生成畫布 結(jié)束繪畫*/ ? ? function saveCanvas() { ? ? ? ? ctx.clearRect(0, 0, can.width, can.height); ? ? ? ? ctxSave.closePath();//結(jié)束路徑狀態(tài),結(jié)束當(dāng)前路徑,如果是一個未封閉的圖形,會自動將首尾相連封閉起來 ? ? ? ? ctxSave.fill();//填充 ? ? ? ? ctxSave.stroke();//繪制 ? ? ? ? pointArr = []; ? ? } ? ? /*清空選區(qū)*/ ? ? $('#deleteCanvas').click(function () { ? ? ? ? ctx.clearRect(0, 0, can.width, can.height); ? ? ? ? ctxSave.clearRect(0, 0, canSave.width, canSave.height); ? ? ? ? pointArr = []; ? ? }); ? ? /*驗(yàn)證canvas畫布是否為空函數(shù)*/ ? ? function isCanvasBlank(canvas) { ? ? ? ? var blank = document.createElement('canvas');//創(chuàng)建一個空canvas對象 ? ? ? ? blank.width = canvas.width; ? ? ? ? blank.height = canvas.height; ? ? ? ? return canvas.toDataURL() == blank.toDataURL();//為空 返回true ? ? } ? ? /*canvas生成圓點(diǎn)*/ ? ? function GetRandomNum(Min, Max) { ? ? ? ? var Range = Max - Min; ? ? ? ? var Rand = Math.random(); ? ? ? ? return (Min + Math.round(Rand * Range)); ? ? } ? ? function makearc(ctx, x, y, r, s, e, color) { ? ? ? ? ctx.clearRect(0, 0, 199, 202);//清空畫布 ? ? ? ? ctx.beginPath(); ? ? ? ? ctx.fillStyle = color; ? ? ? ? ctx.arc(x, y, r, s, e); ? ? ? ? ctx.fill(); ? ? } </script> </body> </html>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
用js實(shí)現(xiàn)終止瀏覽器對頁面HTML的繼續(xù)解析即停止解析 兼容firefox
用js實(shí)現(xiàn)終止瀏覽器對頁面HTML的繼續(xù)解析即停止解析 兼容firefox...2007-11-11ES6學(xué)習(xí)筆記之正則表達(dá)式和字符串正則方法分析
這篇文章主要介紹了ES6學(xué)習(xí)筆記之正則表達(dá)式和字符串正則方法,結(jié)合實(shí)例形式對比分析了ES5與ES6正則操作的常用函數(shù)功能與用法區(qū)別,需要的朋友可以參考下2017-04-04點(diǎn)擊按鈕彈出模態(tài)框的一系列操作代碼實(shí)例
這篇文章主要介紹了js彈出模態(tài)框方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03IE6-8中Date不支持toISOString的修復(fù)方法
這篇文章主要介紹了IE6-8中Date不支持toISOString的修復(fù)方法,需要的朋友可以參考下2014-05-05JavaScript中的alert()函數(shù)使用技巧詳解
這篇文章主要介紹了JavaScript中的alert()函數(shù)使用技巧詳解,本文講解了普通彈出、帶換行的文本、使用制表符、使用變量、使用樣式等選擇,需要的朋友可以參考下2014-12-12