Framer-motion: Layout

최혜린·2024년 9월 29일

Layout

https://www.framer.com/motion/layout-animations/

Layout 기능은 컴포넌트의 레이아웃 변경을 애니메이션으로 처리하는 기능이다. 요소의 크기, 정렬 등이 변경될 때 애니메이션을 통해 부드럽게 전환된다.

layout 속성을 설정하여 애니메이션 효과를 적용할 수 있다.


  const [isExpanded1,setIsExpanded1]=useState(false);


    return(
        <div>
            <motion.div 
            layout
            transition={{duration:2,ease:"easeInOut"}}
            onClick={()=>setIsExpanded1(!isExpanded1)}
            style={{
                width:isExpanded1?300:100,
                height:100,
                backgroundColor:"lightblue",
                margin:"20px auto",
            }} >
                Layout 적용
            </motion.div>
            )

레이아웃 애니메이션에 대해서만 전환을 설정하려는 경우 특정 속성에 대한 transition 지정이 가능하다.

            transition={{
                layout : {
                duration:2,
                ease:"easeInOut" },
                
                opacity:{
                    duration : 1,
                    ease : "linear"
                }
            }}

LayoutGroup

애니메이션이 될 시 다른 인접한 컴포넌트와 조합을 위해 LayoutGroup 을 사용할 수 있다. Layout Group은 여러 motion 컴포넌트들이 함께 레이아웃 애니메이션을 수행하도록 그룹화하는 기능을 제공한다.

import{LayoutGroup ,motion} from 'framer-motion'
import { useState } from 'react'

function Accordian(){
    const [isOpen,setIsOpen] = useState(false)

    return(
        <motion.div
        layout
        style={{height:isOpen?"100px":"500px", backgroundColor:"lightblue"}}
        onClick={()=>setIsOpen(!isOpen)}
        >
          이건 LayoutGroup 아코디언입니다
        </motion.div>

    )
}


function Comp1(){


    return(
        <LayoutGroup>
            <Accordian/>
            <Accordian/>
        </LayoutGroup>
    )
}
export default Comp1

LayoutGroup-LayoutId

layoutId는 여러 motion 요소들 간의 공유 레이아웃 애니메이션을 수행할 수 있도록 도와주는 prop 이다. layoutId를 사용하면 동일한 layoutId를 가진 요소들이 서로 애니메이션을 통해 변환될 수 있다.


import{LayoutGroup, motion} from 'framer-motion'
import { useState } from 'react'

function Tab({label,isSelected, onClick}){

    return(
        <li
         style={{ listStyle:"none",margin:"0 10px",cursor:"pointer"}}
         onClick={onClick}  >
            {label}
            {isSelected? (
                <motion.div
                layoutId='underline'               
                style={{height:2, backgroundColor:"blue", borderRadius:4,
                    marginTop:2}}>

                </motion.div>): null}

        </li>
    )
}

function TabRow({items, selectedTab,onSelect}){
    return(
        <ul style={{display:"flex", padding:0}}>
            {items.map((item,index)=>(
                <Tab key={index}
                label={item.label}
                isSelected={selectedTab === index}
                onClick={(()=>onSelect(index))}>

                </Tab>
            
            ))}
        </ul>
    )
}

function Comp1(){
    const [ selectedTab,setSelectedTab]=useState(0)
    const tabs = [
        {label : "Tab1"},
        {label : "Tab2"},
        {label : "Tab3"}
    ]

    return(
        <LayoutGroup>
            <TabRow
                items={tabs}
                selectedTab={selectedTab}
                onSelect={setSelectedTab}
                />
        </LayoutGroup>
    )
}
export default Comp1


profile
산으로 가는 코딩.. 등산 중..🌄

0개의 댓글