【问题标题】:React and CSS Animation - only animate the clicked element with a shared classNameReact 和 CSS Animation - 仅使用共享的 className 为单击的元素设置动画
【发布时间】:2021-12-29 20:20:07
【问题描述】:

我正在使用 React 开发一个简单的 Web 浏览器绘图应用程序。该应用程序使用按钮的图像来选择要绘制的颜色。这些颜色按钮图像中的每一个都具有相同的 className='color-button'

我关注了这篇文章,了解如何使用 CSS 动画在点击时为彩色按钮图像设置动画: https://dev.to/samwatts98/how-to-easily-animate-your-react-components-on-click-with-css-keyframes-26mg

问题在于,单击任何一种颜色按钮图像会使它们都具有动画效果,因为它们都共享 className='color-button'。我只想为点击的颜色按钮图像设置动画。

当前状态下的实时版本应用在这里: https://master.d3irlm8kk772s.amplifyapp.com/

下面是使用钩子设置“推送”动画状态的代码以及我尝试过的一个附加功能但不起作用:

const [push, setPush] = useState(0);

//This function was tried but didn't solve the problem:
  function changeSetPush(){
    setPush(1);
  }

这是图像本身的代码。第一张图片尝试了 changeSetPush 函数,但得到的结果与其他图片相同:

{/* Circle Color Buttons */}
            <div style={{width: 96}}>
                <img src={BlackCircle} alt='black' className='color-button'
                  onClick={() => {changePenColor('#000000');
                  changeSetPush()}} onAnimationEnd={() => setPush(0)} push={push}
                  />
                <img src={WhiteCircle} alt='white' className='color-button'
                  onClick={() => {changePenColor('#FFFFFF');
                  setPush(1)}} onAnimationEnd={() => setPush(0)} push={push}
                  />
                <img src={RedCircle} alt='red' className='color-button'
                  onClick={() => {changePenColor('#FE2B01');
                  setPush(1)}} onAnimationEnd={() => setPush(0)} push={push}
                  />
                <img src={GreenCircle} alt='green' className='color-button'
                  onClick={() => {changePenColor('#3FF913');
                  setPush(1)}} onAnimationEnd={() => setPush(0)} push={push}
                  />
                <img src={YellowCircle} alt='yellow' className='color-button'
                  onClick={() => {changePenColor('#FCFC0A');
                  setPush(1)}} onAnimationEnd={() => setPush(0)} push={push}
                  />
                <img src={BlueCircle} alt='blue' className='color-button'
                  onClick={() => {changePenColor('#2A2EFE');
                  setPush(1)}} onAnimationEnd={() => setPush(0)} push={push}
                  />
                <img src={OrangeCircle} alt='orange' className='color-button'
                  onClick={() => {changePenColor('#FF8B00');
                  setPush(1)}} onAnimationEnd={() => setPush(0)} push={push}
                  />
                <img src={PurpleCircle} alt='purple' className='color-button'
                  onClick={() => {changePenColor('#F03EFE');
                  setPush(1)}} onAnimationEnd={() => setPush(0)} push={push}
                  />
            </div>

这是动画的 CSS:

.color-button {
  width: 48px;
  height: 48px;
  vertical-align: bottom;
}

.color-button[push='1'] {
  animation: push 200ms 1;
}

@keyframes push {
  25% {
    transform:scale(0.95);
  }
  50% {
    transform:scale(0.90);
  }
  75% {
    transform:scale(0.85);
  }
  100% {
    transform:scale(0.80);
  }
}

GitHub 代码库在这里:https://github.com/Johnsensei/oekaki

React 组件是一个函数式组件,所以我无法使用 this.setState。

我应该在代码中进行哪些更改以仅在单击的颜色按钮上获得动画?

感谢您的帮助。

【问题讨论】:

    标签: css reactjs react-hooks css-selectors css-animations


    【解决方案1】:

    好的,它以一种非常“反应”的方式来解决问题。

    首先,我们创建一个名为 ColorButton 的新组件

    import React, { useState } from 'react';
    
    const ColorButton = ({ alt, onClick, src }) => {
        const [pushed, setPushed] = useState(false);
      
        return (<img 
                 src={src}
                 alt={alt}
                 className={`color-button ${pushed ? "push" : ""}`}
                 onClick={() => {
                    onClick();
                    setPushed(true);
                 }}
                 onAnimationEnd={() => setPushed(false)}
                 />)
      }
    
      export default ColorButton;
    

    然后我们将其导入并实现到 Main 组件中:

    import ColorButton from './ColorButton';
    
    ...
    
    <div style={{width: 96}}>
    
                    <ColorButton
                      src={BlackCircle}
                      alt='black'
                      onClick={() => changePenColor('#000000')}
                    />
                    <ColorButton
                      src={WhiteCircle}
                      alt='white'
                      onClick={() => changePenColor('#FFFFFF')}
                    />
                    <ColorButton
                      src={RedCircle}
                      alt='red'
                      onClick={() => changePenColor('#FE2B01')}
                    />
                    <ColorButton
                      src={GreenCircle}
                      alt='green'
                      onClick={() => changePenColor('#3FF913')}
                    />
                    <ColorButton
                      src={YellowCircle}
                      alt='yellow'
                      onClick={() => changePenColor('#FCFC0A')}
                    />
                    <ColorButton
                      src={BlueCircle}
                      alt='blue'
                      onClick={() => changePenColor('#2A2EFE')}
                    />
                    <ColorButton
                      src={OrangeCircle}
                      alt='orange'
                      onClick={() => changePenColor('#FF8B00')}
                    />
                    <ColorButton
                      src={PurpleCircle}
                      alt='purple'
                      onClick={() => changePenColor('#F03EFE')}
                    />
    
                </div>
    

    最后,更新 CSS 动画:

    .color-button {
      width: 48px;
      height: 48px;
      vertical-align: bottom;
    }
    
    .push {
      animation: push 200ms 1;
    }
    
    @keyframes push {
      25% {
        transform:scale(0.95);
      }
      50% {
        transform:scale(0.90);
      }
      75% {
        transform:scale(0.85);
      }
      100% {
        transform:scale(0.80);
      }
    }
    

    修复现已上线:https://master.d3irlm8kk772s.amplifyapp.com/

    这是我第一次向 Stack Overflow 发帖。每个人都非常乐于助人和支持我,我也在 Discord 和 Slack 频道寻求帮助。来自 freeCodeCamp Nashville 的 Tyler 特别鸣谢。谢谢!

    【讨论】:

      猜你喜欢
      • 2016-11-26
      • 1970-01-01
      • 2018-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-06
      • 1970-01-01
      相关资源
      最近更新 更多