|  | @@ -28,8 +28,43 @@ export const moveData = reactive({
 | 
	
		
			
				|  |  |  	tool: {
 | 
	
		
			
				|  |  |  		isAddAndSub: false,
 | 
	
		
			
				|  |  |  	},
 | 
	
		
			
				|  |  | +	noteCoords: [] as any[],
 | 
	
		
			
				|  |  |  });
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +// 所以可点击音符的dom坐标集合
 | 
	
		
			
				|  |  | +const initNoteCoord = () => {
 | 
	
		
			
				|  |  | +	const allNoteDot: any = Array.from(document.querySelectorAll('.node-dot'));
 | 
	
		
			
				|  |  | + 	moveData.noteCoords = allNoteDot.map((note: any) => {
 | 
	
		
			
				|  |  | +		const note_bbox = note?.getBoundingClientRect?.() || { x: 0, y: 0 };
 | 
	
		
			
				|  |  | +		return {
 | 
	
		
			
				|  |  | +			x: note_bbox.x,
 | 
	
		
			
				|  |  | +			y: note_bbox.y
 | 
	
		
			
				|  |  | +		}
 | 
	
		
			
				|  |  | +	})
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 找出离目标元素最近的音符
 | 
	
		
			
				|  |  | +const computedDistance = (x: number, y: number) => {
 | 
	
		
			
				|  |  | +    let minDistance = -1, minidx = 0;
 | 
	
		
			
				|  |  | +    let a, b, c;
 | 
	
		
			
				|  |  | +	moveData.noteCoords.forEach((note: any, idx: any) => {
 | 
	
		
			
				|  |  | +		//a,b为直角三角形的两个直角边
 | 
	
		
			
				|  |  | +		a = Math.abs(note.x - x)
 | 
	
		
			
				|  |  | +		b = Math.abs(note.y - y)
 | 
	
		
			
				|  |  | +		//c为直角三角形的斜边
 | 
	
		
			
				|  |  | +		c = Math.sqrt(a * a + b * b) as 0
 | 
	
		
			
				|  |  | +		c = Number(c.toFixed(0)) as 0
 | 
	
		
			
				|  |  | +		if (c !== 0 && (minDistance === - 1 || c < minDistance)) {
 | 
	
		
			
				|  |  | +			//min为元素中离目标元素最近元素的距离
 | 
	
		
			
				|  |  | +			minDistance = c
 | 
	
		
			
				|  |  | +			minidx = idx
 | 
	
		
			
				|  |  | +		}		
 | 
	
		
			
				|  |  | +	})
 | 
	
		
			
				|  |  | +    return minidx
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  function initSvgId() {
 | 
	
		
			
				|  |  |  	const svg = document.querySelector("#osmdSvgPage1");
 | 
	
		
			
				|  |  |  	if (!svg) return;
 | 
	
	
		
			
				|  | @@ -132,6 +167,15 @@ export const filterMoveData = async () => {
 | 
	
		
			
				|  |  |  		const list = moveData.modelList
 | 
	
		
			
				|  |  |  			.filter((n) => n.isMove)
 | 
	
		
			
				|  |  |  			.map((n) => {
 | 
	
		
			
				|  |  | +				/**
 | 
	
		
			
				|  |  | +				 * 找到移动后,此时与此元素距离最近的音符,并记录音符的索引和此元素与音符的x轴,y轴的间距
 | 
	
		
			
				|  |  | +				*/
 | 
	
		
			
				|  |  | +				// 元素的位置
 | 
	
		
			
				|  |  | +				const elementX = n.left + n.x, elementY = n.top + n.y;
 | 
	
		
			
				|  |  | +				// 找出距离元素最近的音符
 | 
	
		
			
				|  |  | +				const noteIdx = computedDistance(elementX, elementY);
 | 
	
		
			
				|  |  | +				// 此元素距离最近音符的x轴,y轴距离
 | 
	
		
			
				|  |  | +				const noteRelativeX = elementX - moveData.noteCoords[noteIdx]?.x, noteRelativeY = elementY - moveData.noteCoords[noteIdx]?.y;
 | 
	
		
			
				|  |  |  				const item: any = {
 | 
	
		
			
				|  |  |  					id: n.id,
 | 
	
		
			
				|  |  |  					isMove: n.isMove,
 | 
	
	
		
			
				|  | @@ -143,6 +187,9 @@ export const filterMoveData = async () => {
 | 
	
		
			
				|  |  |  					zoom: n.zoom,
 | 
	
		
			
				|  |  |  					w: moveData.sw,
 | 
	
		
			
				|  |  |  					type: n.type,
 | 
	
		
			
				|  |  | +					noteIdx,
 | 
	
		
			
				|  |  | +					noteRelativeX,
 | 
	
		
			
				|  |  | +					noteRelativeY
 | 
	
		
			
				|  |  |  				};
 | 
	
		
			
				|  |  |  				if (n.type === "vf-lineGroup") {
 | 
	
		
			
				|  |  |  					item.dx = n.dx;
 | 
	
	
		
			
				|  | @@ -250,8 +297,8 @@ const renderSvgItem = (item: any) => {
 | 
	
		
			
				|  |  |  function setModelPostion(item: any, x: number, y: number) {
 | 
	
		
			
				|  |  |  	// console.log(item)
 | 
	
		
			
				|  |  |  	if (item) {
 | 
	
		
			
				|  |  | -		const g = document.querySelector("#" + item.id)!;
 | 
	
		
			
				|  |  | -		const el: HTMLElement = document.querySelector(`[data-id=${item.id}]`)!;
 | 
	
		
			
				|  |  | +		const g = document.querySelector("#" + item.id)!; // svg元素
 | 
	
		
			
				|  |  | +		const el: HTMLElement = document.querySelector(`[data-id=${item.id}]`)!; // svg元素的背景div
 | 
	
		
			
				|  |  |  		if (x === 0 && y === 0) {
 | 
	
		
			
				|  |  |  			g && g.removeAttribute("transform");
 | 
	
		
			
				|  |  |  			el && (el.style.transform = "");
 | 
	
	
		
			
				|  | @@ -262,8 +309,18 @@ function setModelPostion(item: any, x: number, y: number) {
 | 
	
		
			
				|  |  |  			// 	tsX = item.xRem * clientWidth/10
 | 
	
		
			
				|  |  |  			// 	tsY = item.yRem * clientWidth/10
 | 
	
		
			
				|  |  |  			// }
 | 
	
		
			
				|  |  | -			g && g.setAttribute("transform", `translate(${tsX / moveData.zoom}, ${tsY / moveData.zoom})`);
 | 
	
		
			
				|  |  | -			el && (el.style.transform = `translate(${tsX}px, ${tsY}px)`);
 | 
	
		
			
				|  |  | +			if (item.noteIdx >= 0) {
 | 
	
		
			
				|  |  | +				const targetX = moveData.noteCoords[item.noteIdx].x + item.noteRelativeX, targetY = moveData.noteCoords[item.noteIdx].y + item.noteRelativeY;
 | 
	
		
			
				|  |  | +				const original = document.getElementById(item.id)?.getBoundingClientRect() || { x: 0, y: 0 };
 | 
	
		
			
				|  |  | +				tsX = targetX - original.x;
 | 
	
		
			
				|  |  | +				tsY = targetY - original.y;
 | 
	
		
			
				|  |  | +				console.log('距离',tsX,tsY,x,y)
 | 
	
		
			
				|  |  | +				g && g.setAttribute("transform", `translate(${tsX / moveData.zoom}, ${tsY / moveData.zoom})`);
 | 
	
		
			
				|  |  | +				el && (el.style.transform = `translate(${tsX}px, ${tsY}px)`);
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				g && g.setAttribute("transform", `translate(${tsX / moveData.zoom}, ${tsY / moveData.zoom})`);
 | 
	
		
			
				|  |  | +				el && (el.style.transform = `translate(${tsX}px, ${tsY}px)`);
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
	
		
			
				|  | @@ -439,6 +496,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |  			// 	initSvgId();
 | 
	
		
			
				|  |  |  			// }
 | 
	
		
			
				|  |  |  			// renderForMoveData();
 | 
	
		
			
				|  |  | +			nextTick(() => initNoteCoord())
 | 
	
		
			
				|  |  |  			const toolBox = document.getElementById("toolBox");
 | 
	
		
			
				|  |  |  			toolBox && document.body.appendChild(toolBox);
 | 
	
		
			
				|  |  |  		});
 |