Improve(Web): Headless host opens terminal
fix two-finger scroll speed and zoom misdetect
This commit is contained in:
@@ -2059,13 +2059,22 @@ inline std::string GetWebPageHTML() {
|
||||
// Part 8b1: Device connect / terminal session (split to avoid MSVC string literal length limit)
|
||||
html += R"HTML(
|
||||
function connectDevice(id) {
|
||||
const compat = checkWebCodecs();
|
||||
if (!compat.supported) { alert('Browser does not support H264: ' + compat.reason); return; }
|
||||
currentDevice = devices.find(d => d.id === id || d.id === String(id));
|
||||
if (!currentDevice || !currentDevice.online) {
|
||||
const dev = devices.find(d => d.id === id || d.id === String(id));
|
||||
if (!dev || !dev.online) {
|
||||
alert('Device is offline');
|
||||
return;
|
||||
}
|
||||
// 无显示器(screen 字段格式 "n:WxH",n=0 表示无显示器)→ 远程桌面没有意义,
|
||||
// 直接走终端。
|
||||
const screenStr = String(dev.screen || '');
|
||||
const screenCount = parseInt(screenStr.split(':')[0], 10);
|
||||
if (!isNaN(screenCount) && screenCount === 0) {
|
||||
openTerminal(id);
|
||||
return;
|
||||
}
|
||||
const compat = checkWebCodecs();
|
||||
if (!compat.supported) { alert('Browser does not support H264: ' + compat.reason); return; }
|
||||
currentDevice = dev;
|
||||
document.getElementById('device-name').textContent = currentDevice.name;
|
||||
document.getElementById('frame-info').textContent = '';
|
||||
updateScreenStatus('connecting');
|
||||
@@ -2574,9 +2583,20 @@ inline std::string GetWebPageHTML() {
|
||||
// Part 14b: JavaScript - Zoom state and touch helpers
|
||||
html += R"HTML(
|
||||
// Two-finger gesture constants
|
||||
const ZOOM_THRESHOLD = 0.05; // 5% distance change to trigger zoom
|
||||
const SCROLL_SENSITIVITY = 3; // Scroll speed multiplier
|
||||
const SCROLL_DEADZONE = 2; // Minimum scroll delta to send
|
||||
// 缩放 vs 滚动判定(仅在双指 + 触摸场景):
|
||||
// 1) 间距比例变化 > ZOOM_THRESHOLD 且
|
||||
// 2) 间距绝对变化 > ZOOM_MIN_PX 且
|
||||
// 3) 间距变化 > 中心垂直位移 → 判为缩放
|
||||
// 三个条件同时满足才触发缩放,避免双指上下滚动时手指自然张合的 ~5% 抖动被误判。
|
||||
// 真实缩放:双指主动张合,间距变化幅度本身就远大于这些阈值。
|
||||
const ZOOM_THRESHOLD = 0.15; // 间距比例变化阈值(15%)
|
||||
const ZOOM_MIN_PX = 30; // 间距绝对变化阈值(px)
|
||||
// 注:服务端 (WebService.cpp HandleMouse) 把 wheelDelta 钳成 ±120 一格 notch,
|
||||
// SCROLL_SENSITIVITY 实际不起作用;真正决定滚动速度的是 SCROLL_DEADZONE。
|
||||
// 触摸 touchmove 在 60fps 下高频触发,旧值 2px 等于手指动一下就连发一堆 notch,体感非常飘。
|
||||
// 现在 28px ≈ 让手指移动 ~1 个文本行距离才发一格,接近 iOS 原生触摸滚动节奏。
|
||||
const SCROLL_SENSITIVITY = 1; // (server clamps to ±120, kept for clarity only)
|
||||
const SCROLL_DEADZONE = 28; // Minimum finger-Y delta (px) to send one wheel notch
|
||||
|
||||
// Pinch-to-zoom state
|
||||
let zoomState = {
|
||||
@@ -2595,7 +2615,9 @@ inline std::string GetWebPageHTML() {
|
||||
// Two-finger gesture detection
|
||||
hasZoomed: false, // Whether zoom occurred in current gesture
|
||||
lastScrollY: 0, // For scroll delta calculation
|
||||
initialPinchDist: 0 // Distance at gesture start (for cumulative detection)
|
||||
initialPinchDist: 0, // Distance at gesture start (for cumulative detection)
|
||||
initialCenterX: 0, // Pinch center at gesture start (for scroll-vs-zoom intent)
|
||||
initialCenterY: 0
|
||||
};
|
||||
const zoomIndicator = document.getElementById('zoom-indicator');
|
||||
let zoomIndicatorTimer = null;
|
||||
@@ -2801,6 +2823,8 @@ inline std::string GetWebPageHTML() {
|
||||
const center = getPinchCenter(e.touches);
|
||||
zoomState.pinchCenterX = center.x;
|
||||
zoomState.pinchCenterY = center.y;
|
||||
zoomState.initialCenterX = center.x;
|
||||
zoomState.initialCenterY = center.y;
|
||||
zoomState.lastScrollY = center.y;
|
||||
|
||||
if (zoomState.scale === 1) {
|
||||
@@ -2904,16 +2928,28 @@ inline std::string GetWebPageHTML() {
|
||||
const totalDelta = newDist / zoomState.initialPinchDist; // Cumulative change from gesture start
|
||||
|
||||
// Detect gesture type: zoom vs scroll
|
||||
// Use CUMULATIVE change to detect zoom intent (catches slow pinch gestures)
|
||||
// Also treat as zoom if already at scale boundary and trying to zoom further
|
||||
// 缩放意图 = 间距比例显著变 + 间距绝对显著变 + 间距变化 > 中心垂直位移
|
||||
// 单纯比例阈值 5% 太敏感:双指上下滚动时手指自然张合 ~5% 就被误判为缩放。
|
||||
// 结合绝对像素阈值 + "间距变化 vs 中心位移" 的方向性,能稳定区分两种意图。
|
||||
const distAbsChange = Math.abs(newDist - zoomState.initialPinchDist);
|
||||
const distRatioChange = Math.abs(totalDelta - 1);
|
||||
const centerMoveY = Math.abs(newCenter.y - zoomState.initialCenterY);
|
||||
|
||||
const isClearZoom = distRatioChange > ZOOM_THRESHOLD &&
|
||||
distAbsChange > ZOOM_MIN_PX &&
|
||||
distAbsChange > centerMoveY;
|
||||
|
||||
// 已到缩放边界仍朝同方向尝试 → 给视觉反馈,但要求绝对像素变化 > 半阈值,
|
||||
// 避免静止时手指轻微抖动也被认为"想缩放"。
|
||||
const atMinScale = zoomState.scale <= zoomState.minScale;
|
||||
const atMaxScale = zoomState.scale >= zoomState.maxScale;
|
||||
const tryingToShrink = totalDelta < 1; // Use cumulative for direction
|
||||
const tryingToShrink = totalDelta < 1;
|
||||
const tryingToEnlarge = totalDelta > 1;
|
||||
const boundaryFeedback = distAbsChange > ZOOM_MIN_PX / 2 && (
|
||||
(atMinScale && tryingToShrink) || (atMaxScale && tryingToEnlarge)
|
||||
);
|
||||
|
||||
if (Math.abs(totalDelta - 1) > ZOOM_THRESHOLD ||
|
||||
(atMinScale && tryingToShrink) ||
|
||||
(atMaxScale && tryingToEnlarge)) {
|
||||
if (isClearZoom || boundaryFeedback) {
|
||||
zoomState.hasZoomed = true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user