fix: maintain visual position during zoom - eliminate perspective effect
When zooming, the page was scaling from a fixed point causing content to appear to "move through" the viewport like a 3D perspective effect. This made the zoom feel disorienting as the visible content would shift. Solution: Proportional scroll compensation - Track current scale before applying new scale - Calculate scale ratio (newScale / currentScale) - Adjust scroll position by multiplying by scale ratio - Example: scrollTop 1000px at 100% → 1500px at 150% Benefits: - Content you're viewing stays in the same visual position - Zoom feels more like "magnification" than "perspective" - Smooth, stable zoom experience without content shifting - Eliminates the "going through me and getting farther" effect Technical changes: - Extract current scale from transform property via regex - Calculate proportional scroll adjustment - Apply synchronized transform + scroll in requestAnimationFrame
This commit is contained in:
+17
-6
@@ -322,18 +322,29 @@
|
|||||||
const cvPaper = document.querySelector('.cv-paper');
|
const cvPaper = document.querySelector('.cv-paper');
|
||||||
if (!cvPaper) return;
|
if (!cvPaper) return;
|
||||||
|
|
||||||
// Convert percentage to scale factor (100 = 1.0, 150 = 1.5, etc.)
|
// Get current scale from the element (if any)
|
||||||
const scaleFactor = zoomValue / 100;
|
const currentTransform = cvPaper.style.transform;
|
||||||
|
const currentScaleMatch = currentTransform.match(/scale\(([\d.]+)\)/);
|
||||||
|
const currentScale = currentScaleMatch ? parseFloat(currentScaleMatch[1]) : 1.0;
|
||||||
|
|
||||||
// Preserve scroll position (matching existing toggle pattern)
|
// Convert percentage to scale factor (100 = 1.0, 150 = 1.5, etc.)
|
||||||
|
const newScale = zoomValue / 100;
|
||||||
|
|
||||||
|
// Calculate scale ratio for scroll adjustment
|
||||||
|
const scaleRatio = newScale / currentScale;
|
||||||
|
|
||||||
|
// Preserve visual position by adjusting scroll proportionally
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
|
||||||
// Apply transform
|
// Apply transform
|
||||||
cvPaper.style.transform = `scale(${scaleFactor})`;
|
cvPaper.style.transform = `scale(${newScale})`;
|
||||||
|
|
||||||
// Restore scroll position
|
// Adjust scroll position to maintain visual stability
|
||||||
window.scrollTo(0, scrollTop);
|
// When zooming in (scaleRatio > 1), scroll more to keep same content visible
|
||||||
|
// When zooming out (scaleRatio < 1), scroll less
|
||||||
|
const newScrollTop = scrollTop * scaleRatio;
|
||||||
|
window.scrollTo(0, newScrollTop);
|
||||||
|
|
||||||
// Update display
|
// Update display
|
||||||
updateZoomDisplay(zoomValue);
|
updateZoomDisplay(zoomValue);
|
||||||
|
|||||||
Reference in New Issue
Block a user