知识介绍
- 对SVG元素实现拖拽视图的功能
代码分析
- 对于SVG元素的viewBox属性(x, y, w, h),我们设置x,y作为信号量
const [boxLocation, setboxLocation] = createSignal({ x: 0, y: 0 });
- 添加拖拽所需的变量和事件
let isDragging = false;let startX: number;let startY: number;// 鼠标按下事件处理const handleMouseDown = (event) => {isDragging = true;startX = event.clientX + boxLocation().x;startY = event.clientY + boxLocation().y;event.currentTarget.style.cursor = 'grabbing';};// 鼠标拖动事件处理const handleMouseMoveDrag = (event) => {if (isDragging) {setboxLocation({x: -event.clientX + startX,y: -event.clientY + startY});}};// 鼠标松开事件处理const handleMouseUp = (event) => {isDragging = false;event.currentTarget.style.cursor = 'grab';};
这里有一个关键逻辑:
设鼠标按下时当前光标坐标为start,拖动时当前光标坐标为end。
则handleMouseDown时startX = start.x+boxLocation().x;startY = start.y+boxLocation().y。
在handleMouseMoveDrag时,实时设置boxLocation.x为-end.x+startX,boxLocation.y为-end.y+startY,即
实时设置boxLocation.x = -end.x + start.x+boxLocation().x = (拖拽后位置的x坐标 - 初始位置的x坐标) + boxLocation()的x坐标;
实时设置boxLocation.y = -end.y + start.y+boxLocation().y = (拖拽后位置的y坐标 - 初始位置的y坐标) + boxLocation()的y坐标;
当前拖拽方向和SVG内元素移动方向相同
3. 组件挂载
// 组件挂载和卸载时的事件处理createEffect(() => {const svgElement = document.querySelector('.match-svg');svgElement.addEventListener('mousedown', handleMouseDown);svgElement.addEventListener('mousemove', handleMouseMoveDrag);svgElement.addEventListener('mouseup', handleMouseUp);onCleanup(() => {svgElement.addEventListener('mousedown', handleMouseDown);svgElement.addEventListener('mousemove', handleMouseMoveDrag);svgElement.addEventListener('mouseup', handleMouseUp);});});