자바스크립트에서 뷰-마스터 효과 재현하기

자바스크립트에서 뷰-마스터 효과 재현하기

2022-10-19 last update

7 minutes reading
저는 이번 주에 표준 썸네일 보기를 기반으로 서브렛을 공유하고 찾기 위한 플랫폼인 React 프로젝트에서 작업하고 있었습니다. 예를 들어 목록 보기(아파트에는 쓸모가 없습니다!) 또는 지도 보기와 반대입니다. 아파트 검색은 데이트와 같습니다. 귀찮게 가서 보기 전에 보고 싶은 것입니다.

각 목록은 개별 구성 요소로 렌더링되었습니다. 여기에 썸네일 사진을 통합하는 것은 쉬웠습니다. 내가 초안을 작성한 db.json 파일에 저장된 대로 목록 개체 내의 이미지 배열에서 첫 번째 이미지를 호출하기만 하면 됩니다. 개체는 다음과 같이 생겼습니다.

{
      "id": 3,
      "title": "Sun-dappled 1 bedroom",
      "description": "Clean and open 1 bed 1 bath apartment right in the middle of downtown LA. Come take a look today and make it your own!",
      "location": "Los Angeles, California",
      "price": 2170,
      "bedrooms": 1,
      "baths": 1,
      "availability": "10/11",
      "email": "[email protected]",
      "image": [
        "./images/image3.jpg",
        "./images/image9.jpg",
        "./images/image16.jpg"
      ]
    }


따라서 html 구성 요소는 <img src={listing.image[0]} alt={listing.title} />
그러나 축소판 보기에 남아 있는 동안 이미지를 뒤집어서 미리 볼 수 있는 효과를 얻는 방법은 무엇입니까? View-Master 릴을 들여다보는 것처럼?

온라인에서 찾아낸 .png 아이콘을 사용하여 이미지를 마운트할 오른쪽과 왼쪽의 두 개의 버튼을 만들기로 결정했습니다. 수동으로 위치를 지정하고 .css 파일에 호버 효과를 생성하여 기본적으로 보기에서 숨겨지고 방문 커서를 정중하게 맞이하기 위해서만 등장합니다.



코드는 매우 간단했습니다.

CSS:

.button-container {
  visibility: hidden;
}

.image-container:hover .button-container {
  visibility: visible;
}


js:

<div className="image-container">
  <img src={listing.image[0]} alt={listing.title} />
  <div className="button-container">
    <button className="right-btn"><span className='right-icon'></span></button>
    <button className="left-btn"><span className='left-icon'></span></button>
  </div>
</div>


그러나 실제 기능은 어떻습니까? 저는 항상 두 가지 상태 솔루션을 선호했습니다. 그래서 상단에 기본적으로 첫 번째로 기본 설정된 이미지의 상태와 호출할 이미지의 인덱스에 대한 상태를 설정했으며 기본적으로 0으로 기본 설정되었습니다.

const [imageToDisplay, setImageToDisplay] = useState(listing.image[0])
const [imageToDisplayIndex, setImageToDisplayIndex] = useState(0)


그런 다음 상태 변수와 필수 onClick 함수를 통합하도록 반환된 html 구성 요소를 업데이트했습니다.

<div className="image-container">
  <img src={imageToDisplay} alt={listing.title} />
  <div className="button-container">
    <button onClick={handleRightClick} className="right-btn"><span className='right-icon'></span></button>
    <button onClick={handleLeftClick} className="left-btn"><span className='left-icon'></span></button>
  </div>
</div>


상태 변수를 업데이트해야 하는 앞서 언급한 핸들 함수만 남았습니다. 우클릭을 위한 간단한 알고리즘을 구성했습니다. 배열의 길이가 여전히 1 + 인덱스(또는 "imageToDisplayIndex"라고 함)보다 큰 경우 인덱스를 1만큼 늘리고 이미지를 업데이트합니다. 아직 배열의 끝이 아니기 때문입니다. (인덱싱이 0에서 시작한다는 사실 때문에 1을 추가해야 합니다.) 그렇지 않으면, 즉 최종 이미지에 도달한 경우 카운터를 재설정하고 이미지를 배열의 첫 번째 이미지로 만듭니다.
(기본 구성 요소를 클릭할 수 있으므로 stopPropagation()도 호출해야 합니다. 그렇지 않으면 오른쪽 버튼을 클릭하면 전체 목록 카드를 클릭하는 것처럼 작동합니다.)

왼쪽 클릭의 경우 논리는 동일하며 반대입니다. 첫 번째 이미지보다 앞서 있으면 인덱스를 1만큼 줄이십시오. 그러나 첫 번째 이미지에 있는 경우 인덱스와 이미지를 배열의 마지막 이미지로 설정합니다(즉, 배열의 길이 - 1).

function handleRightClick(e){
  e.stopPropagation()
  if (listing.image.length > (imageToDisplayIndex+1)){
    setImageToDisplay(listing.image[imageToDisplayIndex+1])
    setImageToDisplayIndex(imageToDisplayIndex+1)
  }
  else{
    setImageToDisplayIndex(0)
    setImageToDisplay(listing.image[0])
  }
}

function handleLeftClick(e){
  e.stopPropagation()
  if (imageToDisplayIndex > 0){
    setImageToDisplay(listing.image[imageToDisplayIndex-1])
    setImageToDisplayIndex(imageToDisplayIndex-1)
  }
  else{
    setImageToDisplay(listing.image[listing.image.length-1])
    setImageToDisplayIndex(listing.image.length-1)
  }
} 


그리고 우리의 결과는 다음과 같습니다! 물론 이것들은 뻔뻔하게 스톡 사진입니다. 분명히 그들은 같은 재산에 속하지 않습니다.



어딘가에 라이브러리를 사용하여 이것을 작성하는 더 효율적인 방법이 있다고 확신합니다. 하지만 부동산 게임에 빠져들려면 Do It Yourself 연습을 해야 하지 않겠습니까?