JS) 스와이프 div


도움을 얻은 블로거
https://velog.io/@parkoon/%EC%88%98%ED%8F%89%EC%9C%BC%EB%A1%9C-%EC%8A%A4%ED%81%AC%EB%A1%A4-%ED%95%A0-%EC%88%98-%EC%9E%88%EB%8A%94-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EB%A7%8C%EB%93%A4%EA%B8%B0

https://velog.io/@miminishin/swiper.js-%EC%97%86%EC%9D%B4-swipe-%EB%A7%8C%EB%93%A4%EC%96%B4%EB%B3%B4%EA%B8%B0-1

두분께 감사의 말씀올리며 포스팅합니다.

const container = document.querySelector('.scroll-container');
const inner = document.querySelector('.inner');
const bbline = document.getElementById('bbline');
const navColor = document.querySelectorAll('.navColor');

let startPos = 0;
let offset = 0;
let curPos = 0;
const cnWidth = container.clientWidth;

window.addEventListener('DOMContentLoaded', e => {
    const body = document.querySelector('body');
    body.classList.add('scrollNonBox');
})

// 이동이벤트
container.addEventListener('touchstart', (e) => {
    startPos = e.touches[0].pageX;  // 터치한 x 좌표
});

container.addEventListener('touchmove', (e) => {
    inner.style.transitionDuration = '0ms';
    offset = curPos + (e.targetTouches[0].pageX - startPos); // 이동중인 x좌표
    inner.style.transform = `translate3d(${offset}px, 0px, 0px)`;
    bbline.style.transform = `translate3d(${-offset/3}px, 0px, 0px)`;
});

container.addEventListener('touchend', (e) => {
    const sum = curPos + (e.changedTouches[0].pageX - startPos); //바낀 x좌표
    let finalX = Math.round(sum / cnWidth) * cnWidth;
    let index = 0;
    clearColor();
    // 0은 첫단 영역의 시작이다  이동될 수록 -
    if (finalX >= 0) {
        finalX = 0;
        index = 1;
    }
    // 끝단 영역보다 더 작으면 끝단으로
    else if (finalX <= -(cnWidth * (3 - 1))) {
        finalX = -(cnWidth * (3 - 1));
        index = 3;
    } else {
        index = 2;
    }
    ex(index, finalX)
});

// 클릭이벤트
navColor.forEach(e => {
    e.addEventListener('click', (e) => {
        let index = 0;
        if(e.pageX < cnWidth/3) {
            index = 1;
        } else if(e.pageX < cnWidth/3*2) {
            index = 2;
        } else {
            index = 3;
        }
        let finalX = (-cnWidth * (index - 1))
        ex(index, finalX);

    })
})


function clearColor() {
    navColor.forEach(e => {
        e.classList.remove("activeBox");
    })
}

function ex(index, finalX) {
    clearColor()
    navColor[index-1].classList.add("activeBox");
    inner.style.transform = `translate3d(${finalX}px, 0px, 0px)`;
    bbline.style.transform = `translate3d(${-finalX/3}px, 0px, 0px)`;
    inner.style.transitionDuration = '300ms';
    bbline.style.transitionDuration = '300ms';
    curPos = finalX;
}

초기 css와 html설정은 위 두분께서 자세히 설명에 적어 놓았으니 참고 부탁드립니다.

우선 크게 2개의 이벤트 터치 이동 완료와 클릭이벤트이다
터치 이동 완료는 3개의 이벤트로 구분할 수 있는데,
터치시 이벤트는 시작되는 x의 좌표를 구할수 있게 해주고 e.touches[0].pageX;
이동 이벤트는 이동시에 계속 좌표지점을 반환을 해준다 e.targetTouches[0].pageX
그래서 이 두가지의 값과 초기 위치 값인 curPos의 변수를 통해서 div의 transform의 x값을 변화시켜서 터치 이동으로 따라오게 만들어져있다.

그리고 터치가 끝나게 되면 최종적으로 도달한 x좌표값을 도출할 수 있는데 이 값에 스크린넓이를 나눈뒤 반올림을 하게되면 현재 위치보다 더 나아갔는지 아니면 그대로인지 등을 계산해 스크린넓이를 다시 곱하게 되면 최종 x의 위치가 나오게 된다. 이 위치를 transform에 전달하는 일련의 과정을 거치면 최종적으로 이동이 된다.

여기서 또한 상단 메뉴바도 이동되게 하기 위해서 간단하게 추가를 해보았다. 3개의 블록으로 이루어져 있기 때문에 -finalX/3을 하게 되면 만들어둔 div선이 동일하게 이동하는 효과를 얻을 수 있었다.

그러면 최종적으로 아래와 같은 효과를 지닌 페이지를 얻을 수 있었다.

좋은 웹페이지 즐겨찾기