fix: bottom bar no touch seek; lyrics seek on Android; smoother NP animation
- initProgressScrub: pass noTouch=true for the bottom mini-bar so touch events are never registered on it; only mouse events remain (desktop-only). The now-playing scrubber is unchanged and keeps full touch support. - Export seekToMs(ms) from player.js; use it in the lyrics click handler instead of S.audio.currentTime which has no effect when HAS_BRIDGE (native ExoPlayer handles playback, not the HTML audio element). - styles.css: add will-change:transform to .player and .np-overlay to keep them on GPU compositor layers during the swipe gesture; tweak NP open transition to cubic-bezier(.4,0,.2,1) for a snappier feel. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
9d8a5a22bb
commit
4856f0ca57
3 files changed
+40
-25
No files matched your search
+35
-21
@@ -656,10 +656,12 @@ export function seekTo(e) {
|
||||
}
|
||||
|
||||
export function initProgressScrub() {
|
||||
// Bottom mini-bar: mouse-only (touch disabled — too easy to accidentally seek on mobile).
|
||||
_initBarScrub(
|
||||
document.getElementById('progress-bar'),
|
||||
document.getElementById('progress-fill'),
|
||||
pos => { document.getElementById('time-cur').textContent = formatDur(pos * _dur()); }
|
||||
pos => { document.getElementById('time-cur').textContent = formatDur(pos * _dur()); },
|
||||
/* noTouch= */ true
|
||||
);
|
||||
_initBarScrub(
|
||||
document.getElementById('np-bar'),
|
||||
@@ -668,7 +670,17 @@ export function initProgressScrub() {
|
||||
);
|
||||
}
|
||||
|
||||
function _initBarScrub(bar, fill, onMove) {
|
||||
// Export for lyrics / other callers that need to seek by ms.
|
||||
export function seekToMs(ms) {
|
||||
if (HAS_BRIDGE) {
|
||||
_setSkipping();
|
||||
_nsBridge('seekTo', Math.round(ms));
|
||||
} else {
|
||||
S.audio.currentTime = ms / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
function _initBarScrub(bar, fill, onMove, noTouch = false) {
|
||||
if(!bar || !fill) return;
|
||||
function getPos(clientX) { const r = bar.getBoundingClientRect(); return Math.max(0, Math.min(1, (clientX-r.left)/r.width)); }
|
||||
function startScrub(pos) { S._scrubbing=true; fill.style.transition='none'; fill.style.width=(pos*100)+'%'; onMove(pos); }
|
||||
@@ -691,25 +703,27 @@ function _initBarScrub(bar, fill, onMove) {
|
||||
fill.style.transition = '';
|
||||
}
|
||||
}
|
||||
// Touch: require ≥8px horizontal drag before committing to scrub.
|
||||
// A plain tap cancels cleanly without seeking.
|
||||
let _touchStartX = 0, _touchMoved = false;
|
||||
bar.addEventListener('touchstart', e => {
|
||||
_touchStartX = e.touches[0].clientX;
|
||||
_touchMoved = false;
|
||||
e.stopPropagation();
|
||||
e.preventDefault(); // block synthetic mousedown/click that would trigger scrub on plain tap
|
||||
});
|
||||
bar.addEventListener('touchmove', e => {
|
||||
const dx = Math.abs(e.touches[0].clientX - _touchStartX);
|
||||
if (!_touchMoved && dx >= 8) { _touchMoved = true; startScrub(getPos(e.touches[0].clientX)); }
|
||||
if (_touchMoved && S._scrubbing) moveScrub(getPos(e.touches[0].clientX));
|
||||
}, {passive:true});
|
||||
bar.addEventListener('touchend', e => {
|
||||
if (_touchMoved && S._scrubbing) endScrub(getPos(e.changedTouches[0].clientX));
|
||||
else S._scrubbing = false;
|
||||
_touchMoved = false;
|
||||
}, {passive:true});
|
||||
if (!noTouch) {
|
||||
// Touch: require ≥8px horizontal drag before committing to scrub.
|
||||
// A plain tap cancels cleanly without seeking.
|
||||
let _touchStartX = 0, _touchMoved = false;
|
||||
bar.addEventListener('touchstart', e => {
|
||||
_touchStartX = e.touches[0].clientX;
|
||||
_touchMoved = false;
|
||||
e.stopPropagation();
|
||||
e.preventDefault(); // block synthetic mousedown/click that would trigger scrub on plain tap
|
||||
});
|
||||
bar.addEventListener('touchmove', e => {
|
||||
const dx = Math.abs(e.touches[0].clientX - _touchStartX);
|
||||
if (!_touchMoved && dx >= 8) { _touchMoved = true; startScrub(getPos(e.touches[0].clientX)); }
|
||||
if (_touchMoved && S._scrubbing) moveScrub(getPos(e.touches[0].clientX));
|
||||
}, {passive:true});
|
||||
bar.addEventListener('touchend', e => {
|
||||
if (_touchMoved && S._scrubbing) endScrub(getPos(e.changedTouches[0].clientX));
|
||||
else S._scrubbing = false;
|
||||
_touchMoved = false;
|
||||
}, {passive:true});
|
||||
}
|
||||
bar.addEventListener('mousedown', e => {
|
||||
startScrub(getPos(e.clientX)); e.preventDefault();
|
||||
const mm = e2 => { if(S._scrubbing) moveScrub(getPos(e2.clientX)); };
|
||||
|
||||
Reference in new issue
Block a user