搜尋

首頁  >  問答  >  主體

使用React和內聯CSS的蘋果動畫問題

我試著在React中使用HTML和CSS重新建立這個動畫,使用內聯樣式和TypeScript。我正在創建一個帶有樣式資訊的對象,並在style屬性中引用它。下面是程式碼。它不起作用,我不確定我做錯了什麼,我懷疑樣式沒有正確定義和引用?

這是我嘗試重寫的原始Codepen範例: Apple動畫

這是我的程式碼

import React from 'react';

const styles = {
    
    '@keyframes showTopText': {
        '0%': { transform: 'translate3d(0, 100%, 0)' },
        '40%, 60%': { transform: 'translate3d(0, 50%, 0)' },
        '100%': { transform: 'translate3d(0, 0, 0)' },
    },
    '@keyframes showBottomText': {
        '0%': { transform: 'translate3d(0, -100%, 0)' },
        '100%': { transform: 'translate3d(0, 0, 0)' },
    },

    animatedTitle: {
        color: '#222',
        fontFamily: 'Roboto, Arial, sans-serif',
        height: '90vmin',
        left: '50%',
        top: '50%',
        transform: 'translate(-50%, -50%)',
        width: '90vmin',
    },
    'animatedTitle > div': {
        height: '50%',
        overflow: 'hidden',
        position: 'absolute',
        width: '100%',
    },
    'animatedTitle > div div': {
        fontSize: '12vmin',
        padding: '2vmin 0',
        position: 'absolute',
    },
    'animatedTitle > div div span': {
        display: 'block',
    },
    'animated-title > div.text-top': {
        borderBottom: '1vmin solid #000',
        top: 0,
    },
    'animatedTitle > div.text-top div': {
        animation: 'showTopText 1s',
        animationDelay: '0.5s',
        animationFillMode: 'forwards',
        bottom: 0,
        transform: 'translate(0, 100%)',
    },
    'animatedTitle > div.text-top div span:first-child': {
        color: '#767676',
    },
    'animatedTitle > div.text-bottom': {
        bottom: 0,
    },
    'animatedTitle > div.text-bottom div': {
        animation: 'showBottomText 0.5s',
        animationDelay: '1.75s',
        animationFillMode: 'forwards',
        top: 0,
        transform: 'translate(0, -100%)',
    },
};

function Design() {
    return (
        <div style={styles.animatedTitle}>
            <div style={styles['animatedTitle > div.text-top div']}>
                <div>
                    <span>mimicking</span>
                    <span>apple's design</span>
                </div>
            </div>
            <div style={styles['animatedTitle > div.text-bottom']}>
                <div>for the win!</div>
            </div>
        </div>
    );
}

export { Design };

P粉729436537P粉729436537394 天前418

全部回覆(1)我來回復

  • P粉115840076

    P粉1158400762024-01-11 10:37:49

    您可以嘗試使用 styled-components 來讓您的元件更靈活和相容。我使用 styled-components 複製了 codepen 的範例,並使其易於擴展。

    因此,TopAnimateBlockBottomAnimateBlock 都有 numOfLine 屬性,表示區塊內有多少行。在BottomAnimateBlock 中的第二個屬性是delayTopLine,它應該與TopAnimateBlock 中的numOfLine 數量相同,因為我們需要等待頂部行播放。

    此外,您可以透過TextStylecolor 屬性輕鬆變更文字顏色,並傳遞顏色值,HEX 顏色或rgba() / hsla()

    TextAnimation.tsx

    import styled, { keyframes } from 'styled-components';
    
    const showTopText = keyframes`
      0% { transform: translate3d(0, 100% , 0); }
      40%, 60% { transform: translate3d(0, 50%, 0); }
      100% { transform: translate3d(0, 0, 0); }
    `;
    const showBottomText = keyframes`
      0% { transform: translate3d(0, -100%, 0); }
      100% { transform: translate3d(0, 0, 0); }
    `;
    
    const Section = styled.section`
      width: calc(100% + 10vmin);
      display: flex;
      flex-flow: column;
      padding: 2vmin 0;
      overflow: hidden;
      &:last-child {
        border-top: 1vmin solid white;
      }
    `;
    
    const Block = styled.div<{ numOfLine: number }>`
      position: relative;
    `;
    const TopAnimateBlock = styled(Block)`
      animation: ${showTopText} calc(0.5s * ${props => props.numOfLine}) forwards;
      animation-delay: 0.5s;
      transform: translateY(calc(100% * ${props => props.numOfLine}));
    `;
    const BottomAnimateBlock = styled(Block)<{ delayTopLine: number }>`
      animation: ${showBottomText} calc(0.5s * ${props => props.numOfLine}) forwards;
      animation-delay: calc(0.7s * ${props => props.delayTopLine});
      transform: translateY(calc(-100% * ${props => props.numOfLine}));
    `;
    
    const TextStyle = styled.p<{ color: string }>`
      font-family: Roboto, Arial, sans-serif;
      font-size: 12vmin;
      color: ${props => props.color};
    `;
    
    export const TextAnimation = () => {
      return (
        <>
          <Section>
            <TopAnimateBlock numOfLine={2}>
              <TextStyle color="grey">mimicking</TextStyle>
              <TextStyle color="white">apple's design</TextStyle>
            </TopAnimateBlock>
          </Section>
          <Section>
            <BottomAnimateBlock numOfLine={1} delayTopLine={2}>
              <TextStyle color="white">for the win!</TextStyle>
            </BottomAnimateBlock>
          </Section>
        </>
      );
    };
    

    如果我們想要動畫化3行而不是2行,只需添加/更改:

    1. 新增新的 TextStyle 元件
    2. TopAnimateBlock 中將numOfLine 從2改為3,在BottomAnimateBlock 中將delayTopLine 從2改為3
    3. 並將關鍵影格替換為以下片段:
    const showTopText = keyframes`
      0% { transform: translate3d(0, 100% , 0); }
      25%, 40% { transform: translate3d(0, 66%, 0); }
      60%, 75% { transform: translate3d(0, 33%, 0); }
      100% { transform: translate3d(0, 0, 0); }
    `;
    

    回覆
    0
  • 取消回覆