如何实现滚动时放大图片特定区域?参考纽约时报交互网站
实现滚动时图片特定区域放大的方案
1. 基础布局结构
需要两个核心容器:一个承载完整原图,一个显示放大后的特定区域。原图可固定在视口(和示例效果一致),放大容器固定在页面侧边或指定位置。
<div class="fixed-image-wrapper"> <img src="your-large-image.jpg" class="original-img" alt="主视觉图"> </div> <div class="zoom-panel"> <img src="your-large-image.jpg" class="zoom-img" alt="放大区域"> </div>
基础样式配置:
.fixed-image-wrapper { position: fixed; top: 0; left: 0; width: 100%; height: 100vh; overflow: hidden; z-index: 1; } .original-img { width: 100%; height: auto; display: block; } .zoom-panel { position: fixed; top: 50%; right: 5vw; transform: translateY(-50%); width: 320px; height: 320px; overflow: hidden; border: 3px solid #fff; box-shadow: 0 4px 12px rgba(0,0,0,0.4); z-index: 2; } .zoom-img { position: absolute; width: 300%; /* 对应3倍放大比例,可按需调整 */ height: auto; transition: transform 0.3s ease; /* 平滑过渡动画 */ }
2. 定义滚动触发的放大区域坐标
提前标记原图上需要放大的关键区域,每个区域对应页面滚动的百分比位置:
// 配置项:滚动百分比 → 原图上的目标区域坐标(x/y为区域左上角像素值) const zoomTargets = [ { scrollPercent: 0, x: 0, y: 0 }, { scrollPercent: 25, x: 180, y: 220 }, { scrollPercent: 50, x: 640, y: 380 }, { scrollPercent: 75, x: 920, y: 560 }, { scrollPercent: 100, x: 420, y: 780 } ];
3. 监听滚动并计算位置
通过滚动事件计算当前滚动进度,匹配对应的放大区域:
window.addEventListener('scroll', () => { requestAnimationFrame(() => { // 计算当前滚动占页面总高度的百分比 const totalScrollable = document.documentElement.scrollHeight - window.innerHeight; const currentScrollPercent = totalScrollable === 0 ? 0 : (window.scrollY / totalScrollable) * 100; updateZoomPanel(currentScrollPercent); }); });
4. 更新放大视图
根据滚动进度,平滑调整放大图的偏移位置,让目标区域显示在放大面板中:
function updateZoomPanel(scrollPercent) { const zoomScale = 3; // 和CSS中zoom-img的宽度比例保持一致 const zoomImg = document.querySelector('.zoom-img'); // 找到当前滚动区间对应的前后目标点 let prevTarget = zoomTargets[0]; let nextTarget = zoomTargets[0]; for (let i = 1; i < zoomTargets.length; i++) { if (scrollPercent < zoomTargets[i].scrollPercent) { prevTarget = zoomTargets[i-1]; nextTarget = zoomTargets[i]; break; } prevTarget = zoomTargets[i]; nextTarget = zoomTargets[i]; } // 计算区间内的插值,实现平滑过渡 const intervalRatio = (scrollPercent - prevTarget.scrollPercent) / (nextTarget.scrollPercent - prevTarget.scrollPercent); const currentX = prevTarget.x + (nextTarget.x - prevTarget.x) * intervalRatio; const currentY = prevTarget.y + (nextTarget.y - prevTarget.y) * intervalRatio; // 应用偏移:放大图的偏移量为负的目标坐标×缩放比例 zoomImg.style.transform = `translate(${-currentX * zoomScale}px, ${-currentY * zoomScale}px)`; }
5. 优化细节
- 性能防抖:用
requestAnimationFrame包裹滚动逻辑,避免频繁触发导致卡顿; - 响应式适配:在小屏设备上可隐藏放大面板,或调整面板尺寸和缩放比例;
- 原图适配:若原图尺寸过大,可提前裁剪或使用
object-fit确保显示完整; - 边界处理:确保目标坐标不会超出原图范围,避免放大区域出现空白。
内容的提问来源于stack exchange,提问作者newuser
相关产品推荐
相关产品推荐

