我正在使用與打字稿的反應。我使用 SVG 在其中繪制矩形。我正在研究兩個功能,第一個是我必須在 SVG 內繪制任意數量的形狀,另一個是允許滑鼠拖動選項。現在,問題是當我繪制一個形狀然后在其中繪制另一個形狀時,第一個繪制的形狀正在移動,而新的形狀正在繪制。
我想做的是,如果我單擊并移動形狀,我的繪圖矩形功能將不起作用,并且如果我正在繪制矩形,則已繪制的形狀將不會移動。發生這種情況是因為我對這兩個邏輯都使用了 mouseup 和 mousemove 事件,這就是它們崩潰的原因。我不知道把它們分開。
這是我的代碼:
import "./styles.css";
import React, { useEffect, useRef } from 'react';
interface Iboxes{
id: string,
coordinates:{
x: number
y: number
width: number
height: number
}
}
export default function App() {
const divRef = useRef<HTMLDivElement>(null);
const svgRef = useRef<SVGSVGElement>(null);
const boxes: Array<Iboxes> = [];
useEffect(() => {
const containerSvg = svgRef.current;
let p:DOMPoint;
let w:number;
let h:number;
if(containerSvg){
const svgPoint = (elem:any, x:number, y:number) => {
const point = containerSvg.createSVGPoint();
point.x = x;
point.y = y;
return point.matrixTransform(elem.getScreenCTM().inverse());
};
containerSvg.addEventListener('mousedown', (event) => {
const rect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
const start = svgPoint(containerSvg, event.clientX, event.clientY);
const drawRect = (e:any) => {
p = svgPoint(containerSvg, e.clientX, e.clientY);
w = Math.abs(p.x - start.x);
h = Math.abs(p.y - start.y);
if (p.x > start.x) {
p.x = start.x;
}
if (p.y > start.y) {
p.y = start.y;
}
rect.setAttributeNS(null, 'x', p.x as unknown as string);
rect.setAttributeNS(null, 'y', p.y as unknown as string);
rect.setAttributeNS(null, 'width', w as unknown as string);
rect.setAttributeNS(null, 'height', h as unknown as string);
rect.setAttributeNS(null, 'class', 'svg_rec');
rect.setAttributeNS(null, 'id', 'rec_' boxes.length as unknown as string)
containerSvg.appendChild(rect);
};
const endDraw = (e:any) => {
containerSvg.removeEventListener('mousemove', drawRect);
containerSvg.removeEventListener('mouseup', endDraw);
boxes.push({id:'rec_' boxes.length as unknown as string, coordinates:{x: p.x, y: p.y, width: w, height: h}})
let offset:any;
let selectedRect: SVGRectElement | null;
rect.addEventListener('mousedown', startDrag);
rect.addEventListener('mousemove', drag);
rect.addEventListener('mouseup', endDrag);
rect.addEventListener('mouseleave', endDrag);
function startDrag(evt:any) {
selectedRect = rect;
if(selectedRect){
offset = getMousePosition(evt);
if(offset){
let rectX = selectedRect.getAttributeNS(null, 'x');
let rectY = selectedRect.getAttributeNS(null, 'y');
if(rectX && rectY){
offset.x -= parseFloat(rectX);
offset.y -= parseFloat(rectY);
}
}
}
}
function drag(evt:any) {
if(selectedRect){
var coord = getMousePosition(evt);
if(coord && offset){
let x = coord.x - offset.x;
let y = coord.y - offset.y;
if(x && y){
selectedRect.setAttributeNS(null, "x", x as unknown as string);
selectedRect.setAttributeNS(null, "y", y as unknown as string);
}
}
}
}
function endDrag() {
selectedRect = null;
}
function getMousePosition(evt:any) {
var CTM = rect.getScreenCTM();
if(CTM){
return {
x: (evt.clientX - CTM.e) / CTM.a,
y: (evt.clientY - CTM.f) / CTM.d
};
}
}
};
containerSvg.addEventListener('mousemove', drawRect);
containerSvg.addEventListener('mouseup', endDraw);
});
}
},[]);
return (
<div className="App">
<div className='container' ref={divRef}>
<svg id="svg" ref={svgRef}>
</svg>
</div>
</div>
);
}
我還創建了一個沙箱環??境來演示我的問題:
這是一個沙箱鏈接
uj5u.com熱心網友回復:
你只需要添加
evt.stopPropagation();
到功能startDrag()上線79。
function startDrag(evt: any) {
evt.stopPropagation();
selectedRect = rect;
// ...
}
這是固定沙箱
編輯
因為頂部的其他矩形可能會掩蓋當前拖動的矩形。一種解決方案是pointer-events在拖動一個矩形時禁用其他矩形:
將以下代碼添加到startDrag函式中
containerSvg.classList.add("dragging");
selectedRect?.classList.add("target");
然后將以下代碼添加到endDrag函式中
containerSvg.classList.remove("dragging");
selectedRect?.classList.remove("target");
然后在您的 css 代碼中,添加以下規則:
.dragging rect:not(.target) {
pointer-events: none;
}
檢查更新的沙箱
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/403054.html
標籤:
