Highlighter with TTS and Lasso Tool

Highlight text and read using TTS with options for voice and speed.

  1. // ==UserScript==
  2. // @name Highlighter with TTS and Lasso Tool
  3. // @namespace http://tampermonkey.net/
  4. // @version 0.1
  5. // @description Highlight text and read using TTS with options for voice and speed.
  6. // @match *://*/*
  7. // @grant none
  8. // ==/UserScript==
  9.  
  10. (function() {
  11. 'use strict';
  12.  
  13. // Create GUI
  14. let gui = document.createElement('div');
  15. gui.style.position = 'fixed';
  16. gui.style.top = '20px';
  17. gui.style.left = '20px';
  18. gui.style.width = '300px';
  19. gui.style.height = '200px';
  20. gui.style.background = 'gray';
  21. gui.style.borderRadius = '10px';
  22. gui.style.boxShadow = '2px 2px 10px rgba(0, 0, 0, 0.5)';
  23. gui.innerHTML = `
  24. <div style="background-color: #ccc; padding: 10px; border-radius: 10px 10px 0 0;">
  25. <span style="font-size: 18px;">Highlighter</span>
  26. </div>
  27. <div style="padding: 10px;">
  28. <button id="lassoButton">Select Text</button>
  29. <br><br>
  30. <button id="readButton">Read</button>
  31. <br><br>
  32. <label for="voiceSelect">Voice: </label>
  33. <select id="voiceSelect"></select>
  34. <br><br>
  35. <label for="speedRange">Speed: </label>
  36. <input type="range" id="speedRange" min="0.5" max="2" step="0.1" value="1">
  37. </div>
  38. `;
  39. document.body.appendChild(gui);
  40.  
  41. // Drag functionality
  42. gui.onmousedown = function(e) {
  43. let shiftX = e.clientX - gui.getBoundingClientRect().left;
  44. let shiftY = e.clientY - gui.getBoundingClientRect().top;
  45.  
  46. function moveAt(pageX, pageY) {
  47. gui.style.left = pageX - shiftX + 'px';
  48. gui.style.top = pageY - shiftY + 'px';
  49. }
  50.  
  51. function onMouseMove(e) {
  52. moveAt(e.pageX, e.pageY);
  53. }
  54.  
  55. document.addEventListener('mousemove', onMouseMove);
  56.  
  57. gui.onmouseup = function() {
  58. document.removeEventListener('mousemove', onMouseMove);
  59. gui.onmouseup = null;
  60. };
  61. };
  62.  
  63. gui.ontouchstart = function(e) {
  64. let shiftX = e.touches[0].clientX - gui.getBoundingClientRect().left;
  65. let shiftY = e.touches[0].clientY - gui.getBoundingClientRect().top;
  66.  
  67. function moveAt(pageX, pageY) {
  68. gui.style.left = pageX - shiftX + 'px';
  69. gui.style.top = pageY - shiftY + 'px';
  70. }
  71.  
  72. function onTouchMove(e) {
  73. moveAt(e.touches[0].pageX, e.touches[0].pageY);
  74. }
  75.  
  76. document.addEventListener('touchmove', onTouchMove);
  77.  
  78. gui.ontouchend = function() {
  79. document.removeEventListener('touchmove', onTouchMove);
  80. gui.ontouchend = null;
  81. };
  82. };
  83.  
  84. // Disable text selection while dragging
  85. gui.ondragstart = function() {
  86. return false;
  87. };
  88.  
  89. // TTS setup
  90. let synth = window.speechSynthesis;
  91. let voices = [];
  92.  
  93. function populateVoiceList() {
  94. voices = synth.getVoices();
  95. let voiceSelect = document.getElementById('voiceSelect');
  96. voiceSelect.innerHTML = '';
  97. voices.forEach((voice, index) => {
  98. let option = document.createElement('option');
  99. option.textContent = voice.name + ' (' + voice.lang + ')';
  100. option.value = index;
  101. voiceSelect.appendChild(option);
  102. });
  103. }
  104.  
  105. populateVoiceList();
  106. if (speechSynthesis.onvoiceschanged !== undefined) {
  107. speechSynthesis.onvoiceschanged = populateVoiceList;
  108. }
  109.  
  110. // Lasso tool to select text
  111. let selectedText = '';
  112. document.getElementById('lassoButton').addEventListener('click', () => {
  113. document.body.style.cursor = 'crosshair';
  114. document.onmouseup = function() {
  115. selectedText = window.getSelection().toString();
  116. document.body.style.cursor = 'default';
  117. document.onmouseup = null;
  118. };
  119. });
  120.  
  121. // Read selected text using TTS
  122. document.getElementById('readButton').addEventListener('click', () => {
  123. if (selectedText) {
  124. let utterThis = new SpeechSynthesisUtterance(selectedText);
  125. utterThis.voice = voices[document.getElementById('voiceSelect').value];
  126. utterThis.rate = document.getElementById('speedRange').value;
  127. synth.speak(utterThis);
  128. } else {
  129. alert('Please select text first.');
  130. }
  131. });
  132. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址