update at 2026-03-04 13:25:26
This commit is contained in:
124
pxterm/scripts/archive/cjs_tools/fix_pointer_scroll.cjs
Normal file
124
pxterm/scripts/archive/cjs_tools/fix_pointer_scroll.cjs
Normal file
@@ -0,0 +1,124 @@
|
||||
const fs = require('fs');
|
||||
let code = fs.readFileSync('src/components/TerminalPanel.vue', 'utf8');
|
||||
|
||||
// Convert Touch Events to Pointer Events for manual scroll tracking.
|
||||
// Since touchmove vanishes but pointermove remains active (with target changing from SPAN to DIV, etc)
|
||||
|
||||
// Let's modify pointer_move to handle scrolling
|
||||
|
||||
let pointerMoveCode = ` onTouchKeyboardPointerMove = (event: PointerEvent) => {
|
||||
// 保持之前的检查,跳除非 touch 事件等
|
||||
if (event.pointerType !== "touch" || touchGatePointerId !== event.pointerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const dx = event.clientX - touchGateStartX;
|
||||
const dy = event.clientY - touchGateStartY;
|
||||
const absDx = Math.abs(dx);
|
||||
const absDy = Math.abs(dy);
|
||||
|
||||
if (absDx > TOUCH_KEYBOARD_TAP_MAX_MOVE_PX || absDy > TOUCH_KEYBOARD_TAP_MAX_MOVE_PX) {
|
||||
touchGateMoved = true;
|
||||
}
|
||||
if (absDy > absDx && absDy > TOUCH_KEYBOARD_TAP_MAX_MOVE_PX) {
|
||||
touchGateScrollLike = true;
|
||||
}
|
||||
|
||||
// 我们不再拦截 touchmove,改用 pointermove 来计算自己的滚动量
|
||||
const hasSelection = hasActiveNativeSelectionInTerminal();
|
||||
if (!hasSelection) {
|
||||
const now = performance.now();
|
||||
const dt = now - touchScrollLastTime;
|
||||
const currentY = event.clientY;
|
||||
const stepDy = currentY - touchScrollLastY;
|
||||
|
||||
// 屏蔽初次的巨大跳跃(手指刚按下时)
|
||||
if (dt > 0 && Math.abs(stepDy) < 200 && touchScrollLastTime > 0) {
|
||||
if (viewportScroller && stepDy !== 0) {
|
||||
viewportScroller.scrollTop -= stepDy;
|
||||
}
|
||||
|
||||
const v = (-stepDy / dt) * 16;
|
||||
if (touchScrollVelocity * v > 0) {
|
||||
touchScrollVelocity = touchScrollVelocity * 0.5 + v * 0.5;
|
||||
} else {
|
||||
touchScrollVelocity = v;
|
||||
}
|
||||
|
||||
const touchMaxSpeed = 120;
|
||||
if (touchScrollVelocity > touchMaxSpeed) touchScrollVelocity = touchMaxSpeed;
|
||||
else if (touchScrollVelocity < -touchMaxSpeed) touchScrollVelocity = -touchMaxSpeed;
|
||||
}
|
||||
|
||||
touchScrollLastY = currentY;
|
||||
touchScrollLastTime = now;
|
||||
}
|
||||
|
||||
// 由于使用了 pointer,不要无脑阻止原生行为,但我们要阻止 xterm 被选中
|
||||
// event.stopImmediatePropagation(); // 我们前面通过 touch-action: none 已经避免了系统层面缩放
|
||||
};`;
|
||||
|
||||
let pointerDownCode = ` onTouchKeyboardPointerDown = (event: PointerEvent) => {
|
||||
console.log("[Scroll Deep] 🟡 POINTER DOWN: ", { pointerId: event.pointerId, type: event.pointerType, target: (event.target as Node)?.nodeName });
|
||||
if (event.pointerType !== "touch") {
|
||||
return;
|
||||
}
|
||||
if (!helperTextarea) {
|
||||
return;
|
||||
}
|
||||
touchGatePointerId = event.pointerId;
|
||||
touchGateStartX = event.clientX;
|
||||
touchGateStartY = event.clientY;
|
||||
touchGateMoved = false;
|
||||
touchGateScrollLike = false;
|
||||
touchGateStartInBand = isTouchInCursorActivationBand(event.clientY);
|
||||
touchGateHadSelectionAtStart = hasActiveNativeSelectionInTerminal();
|
||||
|
||||
// == 初始化滚动参数 ==
|
||||
clearTouchScrollMomentum();
|
||||
touchScrollLastY = event.clientY;
|
||||
touchScrollLastTime = performance.now();
|
||||
touchScrollVelocity = 0;
|
||||
|
||||
if (DEBUG_TOUCH_FOCUS) {
|
||||
console.log("[TouchFocus] pointerdown", {
|
||||
inBand: touchGateStartInBand,
|
||||
selectionStart: touchGateHadSelectionAtStart,
|
||||
});
|
||||
}
|
||||
|
||||
event.stopImmediatePropagation();
|
||||
if (event.cancelable) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
helperTextarea.readOnly = true;
|
||||
|
||||
if (sessionStore.state !== "connected") {
|
||||
return;
|
||||
}
|
||||
};`;
|
||||
|
||||
let pointerUpCode = ` onTouchKeyboardPointerUp = (event: PointerEvent) => {
|
||||
console.log("[Scroll Deep] 🟠 POINTER UP: ", { pointerId: event.pointerId, type: event.pointerType });
|
||||
if (event.pointerType !== "touch" || touchGatePointerId !== event.pointerId) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 释放时触发滚行动量
|
||||
const threshold = 0.2;
|
||||
if (Math.abs(touchScrollVelocity) > threshold && touchGateScrollLike && !hasActiveNativeSelectionInTerminal()) {
|
||||
touchScrollVelocity *= 1.35;
|
||||
console.log(\`[Scroll Deep] 🚀 Pointer 释放,触发JS惯性,速度=\${touchScrollVelocity.toFixed(2)}\`);
|
||||
runTouchScrollMomentum();
|
||||
} else {
|
||||
console.log(\`[Scroll Deep] 🛑 Pointer 静止释放或非滚动释放\`);
|
||||
}
|
||||
`;
|
||||
|
||||
// Now apply pointer changes
|
||||
code = code.replace(/onTouchKeyboardPointerDown = \(event: PointerEvent\) => \{[\s\S]*?if \(sessionStore\.state \!\=\= "connected"\) \{\n\s*return;\n\s*\}\n\s*\};/m, pointerDownCode);
|
||||
code = code.replace(/onTouchKeyboardPointerMove = \(event: PointerEvent\) => \{[\s\S]*?event\.stopImmediatePropagation\(\);\n\s*\};/m, pointerMoveCode);
|
||||
code = code.replace(/onTouchKeyboardPointerUp = \(event: PointerEvent\) => \{[\s\S]*?if \(event\.pointerType \!\=\= "touch" \|\| touchGatePointerId \!\=\= event.pointerId\) \{\n\s*return;\n\s*\}/m, pointerUpCode);
|
||||
|
||||
fs.writeFileSync('src/components/TerminalPanel.vue', code);
|
||||
Reference in New Issue
Block a user