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

React实现类Instagram直播飞心动画:如何让追加Div平滑消失

实现Instagram直播式飞心动画:让生成的爱心平滑消失

我想实现如图所示的飞心动画:用户点击按钮时,在随机X、Y位置生成爱心,爱心能自动平滑消失,效果类似Instagram直播。现有React及CSS代码如下,请教如何让追加的div无缝平滑消失。

飞心效果示例

现有代码:

import React, { useState } from "react";

const MyComponent = () => {
  const [divs, setDivs] = useState([]);

  const addDiv = () => {
    const x = Math.floor(Math.random() * window.innerWidth);
    const y = Math.floor(Math.random() * window.innerHeight);
    const newDiv = (
      <div
        className="animated-div"
        style={{ position: "absolute", left: x, top: y }}
      >
        <svg
          aria-hidden="true"
          focusable="false"
          data-prefix="fas"
          data-icon="heart"
          className="svg-inline--fa fa-heart fa-w-16"
          width="100%"
          height="100%"
          role="img"
          xmlns="http://www.w3.org/2000/svg"
          viewBox="0 0 512 512"
          preserveAspectRatio="none"
        >
          <path
            fill="#f67280"
            d="M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z"
          />
        </svg>
      </div>
    );

    setDivs([...divs, newDiv]);
  };

  return (
    <div>
      <button onClick={addDiv}>Add Div</button>
      <div className="container">{divs}</div>
    </div>
  );
};

export default MyComponent;
.animated-div {
  height: 50px;
  width: 50px;
  animation: fly-in 0.3s ease-out forwards;
  color: white;
  font-size: 1em;
  padding: 10px;
}

@keyframes fly-in {
  from {
    transform: translateY(100%);
    opacity: 0;
  }
  to {
    transform: translateY(0);
    opacity: 1;
  }
}

解决方案

1. 扩展CSS动画,加入淡出阶段

把原来的仅飞入动画改成飞入→停留→上移淡出的完整生命周期动画,让爱心自动完成消失过程:

.animated-div {
  height: 50px;
  width: 50px;
  position: absolute; /* 把定位属性统一移到类中 */
  animation: heart-fly 2s ease-out forwards; /* 总时长和动画关键帧对应 */
  pointer-events: none; /* 避免爱心遮挡按钮点击 */
}

@keyframes heart-fly {
  0% {
    transform: translateY(100%) scale(0.5);
    opacity: 0;
  }
  20% {
    transform: translateY(0) scale(1);
    opacity: 1;
  }
  80% {
    transform: translateY(-50px) scale(1); /* 中间停留并缓慢上移 */
    opacity: 1;
  }
  100% {
    transform: translateY(-100px) scale(0.8);
    opacity: 0;
  }
}

2. 优化React状态管理,存储数据而非元素

直接存React元素无法跟踪生命周期,改为存储爱心的唯一ID和位置数据,渲染时动态生成元素,并自动移除已完成动画的爱心:

import React, { useState, useEffect } from "react";

const MyComponent = () => {
  const [hearts, setHearts] = useState([]);

  const addHeart = () => {
    // 减去爱心宽高,避免生成的爱心超出屏幕
    const x = Math.floor(Math.random() * (window.innerWidth - 70));
    const y = Math.floor(Math.random() * (window.innerHeight - 70));
    const newHeart = {
      id: Date.now() + Math.random(), // 生成唯一ID
      x,
      y
    };
    setHearts(prev => [...prev, newHeart]);
  };

  // 动画结束后自动移除爱心,定时器时长和动画总时长一致
  useEffect(() => {
    if (hearts.length === 0) return;
    const timer = setTimeout(() => {
      setHearts(prev => prev.slice(1));
    }, 2000);
    return () => clearTimeout(timer);
  }, [hearts]);

  return (
    <div style={{ position: "relative", minHeight: "100vh" }}>
      <button onClick={addHeart}>点击生成爱心</button>
      <div className="container">
        {hearts.map(heart => (
          <div
            key={heart.id}
            className="animated-div"
            style={{ left: `${heart.x}px`, top: `${heart.y}px` }}
          >
            <svg
              aria-hidden="true"
              focusable="false"
              data-prefix="fas"
              data-icon="heart"
              className="svg-inline--fa fa-heart fa-w-16"
              width="100%"
              height="100%"
              role="img"
              xmlns="http://www.w3.org/2000/svg"
              viewBox="0 0 512 512"
              preserveAspectRatio="none"
            >
              <path
                fill="#f67280"
                d="M462.3 62.6C407.5 15.9 326 24.3 275.7 76.2L256 96.5l-19.7-20.3C186.1 24.3 104.5 15.9 49.7 62.6c-62.8 53.6-66.1 149.8-9.9 207.9l193.5 199.8c12.5 12.9 32.8 12.9 45.3 0l193.5-199.8c56.3-58.1 53-154.3-9.8-207.9z"
              />
            </svg>
          </div>
        ))}
      </div>
    </div>
  );
};

export default MyComponent;

3. 调整容器样式

给容器添加定位,确保爱心的绝对定位基于容器,同时不干扰下层元素点击:

.container {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
}

修改后,爱心会自动完成飞入→停留→上移淡出的完整动画,动画结束后React会移除对应的DOM元素,实现无缝平滑消失的效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 07:25:02