부자 되기 위한 블로그, 머니킹

안녕하세요. 오늘도 열심히 개발 공부를 하는 중입니다. 개발을 하다보면 모달이나 팝업을 사용할 때가 많은데요. 이번 포스팅에서는 순수 js만으로 창의 사이즈를 조절하는 방법에 대해서 알아보겠습니다.

 

 

창 사이즈 조절 기본 개념

보통 어떤 os던가 창을 조절하는 방법은 마우스 커서를 양 대각선 끝쪽에 위치하면 커서 모양이 변하고 이를 원하는 방향으로 드래그하여 옮기면 사이즈가 조절되는 방식입니다. 

 

따라서 기본 개념은 (1) 마우스를 대각선 끝쪽에 위치하면 커서 모양이 변한다. (2) 그 상태에서 드래그를 하면 창의 사이즈가 조절된다. 입니다. (1)번의 경우는 css 이벤트를 주면 되겠고 (2)번의 경우는 event를 등록하여 드래그 하는 동안 실시간으로 창의 사이즈를 변하게 하면 되겠죠.

 

이번 개발은 혼자만의 생각이 아닌 유튜브를 많이 참조하여 개발을 하게 되었습니다.

 

View 설정

html 설정

<div class="window window--safari w-100 h-100" data-windowBackdrop="true"
     data-window="safari">
  <div class="resizer ne"></div>
  <div class="resizer nw"></div>
  <div class="resizer sw"></div>
  <div class="resizer se"></div>
  <div class="window__handler">
    <div class="window__controls">
      <a class="window__close opt-close"></a>
      <a class="window__minimize"></a>
      <a class="window__maximize"></a>
    </div>
  </div>
  <div class="window__body" style="display: unset;">

    <div class="login">
      <div class="form">
        <div class="login-form">
          <h5 id="login-success-message" style="color:black;"></h5>
          <button id="app-get-btn">app get</button>
          <span class="material-icons">lock</span>
          <input type="text" placeholder="email" id="member-email" required/>
          <input type="password" placeholder="password" id="member-password" required/>
          <button id="login-btn">login</button>
        </div>
      </div>
    </div>

  </div>
</div>

 

우선 각 대각선 끝 쪽에 마우스가 대각선 끝에 위치했다는 것을 알려줄만한 영역이 필요합니다. 각 방향을 따서 ne,nw,sw,se로 클래스 이름을 명명하였습니다. 이들의 css로 위치 및 영역을 설정해야 합니다.

 

 

css 설정

/* resizer */
.resizer {
    position: absolute;
    width: 10px;
    height: 10px;
    border-radius: 5px;
    z-index: 999;
}

.resizer.nw {
    top: -1px;
    right: -1px;
    cursor: ne-resize;
}

.resizer.ne {
    top: -1px;
    left: -1px;
    cursor: nw-resize;
}

.resizer.sw {
    bottom: -1px;
    left: -1px;
    cursor: sw-resize;
}

.resizer.se {
    bottom: -1px;
    right: -1px;
    cursor: se-resize;
}

 

부모의 position을 absolute로 설정하고 이들의 포지션을 각각 대각선 끝 쪽으로 위치시킵니다. 영역의 크기는 정사각형 1px 크기로 설정하였습니다.

 

 

 

창 크기조절 이벤트

// 윈도우 사이즈 창 조절
const window_resize = async () => {
    let app_windows = document.querySelectorAll(".app-window");

    Array.from(app_windows).forEach(function (app_window) {

        const resizers = app_window.querySelectorAll(".resizer");
        let currentResizer;

        for (let resizer of resizers) {
            resizer.addEventListener('mousedown', mousedown);

            function mousedown(e) {
                currentResizer = e.target;
                isResizing = true;

                let prevX = e.clientX;
                let prevY = e.clientY;

                window.addEventListener('mousemove', mousemove);
                window.addEventListener('mouseup', mouseup);

                function mousemove(e) {
                    const rect = app_window.getBoundingClientRect();

                    if (currentResizer.classList.contains("se")) {
                        app_window.style.width = rect.width - (prevX - e.clientX) + "px";
                        app_window.style.height = rect.height - (prevY - e.clientY) + "px";
                    } else if (currentResizer.classList.contains("sw")) {
                        app_window.style.width = rect.width + (prevX - e.clientX) + "px";
                        app_window.style.height = rect.height - (prevY - e.clientY) + "px";
                        app_window.style.left = rect.left - (prevX - e.clientX) + "px";
                    } else if (currentResizer.classList.contains('nw')) {
                        app_window.style.width = rect.width - (prevX - e.clientX) + "px";
                        app_window.style.height = rect.height + (prevY - e.clientY) + "px";
                        app_window.style.top = rect.top - (prevY - e.clientY) + "px";
                    } else {
                        app_window.style.width = rect.width + (prevX - e.clientX) + "px";
                        app_window.style.height = rect.height + (prevY - e.clientY) + "px";
                        app_window.style.top = rect.top - (prevY - e.clientY) + "px";
                        app_window.style.left = rect.left - (prevX - e.clientX) + "px";
                    }


                    prevX = e.clientX;
                    prevY = e.clientY;
                }

                function mouseup() {
                    window.removeEventListener("mousemove", mousemove);
                    window.removeEventListener("mouseup", mouseup);
                    isResizing = false;
                }

            }
        }
    })

}

 

mouseup 이벤트와 mousemove 이벤트를 window 객체 이벤트 리스너에 등록시키고 마우스 움직임을 실시간으로 감지하여 해당 창의 사이즈를 조절합니다.

 

 

이벤트는 각 대각선의 끝 4개를 모두 등록해야 하여 for문을 활용하였으며 해당 요소의 크기를 js의 함수로 사각형 모양을 뽑아주었고 width와 크기를 실시간으로 감지하여 사이즈를 조절시켜주었습니다.

 

 

저도 뭔가 처음 따라했을 때 복잡해서 이해가 안갔는데 계속해서 보시면 아마 이해가 되실것입니다