You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React实现向下滚动时图片拉宽、向上滚动还原的动画效果

React 滚动触发图片拉宽动画实现方案

核心逻辑

监听页面滚动行为,实时计算图片元素在视口中的位置,将滚动进度映射为图片宽度值,配合CSS过渡属性实现平滑动画:向下滚动时图片宽度随滚动距离逐步拉宽,向上滚动时宽度随位置回退自然恢复初始状态。

具体实现

1. 编写基础样式

给外层容器和图片设置基础属性,提前定义过渡效果,避免图片缩放时变形:

.article-wrapper {
  min-height: 120vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20vh 0;
}
.image {
  /* 初始宽度可按业务需求调整 */
  width: 60%;
  height: 600px;
  object-fit: cover;
  /* 平滑过渡参数可自行调整,控制动画快慢 */
  transition: width 0.25s ease-out;
  will-change: width;
}

如果你已经给ArticleWrapper写过布局样式,直接复用现有样式即可,不需要重复编写。

2. 组件逻辑实现

通过ref获取图片DOM节点,绑定滚动监听事件,用requestAnimationFrame做节流优化,实时计算滚动进度并同步更新图片宽度,完全适配你现有的代码结构:

import { useEffect, useRef, useState } from 'react';
import Img from './your-image-asset.png';
// 引入你项目中已有的ArticleWrapper组件
import ArticleWrapper from './your-component-path';

const ScrollImageSection = () => {
  const imageRef = useRef(null);
  const [widthPercent, setWidthPercent] = useState(60);

  useEffect(() => {
    let ticking = false;
    const calcImageWidth = () => {
      if (!imageRef.current) return;
      const rect = imageRef.current.getBoundingClientRect();
      const viewportH = window.innerHeight;
      // 定义动画触发的滚动区间,数值越大动画越平缓
      const triggerRange = viewportH * 0.6;
      // 计算0-1区间的滚动进度
      let progress = (viewportH - rect.top) / (viewportH + triggerRange);
      progress = Math.min(Math.max(progress, 0), 1);
      // 映射宽度:初始60%,最大100%,可按需修改数值
      setWidthPercent(60 + progress * 40);
      ticking = false;
    };

    // 初始化计算首屏位置
    calcImageWidth();
    const scrollHandler = () => {
      if (!ticking) {
        window.requestAnimationFrame(calcImageWidth);
        ticking = true;
      }
    }
    window.addEventListener('scroll', scrollHandler, { passive: true });

    // 组件卸载时移除事件监听,避免内存泄漏
    return () => window.removeEventListener('scroll', scrollHandler);
  }, []);

  return (
    <ArticleWrapper>
      <img
        ref={imageRef}
        className="image"
        src={Img}
        alt="Section image"
        style={{ width: `${widthPercent}%` }}
      />
    </ArticleWrapper>
  );
};

export default ScrollImageSection;

自定义调整说明

  • 宽度范围:修改代码中初始宽度值、进度换算的增量值即可调整初始和最大宽度,比如需要最大宽度为90%,就把progress * 40改成progress * 30
  • 动画节奏:调整CSS中transition的时长、triggerRange的数值,即可控制动画的快慢和触发的滚动距离
  • 滚动容器适配:如果页面是内部容器滚动而非全局window滚动,将滚动事件绑定到对应容器DOM上即可,计算逻辑完全一致
  • 性能保障:代码已通过requestAnimationFrame节流、passive事件监听、will-change属性做了性能优化,正常页面场景下不会出现卡顿

内容的提问来源于stack exchange,提问作者Jaacoubi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 00:21:54