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 을 사용할 수 있다. 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

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
