利用canvas手动绘制图形,点位可拖拽,整体可拖动
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DEMO演示</title>
</head>
<style>
</style>
<body>
<canvas id="demo" width="800" height="400" ></canvas>
</body>
</html>
<script>
var canvas = document.getElementById('demo')
var context = canvas.getContext('2d')
//线段的点的集合
var points = [];
//可拖动圆圈的点的集合
var circles = [];
//整体移动点位
var allpoints = []
var isDragging = false
//是否在绘制区域内
var isInOut = false
//记录鼠标点击位置
var downx = 0
var downy = 0
//每一个点的对象
function Point(x, y) {
this.x = x;
this.y = y;
}
//圆圈对象
function Circle(x, y) {
this.x = x;
this.y = y;
this.radius = 10;
this.color = "blue";
//拖拽点的标记
this.isSelected = false;
}
canvas.onmousedown = function (e) {
var clickX = e.pageX - canvas.offsetLeft;
var clickY = e.pageY - canvas.offsetTop;
downx = clickX
downy = clickY
if (isInt(clickX, clickY)) {
isInOut = true
return
} else {
isInOut = false
}
//判断当前点击点是否在已经绘制的圆圈上,如果是执行相关操作,并return,不进入画线的代码
for (var i = 0; i < circles.length; i++) {
var circle = circles[i];
//使用勾股定理计算这个点与圆心之间的距离
var distanceFromCenter = Math.sqrt(Math.pow(circle.x - clickX, 2)
+ Math.pow(circle.y - clickY, 2));
// 如果是其他的点,则设置可以拖动
if (distanceFromCenter <= circle.radius) {
// 清除之前选择的圆圈
index = i;
isDragging = true;
//停止搜索
return;
}
}
//如果点击新的位置,则进入下面的代码,绘制点
context.clearRect(0, 0, canvas.width, canvas.height);
//遍历数组画圆
var circle = new Circle(clickX, clickY);
circles.push(circle);
allpoints = JSON.parse(JSON.stringify(circles))
circles[0].color = "green";
for (var i = 0; i < circles.length; i++) {
var circle = circles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = "black";
context.fill();
context.stroke();
}
// 画线
var point = new Point(clickX, clickY);
points.push(point);
context.beginPath();
context.lineWidth = 4;
//从起始点开始绘制
context.moveTo(points[0].x, points[0].y);
for (var i = 0; i < points.length; i++) {
context.lineTo(points[i].x, points[i].y);
}
context.closePath()
context.fillStyle = "rgb(2,100,30)";
context.fill();
context.strokeStyle = "#9d4dca";
context.stroke();
};
canvas.onmousemove = function (e) {
// 取得鼠标位置
var x1 = e.pageX - canvas.offsetLeft;
var y1 = e.pageY - canvas.offsetTop;
//判断是否在区域内整体拖动
if (isInOut && !isDragging) {
var x2 = x1 - downx
var y2 = y1 - downy
context.clearRect(0, 0, canvas.width, canvas.height);
for (var j = 0; j < allpoints.length; j++) {
circles[j].x = allpoints[j].x + x2
circles[j].y = allpoints[j].y + y2
}
points = JSON.parse(JSON.stringify(circles))
for (var i = 0; i < circles.length; i++) {
var circle = circles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = "black";
context.fill();
context.stroke();
}
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for (var i = 0; i < points.length; i++) {
context.lineTo(points[i].x, points[i].y);
}
// context.lineTo(points[0].x, points[0].y);
// context.fillStyle="#831f68";
context.closePath()
context.fillStyle = "rgb(2,100,30)";
context.fill();
context.strokeStyle = "#9d4dca";
context.stroke();
}
// 判断圆圈是否开始拖拽
if (isDragging == true) {
// 判断拖拽对象是否存在
context.clearRect(0, 0, canvas.width, canvas.height);
//根据上文得到的index设置index点位置随鼠标改变
circles[index].x = x1;
circles[index].y = y1;
points[index].x = x1;
points[index].y = y1;
allpoints = JSON.parse(JSON.stringify(points))
for (var i = 0; i < circles.length; i++) {
var circle = circles[i];
// 绘制圆圈
context.globalAlpha = 0.85;
context.beginPath();
context.arc(circle.x, circle.y, circle.radius, 0, Math.PI * 2);
context.fillStyle = circle.color;
context.strokeStyle = "black";
context.fill();
context.stroke();
}
context.beginPath();
context.moveTo(points[0].x, points[0].y);
for (var i = 0; i < points.length; i++) {
context.lineTo(points[i].x, points[i].y);
}
// context.lineTo(points[0].x, points[0].y);
// context.fillStyle="#831f68";
context.closePath()
context.fillStyle = "rgb(2,100,30)";
context.fill();
context.strokeStyle = "#9d4dca";
context.stroke();
}
};
//判断点位是否在图形区域内
function isInt(x, y) {
if (!points[2]) {
return
}
var pt = {
x: x,
y: y
}
var poly = points
return PointInPoly(pt, poly)
}
//射线法判断点位
function PointInPoly(pt, poly) {
for (var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)
((poly[i].y <= pt.y && pt.y < poly[j].y) || (poly[j].y <= pt.y && pt.y < poly[i].y))
&& (pt.x < (poly[j].x - poly[i].x) * (pt.y - poly[i].y) / (poly[j].y - poly[i].y) + poly[i].x)
&& (c = !c);
return c;
}
canvas.onmouseup = function () {
isDragging = false;
isInOut = false
allpoints = JSON.parse(JSON.stringify(circles))
};
canvas.onmouseout = function () {
isDragging = false;
isInOut = false
};
</script>