|
@@ -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);
|
|
|
});
|