| 
					
				 | 
			
			
				@@ -156,30 +156,39 @@ export const useSpeak = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         const showDomRect = showDom.getBoundingClientRect();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 判断 上边超出边界
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (y - parentRect?.top > showDomRect.height + fHeight / 2) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          showDom.style.top =
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              y -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              parentRect?.top -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              (showDomRect.height + fHeight / 2) +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              musicContent?.scrollTop
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ).toFixed(2) + 'px';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          console.log(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            false,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            parentRect?.bottom -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            bottom +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // if (y - parentRect?.top > showDomRect.height + fHeight / 2) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   showDom.style.top =
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     (
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       y -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       parentRect?.top -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       (showDomRect.height + fHeight / 2) +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       musicContent?.scrollTop
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     ).toFixed(2) + 'px';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // } else {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // console.log(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   false,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   parentRect?.bottom -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   bottom +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   (showDomRect.height + fHeight / 2) +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   musicContent?.scrollTop
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // );
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        showDom.style.top =
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            parentRect?.top +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (showDomRect.height + fHeight / 2) +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             musicContent?.scrollTop
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          );
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          showDom.style.top =
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              y -
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              parentRect?.top +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              (showDomRect.height + fHeight / 2) +
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              musicContent?.scrollTop
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ).toFixed(2) + 'px';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ).toFixed(2) + 'px';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // console.log({
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   parentRectWidth: parentRect?.width,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   firstRectLeft: x,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   parentRectLeft: parentRect?.left,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   parentRectStatus:
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //     parentRect?.width - (x - parentRect?.left) > showDomRect.width,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   diff: parentRect?.width - (x - parentRect?.left),
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   showDomRect: showDomRect.width
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // });
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (parentRect?.width - (x - parentRect?.left) > showDomRect.width) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           // 判断是否选择到最右边 超出边界
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           showDom.style.left = (x - parentRect?.left).toFixed(2) + 'px';
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -257,8 +266,11 @@ export const useSpeak = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const textContainer: any = document.querySelector('#musicContent');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const sentences: any = textContainer?.querySelectorAll('label.speak-label');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // console.log(options, '--endIndex');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     let currentSentenceIndex = options.startIndex || 0;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    const end = options.endIndex || sentences.length - 1;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    const end =
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      options.endIndex === undefined ? sentences.length - 1 : options.endIndex;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     // 高亮显示
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const highlightSentence = (index: number) => {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       sentences.forEach((sentence: any, i: number) => {
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -277,6 +289,12 @@ export const useSpeak = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     const speaker = () => {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       try {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         state.synth = window.speechSynthesis;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 获取可用的 voice 列表
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // const voices = speechSynthesis.getVoices();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 选择一个特定的 voice
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // const voice = voices.find(voice => voice.lang === 'zh-CN');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // console.log(voice, 'voice');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 如果当前正在播放,先暂停
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (state.synth.speaking) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           state.synth.cancel(); // 取消当前播放
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -288,29 +306,42 @@ export const useSpeak = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           return;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         // 判断是否为选中的内容播放
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (options.startIndex === options.endIndex) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          options.startIndex === options.endIndex &&
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          options.endIndex !== undefined
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           sentence = sentence.substr(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             options.anchorOffset,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             (options.focusOffset || 0) - (options.anchorOffset || 0)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           );
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           if (options.startIndex === currentSentenceIndex) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            sentence = sentence.substr(
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              options.anchorOffset,
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              sentence.length - 1
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            );
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            sentence = sentence.substr(options.anchorOffset, sentence.length);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           if (options.endIndex === currentSentenceIndex) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             sentence = sentence.substr(0, options.focusOffset);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        const utterance = new SpeechSynthesisUtterance();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const replaceText = ['长笛', '曲'];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const afterReplaceText = ['尝笛', '取'];
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (sentence) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          replaceText.forEach((item: string, index: number) => {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (sentence.includes(item)) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              const regex = new RegExp(item, 'g');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sentence = sentence.replace(regex, afterReplaceText[index]);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          });
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        console.log(sentence, currentSentenceIndex, end, '---------');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        const utterance = new SpeechSynthesisUtterance(sentence);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         utterance.lang = 'zh-CN';
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         utterance.volume = 1;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         utterance.rate = 0.8; // 语速 0.1到10
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         utterance.pitch = 1.5; // 范围从0(最小)到2(最大)
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        utterance.text = sentence;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // utterance.text = sentence;
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         if (utterance) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           utterance.onstart = null;
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -345,7 +376,7 @@ export const useSpeak = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         };
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         setTimeout(() => {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           state.synth.speak(utterance);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }, 100);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }, 80);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } catch (e) {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         console.log(e, 'e');
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       }
 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -387,10 +418,12 @@ export const useSpeak = () => { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   onMounted(async () => {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     document.addEventListener('mouseup', getSelectText);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    document.addEventListener('touchend', getSelectText);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   });
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   onUnmounted(() => {
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     document.removeEventListener('mouseup', getSelectText);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    document.addEventListener('touchend', getSelectText);
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     onCloseSpeak();
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   });
 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 
 
			 |