diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/components/Branding/Branding.module.scss | 41 | ||||
| -rw-r--r-- | src/components/Branding/Branding.tsx | 38 | ||||
| -rw-r--r-- | src/styles/base/_animations.scss | 61 |
3 files changed, 136 insertions, 4 deletions
diff --git a/src/components/Branding/Branding.module.scss b/src/components/Branding/Branding.module.scss index 54bbece..402fa8b 100644 --- a/src/components/Branding/Branding.module.scss +++ b/src/components/Branding/Branding.module.scss @@ -16,6 +16,8 @@ } .logo { + --branding-logo-animation: none; + grid-column: 1; grid-row: 1 / -1; justify-self: center; @@ -27,6 +29,7 @@ border-radius: 50%; transition: all 0.6s linear 0s; transform-style: preserve-3d; + animation: var(--branding-logo-animation); &__front, &__back { @@ -78,22 +81,60 @@ } .name { + --branding-name-animation: none; + grid-column: 2; grid-row: 1; margin: 0; font-family: var(--font-family-secondary); font-size: clamp(var(--font-size-xl), 6vw, var(--font-size-2xl)); font-weight: 500; + letter-spacing: 0.01ex; + position: relative; + + &::after { + content: "|"; + display: block; + width: 0; + height: 100%; + position: absolute; + top: 0; + right: 0; + background: var(--color-bg); + color: var(--color-primary-darker); + font-weight: 400; + visibility: hidden; + animation: var(--branding-name-animation); + } } .job { + --branding-job-animation: none; + grid-column: 2; grid-row: 2; + width: max-content; margin: 0; color: var(--color-fg-light); font-family: var(--font-family-secondary); font-size: var(--font-size-lg); font-weight: 500; + position: relative; + + &::after { + content: "|"; + display: block; + width: 0; + height: 100%; + position: absolute; + top: 0; + right: 0; + background: var(--color-bg); + color: var(--color-primary-darker); + font-weight: 400; + visibility: hidden; + animation: var(--branding-job-animation); + } } .link { diff --git a/src/components/Branding/Branding.tsx b/src/components/Branding/Branding.tsx index 317a8f3..517deb8 100644 --- a/src/components/Branding/Branding.tsx +++ b/src/components/Branding/Branding.tsx @@ -4,7 +4,7 @@ import Head from 'next/head'; import Image from 'next/image'; import Link from 'next/link'; import { useRouter } from 'next/router'; -import { ReactElement } from 'react'; +import { ReactElement, useEffect, useRef } from 'react'; import { useIntl } from 'react-intl'; import { Person, WithContext } from 'schema-dts'; import styles from './Branding.module.scss'; @@ -16,6 +16,36 @@ const Branding: BrandingReturn = ({ isHome = false }) => { const intl = useIntl(); const { locale } = useRouter(); const TitleTag = isHome ? 'h1' : 'p'; + const logoRef = useRef<HTMLDivElement>(null); + const titleRef = useRef<HTMLHeadingElement | HTMLParagraphElement>(null); + const jobRef = useRef<HTMLParagraphElement>(null); + + useEffect(() => { + if (logoRef.current) { + logoRef.current.style.setProperty( + '--branding-logo-animation', + 'flip-logo 5.4s ease-in 0s 1' + ); + } + }, []); + + useEffect(() => { + if (titleRef.current) { + titleRef.current.style.setProperty( + '--branding-name-animation', + 'blink 0.5s ease-in-out 0s 1, branding-name-typing 2.8s linear 0s 1' + ); + } + }, []); + + useEffect(() => { + if (jobRef.current) { + jobRef.current.style.setProperty( + '--branding-job-animation', + 'branding-job-typing 7s linear 0s 1, Blink 0.8s ease-in-out 5s 3' + ); + } + }, []); const schemaJsonLd: WithContext<Person> = { '@context': 'https://schema.org', @@ -39,7 +69,7 @@ const Branding: BrandingReturn = ({ isHome = false }) => { ></script> </Head> <div id="branding" className={styles.wrapper}> - <div className={styles.logo}> + <div className={styles.logo} ref={logoRef}> <div className={styles.logo__front}> <Image src={photo} @@ -59,12 +89,12 @@ const Branding: BrandingReturn = ({ isHome = false }) => { <Logo /> </div> </div> - <TitleTag className={styles.name}> + <TitleTag ref={titleRef} className={styles.name}> <Link href="/"> <a className={styles.link}>{settings.name}</a> </Link> </TitleTag> - <p className={styles.job}> + <p ref={jobRef} className={styles.job}> {locale?.startsWith('en') ? settings.baseline.en : settings.baseline.fr} diff --git a/src/styles/base/_animations.scss b/src/styles/base/_animations.scss index 325c673..773bf1d 100644 --- a/src/styles/base/_animations.scss +++ b/src/styles/base/_animations.scss @@ -75,3 +75,64 @@ transform: translateY(0); } } + +@keyframes flip-logo { + 0%, + 85% { + transform: rotateY(180deg); + } + + 100% { + transform: rotateY(0deg); + } +} + +@keyframes branding-name-typing { + 0%, + 20% { + width: 100%; + visibility: visible; + } + + 100% { + width: 0; + } +} + +@keyframes branding-job-typing { + 0% { + width: 100%; + content: ""; + visibility: visible; + } + + 48% { + content: ""; + } + + 49% { + content: "|"; + } + + 51% { + width: 100%; + } + + 70% { + width: 0; + } + + 100% { + width: 0; + } +} + +@keyframes blink { + 0% { + color: var(--color-primary-darker); + } + + 100% { + color: var(--color-bg-tertiary); + } +} |
