基于d3的鼠标动态绘制矩形和圆
undefined
安装d3依赖 npm i d3
效果
绘制圆
绘制矩形
react实现版
import * as d3 from 'd3'
import React, {useRef, useEffect, useState} from 'react'
const DrawRect = () => {
// CRICLE 圆 RECT 矩形
const type = 'CRICLE'
const svgBase = useRef()
const carrierSvg = useRef()
const isDraw = useRef(true)
const currentId = useRef(0)
const [allId, setAllId] = useState([0])
// [x0,y0,x1,y1]
const [rectCoor, setRectCoor] = useState([0, 0, 0, 0])
const [, setIsDraw] = useState(true)
const [, setCarrierSvg] = useState(null)
useEffect(() => {
const svg = d3.select(svgBase.current)
.append('svg')
.attr('width', '100vw')
.attr('height', '100vh')
carrierSvg.current = svg
setCarrierSvg(svg)
}, [])
const drawRect = (endX, endY, id) => {
const delEl = document.getElementById(id)
if (delEl) {
delEl.remove()
}
carrierSvg.current.append('rect')
.attr('id', id)
.attr('width', Math.abs(endX - rectCoor[0]))
.attr('height', Math.abs(endY - rectCoor[1]))
.attr('x', rectCoor[0] > endX ? endX : rectCoor[0])
.attr('y', rectCoor[1] > endY ? endY : rectCoor[1])
.attr('fill', 'rgba(255,10,10,0.4)')
.attr('stroke', 'rgba(255,10,10,1)')
}
const drawCircle = (endX, endY, id) => {
const delEl = document.getElementById(id)
if (delEl) {
delEl.remove()
}
const xr = Math.abs(endX - rectCoor[0])
const yr = Math.abs(endY - rectCoor[1])
const r = Math.sqrt(xr * xr + yr * yr) / 2
carrierSvg.current.append('circle')
.attr('id', id)
.attr('r', r)
.attr('cx', xr / 2 + endX > rectCoor[0] ? rectCoor[0] : endX)
.attr('cy', yr / 2 + endY > rectCoor[1] ? rectCoor[1] : endY)
.attr('fill', 'rgba(10,255,10,0.4)')
.attr('stroke', 'rgba(10,255,10,1)')
}
useEffect(() => {
// 鼠标按下
svgBase.current.onmousedown = e => {
const x0 = e.offsetX
const y0 = e.offsetY
rectCoor[0] = x0
rectCoor[1] = y0
setRectCoor(rectCoor)
setIsDraw(false)
isDraw.current = false
}
// 鼠标移动
svgBase.current.onmousemove = e => {
const x1 = e.offsetX
const y1 = e.offsetY
if (!isDraw.current) {
if (type === 'RECT') {
drawRect(x1, y1, currentId.current)
}
if (type === 'CRICLE') {
drawCircle(x1, y1, currentId.current)
}
}
}
svgBase.current.onmouseup = e => {
const x1 = e.offsetX
const y1 = e.offsetY
rectCoor[2] = x1
rectCoor[3] = y1
setRectCoor(rectCoor)
if (type === 'RECT') {
drawRect(x1, y1, currentId.current)
}
if (type === 'CRICLE') {
drawCircle(x1, y1, currentId.current)
}
setIsDraw(true)
isDraw.current = true
currentId.current += 1
setAllId(allId.push(currentId.current))
}
}, [])
return <div ref={svgBase} style={{zIndex: 10, position: 'absolute', background: '#fff'}} />
}
export default DrawRect
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具