Orbit Animation (#48)
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import clsx from 'clsx'
|
||||
import gsap from 'gsap'
|
||||
import * as React from 'react'
|
||||
import mergeRefs from 'react-merge-refs'
|
||||
|
||||
import { useAnimationContext } from '~/context/animation'
|
||||
import { useIsomorphicLayoutEffect } from '~/hooks/use-isomorphic-layout-effect'
|
||||
import { gsap } from '~/lib/gsap'
|
||||
|
||||
import s from './section.module.scss'
|
||||
|
||||
|
||||
@@ -207,3 +207,16 @@
|
||||
|
||||
margin-top: tovw(32px, 'default', 32px);
|
||||
}
|
||||
|
||||
.ball {
|
||||
width: tovw(270px, 'default', 270px);
|
||||
height: tovw(270px, 'default', 270px);
|
||||
background-color: var(--color-white);
|
||||
box-shadow: 0px 4px 115px 15px #0000f4, 0px 0px 70px 20px #0a33ff,
|
||||
inset -39px -20px 100px rgb(0 0 244 / 0.73);
|
||||
border-radius: 100%;
|
||||
overflow: hidden;
|
||||
top: 39.2%;
|
||||
left: 20.7%;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import clsx from 'clsx'
|
||||
import * as React from 'react'
|
||||
|
||||
import { Arrow } from '~/components/icons/arrow'
|
||||
import Line from '~/components/icons/line'
|
||||
@@ -6,6 +7,9 @@ import { Container } from '~/components/layout/container'
|
||||
import Section from '~/components/layout/section'
|
||||
import { ButtonLink } from '~/components/primitives/button'
|
||||
import Heading from '~/components/primitives/heading'
|
||||
import { useIsomorphicLayoutEffect } from '~/hooks/use-isomorphic-layout-effect'
|
||||
import { useMedia } from '~/hooks/use-media'
|
||||
import { gsap } from '~/lib/gsap'
|
||||
|
||||
import Benefit from './benefit'
|
||||
import s from './benefits.module.scss'
|
||||
@@ -25,6 +29,34 @@ import {
|
||||
} from './icons'
|
||||
|
||||
const Benefits = () => {
|
||||
const ballRef = React.useRef<HTMLDivElement>(null)
|
||||
const gridRef = React.useRef<HTMLDivElement>(null)
|
||||
const userRef = React.useRef<HTMLDivElement>(null)
|
||||
const isMobile = useMedia('(max-width: 768px)')
|
||||
|
||||
useIsomorphicLayoutEffect(() => {
|
||||
if (isMobile || typeof isMobile === 'undefined') return
|
||||
if (!ballRef.current) return
|
||||
|
||||
const timeline = gsap.timeline({
|
||||
paused: true,
|
||||
smoothChildTiming: true
|
||||
})
|
||||
|
||||
timeline.to(ballRef.current, {
|
||||
ease: 'power2.inOut',
|
||||
motionPath: {
|
||||
path: 'M3.99988.5S35.5 437.5 456.999 457C895.558 477.289 1013.5 653.5 1013.5 653.5',
|
||||
align: 'self'
|
||||
},
|
||||
scrollTrigger: {
|
||||
trigger: gridRef.current,
|
||||
start: 'top 20%',
|
||||
endTrigger: userRef.current,
|
||||
scrub: 1
|
||||
}
|
||||
})
|
||||
}, [isMobile])
|
||||
return (
|
||||
<Section className={s['section']}>
|
||||
<Container className={s['header']}>
|
||||
@@ -32,6 +64,7 @@ const Benefits = () => {
|
||||
Benefits
|
||||
</Heading>
|
||||
<div className={s['grid']}>
|
||||
<div className={s['ball']} ref={ballRef} />
|
||||
<div className={s['icon']}>
|
||||
<Arrow />
|
||||
</div>
|
||||
@@ -60,7 +93,7 @@ const Benefits = () => {
|
||||
/>
|
||||
<div className={s['background']}>
|
||||
<Container className={s['developers']}>
|
||||
<div className={s['service__header']}>
|
||||
<div className={s['service__header']} ref={gridRef}>
|
||||
<span>01</span>
|
||||
<Line className={s['line']} height={144} />
|
||||
<Heading as="h3" variant="sm">
|
||||
@@ -104,7 +137,7 @@ const Benefits = () => {
|
||||
/>
|
||||
<Container className={s['users__container']}>
|
||||
<Container className={s['users']}>
|
||||
<div className={s['service__header']}>
|
||||
<div className={s['service__header']} ref={userRef}>
|
||||
<span>02</span>
|
||||
<Line className={s['line']} height={112} />
|
||||
<Heading as="h3" variant="sm">
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
import gsap from 'gsap'
|
||||
import { CSSRulePlugin } from 'gsap/dist/CSSRulePlugin'
|
||||
import { CustomEase } from 'gsap/dist/CustomEase'
|
||||
import { MotionPathPlugin } from 'gsap/dist/MotionPathPlugin'
|
||||
import { Observer } from 'gsap/dist/Observer'
|
||||
import { ScrollSmoother } from 'gsap/dist/ScrollSmoother'
|
||||
import { ScrollTrigger } from 'gsap/dist/ScrollTrigger'
|
||||
import { SplitText } from 'gsap/dist/SplitText'
|
||||
|
||||
gsap.registerPlugin(
|
||||
CSSRulePlugin,
|
||||
CustomEase,
|
||||
Observer,
|
||||
ScrollSmoother,
|
||||
@@ -15,6 +14,8 @@ gsap.registerPlugin(
|
||||
SplitText
|
||||
)
|
||||
|
||||
gsap.registerPlugin(MotionPathPlugin)
|
||||
|
||||
const GOLDEN_RATIO = (1 + Math.sqrt(5)) / 2
|
||||
const RECIPROCAL_GR = 1 / GOLDEN_RATIO
|
||||
const DURATION = RECIPROCAL_GR * 0.85
|
||||
@@ -159,10 +160,10 @@ gsap.registerEffect({
|
||||
})
|
||||
|
||||
export {
|
||||
CSSRulePlugin,
|
||||
CUSTOM_EASE,
|
||||
DURATION,
|
||||
gsap,
|
||||
MotionPathPlugin,
|
||||
Observer,
|
||||
ScrollSmoother,
|
||||
ScrollTrigger,
|
||||
|
||||
Reference in New Issue
Block a user