마우스 드래그 스크롤

김종원·2023년 5월 15일
0

[TIL (Today I Learned)]

목록 보기
42/45

구조

   <div className='brandAI'>
     <div className={`itemList ${props.type}`}>
       {props.itemLists && props.itemLists.map((item, index) => {
          return (
           <>
           	<div className='item' key={`${item.item_name}_${index}`}>
              <div 
              	className='itemImg'
                style={{backgroundImage: item.file_path ? `URL(${item.file_path})` : 'URL(/user/img/image_none.jpg)',}}
              />
                <h5>{item.brand_name}</h5>
                <p className={cc.ellipsis}>{item.item_name}</p>
                <div>
                 <span>{100 - Math.floor((item.discount_price / item.price) * 100) + '%'}</span>
                </div>
              </div>
            </>
           )
           })}
         </div>
       </div>

이런 화면을
마우스 드래그를 통해서 움직일 수 있는 화면을 만들고 싶었습니다.

처음에는
부모div에 고정 width와 overflow: auto를 주고
자식 태그에 display: flex를 주어서 스크롤 형식으로 주고 싶었으나
아무리 style을 줘도 style이 적용되지 않았습니다.

그러다 구글링을 통해 알아봤는데
https://velog.io/@tunakim/%EB%A7%88%EC%9A%B0%EC%8A%A4-%EB%93%9C%EB%9E%98%EA%B7%B8%EB%A1%9C-%EC%A2%8C%EC%9A%B0-%EC%8A%A4%ED%81%AC%EB%A1%A4-%EA%B5%AC%ED%98%84-ft.-React
이 분의 글을 보고 적용해보기로 했습니다.

최종 코드

  const scrollRef = useRef<any>([])
  const [isDrag, setIsDrag] = useState<boolean>(false)
  const [startX, setStartX] = useState<number>(0)

  const onDragStart = (e: React.MouseEvent<HTMLDivElement>) => {
    const index = Number(e.currentTarget.id)
    e.preventDefault()
    if (scrollRef.current[index]) {
      setIsDrag(true)
      setStartX(e.pageX + scrollRef.current[index]?.scrollLeft)
    }
  }

  const onDragEnd = () => {
    setIsDrag(false)
  }
  
   <div className='brandAI'>
      <div
        id='0'
        className={`itemList ${props.type}`}
        onMouseDown={onDragStart}
        onMouseMove={onDragMove}
        onMouseUp={onDragEnd}
       	onMouseLeave={onDragEnd}
        ref={(e) => (scrollRef.current[0] = e)}
      >
       {props.itemLists && props.itemLists.map((item, index) => {
          return (
           <>
           	<div className='item' key={`${item.item_name}_${index}`}>
              <div 
              	className='itemImg'
                style={{backgroundImage: item.file_path ? `URL(${item.file_path})` : 'URL(/user/img/image_none.jpg)',}}
              />
                <h5>{item.brand_name}</h5>
                <p className={cc.ellipsis}>{item.item_name}</p>
                <div>
                 <span>{100 - Math.floor((item.discount_price / item.price) * 100) + '%'}</span>
                </div>
              </div>
            </>
           )
           })}
         </div>  
profile
발전하기위한 기록

0개의 댓글