diff --git a/pdf提词器/index.html b/pdf提词器/index.html
deleted file mode 100644
index ebbcc69..0000000
--- a/pdf提词器/index.html
+++ /dev/null
@@ -1,88 +0,0 @@
-
-
-
-
-
- PDF提词器
-
-
-
-
-
- PDF提词器
- 上传PDF文件,自动生成镜像提词效果
-
-
-
-
-
-
点击或拖拽PDF文件到此处
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 2
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/pdf提词器/script.js b/pdf提词器/script.js
deleted file mode 100644
index c81e4c9..0000000
--- a/pdf提词器/script.js
+++ /dev/null
@@ -1,408 +0,0 @@
-class PDFTeleprompter {
- constructor() {
- this.pdfDoc = null;
- this.pages = [];
- this.isPlaying = false;
- this.animationId = null;
- this.scrollPosition = 0;
- this.scrollSpeed = 2;
-
- this.initializeElements();
- this.bindEvents();
- }
-
- initializeElements() {
- this.uploadArea = document.getElementById('uploadArea');
- this.fileInput = document.getElementById('fileInput');
- this.controls = document.getElementById('controls');
- this.displayArea = document.getElementById('displayArea');
- this.teleprompterContent = document.getElementById('teleprompterContent');
- this.loading = document.getElementById('loading');
- this.speedSlider = document.getElementById('speedSlider');
- this.speedValue = document.getElementById('speedValue');
- this.playBtn = document.getElementById('playBtn');
- this.pauseBtn = document.getElementById('pauseBtn');
- this.resetBtn = document.getElementById('resetBtn');
- this.fullscreenBtn = document.getElementById('fullscreenBtn');
-
- // 悬浮控制面板元素
- this.floatingControls = document.getElementById('floatingControls');
- this.floatPlayBtn = document.getElementById('floatPlayBtn');
- this.floatResetBtn = document.getElementById('floatResetBtn');
- this.floatExitBtn = document.getElementById('floatExitBtn');
- this.floatSpeedSlider = document.getElementById('floatSpeedSlider');
- this.floatSpeedValue = document.getElementById('floatSpeedValue');
-
- // 滚动容器
- this.teleprompterContainer = document.querySelector('.teleprompter-container');
- }
-
- bindEvents() {
- this.uploadArea.addEventListener('click', () => this.fileInput.click());
- this.fileInput.addEventListener('change', (e) => this.handleFileUpload(e));
- this.uploadArea.addEventListener('dragover', (e) => this.handleDragOver(e));
- this.uploadArea.addEventListener('drop', (e) => this.handleDrop(e));
-
- this.speedSlider.addEventListener('input', (e) => {
- this.scrollSpeed = parseFloat(e.target.value);
- this.speedValue.textContent = this.scrollSpeed;
- if (this.floatSpeedSlider) {
- this.floatSpeedSlider.value = this.scrollSpeed;
- this.floatSpeedValue.textContent = this.scrollSpeed;
- }
- });
-
- this.playBtn.addEventListener('click', () => this.play());
- this.pauseBtn.addEventListener('click', () => this.pause());
- this.resetBtn.addEventListener('click', () => this.reset());
- this.fullscreenBtn.addEventListener('click', () => this.toggleFullscreen());
-
- // 悬浮控制面板事件
- if (this.floatPlayBtn) {
- this.floatPlayBtn.addEventListener('click', () => this.togglePlayPause());
- this.floatResetBtn.addEventListener('click', () => this.reset());
- this.floatExitBtn.addEventListener('click', () => this.exitFullscreen());
-
- this.floatSpeedSlider.addEventListener('input', (e) => {
- this.scrollSpeed = parseFloat(e.target.value);
- this.floatSpeedValue.textContent = this.scrollSpeed;
- this.speedSlider.value = this.scrollSpeed;
- this.speedValue.textContent = this.scrollSpeed;
- });
- }
-
- // 全屏状态变化监听
- ['fullscreenchange', 'webkitfullscreenchange', 'mozfullscreenchange', 'MSFullscreenChange'].forEach(event => {
- document.addEventListener(event, () => this.handleFullscreenChange());
- });
-
- // 手动滚动监听
- this.teleprompterContainer.addEventListener('scroll', () => {
- if (!this.isPlaying) {
- this.scrollPosition = this.teleprompterContainer.scrollTop;
- }
- });
-
- // 防止滚动时自动播放
- this.teleprompterContainer.addEventListener('mousedown', () => {
- if (this.isPlaying) {
- this.pause();
- }
- });
-
- // 键盘快捷键
- document.addEventListener('keydown', (e) => {
- if (e.key === ' ' || e.key === 'Spacebar') {
- e.preventDefault();
- this.togglePlayPause();
- } else if (e.key === 'f' || e.key === 'F') {
- e.preventDefault();
- this.toggleFullscreen();
- } else if (e.key === 'Escape') {
- if (document.fullscreenElement) {
- this.exitFullscreen();
- }
- }
- });
-
- // 触摸手势支持
- let touchStartY = 0;
- this.teleprompterContainer.addEventListener('touchstart', (e) => {
- touchStartY = e.touches[0].clientY;
- if (this.isPlaying) {
- this.pause();
- }
- });
-
- this.teleprompterContainer.addEventListener('touchmove', (e) => {
- e.preventDefault();
- const touchY = e.touches[0].clientY;
- const deltaY = touchStartY - touchY;
- this.teleprompterContainer.scrollTop += deltaY;
- touchStartY = touchY;
- this.scrollPosition = this.teleprompterContainer.scrollTop;
- });
- }
-
- async handleFileUpload(event) {
- const file = event.target.files[0];
- if (file && file.type === 'application/pdf') {
- await this.processPDF(file);
- }
- }
-
- async processPDF(file) {
- this.showLoading(true);
-
- try {
- const arrayBuffer = await file.arrayBuffer();
- this.pdfDoc = await pdfjsLib.getDocument({ data: arrayBuffer }).promise;
-
- await this.renderAllPages();
- this.showControls();
-
- } catch (error) {
- console.error('Error processing PDF:', error);
- alert('处理PDF文件时出错,请重试');
- } finally {
- this.showLoading(false);
- }
- }
-
- async renderAllPages() {
- this.pages = [];
- this.teleprompterContent.innerHTML = '';
-
- const totalPages = this.pdfDoc.numPages;
-
- for (let pageNum = 1; pageNum <= totalPages; pageNum++) {
- const page = await this.pdfDoc.getPage(pageNum);
- const canvas = await this.renderPageToCanvas(page);
-
- const img = document.createElement('img');
- img.src = canvas.toDataURL('image/png');
- img.style.width = '100%';
- img.style.height = 'auto';
- img.style.marginBottom = '20px';
-
- this.teleprompterContent.appendChild(img);
- this.pages.push(img);
- }
- }
-
- async renderPageToCanvas(page) {
- const viewport = page.getViewport({ scale: 1.5 });
- const canvas = document.createElement('canvas');
- const context = canvas.getContext('2d');
-
- canvas.width = viewport.width;
- canvas.height = viewport.height;
-
- const renderContext = {
- canvasContext: context,
- viewport: viewport
- };
-
- await page.render(renderContext).promise;
- return canvas;
- }
-
- showLoading(show) {
- this.loading.style.display = show ? 'block' : 'none';
- }
-
- showControls() {
- this.uploadArea.parentElement.style.display = 'none';
- this.controls.style.display = 'flex';
- this.displayArea.style.display = 'block';
- }
-
- play() {
- if (!this.isPlaying) {
- this.isPlaying = true;
- this.playBtn.disabled = true;
- this.pauseBtn.disabled = false;
- this.animateScroll();
- }
- }
-
- pause() {
- this.isPlaying = false;
- this.playBtn.disabled = false;
- this.pauseBtn.disabled = true;
- if (this.animationId) {
- cancelAnimationFrame(this.animationId);
- }
- }
-
- reset() {
- this.pause();
- this.scrollPosition = 0;
- this.teleprompterContainer.scrollTop = 0;
- }
-
- animateScroll() {
- if (!this.isPlaying) return;
-
- const contentHeight = this.teleprompterContent.scrollHeight;
- const containerHeight = this.teleprompterContainer.offsetHeight;
-
- this.scrollPosition += this.scrollSpeed;
-
- if (this.scrollPosition > contentHeight) {
- this.scrollPosition = 0;
- }
-
- this.teleprompterContainer.scrollTop = this.scrollPosition;
-
- this.animationId = requestAnimationFrame(() => this.animateScroll());
- }
-
- toggleFullscreen() {
- if (!document.fullscreenElement) {
- this.enterFullscreen();
- } else {
- this.exitFullscreen();
- }
- }
-
- enterFullscreen() {
- const element = this.displayArea;
-
- if (element.requestFullscreen) {
- element.requestFullscreen();
- } else if (element.webkitRequestFullscreen) {
- element.webkitRequestFullscreen();
- } else if (element.msRequestFullscreen) {
- element.msRequestFullscreen();
- } else if (element.mozRequestFullScreen) {
- element.mozRequestFullScreen();
- }
- }
-
- exitFullscreen() {
- if (document.exitFullscreen) {
- document.exitFullscreen();
- } else if (document.webkitExitFullscreen) {
- document.webkitExitFullscreen();
- } else if (document.msExitFullscreen) {
- document.msExitFullscreen();
- } else if (document.mozCancelFullScreen) {
- document.mozCancelFullScreen();
- }
- }
-
- handleFullscreenChange() {
- const isFullscreen = !!(
- document.fullscreenElement ||
- document.webkitFullscreenElement ||
- document.mozFullScreenElement ||
- document.msFullscreenElement
- );
-
- if (isFullscreen) {
- this.displayArea.classList.add('fullscreen');
- document.body.classList.add('fullscreen');
- this.floatingControls.style.display = 'flex';
- this.fullscreenBtn.innerHTML = `
-
- 退出全屏
- `;
- } else {
- this.displayArea.classList.remove('fullscreen');
- document.body.classList.remove('fullscreen');
- this.floatingControls.style.display = 'none';
- this.fullscreenBtn.innerHTML = `
-
- 全屏
- `;
- }
- }
-
- togglePlayPause() {
- if (this.isPlaying) {
- this.pause();
- this.updatePlayButtons(false);
- } else {
- this.play();
- this.updatePlayButtons(true);
- }
- }
-
- updatePlayButtons(isPlaying) {
- const playIcon = `
-
- `;
- const pauseIcon = `
-
- `;
-
- if (isPlaying) {
- this.floatPlayBtn.innerHTML = pauseIcon;
- } else {
- this.floatPlayBtn.innerHTML = playIcon;
- }
- }
-
- play() {
- if (!this.isPlaying) {
- this.isPlaying = true;
- this.playBtn.disabled = true;
- this.pauseBtn.disabled = false;
- this.updatePlayButtons(true);
- this.animateScroll();
- }
- }
-
- pause() {
- this.isPlaying = false;
- this.playBtn.disabled = false;
- this.pauseBtn.disabled = true;
- this.updatePlayButtons(false);
- if (this.animationId) {
- cancelAnimationFrame(this.animationId);
- }
- }
-
- // 键盘快捷键
- setupKeyboardShortcuts() {
- document.addEventListener('keydown', (e) => {
- switch(e.code) {
- case 'Space':
- e.preventDefault();
- if (this.isPlaying) {
- this.pause();
- } else {
- this.play();
- }
- break;
- case 'KeyR':
- if (e.ctrlKey || e.metaKey) {
- e.preventDefault();
- this.reset();
- }
- break;
- }
- });
- }
-}
-
-// 初始化应用
-document.addEventListener('DOMContentLoaded', () => {
- const teleprompter = new PDFTeleprompter();
- teleprompter.setupKeyboardShortcuts();
-});
-
-// 添加触摸手势支持
-let touchStartY = 0;
-document.addEventListener('touchstart', (e) => {
- touchStartY = e.touches[0].clientY;
-});
-
-document.addEventListener('touchend', (e) => {
- const touchEndY = e.changedTouches[0].clientY;
- const diff = touchStartY - touchEndY;
-
- if (Math.abs(diff) > 50) {
- // 滑动控制滚动速度
- const speedSlider = document.getElementById('speedSlider');
- const currentSpeed = parseInt(speedSlider.value);
-
- if (diff > 0 && currentSpeed < 10) {
- speedSlider.value = currentSpeed + 1;
- } else if (diff < 0 && currentSpeed > 1) {
- speedSlider.value = currentSpeed - 1;
- }
-
- speedSlider.dispatchEvent(new Event('input'));
- }
-});
\ No newline at end of file
diff --git a/pdf提词器/styles.css b/pdf提词器/styles.css
deleted file mode 100644
index 7a3fb7e..0000000
--- a/pdf提词器/styles.css
+++ /dev/null
@@ -1,407 +0,0 @@
-* {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
-}
-
-body {
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
- min-height: 100vh;
- color: #333;
-}
-
-.container {
- max-width: 1200px;
- margin: 0 auto;
- padding: 20px;
-}
-
-header {
- text-align: center;
- margin-bottom: 40px;
- color: white;
-}
-
-h1 {
- font-size: 2.5rem;
- margin-bottom: 10px;
- font-weight: 300;
-}
-
-.subtitle {
- font-size: 1.1rem;
- opacity: 0.9;
-}
-
-.upload-section {
- margin-bottom: 30px;
-}
-
-.upload-area {
- border: 2px dashed rgba(255, 255, 255, 0.5);
- border-radius: 15px;
- padding: 60px 20px;
- text-align: center;
- cursor: pointer;
- transition: all 0.3s ease;
- background: rgba(255, 255, 255, 0.1);
- backdrop-filter: blur(10px);
-}
-
-.upload-area:hover {
- border-color: rgba(255, 255, 255, 0.8);
- background: rgba(255, 255, 255, 0.2);
- transform: translateY(-2px);
-}
-
-.upload-area.dragover {
- border-color: white;
- background: rgba(255, 255, 255, 0.3);
- transform: scale(1.02);
-}
-
-.upload-icon {
- width: 60px;
- height: 60px;
- color: white;
- margin-bottom: 15px;
-}
-
-.upload-text {
- color: white;
- font-size: 1.2rem;
- font-weight: 300;
-}
-
-.controls {
- background: white;
- border-radius: 15px;
- padding: 30px;
- margin-bottom: 30px;
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
- display: flex;
- align-items: center;
- justify-content: space-between;
- flex-wrap: wrap;
- gap: 20px;
-}
-
-.control-group {
- display: flex;
- align-items: center;
- gap: 15px;
-}
-
-.control-group label {
- font-weight: 500;
- color: #555;
-}
-
-input[type="range"] {
- width: 150px;
- height: 6px;
- border-radius: 3px;
- background: #ddd;
- outline: none;
- -webkit-appearance: none;
-}
-
-input[type="range"]::-webkit-slider-thumb {
- -webkit-appearance: none;
- width: 18px;
- height: 18px;
- border-radius: 50%;
- background: #667eea;
- cursor: pointer;
-}
-
-#speedValue {
- font-weight: bold;
- color: #667eea;
- min-width: 20px;
-}
-
-.btn {
- padding: 12px 24px;
- border: none;
- border-radius: 8px;
- font-size: 1rem;
- cursor: pointer;
- transition: all 0.3s ease;
- font-weight: 500;
-}
-
-.btn.primary {
- background: #667eea;
- color: white;
-}
-
-.btn.primary:hover {
- background: #5a6fd8;
- transform: translateY(-1px);
-}
-
-.btn.secondary {
- background: #f1f3f4;
- color: #333;
-}
-
-.btn.secondary:hover:not(:disabled) {
- background: #e8eaed;
- transform: translateY(-1px);
-}
-
-.btn:disabled {
- opacity: 0.5;
- cursor: not-allowed;
-}
-
-.display-area {
- background: white;
- border-radius: 15px;
- overflow: hidden;
- box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1);
- margin: 20px;
- max-height: 70vh;
-}
-
-.teleprompter-container {
- height: 500px;
- overflow-y: auto;
- overflow-x: hidden;
- position: relative;
- background: #000;
- cursor: grab;
- scrollbar-width: thin;
- scrollbar-color: #666 #222;
-}
-
-.teleprompter-container::-webkit-scrollbar {
- width: 8px;
-}
-
-.teleprompter-container::-webkit-scrollbar-track {
- background: #222;
-}
-
-.teleprompter-container::-webkit-scrollbar-thumb {
- background: #666;
- border-radius: 4px;
-}
-
-.teleprompter-container::-webkit-scrollbar-thumb:hover {
- background: #888;
-}
-
-.teleprompter-container:active {
- cursor: grabbing;
-}
-
-.teleprompter-content {
- padding: 20px;
- transform: scaleX(-1);
- transition: transform 0.3s ease;
- min-height: 100%;
-}
-
-.teleprompter-content img {
- width: 100%;
- height: auto;
- display: block;
- margin-bottom: 20px;
- border-radius: 8px;
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
-}
-
-/* 全屏模式无边框 */
-.display-area.fullscreen {
- position: fixed;
- top: 0;
- left: 0;
- width: 100vw;
- height: 100vh;
- z-index: 999;
- border-radius: 0;
- margin: 0;
- max-height: none;
-}
-
-.display-area.fullscreen .teleprompter-container {
- height: 100vh;
- border-radius: 0;
- margin: 0;
- padding: 0;
-}
-
-.display-area.fullscreen .teleprompter-content {
- padding: 0;
-}
-
-.display-area.fullscreen .teleprompter-content img {
- border-radius: 0;
- box-shadow: none;
- margin-bottom: 0;
-}
-
-/* 滚动提示 */
-.scroll-indicator {
- position: absolute;
- right: 10px;
- top: 50%;
- transform: translateY(-50%);
- background: rgba(0, 0, 0, 0.5);
- color: white;
- padding: 8px 12px;
- border-radius: 20px;
- font-size: 12px;
- opacity: 0;
- transition: opacity 0.3s ease;
- pointer-events: none;
- z-index: 10;
-}
-
-.teleprompter-container:hover .scroll-indicator {
- opacity: 1;
-}
-
-.loading {
- text-align: center;
- color: white;
- padding: 40px;
-}
-
-.spinner {
- width: 40px;
- height: 40px;
- border: 4px solid rgba(255, 255, 255, 0.3);
- border-top: 4px solid white;
- border-radius: 50%;
- animation: spin 1s linear infinite;
- margin: 0 auto 20px;
-}
-
-@keyframes spin {
- 0% { transform: rotate(0deg); }
- 100% { transform: rotate(360deg); }
-}
-
-.btn-icon {
- width: 16px;
- height: 16px;
- margin-right: 8px;
- vertical-align: middle;
-}
-
-.floating-controls {
- position: fixed;
- top: 20px;
- right: 20px;
- background: rgba(0, 0, 0, 0.8);
- backdrop-filter: blur(10px);
- border-radius: 15px;
- padding: 15px;
- display: flex;
- align-items: center;
- gap: 10px;
- z-index: 1000;
- transition: all 0.3s ease;
- box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
-}
-
-.floating-controls:hover {
- background: rgba(0, 0, 0, 0.9);
- transform: translateY(-2px);
-}
-
-.float-btn {
- width: 45px;
- height: 45px;
- border: none;
- border-radius: 50%;
- background: rgba(255, 255, 255, 0.2);
- color: white;
- cursor: pointer;
- display: flex;
- align-items: center;
- justify-content: center;
- transition: all 0.3s ease;
- backdrop-filter: blur(5px);
-}
-
-.float-btn:hover {
- background: rgba(255, 255, 255, 0.3);
- transform: scale(1.1);
-}
-
-.float-btn svg {
- width: 20px;
- height: 20px;
-}
-
-.float-speed-control {
- display: flex;
- align-items: center;
- gap: 8px;
- padding: 0 10px;
-}
-
-.float-speed-control input[type="range"] {
- width: 100px;
- height: 4px;
- background: rgba(255, 255, 255, 0.3);
-}
-
-.float-speed-control input[type="range"]::-webkit-slider-thumb {
- width: 14px;
- height: 14px;
- background: white;
-}
-
-#floatSpeedValue {
- color: white;
- font-size: 0.9rem;
- font-weight: bold;
- min-width: 25px;
-}
-
-/* 全屏模式样式 */
-.display-area.fullscreen {
- position: fixed;
- top: 0;
- left: 0;
- width: 100vw;
- height: 100vh;
- z-index: 999;
- border-radius: 0;
- margin: 0;
-}
-
-.display-area.fullscreen .teleprompter-container {
- height: 100vh;
- border-radius: 0;
-}
-
-/* 全屏时隐藏原控制面板 */
-body.fullscreen .controls {
- display: none !important;
-}
-
-@media (max-width: 768px) {
- .controls {
- flex-direction: column;
- align-items: stretch;
- }
-
- .control-group {
- justify-content: center;
- }
-
- h1 {
- font-size: 2rem;
- }
-
- .teleprompter-container {
- height: 400px;
- }
-}
\ No newline at end of file