面试题:React实现鼠标托转文字绕原点旋转

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;

}

版本2.0

================================================================

运行效果:

================================================================

在这里插入图片描述

思路:改进了一些地方,通过两直线相交,将起点改为了与DIV的交点。同时终点距离黄色圆圈有一定距离。

============================================================================================================

方法:

  1. 两直线相交

  2. 相似

React代码:

===================================================================

App.js


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) {

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值