CSS 트랜지션 이벤트 활용
.circle {
transition-property: width, height, margin-left, margin-top;
transition-duration:1s;
position: fixed;
transform: translateX(-50%) translateY(-50%);
background-color: red;
border-radius: 50%;
}
<!DOCTYPE html>
<html>
<head>
<script src="test.js" defer></script>
<link rel="stylesheet" href="test.css">
</head>
<body>
<button >start</button>
</body>
</html>
function showCircle(cx, cy, radius, callback){
let div = document.createElement('div');
div.style.width = 0;
div.style.height = 0;
div.style.left =cx+'px';
div.style.top = cy +'px';
div.className = 'circle';
document.body.append(div);
// CSS트랜지션 발생시킨다.
setTimeout(() => {
div.style.width = radius * 2 + 'px';
div.style.height = radius * 2 + 'px';
}, 0);
// 주의사항
// style 속성하나하나가 개별적으로 트랜지션이벤트를 발생시킨다.
// width 한번, height 한번 , 총 2번 발생한다.
// 트랜지션이벤트 등록한다.
// transitionend 이벤트가 완료되었을때 발생
div.addEventListener('transitionend', function (ev) {
callback(ev);//이벤트 완료시 콜백함수 호출
},{once:true});
}
// 2번이벤트가 발생하므로 {once:true} 한번만 발생하게한다.
// 트랜지션이벤트 완료시 자동으로 호출되는 콜백
function callback(ev){
ev.target.classList.add('message-ball');
ev.target.append("안녕하세요!");
}
// div요소이므로 텍스트노드를 추가하고 div컨테이너에 스타일을 지정하면 된다. 구지 div를 또만들어서 넣을 필요가 없다.
let btn = document.querySelector('button');
btn?.addEventListener('click',()=>{
showCircle(150, 150, 100, callback);
});
원이 커지는 트랜지션이벤트가 언제 완료될지 사용자는 모르기때문에 콜백을 사용한다.
이벤트가 완료되었을때 호출되는 콜백함수를 만들어서 버튼이벤트에부터 넣고 원그리는 함수에서 받고 트랜지션이벤트에서 호출해야 한다.
promise를 이용한 예
function showCircle(cx, cy, radius){
let div = document.createElement('div');
div.style.width = 0;
div.style.height = 0;
div.style.left =cx+'px';
div.style.top = cy +'px';
div.className = 'circle';
document.body.append(div);
// CSS트랜지션 발생시킨다.
setTimeout(() => {
div.style.width = radius * 2 + 'px';
div.style.height = radius * 2 + 'px';
}, 0);
// 비동기작업을 Promise로 감싸고 Promise객체를 반환한다.
// 완료시 resolve호출한다.
return new Promise(function(resolve){
div.addEventListener('transitionend', function (ev) {
resolve(ev.target);
},{once:true});
});
}
let btn = document.querySelector('button');
btn?.addEventListener('click',()=>{
// Promise객체에 소비자함수를 연결하고 기다린다.
showCircle(150, 150, 100).then(div => {
div.classList.add('message-ball');
div.append("Hello, world!");
});
});