国庆七天乐-砸金蛋小游戏

865 阅读2分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

先看一下效果图:

最近挺累的,搞一个小动画游戏,放松一下心情...

js代码

export default () => {
  const [play, setPlay] = useState(false); // 动画是否运转
  const [target, setTarget] = useState(0);

  const handleStart = () => {
    setPlay((paly) => !paly);
    setTarget(0);
  };

  const handleItem = (i) => {
    if (!play) return;

    setPlay((paly) => !paly);
    setTarget(i);

    setTimeout(() => {
      message.info('一等奖')
    }, 800)
  };

  const animationStyle = {
    animationPlayState: play ? 'running' : 'paused',
  };

  return (
    <div className="wrap">
      <div className="egg-content">
        <div
          className="egg-item transformStyle1"
          style={animationStyle}
          onClick={() => handleItem(1)}
        >
          <div className={`egg ${target === 1 && 'activeEgg'}`} />
          <img
            src={hammer}
            className={`hammer ${target === 1 && 'hammerTransform'}`}
          />
        </div>
        <div
          className="egg-item transformStyle2"
          style={animationStyle}
          onClick={() => handleItem(2)}
        >
          <div className={`egg ${target === 2 && 'activeEgg'}`} />
          <img
            src={hammer}
            className={`hammer ${target === 2 && 'hammerTransform'}`}
          />
        </div>
        <div
          className="egg-item transformStyle3"
          style={animationStyle}
          onClick={() => handleItem(3)}
        >
          <div className={`egg ${target === 3 && 'activeEgg'}`} />
          <img
            src={hammer}
            className={`hammer ${target === 3 && 'hammerTransform'}`}
          />
        </div>
      </div>
      <Row justify="center">
        <Button type="primary" onClick={handleStart}>
          {play ? 'pause' : 'start'}
        </Button>
      </Row>
    </div>
  );
};

css 代码

.wrap {
  .egg-content {
    height: 460px;
    width: 600px;
    background-color:cornsilk;
    position: relative;
    margin: 0 auto;
  }

  .egg-item {
    position: absolute;
    width: 200px;
    height: 190px;
  }
  .egg {
    height: 200px;
    width: 190px;
    background-image: url('../../../public/egg_1.png');
    background-repeat: no-repeat;
    background-size: contain;
  }
  .hammer {
    position: absolute;
    top: -80px,;
    left: 50%;
    height: 80px;
    width: 70px;
    visibility: hidden;
  }

  .transformStyle1 {
    animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -4.5s infinite alternate,
      animY 9s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate,
      scale 18s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate;
  }
  .transformStyle2 {
    animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -10.5s infinite alternate,
      animY 9s cubic-bezier(0.5, 0, 0.5, 1) -6s infinite alternate,
      scale 18s cubic-bezier(0.5, 0, 0.5, 1) -6s infinite alternate;

  }
  .transformStyle3 {
    animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -16.5s infinite alternate,
      animY 9s cubic-bezier(0.5, 0, 0.5, 1) -12s infinite alternate,
      scale 18s cubic-bezier(0.5, 0, 0.5, 1) -12s infinite alternate;
  }

  .hammerTransform {
    visibility: visible;
    transform: rotate(-45deg);
    transform-origin: 80px 70px;
    animation-name: hammer;
    animation-timing-function: ease;
    animation-duration: 0.5s;
  }

  .activeEgg {
    background-image: url('../../../public/egg_2.png');
    transition-property: background-image;
    transition-delay: 0.3s;
  }
}
// 小锤子动画
@keyframes hammer {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(-45deg);
  }
}

@keyframes animX{
  0% {left: 0px;}
  100% {left: 400px;}
}
@keyframes animY{
  0% {top: 50px;}
  100% {top: 200px;}
}
@keyframes scale {
  0% {
    transform: scale(0.8);
    z-index: 10
  }
  50% {
    transform: scale(1);
    z-index: 100;
  }
  100% {
    transform: scale(0.8);
    z-index: 10
  }
}

动画效果解析

怎么让金蛋动起来?

  • 将金蛋设置 positon: absolute,使其脱离文档流,然后添加动画
  • 水平(X轴)和垂直(Y轴)方向,即实时改变元素的 topleft
  • 在金蛋运动的过程中,改变金蛋的大小,改变元素的 scale
  • 设置动画关键帧 @keyframes
  • 设置 animation
    .transformStyle1 {
        animation: animX 9s cubic-bezier(0.5, 0, 0.5, 1) -4.5s infinite alternate,
          animY 9s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate,
          scale 18s cubic-bezier(0.5, 0, 0.5, 1) 0s infinite alternate;
      }
    

    动画属性:

    1. animation-nameanimX animYscale
    2. animation-duration: 9s9s18s
    3. animation-timing-function: cubic-bezier(0.5, 0, 0.5, 1)贝塞尔曲线
    4. animation-delay: -4.5s0s0s
    5. animation-iteration-countinfinite(无限循环)
    6. animation-directionalternate(动画交替反向运行)

    动画时间计算

    1. x和y轴的时间总和是 scale的时间

    2. 3个图x和y轴动画加起来是18s , 18s/3 等于 6s

    3. 每个球y轴动画延迟 从0递减6s,

    4. x轴与y轴相差动画时长的一半(9s/2)

结语

如果这篇文章帮到了你,欢迎点赞👍和关注⭐️。

文章如有错误之处,希望在评论区指正🙏🙏。