moveFlag: false
})
}
}
_cleanCanvas(drawNewLine) {
// 清空画布
let canvas = document.querySelector(‘#canvas’);
let ctx = canvas.getContext(‘2d’);
canvas.height = 800;
drawNewLine && drawNewLine(ctx)
}
_drawNewLine(ctx, left, top) {
ctx.moveTo(left, top);
// 4. 绘制直线
ctx.lineTo(401, 401);
// 5. 描边
ctx.stroke();
}
}
export default App;
App.css
*{
margin: 0;
padding: 0;
}
.app{
width: 800px;
height: 800px;
/background-color: red;/
position: relative;
border: 1px solid #000;
}
.circle{
height: 6px;
width: 6px;
border-radius: 50%;
background-color: orange;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-3px);
}
.text{
padding: 0;
margin: 0;
border: 1px solid #999999;
font-weight: bolder;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
z-index: 999;
user-select: none;
}
.inside_circle{
height: 6px;
width: 6px;
border-radius: 50%;
background-color: #00ff18;
position: absolute;
cursor: pointer;
}
================================================================
================================================================
思路:改进了一些地方,通过两直线相交,将起点改为了与DIV的交点。同时终点距离黄色圆圈有一定距离。
============================================================================================================
方法:
-
两直线相交
-
相似
===================================================================
import ‘./App.css’;
import React from ‘react’
class App extends React.Component {
constructor(props) {
super(props);
this.circle = React.createRef();
this.state = {
left: 0,
top: 0,
moveFlag: false,
orangeX: 401,
orangeY: 404
}
}
componentDidMount() {
document.onmousemove = (e) => {
if (this.state.moveFlag) {
let {pageX, pageY} = e;
// 1. 更改矩形位置
if (this.state.moveFlag) {
this.setState({
left: pageX - 25,
top: pageY - 10
})
}
// 2. 清空画布并绘制新的线
this._cleanCanvas((ctx) => {
// 2.1 生成text和circle
const text = {
getBBox: () => {
return {
x: pageX,
y: pageY,
width: 50,
height: 20
}
}
}
const circle = {
center: {
x: 401,
y: 404
},
radius: 3
}
let res = this._around(text, circle)
this._drawNewLine(ctx, res);
// this._drawNewLine(ctx, pageX, pageY);
});
}
}
}
render() {
const {left, top} = this.state
return (
ref={this.circle}
style={{left, top}}
className=‘text’>RPL10
<span
onMouseDown={(e) => this._mouseDown(e)}
onMouseUp={(e) => this._mouseUp(e)}
className=‘inside_circle’
/>
);
}
_mouseDown(e) {
this.setState({
moveFlag: true
})
this.circle.current.style.left = 50
}
_mouseUp(e) {
if (this.state.moveFlag) {
this.setState({
moveFlag: false
})
}
}
_cleanCanvas(drawNewLine) {
// 清空画布
let canvas = document.querySelector(‘#canvas’);
let ctx = canvas.getContext(‘2d’);
canvas.height = 800;
drawNewLine && drawNewLine(ctx)
}
_drawNewLine(ctx, linePoint) {
ctx.moveTo(linePoint.startPt.x, linePoint.startPt.y);
// 4. 绘制直线
ctx.lineTo(linePoint.endPt.x, linePoint.endPt.y);
// 5. 描边
ctx.stroke();
}
_around(text, circle) {
const bBox = text.getBBox();
const centerBox = {
x: bBox.x,
y: bBox.y,
};
const centerCircle = {
x: circle.center.x,
y: circle.center.y
}
const radius = circle.radius;
const endPtDistCircle = 3;
let lineSeg = {
startPt: {
x: undefined,
y: undefined
},
endPt: {
x: undefined,
y: undefined
}
}
// 计算lineSeq
// 1. 获取正方形四个点,根据不同情况,判断四点交点,计算起始点
const leftTop = {
x: centerBox.x - bBox.width * 0.5,
y: centerBox.y - bBox.height * 0.5
};
const leftBottom = {
x: centerBox.x - bBox.width * 0.5,
y: centerBox.y + bBox.height * 0.5
};
const rightTop = {
x: centerBox.x + bBox.width * 0.5,
y: centerBox.y - bBox.height * 0.5
};
const rightBottom = {
x: centerBox.x + bBox.width * 0.5,
y: centerBox.y + bBox.height * 0.5
}
// 2. 计算终点
// 2.1 计算两个圆点之间的距离
let distance = this._distance(centerCircle, centerBox);
let diffX = 6 * (centerCircle.x - centerBox.x) / distance;
let diffY = 6 * (centerCircle.y - centerBox.y) / distance;
if (centerBox.x < centerCircle.x && centerBox.y < centerCircle.y) {
// 左上
lineSeg.startPt = this._interSectionPoint(leftBottom, rightBottom, centerBox, centerCircle) || this._interSectionPoint(rightTop, rightBottom, centerBox, centerCircle)
lineSeg.endPt = {
x: centerCircle.x - diffX,
y: centerCircle.y - diffY
}
} else if (centerBox.x < centerCircle.x && centerBox.y > centerCircle.y) {
// 左下
lineSeg.startPt = this._interSectionPoint(leftTop, rightTop, centerBox, centerCircle) || this._interSectionPoint(rightTop, rightBottom, centerBox, centerCircle)
lineSeg.endPt = {
x: centerCircle.x - diffX,
y: centerCircle.y - diffY
}
} else if (centerBox.x > centerCircle.x && centerBox.y < centerCircle.y) {
// 右上
lineSeg.startPt = this._interSectionPoint(leftTop, leftBottom, centerBox, centerCircle) || this._interSectionPoint(leftBottom, rightBottom, centerBox, centerCircle)
lineSeg.endPt = {
x: centerCircle.x - diffX,
y: centerCircle.y - diffY
}
} else if (centerBox.x > centerCircle.x && centerBox.y > centerCircle.y) {
// 右下
lineSeg.startPt = this._interSectionPoint(leftTop, rightTop, centerBox, centerCircle) || this._interSectionPoint(leftBottom, leftTop, centerBox, centerCircle)
lineSeg.endPt = {
x: centerCircle.x - diffX,
y: centerCircle.y - diffY
}
}
return lineSeg;
}
/**
- 直线ab和直线cd的交点坐标
*/
_interSectionPoint(a, b, c, d) {
let denominator = (b.y - a.y) * (d.x - c.x) - (a.x - b.x) * (c.y - d.y);
if (denominator === 0) {