console
// var redInput=document.getElementById("red")
// var greenInput=document.getElementById("green")
// redInput.oninput=(e)=>{
// }
// greenInput.oninput=(e)=>{
// }
var points = {
rect1: [
{ x: 20, y: 20, isSelected: false },
{ x: 120, y: 20, isSelected: false },
{ x: 120, y: 120, isSelected: false },
{ x: 20, y: 120, isSelected: false },
],
rect2: [
{ x: 140, y: 20, isSelected: false },
{ x: 240, y: 20, isSelected: false },
{ x: 240, y: 120, isSelected: false },
{ x: 140, y: 120, isSelected: false },
]
}
var moved = false
var mouseInit = {}
// 画图
function drawRect(Array) {
// 设置线的样式
// context.setLineDash([4, 2])
// 设置连线点样式
context.lineJoin = 'round'
context.beginPath()
// 遍历坐标点
for (let i = 0; i < Array.length; i++) {
const ele = Array[i];
if (i < 1) {
context.moveTo(ele.x, ele.y);
} else {
context.lineTo(ele.x, ele.y);
}
}
context.lineWidth = 3;
// 判断显示不同颜色的四边形
if (Array == points.rect1) {
context.strokeStyle = 'red'
} else {
context.strokeStyle = 'green'
}
// 随机颜色
// context.strokeStyle = '#'+(Math.random()*0xffffff<<0).toString(16);
context.closePath();
context.stroke();
drawArc(Array)
}
//画四角圆
function drawArc(Array) {
// 遍历坐标点
for (let i = 0; i < Array.length; i++) {
const ele = Array[i];
context.beginPath()
context.lineWidth = 3;
context.fillStyle = '#FFF'
context.arc(ele.x, ele.y, 5, 0, Math.PI * 2, false);
// 判断显示不同颜色的四边形
if (Array == points.rect1) {
context.strokeStyle = 'red'
} else {
context.strokeStyle = 'green'
}
// 随机颜色
// context.strokeStyle = '#'+(Math.random()*0xffffff<<0).toString(16);
context.closePath();
context.fill();
context.stroke();
}
}
// 画点连线
function drawRects() {
// 清除画布,准备绘制
context.clearRect(0, 0, canvas.width, canvas.height);
drawRect(points.rect1)
drawRect(points.rect2)
}
// 遍历元素在哪一个圆上
var selectObject
function circle(Array, clientX, clientY) {
for (let i = 0; i < Array.length; i++) {
const ele = Array[i];
// Math.abs返回绝对值
// Math.sqrt返回一个数的平方根
// Math.pow幂函数运算
var line = Math.abs(Math.sqrt(Math.pow((ele.x - clientX), 2) + Math.pow((ele.y - clientY), 2)))
// 判断点击的位置在哪一个圆里面
if (line - 5 < 0) {
ele.isSelected = true
isDragging = true
selectObject = Array[i]
} else {
ele.isSelected = false
}
}
}
//是否在圆上
function inCircle(Array, clientX, clientY) {
let t = false
for (let i = 0; i < Array.length; i++) {
const ele = Array[i];
// Math.abs返回绝对值
// Math.sqrt返回一个数的平方根
// Math.pow幂函数运算
var line = Math.abs(Math.sqrt(Math.pow((ele.x - clientX), 2) + Math.pow((ele.y - clientY), 2)))
// 判断点击的位置在哪一个圆里面
if (line - 5 < 0) {
t = true
}
}
return t
}
// Canvas点击事件
// 遍历所有的坐标点
function clickPoint(e) {
// 屏幕事件
var ev = window.event || e;
// 判断屏幕,减去屏幕中的偏移量
//offsetLeft会受父级的position属性影响,同理offsetTop也会
var clientX = e.clientX - this.offsetLeft;
var clientY = e.clientY - this.offsetTop;
isDragging = true
circle(points.rect1, clientX, clientY)
circle(points.rect2, clientX, clientY)
let point = {
x: e.offsetX,
y: e.offsetY
}
// 判断是否可拖动
if (isIn(point, points, e).isRect) {
moved = true
mouseInit = point
} else {
moved = false
}
}
var isDragging = false
function dragCircle(e) {
// 判断是否可以拖动
let point = {
x: e.offsetX,
y: e.offsetY
}
//改变鼠标形状
if (isIn(point, points, e).isRect) {
canvas.style.cursor = 'move'
} else {
if (isIn(point, points, e).isC) {
canvas.style.cursor = 'pointer'
} else {
canvas.style.cursor = 'default'
}
}
if (isDragging && !moved) {
// 取得画布上被点击的点
//offsetLeft会受父级的position属性影响,同理offsetTop也会
var clickX = e.pageX - canvas.offsetLeft;
var clickY = e.pageY - canvas.offsetTop;
selectObject.x = clickX
selectObject.y = clickY
drawRects()
}
//移动图形
if (moved) {
throttle(_drawRects)(e, point)
}
}
function isIn(pt, objs, e) {
let arrKeys = Object.keys(objs)
let t = false//是否在多边形内
let tc = false//是否在圆圈内
let keys = ''//所在多边形key
for (let i = 0; i < arrKeys.length; i++) {
if (pointInPoly(pt, objs[arrKeys[i]])) {
t = true
keys = arrKeys[i]
}
if (!tc) {
tc = inCircle(objs[arrKeys[i]], e.offsetX, e.offsetY)
}
}
return {
isRect: t,
isC: tc,
keys: keys
}
}
//计算一个点是否在多边形里,参数:点,多边形数组
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;
}
// 停止拖动事件
function stopDragging() {
isDragging = false
moved = false
mouseInit = {}
// 鼠标结束时的坐标
selectObject = {}
}
// 移动重绘
function _drawRects(e, point) {
let movex = e.offsetX - mouseInit.x
let movey = e.offsetY - mouseInit.y
let arrKeys = Object.keys(points)
mouseInit.x = e.offsetX
mouseInit.y = e.offsetY
for (let i = 0; i < arrKeys.length; i++) {
if (isIn(point, points, e).keys === arrKeys[i]) {
points[arrKeys[i]].map((item, index) => {
item.x = item.x + movex
item.y = item.y + movey
})
}
}
drawRects()
}
function stopDragging() {
isDragging = false
moved = false
// 鼠标结束时的坐标
selectObject = {}
}
//防抖
function throttle(fn, time = 10) {
let timer = null
return (...args) => {
if (!timer) {
timer = setTimeout(() => {
fn.apply(null, args)
timer = null
}, time)
}
}
}
var canvas = document.getElementById('canvas')
var context = canvas.getContext('2d')
drawRects()
canvas.onmousedown = clickPoint;
canvas.onmouseup = stopDragging;
canvas.onmousemove = dragCircle
// canvas.onmouseout = stopDragging;
<!-- <div class="head">
<label for="red">红色框</label>
<input id="red" max=5 min=0 step=1 type="number"/>
<label for="green">绿色框</label>
<input id="green" max=5 min=0 step=1 type="number"/>
</div> -->
<canvas id="canvas" width="800" height="600"></canvas>
.head{
height: 50px;
line-height: 50px;
}
canvas{
background-color: #333
}