fix: improve mobile scrollbar visibility and resize handling
This commit is contained in:
@@ -43,21 +43,30 @@ const handlePointerDown = (e) => {
|
||||
const now = Date.now();
|
||||
if (now - lastTap < 300) {
|
||||
// Double tap -> X (Force)
|
||||
clearLongPress();
|
||||
emit('start-drag', props.r, props.c, true, true);
|
||||
lastTap = 0;
|
||||
} else {
|
||||
// Single tap / Start drag -> Fill
|
||||
emit('start-drag', props.r, props.c, false, false);
|
||||
lastTap = now;
|
||||
|
||||
// Start Long Press Timer
|
||||
clearLongPress();
|
||||
longPressTimer = setTimeout(() => {
|
||||
if (navigator.vibrate) navigator.vibrate(50);
|
||||
// Switch to Cross (Right click logic, force=true to overwrite the just-placed Fill)
|
||||
emit('start-drag', props.r, props.c, true, true);
|
||||
}, 500);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePointerUp = (e) => {
|
||||
// Handled in pointerdown
|
||||
clearLongPress();
|
||||
};
|
||||
|
||||
const handlePointerCancel = (e) => {
|
||||
// Handled in pointerdown
|
||||
clearLongPress();
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
@@ -27,17 +27,28 @@ let dragStartLeft = 0;
|
||||
const checkScroll = () => {
|
||||
const el = scrollWrapper.value;
|
||||
if (!el) return;
|
||||
|
||||
const content = el.firstElementChild;
|
||||
const contentWidth = content ? content.offsetWidth : el.scrollWidth;
|
||||
const sw = el.scrollWidth;
|
||||
const cw = el.clientWidth;
|
||||
|
||||
// Only show custom scrollbar on mobile/tablet (width < 768px) and if content overflows
|
||||
const isMobile = window.innerWidth <= 768;
|
||||
showScrollbar.value = isMobile && (sw > cw + 1);
|
||||
// Use contentWidth to check for overflow, as scrollWidth might be misleading
|
||||
showScrollbar.value = isMobile && (contentWidth > cw + 1);
|
||||
|
||||
if (showScrollbar.value) {
|
||||
// Thumb width percentage = (viewport / total) * 100
|
||||
const ratio = cw / sw;
|
||||
// Use contentWidth for more accurate ratio
|
||||
const ratio = cw / contentWidth;
|
||||
thumbWidth.value = Math.max(10, ratio * 100);
|
||||
|
||||
// Hide if content fits or almost fits (prevent useless scrollbar)
|
||||
// Increased tolerance to 95%
|
||||
if (ratio >= 0.95) {
|
||||
showScrollbar.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -175,21 +186,38 @@ const handleGridLeave = () => {
|
||||
activeCol.value = null;
|
||||
};
|
||||
|
||||
const handleResize = () => {
|
||||
computeCellSize();
|
||||
checkScroll();
|
||||
// Re-check after potential layout animation/transition
|
||||
setTimeout(() => {
|
||||
computeCellSize();
|
||||
checkScroll();
|
||||
}, 300);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
computeCellSize();
|
||||
checkScroll();
|
||||
// Extra check for slow layout/font loading or orientation changes
|
||||
setTimeout(() => {
|
||||
computeCellSize();
|
||||
checkScroll();
|
||||
}, 300);
|
||||
});
|
||||
isFinePointer.value = window.matchMedia('(pointer: fine)').matches;
|
||||
window.addEventListener('resize', computeCellSize);
|
||||
window.addEventListener('resize', checkScroll);
|
||||
|
||||
window.addEventListener('resize', handleResize);
|
||||
window.addEventListener('orientationchange', handleResize);
|
||||
window.addEventListener('mouseup', handleGlobalMouseUp);
|
||||
window.addEventListener('pointerup', handleGlobalPointerUp);
|
||||
window.addEventListener('touchend', handleGlobalPointerUp, { passive: true });
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener('resize', computeCellSize);
|
||||
window.removeEventListener('resize', checkScroll);
|
||||
window.removeEventListener('resize', handleResize);
|
||||
window.removeEventListener('orientationchange', handleResize);
|
||||
window.removeEventListener('mouseup', handleGlobalMouseUp);
|
||||
window.removeEventListener('pointerup', handleGlobalPointerUp);
|
||||
window.removeEventListener('touchend', handleGlobalPointerUp);
|
||||
@@ -199,6 +227,10 @@ watch(() => store.size, async () => {
|
||||
await nextTick();
|
||||
computeCellSize();
|
||||
checkScroll();
|
||||
setTimeout(() => {
|
||||
computeCellSize();
|
||||
checkScroll();
|
||||
}, 300);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user