이전 애니메이션
미리보기
이번 과정을 따라오시면 아래와 같이 스트리밍 되는 듯한 토글 애니메이션을 구현하실 수 있게 됩니다.
HTML
마크업은 크게 추가할 것은 없습니다. 아래와 같이 두 가지 요소만 만들어주면 됩니다. 나중에 box 태그 내부에 스트리밍 효과의 span 태그를 추가할 예정입니다.
<div class="container">
<div class="box">
</div>
</div>
CSS
CSS 기본 여백 제거
우선 브라우저에 기본 적용된 여백을 제거하고, 콘텐츠의 길이와 높이를 계산 시 margin 과 padding 을 포함하도록 box-sizing 을 border-box 로 지정해주고, 여백 제거를 위해 margin 과 padding을 모두 0으로 설정해줍니다.
* {
margin:0;
padding:0;
box-sizing:border-box;
}
body 태그 설정
배경은 약간 밝고 어두운 계열의 #333 을 지정해주고, body 태그 내부의 요소가 가로-세로 모두 중앙정렬이 될 수 있도록 display 속성을 flex 로 지정 후, align-items 와 jsutify-content 속성 모두 center 로 지정 해줍니다.
body {
background:#333;
width:100%;
height:100vh;
display:flex;
align-items:center;
justify-content:center;
}
.box 꾸미기
position을 relative 로 설정하여, 향후 .box 태그 내부에 추가할 자식요소의 position을 absolute 로 지정하여도 좌표 기준이 box 태그가 되도록 해줍니다. 또한 자식요소가 랜덤한 위치에 배치될 때 부모 요소 바깥으로 나가도 보이지 않도록 overflow를 hidden 으로 지정합니다. 그 외에는 모양을 만들어주기 위한 속성이므로 원하는 모양으로 꾸미셔도 상관 없습니다.
.box {
position:relative;
overflow:hidden;
border-radius:20px;
width:100px;
height:45px;
border:none;
box-shadow:0 0 100px white;
}
그 코드를 그대로 적용한다면, 아래와 같은 형태가 만들어집니다.
line 꾸미기
스트리밍 처럼 움직여줄 line 을 꾸며줍니다. 이는 자바스크립트에서 동적으로 생성되어 DOM 에 삽입될 span 태그를 나타냅니다. box 태그 내부에서 랜덤한 Y 축에 배치될 것이므로 position을 absolute 로 지정하고, width의 경우에는 앞서 .box 박스(상위 부모요소)의 width/2-1 이 되도록 설정해줍니다. height의 경우에는 적절한 값을 넣어주기만 하면 됩니다. 이는 완성후에 나타나는 모양에 따라서 조절합시다.
.line {
box-shadow:0 4px 0px 0 white;
transition: 0.5s left ease;
width:49px;
height:2px;
border-radius:5%;
background:white;
position:absolute;
left:0;
top:0;
}
나머지는 애니메이션 효과를 위한 부분과 위치좌표를 부모요소의 (0,0) 좌표로 고정시키기 위한 left 와 top 속성을 지정하는 등 부수적인 것이므로 설명을 넘어가도록 하겠습니다.
.active 속성 추가 시 line의 이동 거리 설정
CSS 설정 마지막입니다. 향후 박스를 사용자가 클릭하면 해당 .box 는 새로운 클래스인 .active를 받게 됩니다. 즉, 활성화 시 line의 이동 거리를 설정해주는데, 이 또한 부모요소의 넓이/2-1 이 되도록 설정해주면 됩니다. 참고로 일일이 계산하기 귀찮다고 느끼신다면, calc(var(--parent-wdith)/2px-1)) 와 같이 CSS의 계산기 함수와 변수를 사용해도 동일한 결과를 얻으 실 수 있습니다.
.active.box {
.line {
left:49px;
}
}
JS
box 태그 가져오기
우선 box 태그를 가져와서 box 변수에 할당해 줍니다.
const box = document.querySelector('.box')
box 에 이벤트 리스너 등록 및 handleToggle 함수 구현하기
그 후 box 태그에 click 이벤트를 등록해주고, 이벤트 콜백으로 실행할 handleToggle 함수를 구현해 줍니다.
box.addEventListener('click',handleToggle)
function handleToggle(e){
const target = e.currentTarget
target.classList.toggle('active')
}
handleToggle 함수의 경우, box 태그의 classList 객체에 .activle 클래스를 토글(toggle) 하여 추가 및 제거를 손쉽게 할 수 있도록 해주는 함수입니다.
createRandomPositionElement | 요소 생성 함수 구현하기
이번에는 매개변수로 전달받은 요소를 갯수 만큼 생성하여 반환하는 함수를 구현 합니다. 이 때 요소를 생성함과 동시에 각 요소에 style 속성 중 transform:translate 를 적용하여 순차적으로 요소가 상단에서 하단으로 그려지도록 해줍니다. 또한, transition 적용 시 딜레이를 랜덤하게 설정하여 스트리밍 효과가 나타나도록 만들어줍니다. 해당 로직들이 애니메이션의 핵심이 되겠습니다.
/** 요소 생성*/
function createRandomPositionElement(count=1, elName='span', className='line'){
const elements = []
for(let i=0; i<count; i++) {
const position= i
const el = document.createElement(elName)
el.classList.add(className)
el.style.transform=`translate(0,${position}px)` // Y 축 위치에 요소를 차례대로 배치합니다.
el.style.transitionDelay=`${Math.random()*0.5}s`// 생성된 각 요소에 transition 시 지연시간을 랜덤하게 추가해줍니다.
elements.push(el)
}
return elements
}
renderElement | 생성 요소를 DOM 에 렌더링하는 함수 구현
마지막으로 앞서 create 함수를 통해 생성된 요소를 실제 DOM 에 그려주는 함수를 구현합니다. 매개변수로 요소를 추가할 부모요소인 target 과 각 요소들을 의미하는 elements 를 받습니다. 그리고 해당 요소들은 배열 형태로 받기 때문에 target.append(...elements) 와 같이 전개연산자를 사용하여 [span, span] 형식을 span, span 형식으로 만들어주고 이를 target 요소의 자식 요소로 모두 추가하도록 해줍니다. 이렇게 되면 굳이 element의 수 만큼 반복문을 돌 필요 없이 성능을 최적화할 수 있습니다.
/** DOM 요소 렌더링 */
function renderElement(target, elements){
target.append(...elements)
}
구현한 함수 호출하기
앞서 요소를 만들고, 요소를 DOM 에 반영하는 함수를 호출해주면 끝입니다.
const elements = createRandomPositionElement(40, 'span','line')
renderElement(box, elements )
구현결과
이상 애니메이션 구현을 마치도록 하겠습니다. 고생 많으셨습니다.
See the Pen 샤샤샥 토글 by youngwan2 (@youngwan2) on CodePen.
'UI 디자인 애니메이션 연구소' 카테고리의 다른 글
스크롤링 헤드라인 이라 불리는 뉴스티커 UI, 원리부터 구현 까지 (1) | 2024.06.27 |
---|---|
HTML, CSS 로 불타는 입력창(Input) 만들기 (0) | 2024.06.20 |
CSS, JS를 이용한 웅장한 N-S(자석) 애니메이션 제작 (0) | 2024.06.07 |
HTML,CSS 를 사용한 3D 카드 회전 애니메이션 만들기 (0) | 2024.06.01 |
HTML,CSS,JS 로 간단한 무한 슬라이드 만들기 3탄 (0) | 2024.05.31 |