为什么80%的码农都做不了架构师?>>>
项目中需要用到鼠标点画任意多个角的凸多边形,不允许有凹进去的角,思路是用到直线方程判断落点的位置,前两个点可以任意落点,从第三个点开始起进行判断,如果落点与之前的点结合之后形成的是凹进去的角,则不允许落点,单击画点,双击闭合路径,代码如下:
html:
直接使用canvas标签
js:
var canvas = document.getElementById("canvas") //获取到canvas元素
var context = canvas.getContext("2d") //获取上下文的环境
function drawPoint(cxt, x, y, w, borderWidth, borderColor, fillColor) {
cxt.beginPath()
cxt.moveTo(x - w, y - w)
cxt.lineTo(x + w, y - w)
cxt.lineTo(x + w, y + w)
cxt.lineTo(x - w, y + w)
cxt.lineWidth = borderWidth
cxt.strokeStyle = borderColor
cxt.fillStyle = fillColor
cxt.closePath()
cxt.fill()
cxt.stroke()
}
function drawPolygon(cxt, dbl, borderWidth, borderColor, fillColor, t) {
for (var i = 0; i < dbl.length; i++) {
drawPoint(cxt, dbl[i].x, dbl[i].y, 2, 1, 'red', 'skyblue')
}
cxt.moveTo(dbl[0].x, dbl[0].y)
for (var i = 1; i < dbl.length; i++) {
cxt.lineTo(dbl[i].x, dbl[i].y)
}
if (t) {
cxt.closePath()
cxt.fillStyle = fillColor
cxt.fill()
}
cxt.lineWidth = borderWidth
cxt.strokeStyle = borderColor
cxt.stroke()
}
function z(x, y, x1, y1, x2, y2) {
if (((x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)) > 0) {
return 1
} else if (((x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)) < 0) {
return 3
} else {
return 2
}
}
获取到canvas之后,定义画点和连线以及闭合路径的函数
var timeId;
var dbl = [], arr = []
canvas.ondblclick = function () {
if (arr.length > 2) {
drawPolygon(context, arr, 1, 'red', "rgba(0, 0, 0, .1)", true)
// 这里执行完成闭合之后,清空坐标数组,便于另外新建
dbl = arr
arr = []
}
}
canvas.onclick = function (e) {
clearTimeout(timeId);
timeId = setTimeout(function () {
x = e.offsetX
y = e.offsetY
if (arr.length >= 3) {
var n1= z(arr[2].x, arr[2].y, arr[0].x, arr[0].y, arr[1].x, arr[1].y)
var n2 = z(arr[arr.length - 1].x, arr[arr.length - 1].y, arr[0].x, arr[0].y, x, y)
var n3= z(arr[1].x, arr[1].y, arr[0].x, arr[0].y, x, y)
var n4= z(arr[arr.length - 1].x, arr[arr.length - 1].y, arr[arr.length - 2].x, arr[arr.length - 2].y, x, y)
if (n1=== 1) {
// 代表第2点在线左边,这时判断第4个点的位置,如果在左边就不允许落点
if (n2 === 1 || n3=== 1 || n4=== 1) {
return
}
}
if (n1=== 3) {
// 代表第2点在线右边,这时判断第4个点的位置,如果在右边就不允许落点
if (n2 === 3 || n3=== 3 || n4=== 3) {
return
}
}
arr.push({x: x, y: y})
}
arr.length < 3 ? arr.push({x: x, y: y}) : null
drawPolygon(context, arr, 1, 'blue')
}, 250)
}
根据判断落点位置的函数来进行落点位置的控制,最后双击进行闭合路径填充颜色,另外项目里还有用到画任意数量大小矩形,思路也是差不多的,我是通过的鼠标点击后移动鼠标来实现控制