最终实现效果如图
根据需要创建多个c.getContext(“2d”)对象,后期更改直线的位置只需要更改对应的c.getContext(“2d”)对象。
第一次绘制时不要清除画布,每次更改位置前再清除画布,这样就不会吧前一步的轨迹给清除了
代码如下:
import React from 'react'
export default class Line extends React.Component {
constructor(props) {
super(props)
this.state = {
flag: false,
currentMove: 1,//移动的是那条线
currentId: '',//移动对象的id
list: [{ id: 1, x: 300, y: 300 }, { id: 2, x: 200, y: 150 }]
}
this.ctx = {}
this.drawItem = {}
}
componentDidMount() {
if (document.getElementById("myCanvas")) {
var c = document.getElementById("myCanvas")
c.width = 600
c.height = 600
this.state.list.forEach(item => {
this.ctx[item.id] = c.getContext("2d")
let cx = item.x
let cy = item.y
let position = {
x1: cx - 100,
y1: cy + 100,
x2: cx + 100,
y2: cy + 100
}
this.drawItem[item.id] = position
this.draw(cx, cy, cx - 100, cy + 100, cx + 100, cy + 100, item.id)
})
}
}
draw = (cx, cy, x1, y1, x2, y2, id) => {
this.ctx[id].beginPath()
this.ctx[id].moveTo(cx, cy);
this.ctx[id].lineTo(x1, y1);
this.ctx[id].stroke()
this.ctx[id].beginPath()
this.ctx[id].moveTo(cx, cy);
this.ctx[id].lineTo(x2, y2);
this.ctx[id].stroke()
this.ctx[id].closePath()
}
handleMouseDown = (e) => {
let c = document.getElementById("myCanvas");
let b = document.body
let x = e.clientX - c.offsetLeft - b.scrollLeft
let y = e.clientY - c.offsetTop - b.scrollTop
let drawItem = this.drawItem
for (var i in drawItem) {
if (x >= drawItem[i].x1 - 5 && x <= drawItem[i].x1 + 5 && y >= drawItem[i].y1 - 5 && y <= drawItem[i].y1 + 5) {
c.style.cursor = 'pointer'
this.setState({
currentMove: 1,
flag: true,
currentId: i,
})
}
if (x >= drawItem[i].x2 - 5 && x <= drawItem[i].x2 + 5 && y >= drawItem[i].y2 - 5 && y <= drawItem[i].y2 + 5) {
c.style.cursor = 'pointer'
this.setState({
currentMove: 2,
flag: true,
currentId: i,
})
}
}
}
handleMouseMove = (e) => {
let c = document.getElementById("myCanvas");
let b = document.body
let cx
let cy
let currentId = this.state.currentId
this.state.list.forEach(item => {
if (item.id == this.state.currentId) {
cx = item.x
cy = item.y
}
})
if (this.state.flag) {
let x = e.clientX - c.offsetLeft - b.scrollLeft
let y = e.clientY - c.offsetTop - b.scrollTop
if (this.state.currentMove == 1) {
this.drawItem[currentId].x1 = x
this.drawItem[currentId].y1 = y
// 清除画布
this.ctx[currentId].clearRect(0, 0, 600, 600)
this.state.list.forEach(item1 => {
if (item1.id != currentId) {
var cx1 = item1.x
var cy1 = item1.y
//如果当前点位的角度被改变过那就用改变后的坐标,如果没有那就用初始坐标
this.draw(cx1, cy1, this.drawItem[item1.id].x1 ? this.drawItem[item1.id].x1 : cx1 - 100, this.drawItem[item1.id].y1 ? this.drawItem[item1.id].y1 : cy1 + 100, this.drawItem[item1.id].x2 ? this.drawItem[item1.id].x2 : cx1 + 100, this.drawItem[item1.id].y2 ? this.drawItem[item1.id].y2 : cy1 + 100, item1.id)
}
})
this.draw(cx, cy, x, y, this.drawItem[currentId].x2, this.drawItem[currentId].y2, currentId)
}
else {
this.drawItem[currentId].x2 = x
this.drawItem[currentId].y2 = y
this.ctx[currentId].clearRect(0, 0, 600, 600)
this.state.list.forEach(item1 => {
if (item1.id != currentId) {
var cx1 = item1.x
var cy1 = item1.y
//如果当前点位的角度被改变过那就用改变后的坐标,如果没有那就用初始坐标
this.draw(cx1, cy1, this.drawItem[item1.id].x1 ? this.drawItem[item1.id].x1 : cx1 - 100, this.drawItem[item1.id].y1 ? this.drawItem[item1.id].y1 : cy1 + 100, this.drawItem[item1.id].x2 ? this.drawItem[item1.id].x2 : cx1 + 100, this.drawItem[item1.id].y2 ? this.drawItem[item1.id].y2 : cy1 + 100, item1.id)
}
})
this.draw(cx, cy, this.drawItem[currentId].x1, this.drawItem[currentId].y1, x, y, currentId)
}
}
}
handleMouseUp = (e) => {
var c = document.getElementById("myCanvas");
c.style.cursor = ''
this.setState({
flag: false
})
}
render() {
return (
<canvas onMouseUp={this.handleMouseUp} onMouseMove={this.handleMouseMove} onMouseDown={this.handleMouseDown} id="myCanvas" ></canvas>
)
}
}