콜백을 이용한 움직이는 원

lee jae hwan·2022년 8월 2일

javascript

목록 보기
79/107

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!");
  });
});

0개의 댓글