• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 가로스크롤 질문있습니다.

가로스크롤 질문있습니다.

4 글 보임 - 1 에서 4 까지 (총 4 중에서)
  • 글쓴이
  • #75500

    정중식
    참가자
    저번에 선생님께 질문을드렸는데, 선생님이 알려주신곳  을 참고해서 다음과 같이 작성해봤습니다.
    
    먼저 ,
    Gallery.tsx입니다.
    
    
    import React, { useRef } from 'react';
    import styled from 'styled-components';
    import { useScroll } from '../utils/useScroll';
    import { photos } from '../utils/photos';
    const Container = styled.div`
      background: #000;
      overflow: hidden;
    `;
    const List = styled.ul`
      overflow-x: hidden;
      display: flex;
      position: sticky;
      top: 0;
    `;
    const Item = styled.li`
      min-width: 50vw;
      min-height: 100vh;
      display: flex;
      justify-content: center;
      align-items: center;
      font-size: 4ch;</pre>
    <pre>  :nth-child(even) {
        background-color: teal;
        color: white;
      }</pre>
    <pre>  img {
        max-width: 100%;
        /* height: 500px; */
        height: 200px;
      }
    `;
    // const Item = styled.li`
    //   margin: 0.5rem;
    //   min-width: 35vw;
    //   position: relative;
    //   display: flex;
    //   justify-content: center;
    //   align-items: center;</pre>
    <pre>//   img {
    //     max-width: 100%;
    //     /* height: 500px; */
    //     height: 200px;
    //   }
    // `;
    const Gallery = () => {
      const containRef = useRef<HTMLDivElement>(null);
      const scrollRef = useScroll(containRef);
      return (
        <Container ref={containRef}>
          <List ref={scrollRef}>
            {photos.map((photo) => (
              <Item key={photo.id}>
                < img src={photo.src} alt='' />
              </Item>
            ))}
          </List>
        </Container>
      );
    };
    export default Gallery;
    다음은 useScroll.tsx 입니다.
    
    
    import { useRef, useEffect } from 'react';
    export function useScroll(containRef: any) {
      const elRef = useRef<any>();
      useEffect(() => {
        const el = elRef.current;
        const container = containRef.current;
        if (el) {
          const setStickyContainersSize = () => {
            if (container) {
              const stickyContainerHeight = container.scrollWidth;
              container.setAttribute(
                'style',
                'height: ' + stickyContainerHeight + 'px'
              );
            }
          };
          const isElementInViewport = (el: any) => {
            const rect = el.getBoundingClientRect();
            return (
              rect.top <= 0 && rect.bottom > document.documentElement.clientHeight
            );
          };
          setStickyContainersSize();
          const onWheel = (e: any) => {
            if (e.deltaY === 0) return;
            const containerInViewPort = isElementInViewport(container);
            if (!containerInViewPort) {
              return;
            }
            e.preventDefault();
            var isPlaceHolderBelowTop =
              el.offsetTop < document.documentElement.scrollTop;
            var isPlaceHolderBelowBottom =
              el.offsetTop + el.offsetHeight > document.documentElement.scrollTop;
            let g_canScrollHorizontally =
              isPlaceHolderBelowTop && isPlaceHolderBelowBottom;
            if (g_canScrollHorizontally) {
              el.scrollTo({
                left: el.scrollLeft + e.deltaY,
                // behavior: strength > 70 ? 'auto' : 'smooth',
              });
            }
          };
          el.addEventListener('wheel', onWheel);
          return () => {
            el.removeEventListener('wheel', onWheel);
          };
        }
      }, [containRef]);
      return elRef;
    }
    이렇게 작성했는데 동작이 조금 거시기해서요...
    
    
    https://youtu.be/P1rLgQLQEcw
    뭐라고해야할까요.. 이곳 처럼
     
    스크롤을 쭉 쭉 내리다가 해당 요소에 화면이 닿으면 가로로 쭉쭉 내려가지만 스크롤은 세로로 내려가고있어야하고,
    가로스크롤이끝나면 그대로 아래로 내려가게끔 해주고싶은데
    
    아.. 이틀을 붙잡고있었는데 제 머리론 방안이 도저히 안떠오르네요..
    
    선생님 그리고 추가로 setStickyContainersSize 함수를 꼭 써줘야하나요? 
    (필요없을거같아서 함수를 삭제하고 실행해봤는데 불안정하게 동작하던 가로스크롤도 아예안되네요.)
    
    
    #75547

    codingapple
    키 마스터
    원하는 사이트는 position sticky만 대충 주고
    스크롤양에 비례해서 transform : translateX를 수정시켜서 박스를 왼쪽이동시켜준거같군요
    #75643

    정중식
    참가자
    센세.. 코드를 이런식으로 쳤는데요
    
    
      const containRef = useRef<HTMLDivElement>(null);
      const scrollRef = useRef<any>(null);
      useEffect(() => {
        const onScroll = () => {
          if (scrollRef.current && containRef.current) {
            let viewWidth = window.innerWidth;
            let galleryPosition = containRef.current.offsetTop;
            let scrollLocation = document.documentElement.scrollTop;
            if (
              viewWidth >= 768 &&
              scrollLocation >= galleryPosition &&
              scrollLocation < galleryPosition + 4000
            ) {
              let percent = ((scrollLocation - galleryPosition) / 4000) * -80;
              scrollRef.current.style.transform = 'translateX(' + percent + '%)';
            }
          }
        };
        window.addEventListener('scroll', onScroll);
        return () => {
          window.removeEventListener('scroll', onScroll);
        };
      }, []);
    
    영상    이렇게 나옵니다. 포지션 스티키가 안먹는것같은데 혹시 제가 스크롤양에 비례해서 이동시켜주는 코드를 잘못짰을까요?
    
    전체코드는 이렇습니다.
    
    import React, { useRef, useEffect } from 'react';
    import styled from 'styled-components';
    import { photos } from '../utils/photos';
    const Container = styled.section`
      background-color: #edf2f4;
      width: 100vw;</pre>
    <pre>  @media (min-width: 768px) {
        height: 4000px;
      }
    `;
    const Wrapper = styled.div`
      position: sticky;
      overflow: hidden;
      padding-top: 6.25rem;
      top: 0;
      width: 100%;
    `;
    const List = styled.ul`
      @media (min-width: 768px) {
        width: 4000px;
        height: 100vh;
        display: flex;
        flex-direction: row;
        justify-content: space-around;
        align-items: stretch;
        flex-wrap: nowrap;
      }
    `;
    const Item = styled.li`
      @media (min-width: 768px) {
        :nth-child(odd) {
          display: flex;
          flex-direction: row;
          justify-content: space-around;
          align-items: flex-end;
          flex-wrap: nowrap;
        }</pre>
    <pre>    :nth-child(1) {
          width: 18.75rem;
          height: 100%;
        }</pre>
    <pre>    &:nth-child(2) {
          img {
            height: 31.25rem;
            overflow: hidden;
            object-fit: cover;
          }
        }</pre>
    <pre>    &:nth-child(3) {
          img {
            height: 31.25rem;
            width: 43.75rem;
            transform: translateY(-25vh);
            overflow: hidden;
            object-fit: cover;
          }
        }
      }</pre>
    <pre>  img {
        max-width: 100%;
        border-radius: 0.625rem;
        box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.3);</pre>
    <pre>    @media (min-width: 768px) {
          width: clamp(500px px, 50% + 20px, 900px);
          transform: translateX(-1%);
        }
      }
    `;
    const Gallery = () => {
      const containRef = useRef<HTMLDivElement>(null);
      const scrollRef = useRef<any>(null);
      useEffect(() => {
        const onScroll = () => {
          if (scrollRef.current && containRef.current) {
            let viewWidth = window.innerWidth;
            let galleryPosition = containRef.current.offsetTop;
            let scrollLocation = document.documentElement.scrollTop;
            if (
              viewWidth >= 768 &&
              scrollLocation >= galleryPosition &&
              scrollLocation < galleryPosition + 4000
            ) {
              let percent = ((scrollLocation - galleryPosition) / 4000) * -80;
              scrollRef.current.style.transform = 'translateX(' + percent + '%)';
            }
          }
        };
        window.addEventListener('scroll', onScroll);
        return () => {
          window.removeEventListener('scroll', onScroll);
        };
      }, []);
      return (
        <Container ref={containRef}>
          <Wrapper>
            <List ref={scrollRef}>
              <Item />
              {photos.map((photo) => (
                <Item key={photo.id}>
                  < img src={photo.src} alt='' />
                </Item>
              ))}
            </List>
          </Wrapper>
        </Container>
      );
    };
    export default Gallery;
     
     
    #75692

    codingapple
    키 마스터
    sticky주려는 박스에 height도 적절히 줘야합니다
4 글 보임 - 1 에서 4 까지 (총 4 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관, 개인정보처리방침
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠