Forráskód Böngészése

Merge branch 'new-feature-tianyong' into ktyq-online

TIANYONG 1 éve
szülő
commit
605b19694f

+ 98 - 11
src/view/plugins/move-music-score/index.tsx

@@ -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,7 +167,16 @@ export const filterMoveData = async () => {
 		const list = moveData.modelList
 			.filter((n) => n.isMove)
 			.map((n) => {
-				const item: any = {
+				/**
+				 * 找到移动后,此时与此元素距离最近的音符,并记录音符的索引和此元素与音符的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;
+				let item: any = {
 					id: n.id,
 					isMove: n.isMove,
 					isDelete: n.isDelete,
@@ -143,10 +187,18 @@ 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;
 				}
+				if (n.id.includes('text')) {
+					// let copyDom = document.querySelector("#" + n.id)!.cloneNode(true) as SVGSVGElement
+					const textContent = document.querySelector("#" + n.id)?.querySelector("text")?.innerHTML || ''
+					item.textContent = textContent
+				}
 				return item;
 			});
 		// if (!list.length) {
@@ -176,6 +228,7 @@ const dragData = {
 	startY: 0,
 	x: 0,
 	y: 0,
+	repeatEdit: false,
 };
 
 // 记录
@@ -195,6 +248,7 @@ function onDown(e: MouseEvent) {
 		dragData.startY = e.clientY;
 		dragData.x = item.x;
 		dragData.y = item.y;
+		dragData.repeatEdit = item.noteIdx >= 0 ? true : false;
 		// console.log("🚀 ~ 按下", index, el, item.x, item.y);
 		document.onmousemove = onMove;
 		document.onmouseup = onUp;
@@ -213,7 +267,7 @@ function onMove(e: MouseEvent) {
 	if (dragData.open) {
 		const _x = e.clientX - dragData.startX + dragData.x;
 		const _y = e.clientY - dragData.startY + dragData.y;
-		setModelPostion(moveData.modelList[moveData.activeIndex], _x, _y);
+		setModelPostion(moveData.modelList[moveData.activeIndex], _x, _y, dragData.repeatEdit);
 	}
 }
 function onUp(e: MouseEvent) {
@@ -247,23 +301,37 @@ const renderSvgItem = (item: any) => {
 };
 
 /** 设置元素位置 */
-function setModelPostion(item: any, x: number, y: number) {
+async function setModelPostion(item: any, x: number, y: number, repeatEdit?: boolean) {
 	// console.log(item)
+	//console.log('位置',x,y)
 	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 = "");
 		} else {
 			/** 如果是app内嵌打开,需要通过rem转换 */
 			let tsX = x, tsY = y;
-			if (storeData.isApp && (item.xRem || item.yRem)) {
-				tsX = item.xRem * clientWidth/10
-				tsY = item.yRem * clientWidth/10
+			// if (storeData.isApp && (item.xRem || item.yRem)) {
+			// 	tsX = item.xRem * clientWidth/10
+			// 	tsY = item.yRem * clientWidth/10
+			// }
+			if (item.noteIdx >= 0 && !repeatEdit) {
+				if (!moveData.noteCoords.length) {
+					await initNoteCoord()
+				}
+				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)`);
 			}
-			g && g.setAttribute("transform", `translate(${tsX / moveData.zoom}, ${tsY / moveData.zoom})`);
-			el && (el.style.transform = `translate(${tsX}px, ${tsY}px)`);
 		}
 	}
 }
@@ -412,7 +480,25 @@ export const renderForMoveData = () => {
 		nextTick(() => {
 			console.log("🚀 ~ list", list);
 			list.forEach((item: any) => {
-				const index = moveData.modelList.findIndex((n: any) => n.id === item.id);
+				let index = moveData.modelList.findIndex((n: any) => n.id === item.id);
+				if (item.type === 'vf-text' && item.textContent) {
+					let textValue = document.querySelector("#" + moveData.modelList[index].id)?.querySelector("text")?.innerHTML || ''
+					let targetIndex = index, preEnd = false;
+					while (textValue !== item.textContent) {
+						if (preEnd) {
+							targetIndex = targetIndex + 1
+						} else {
+							targetIndex = targetIndex > 0 ? targetIndex - 1 : targetIndex
+						}
+						if (targetIndex == 0) preEnd = true
+						textValue = document.querySelector("#" + moveData.modelList[targetIndex].id)?.querySelector("text")?.innerHTML || ''
+					}
+					// index = targetIndex + 1
+					// item.id = `text${index}`
+					index = targetIndex
+					item.id = `text${targetIndex+1}`
+				}
+				console.log(66666666,index)
 				if (index > -1) {
 					moveData.modelList[index] = {
 						...moveData.modelList[index],
@@ -439,6 +525,7 @@ export default defineComponent({
 			// 	initSvgId();
 			// }
 			// renderForMoveData();
+			nextTick(() => initNoteCoord())
 			const toolBox = document.getElementById("toolBox");
 			toolBox && document.body.appendChild(toolBox);
 		});

+ 11 - 0
src/view/selection/index.module.less

@@ -13,6 +13,7 @@
 
 .note {
     cursor: pointer;
+    // background: rgba(0,0,0,0.3);
 }
 
 
@@ -243,4 +244,14 @@
         min-height: 94Px;
         transform: translateX(8.5Px,-50%);
     } 
+}
+
+.noteDot {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    transform: translate(-50%);
+    width: 2px;
+    height: 2px;
+    // background: #07c160;
 }

+ 3 - 2
src/view/selection/index.tsx

@@ -1,4 +1,4 @@
-import { computed, defineComponent, onMounted, reactive, Transition } from "vue";
+import { computed, defineComponent, onMounted, reactive, Transition, nextTick } from "vue";
 import state, { EnumMusicRenderType, handleSelection, skipNotePlay, IPlatform } from "/src/state";
 import styles from "./index.module.less";
 import { metronomeData } from "/src/helpers/metronome";
@@ -211,7 +211,7 @@ export default defineComponent({
 			// 初始化谱面可移动的元素位置
 			try {
 			moveData.partIndex = query['part-index'] as string || '0'
-			renderForMoveData()
+			nextTick(() => renderForMoveData())
 			} catch (error) {}
 		});
 		return () => (
@@ -299,6 +299,7 @@ export default defineComponent({
 								<Icon name="success" />
 								<Icon name="cross" />
 							</div>
+							<div class={[styles.noteDot, 'node-dot']}></div>
 						</div>
 					);
 				})}

+ 72 - 72
vite.config.ts

@@ -7,77 +7,77 @@ import postCssPxToRem from "postcss-pxtorem";
 
 // https://vitejs.dev/config/
 export default defineConfig({
-  base: "./",
-  resolve: {},
-  plugins: [
-    // mkcert(), // 本地https
-    legacy({
-      targets: ["Chrome 63"],
-      additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
-      modernPolyfills: true,
-    }),
-    vue(),
-    vueJsx(),
-  ],
-  css: {
-    postcss: {
-      plugins: [
-        postCssPxToRem({
-          rootValue: 37.5,
-          propList: ["*"],
-          selectorBlackList: [".norem"],
-        }),
-      ],
-    },
-  },
-  build: {
-    rollupOptions: {
-      input: {
-        gym: resolve(__dirname, "index.html"),
-        colexiu: resolve(__dirname, "colexiu.html"),
-        orchestra: resolve(__dirname, "orchestra.html"),
-        "report-share": resolve(__dirname, "report-share.html"),
-        instrument: resolve(__dirname, "instrument.html"),
-      },
-    },
-  },
-  server: {
-    cors: true,
-    port: 3000,
-    // https: true,
-    proxy: {
-      "^/gym/.*": {
-        target: "https://mstutest.dayaedu.com",
-        // target: "https://online.dayaedu.com",
-        changeOrigin: true,
-        rewrite: (path) => path.replace(/^\/gym/, ""),
-      },
-      "^/colexiu/.*": {
-        target: "https://dev.colexiu.com",
-        // target: "https://online.colexiu.com",
-        changeOrigin: true,
-        rewrite: (path) => path.replace(/^\/colexiu/, ""),
-      },
-      "^/orchestra/.*": {
-        target: "https://test.lexiaoya.cn",
-        changeOrigin: true,
-        rewrite: (path) => path.replace(/^\/orchestra/, ""),
-      },
-      "^/instrument/.*": {
-        // target: "https://kt.colexiu.com",
-        // target: "https://test.lexiaoya.cn",
-        // target: "https://dev.kt.colexiu.com",
-        // target: "https://test.resource.colexiu.com", // 内容平台开发环境,内容平台开发,需在url链接上加上isCbs=true
-        // target: "https://test.resource.colexiu.com",
-        target: "https://test.kt.colexiu.com",
-        changeOrigin: true,
-        rewrite: (path) => path.replace(/^\/instrument/, ""),
-      },
-    },
-  },
-  preview: {
-    port: 3000,
-    host: "192.168.3.114",
-  },
+	base: "./",
+	resolve: {},
+	plugins: [
+		// mkcert(), // 本地https
+		legacy({
+			targets: ['Chrome 63'],
+			additionalLegacyPolyfills: ['regenerator-runtime/runtime'],
+			modernPolyfills: true
+		  }),
+		vue(),
+		vueJsx(),
+	],
+	css: {
+		postcss: {
+			plugins: [
+				postCssPxToRem({
+					rootValue: 37.5,
+					propList: ["*"],
+					selectorBlackList: [".norem"],
+				}),
+			],
+		},
+	},
+	build: {
+		rollupOptions: {
+			input: {
+				gym: resolve(__dirname, "index.html"),
+				colexiu: resolve(__dirname, "colexiu.html"),
+				orchestra: resolve(__dirname, "orchestra.html"),
+				"report-share": resolve(__dirname, "report-share.html"),
+				instrument: resolve(__dirname, "instrument.html"),
+			},
+		},
+	},
+	server: {
+		cors: true,
+		port: 3000,
+		// https: true,
+		proxy: {
+			"^/gym/.*": {
+				target: "https://mstutest.dayaedu.com",
+				// target: "https://online.dayaedu.com",
+				changeOrigin: true,
+				rewrite: (path) => path.replace(/^\/gym/, ""),
+			},
+			"^/colexiu/.*": {
+				target: "https://dev.colexiu.com",
+				// target: "https://online.colexiu.com",
+				changeOrigin: true,
+				rewrite: (path) => path.replace(/^\/colexiu/, ""),
+			},
+			"^/orchestra/.*": {
+				target: "https://test.lexiaoya.cn",
+				changeOrigin: true,
+				rewrite: (path) => path.replace(/^\/orchestra/, ""),
+			},
+			"^/instrument/.*": {
+				// target: "https://kt.colexiu.com",
+				// target: "https://test.lexiaoya.cn",
+				// target: "https://dev.kt.colexiu.com",
+				// target: "https://test.resource.colexiu.com", // 内容平台开发环境,内容平台开发,需在url链接上加上isCbs=true
+				target: "https://test.resource.colexiu.com",
+				// target: "https://test.kt.colexiu.com",
+				changeOrigin: true,
+				rewrite: (path) => path.replace(/^\/instrument/, ""),
+			},
+		},
+	},
+	preview:{
+		port: 3000,
+		host: '192.168.3.114'
+	}
 });
 // vite.config.js