add reline can be moved

main pre
土狗 2 months ago
parent b85e6838e4
commit cfbebfef6c

@ -0,0 +1,142 @@
export class DraggableLine {
constructor() {
this.readingLine = document.getElementById('readingLine');
this.isDragging = false;
this.startY = 0;
this.startTop = 0;
this.defaultPosition = 25; // 默认位置25%
this.init();
}
init() {
if (!this.readingLine) return;
// 绑定事件
this.readingLine.addEventListener('mousedown', this.onMouseDown.bind(this));
document.addEventListener('mousemove', this.onMouseMove.bind(this));
document.addEventListener('mouseup', this.onMouseUp.bind(this));
// 触摸事件支持
this.readingLine.addEventListener('touchstart', this.onTouchStart.bind(this));
document.addEventListener('touchmove', this.onTouchMove.bind(this));
document.addEventListener('touchend', this.onTouchEnd.bind(this));
// 双击重置位置
this.readingLine.addEventListener('dblclick', this.resetPosition.bind(this));
}
onMouseDown(e) {
e.preventDefault();
this.startDrag(e.clientY);
}
onTouchStart(e) {
e.preventDefault();
this.startDrag(e.touches[0].clientY);
}
startDrag(clientY) {
this.isDragging = true;
this.startY = clientY;
// 获取当前top值百分比
const computedStyle = window.getComputedStyle(this.readingLine);
const currentTop = computedStyle.top;
if (currentTop.includes('%')) {
this.startTop = parseFloat(currentTop);
} else {
// 如果是像素值,转换为百分比
const topPx = parseFloat(currentTop);
this.startTop = (topPx / window.innerHeight) * 100;
}
this.readingLine.classList.add('dragging');
document.body.style.userSelect = 'none';
}
onMouseMove(e) {
if (!this.isDragging) return;
this.updatePosition(e.clientY);
}
onTouchMove(e) {
if (!this.isDragging) return;
e.preventDefault();
this.updatePosition(e.touches[0].clientY);
}
updatePosition(clientY) {
const deltaY = clientY - this.startY;
const deltaPercent = (deltaY / window.innerHeight) * 100;
let newTop = this.startTop + deltaPercent;
// 限制范围在5%到95%之间
newTop = Math.max(5, Math.min(95, newTop));
this.readingLine.style.top = newTop + '%';
}
onMouseUp() {
this.endDrag();
}
onTouchEnd() {
this.endDrag();
}
endDrag() {
if (!this.isDragging) return;
this.isDragging = false;
this.readingLine.classList.remove('dragging');
document.body.style.userSelect = '';
// 保存当前位置
this.savePosition();
}
resetPosition() {
this.readingLine.style.top = this.defaultPosition + '%';
this.savePosition();
}
savePosition() {
// 保存位置到localStorage
const currentTop = window.getComputedStyle(this.readingLine).top;
let topPercent;
if (currentTop.includes('%')) {
topPercent = parseFloat(currentTop);
} else {
const topPx = parseFloat(currentTop);
topPercent = (topPx / window.innerHeight) * 100;
}
localStorage.setItem('readingLinePosition', topPercent.toString());
}
loadPosition() {
// 从localStorage加载位置
const savedPosition = localStorage.getItem('readingLinePosition');
if (savedPosition) {
const position = parseFloat(savedPosition);
if (position >= 5 && position <= 95) {
this.readingLine.style.top = position + '%';
return;
}
}
// 如果没有保存的位置或位置无效,使用默认位置
this.readingLine.style.top = this.defaultPosition + '%';
}
getCurrentPosition() {
const currentTop = window.getComputedStyle(this.readingLine).top;
if (currentTop.includes('%')) {
return parseFloat(currentTop);
} else {
const topPx = parseFloat(currentTop);
return (topPx / window.innerHeight) * 100;
}
}
}
// 模块已在main.js中统一初始化

@ -6,7 +6,7 @@ import { AudioController } from './audio.js';
import { SettingsController } from './settings.js';
import { WatermarkController } from './watermark.js';
import { FlipController } from './flip.js';
import { defaultText } from './defaultText.js';
import { DraggableLine } from './draggable-line.js';
// 主应用程序入口
class TeleprompterApp {
@ -31,6 +31,8 @@ class TeleprompterApp {
window.settingsController = new SettingsController();
window.watermarkController = new WatermarkController();
window.flipController = new FlipController();
window.draggableLine = new DraggableLine();
window.draggableLine.loadPosition();
this.setupEventListeners();
this.loadDefaultText();

@ -81,10 +81,22 @@ body {
left: 0;
right: 0;
height: 4px;
background: linear-gradient(to right, transparent 0%, #ff4444 10%, #ff4444 95%, transparent 100%);
background: linear-gradient(to right, transparent 0%, #ff4444 15%, #ff4444 90%, transparent 100%);
z-index: 500;
box-shadow: 0 0 40px rgba(255, 68, 68, 0.9);
transition: opacity 0.3s ease;
cursor: ns-resize;
padding: 1px 0;
}
.reading-line:hover {
box-shadow: 0 0 60px rgba(255, 68, 68, 1);
transform: all 0.3s ease;
}
.reading-line.dragging {
transition: none;
box-shadow: 0 0 80px rgba(255, 68, 68, 1);
}
/* 主内容区域 */

Loading…
Cancel
Save