[CSS] - 아마존 클론#3 (캐러셀)

sarang_daddy·2023년 3월 26일
0

CSS

목록 보기
5/6
post-thumbnail

🚫 아마존 웹사이트를 클론해보면서 CSS와 JS를 학습하는 내용입니다.
구현은 되었으나 정확한 코드가 아니며 더 좋은 방법은 학습해가며 수정하려고 합니다.

🌱 학습 키워드

✅ Transitions (전환)

움직임에는 의미 전달이 향상되고 사용자와의 상호 작용을 방해하지 않아야 함을 항상 고민하고 사용하자.

  • 전환은 요소를 매끄럽고 점진적으로 한 상태를 다른 상태로 변경함을 말한다.
  • CSS 변환의 윤활유 역할을 한다고 할 수 있다. 전환이 없으면 다른 상태로의 변경이 갑자기 이루어 진다.

transitions을 적용하기 위해서는 아래의 두 속성이 필요하다.

  1. transition-property : 전환할 속성 (ex : background-color, tranform)
  2. transition-duration : 전환할 기간
  3. transition-timing *(optional)*
  4. `transition-delay``
div {
  transition: [property] [duration] [timing-function] [delay];
}

✅ Transforms (변환)

상태의 변환에 윤활유 역할을 한 transitions을 기억하면서
요소의 한 상태를 다른 상태로 변경하는 transforms에 대해 알아보자.

  • transforms을 사용하여 CSS 속성을 변환하여 요소의 크기조정, 이동, 회전 등을 할수 있다.
  • transform은 변경될 요소에 부여해야 한다.
  • 원본 요소에는 transition를 부여한다.

참고자료

케러셀은 영어로 “merry-go-round”라 불리며, 원형으로 되어있는 놀이기구 회전목마를 생각하면 된다.
쭉 이어진 이미지들이 원형으로 돌아가면서 해당 장소로 반복하면서 돌아오는 구조를 생각해주면 된다.


🔥  캐러셀 구현

✅ 배너가 순차적으로 돌아가는 트랙 생성

function Track() {
  this.element = document.querySelector(".banner__track");
  this.leftBtn = document.querySelector(".banner__btn:first-child");
  this.rightBtn = document.querySelector(".banner__btn:last-child");
  this.directionByNum = 0;
}

Track.prototype.moveTrack = function (direction) {
  if (direction === "left") {
    this.directionByNum = 1;
  } else if (direction === "right") {
    this.directionByNum = -1;
  }
  this.element.style.transition = "transform .5s ease-in-out";
  this.element.style.transform = `translateX(${
    (this.directionByNum * 100) / banners.imgList.length
  }%)`;
  this.element.ontransitionend = () => {
    this.reorgannizeEl(direction);
  };
};

Track.prototype.reorgannizeEl = function (direction) {
  this.element.removeAttribute("style");
  direction === "left"
    ? this.element.insertBefore(
        this.element.lastElementChild,
        this.element.firstElementChild
      )
    : this.element.appendChild(this.element.firstElementChild);
};

Track.prototype.addEvent = function () {
  this.leftBtn.addEventListener("click", this.moveTrack.bind(this, "left"));
  this.rightBtn.addEventListener("click", this.moveTrack.bind(this, "right"));
};
  • function Track() 생성자 생성
  • Track 생성자는 해당 엘리먼트와 좌, 우 버튼 엘리먼트를 가진다.
  • 프로토타입으로 moveTrack, reorgannizeEl, addEvent 메서드 생성
  • 좌, 우 버튼 클릭 시 매개변수로 회전 방향을 결정하고 배너 당 크기만큼 이동 시킨다.
  • 렌더링 과정이 가벼운 transform으로 애니메이션 효과를 준다.
  • 애니메이션이 끝나면 (ontransitionend) 스타일을 초기화 하고 무한 회전을 위해 DOM을 조작해준다.
  • 좌로 움직일시 배너 DOM의 마지막 노드를 제일 앞으로 가져온다.
  • 우로 움직일시 배너 DOM의 첫 노드를 제일 뒤로 가져간다.

🧐 주의사항

this.element.style.transition = "transform .5s ease-in-out"
트랜지션을 CSS에서 부여하면 this.element.removeAttribute("style") 후
셋팅된 CSS 로 돌아가기에 애니메이션이 중복해서 발생된다.

✅ 배너들(ex.이미지) 생성

function Banner() {
  this.imgList = [
    "bannerImg1",
    "bannerImg2",
    "bannerImg3",
    "bannerImg4",
    "bannerImg5",
    "bannerImg6",
  ];
}

Banner.prototype.toBeElement = function (imgName) {
  const div = document.createElement("div");
  const img = document.createElement("img");
  div.classList.add("banner__column");
  img.classList.add("banner__img");
  img.src = `photo/${imgName}.jpg`;
  div.appendChild(img);
  track.element.appendChild(div);
};

Banner.prototype.setBanners = function () {
  this.imgList.forEach((imgName) => {
    this.toBeElement(imgName);
  });
};
  • Banner 생성자 생성
  • Banner 생성자는 배너에 사용되는 이미지 파일 리스트를 가진다.
  • toBeElement, setBanners 메서드를 가진다.
  • setBanners를 통해 각 이미지들을 toBeElement를 사용하여 엘리먼트로 만든다.
  • 생성된 배너들은 track에 들어간다.

✅ 캐러셀 스타일 구성

.banner {
  width: 1500px; // 보여지는 이미지 크기
  overflow-x: hidden; // 보여지는 이미지를 벗어나면 가려준다.
  margin: 0 auto; // 가운데 정렬
}

.banner__track {
  display: flex; // 트랙내 이미지들 플레스 배치
	position: relative;
  width: 9000px; // 트랙에 들어가는 이미지 총 사이즈
	~~transition: transform 0.3s ease-in-out; // 트렌지션 부여~~
	left: -1500px; // 배너들 첫 세팅 시 제일 앞 배너가 위치하면 안된다.
}

.banner__img {
  width: 1500px; // 이미지 크기
  height: 600px;
}

Carousel practice
캐러셀 구현하기 참고자료

✅ 구현된 캐러셀

profile
한 발자국, 한 걸음 느리더라도 하루하루 발전하는 삶을 살자.

0개의 댓글