ํ‹ฐ์Šคํ† ๋ฆฌ ๋ทฐ

Carousel Slide

๊ธฐ๋Šฅ ๊ตฌํ˜„

 

Carousel Slide๋Š” ์ด๋ฒˆ WETCHAPEDIA ํ”„๋กœ์ ํŠธ์—์„œ ๋‚ด๊ฐ€ ๋งก์€ ํ•ต์‹ฌ ๊ธฐ๋Šฅ์ด์ž ๊ฐ€์žฅ ๊ณ ๋ฏผํ–ˆ๋˜ ๋ถ€๋ถ„์ด๋‹ค.

 

๋‹จ์ˆœํžˆ ๊ธฐ๋Šฅ์ด ์›ํ™œํ•˜๊ฒŒ ๋™์ž‘๋˜๋Š” ๊ฒƒ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ์–ผ๋งˆ๋‚˜ ํšจ์œจ์ ์œผ๋กœ ๋งŒ๋“œ๋Š” ๊ฒƒ์ธ๊ฐ€์— ๋Œ€ํ•ด์„œ ๋Š์ž„ ์—†์ด ๊ณ ๋ฏผํ•˜์˜€๊ธฐ์— ์ด์— ๋Œ€ํ•ด์„œ ํฌ์ŠคํŒ…ํ•ด๋ณด๊ณ ์ž ํ•œ๋‹ค.

 

์ฒ˜์Œ์— Carousel Slide ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ผ์ • ์˜์—ญ์„ Fixed View๋กœ ์ง€์ •ํ•ด ๋‘” ๋’ค overflow value๋ฅผ hidden์œผ๋กœ ํ•˜์—ฌ, ๋ฒ„ํŠผ ์š”์†Œ๋ฅผ ๋ˆ„๋ฅด๊ฒŒ ๋˜๋ฉด ํ•ด๋‹น View์˜ ๋„ˆ๋น„๋งŒํผ transformX ๊ฐ’์„ ํผ์„ผํŠธ(%) ๋‹จ์œ„๋กœ ์ด๋™ํ•˜๊ฒŒ๋” ํ•˜์˜€๋‹ค.

 

๊ทธ๋ฆฌ๊ณ  Carousel Container ๋‚ด์— ๋งˆ์šฐ์Šค๊ฐ€ hover๊ฐ€ ๋˜๋ฉด overflow value๋ฅผ scroll๋กœ ๋ฐ”๊พธ์–ด, ์‚ฌ์šฉ์ž๊ฐ€ ์ผ๋ฐ˜ ๊ฐ€๋กœ ์Šคํฌ๋กค์œผ๋กœ๋„ ๋‹ค์–‘ํ•œ UI๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

 

ํ•˜์ง€๋งŒ overflow์˜ value ๊ฐ’์„ ์ด๋ ‡๊ฒŒ ์œ ๋™์ ์œผ๋กœ ๋ฐ”๊พธ๋‹ค ๋ณด๋‹ˆ, ์ด์ „์˜ Feeds ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค์ง€ ๋ชป ํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์˜€๋‹ค.

 

๋„˜์ณ๋‚˜๋Š” ์š”์†Œ๋ฅผ ์ˆจ๊น€ ์ฒ˜๋ฆฌ๋กœ ํ–ˆ์—ˆ๋˜ Container ๋‚ด์—์„  Slide Bar๋ฅผ X์ถ•์œผ๋กœ ๋Œ์–ด ๋‹น๊น€์œผ๋กœ์จ, ์ˆจ๊ฒจ์ ธ ์žˆ๋˜ ๋‚˜๋จธ์ง€ ์š”์†Œ๋“ค์„ ๋ณผ ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ์ธ๋ฐ, ์ผ๋ฐ˜ ์Šคํฌ๋กค ์˜์—ญ์œผ๋กœ ๋ฐ”๋€Œ๊ฒŒ ๋˜๋ฉด์„œ ์Šคํฌ๋กค ์‹œ์ž‘ ์ง€์  ์ด์ „์˜ ์š”์†Œ๋Š” ํ™•์ธํ•  ์ˆ˜ ์—†๊ฒŒ ๋œ ๊ฒƒ์ด๋‹ค.

 

์ด์— ์ด๋Ÿฌํ•œ ํ˜„์ƒ์„ ์–ด๋–ป๊ฒŒ ํ•ด๊ฒฐํ•  ๊ฒƒ์ธ์ง€ ๊ณ ๋ฏผํ•˜๋‹ค๊ฐ€ useRef()๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ๋กœ ํ•˜์˜€๋‹ค.

useRef()๋Š” querySelector()๋‚˜ getElementById()์™€ ๊ฐ™์ด DOM์— ํŠน์ • ์š”์†Œ์— ์ ‘๊ทผํ•œ๋‹ค.

 

useRef()์˜ ์ด๋Ÿฌํ•œ ํŠน์„ฑ์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ, Carousel Container ๋‚ด์—์„œ ์š”์†Œ๋ฅผ ๋‹ด์„ Slide Bar ๋‹ด๋‹น์˜ ์š”์†Œ์— ๊ธฐ๋ณธ overflow value๋ฅผ scroll๋กœ ๊ฐ’์„ ์„ค์ •ํ•ด์ค€ ๋’ค ref๋ฅผ ์ง€์ •ํ•ด ๋‘์—ˆ๋‹ค.

 <div ref={ref => (this.carouselSildeRef = ref)} />

 

๊ทธ๋ฆฌ๊ณ  ๋ฒ„ํŠผ ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๊ฑฐ๋‚˜ ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์‹œ, moveToX() ๋ผ๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ ๋™์ž‘๋˜๋„๋ก ํ•˜์˜€๋‹ค.

 

moveToX๋Š” event.type ๊ฐ’์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•œ๋‹ค.

ํด๋ฆญ ์ด๋ฒคํŠธ์ผ ๊ฒฝ์šฐ์—๋Š” ํ•ด๋‹น ์˜์—ญ์˜ View ๋„ˆ๋น„๋งŒํผ ScrollLeft ๊ฐ’์„ ํ• ๋‹นํ•˜์—ฌ ๋™์ ์œผ๋กœ ์ด๋™ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ์‚ฌ์šฉ์ž์—๊ฒŒ ๋ณด์—ฌ์ง€๊ฒŒ๋” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

if (eventType === 'click') {
      let { curTranslatePosX } = this.state;
      let { name } = getTarget(event.target, 'carouselControl');

      if (name === 'right') {
        this.carouselSildeRef.scrollLeft = curTranslatePosX + slideMove;
        this.setState({
          curTranslatePosX: curTranslatePosX + slideMove,
        });
      } else {
        this.carouselSildeRef.scrollLeft = curTranslatePosX - slideMove;
        this.setState({
          curTranslatePosX: curTranslatePosX - slideMove,
        });
      }
    }

 

transform์œผ๋กœ Slide Bar๋ฅผ ์›€์ง์—ฌ ์คฌ๋˜ ๊ฒƒ๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ(transform์€ ์‹ค์ œ ๋ณด์—ฌ์ง€๋Š” ๊ฒƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ layout์—” ๋ณ€ํ•จ์ด ์—†๊ธฐ ๋•Œ๋ฌธ์— ์ด์ „ ๊ฐ’์„ ์ฐธ์กฐํ•  ํ•„์š”์—†์ด 100% => 200% => 300% ... ์‹์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค) ์ด์ „์˜ ๊ฐ’์„ ์ฐธ์กฐํ•œ ๋’ค ํ•ด๋‹น ๊ฐ’์— ๊ฐ€์‚ฐํ•œ ๊ฐ’๋งŒํผ ์Šคํฌ๋กค์ด ์›€์ง์—ฌ์•ผ ์ •์ƒ์ ์œผ๋กœ ์Šฌ๋ผ์ด๋”ฉ ๊ธฐ๋Šฅ์ด ๋™์ž‘๋˜๊ธฐ ๋•Œ๋ฌธ์— Component ๋‚ด state ๊ฐ’์œผ๋กœ ์ง€์†์ ์œผ๋กœ ์Šคํฌ๋กค ๋œ ๊ธธ์ด๋ฅผ ์ ์žฌ ๋ฐ ๊ด€๋ฆฌํ•ด์ฃผ์—ˆ๋‹ค.

 

 ๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ์— event.type์ด Click์ด ์•„๋‹Œ Scroll์ผ ๊ฒฝ์šฐ์—๋Š” ๋ณ„๋„์˜ ์ด๋™ ์—ฐ์‚ฐ์€ ํ•˜์ง€ ์•Š๊ณ  ์ดํ›„ ํด๋ฆญ ์ด๋ฒคํŠธ ์‹œ ์Šฌ๋ผ์ด๋“œ ๋ฐ”์˜ ์ •ํ™•ํ•œ ์ด๋™์„ ์œ„ํ•ด์„œ ์Šคํฌ๋กค ๋œ ์–‘๋งŒ์„ ์•ž์„  state ๊ฐ’์— ์ €์žฅํ•ด ์ฃผ๋Š” ๋กœ์ง๋งŒ์„ ์ž‘์„ฑํ•˜์˜€๋‹ค.

else {
      let curScrollLeftPos = event.target.scrollLeft;
      this.setState({ curTranslatePosX: curScrollLeftPos });
    }

 

 

๊ธฐ๋Šฅ ์ž์ฒด๋Š” ์กฐ๊ธˆ๋งŒ ๊ณ ๋ฏผ์„ ํ•ด๋ณธ๋‹ค๋ฉด ๊ทธ๋ฆฌ ์–ด๋ ค์šด ์‚ฌํ•ญ์€ ์•„๋‹ˆ์—ˆ์ง€๋งŒ, ๊ธฐ๋Šฅ ์ž์ฒด์ ์ธ ๊ฒƒ๋ณด๋‹ค ๋‚˜๋ฅผ ๋” ๊ณ ๋ฏผํ•˜๊ฒŒ ํ–ˆ๋˜ ๊ฒƒ์€ ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋…๋ฆฝ์ ์ธ ํ•˜๋‚˜์˜ ๋ชจ๋“ˆ๋กœ์„œ ์ž‘๋™ํ•˜๊ฒŒ๋” ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์™€์˜ ๊ด€๊ณ„๋ฅผ ์„ค์ •ํ•˜๊ณ  ๋‚ด๋ถ€ ๋กœ์ง์„ ์ตœ๋Œ€ํ•œ ๋ฒ”์šฉ์„ฑ ์žˆ๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ์ž‘์„ฑํ•˜๋Š” ์ผ์ด์—ˆ๋‹ค.

 

์ฆ‰, Carousel Slide Component๋ฅผ Common Component๋กœ์„œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋„๋ก ๋ชฉํ‘œํ•˜์˜€๊ณ  ์ด๋ฅผ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์‚ฌํ•ญ์„ ๋กœ์ง์— ๋ฐ˜์˜ํ•˜์˜€๋‹ค.

 

์ฒซ ๋ฒˆ์งธ, Carousel Slide Bar์— ๋“ค์–ด๊ฐ€๋Š” Feeds(์˜ํ™” ๊ด€๋ จ ์ •๋ณด๋“ค)๋“ค์„ Mappingํ•˜์—ฌ ํ•˜๋‚˜์˜ ์ˆœํšŒ ๊ฐ€๋Šฅํ•œ ๋ฆฌ์ŠคํŠธ ์ž๋ฃŒ ๊ตฌ์กฐ์ธ ๋ฐฐ์—ด๋กœ ๋งŒ๋“ค์–ด ์ค€ ๋’ค, ์ด๋ฅผ CarouselSlide Components ๋‚ด ul ์š”์†Œ๋กœ style ๊ฐ’์„ ์ง€์ •ํ•œ Container ๋‚ด์— ๋ฐ”์ธ๋”ฉ ์‹œ์ผฐ๋‹ค.

 

์ด๋Ÿฐ ์‹์œผ๋กœ Component ๋‚ด๋ถ€์— ์žˆ๋Š” ๋ฆฌ์ŠคํŠธ ๊ฐ’์„ children ๊ฐ’์œผ๋กœ ์œ ๋™์ ์œผ๋กœ ํ• ๋‹น ๋ฐ›์Œ์œผ๋กœ์จ, ํ•ด๋‹น ์ปดํฌ๋„ŒํŠธ์˜ ํ™•์žฅ์„ฑ์„ ์ฆ๋Œ€์‹œ์ผฐ๋‹ค.

	<div
          ref={ref => (this.carouselSildeRef = ref)}
          className="feedsCarousel"
          onScroll={this.moveToX}
          style={{ width: { slideWidth } }}
        >
          <ul className="carouselSlider">{children}</ul> //children์€ Mapping๋œ ํ•˜๋‚˜์˜ ๋ฆฌ์ŠคํŠธ์ด๋‹ค.
          
	( ... )

 

๊ทธ ๋‹ค์Œ์œผ๋ก  CarouselSlide Component ๋‚ด์— Fixed ๋œ View์˜ ๊ฐ’์„ ํ™”๋ฉด ํฌ๊ธฐ์— ๋”ฐ๋ผ ์œ ๋™์ ์œผ๋กœ ๋ฐ”๊ฟ”์ฃผ๊ธฐ ์œ„ํ•˜์—ฌ slideWidth์™€ slideMove ๋‘ ๊ฐœ์˜ props๋ฅผ ์„ค์ •ํ•ด์ฃผ์–ด ๋‹ค๋ฅธ page ๋‚ด์—์„œ ๊ฐ€๋ณ€ ๋œ ํ™”๋ฉด์—๋„ ํ•ด๋‹น Carousel Bar์˜ ์‚ฌ์ด์ฆˆ์™€ ์›€์ง์ด๋Š” ์ •๋„๊ฐ€ ๋น„์œจ๋Œ€๋กœ๋งž์ถฐ์ง€๋„๋ก ๋กœ์ง์„ ์ž‘์„ฑํ•˜์˜€๋‹ค.

<CarouselSlide slideWidth={1320} slideMove={1327}>
                <MovieList type={feedsType} movieListData={movies} />
              </CarouselSlide>
 // slideWidth๋Š” ์‹ค์ œ View ํฌ๊ธฐ, slideMove๋Š” ์‹ค์ œ ์Šคํฌ๋กค์ด ์›€์ง์—ฌ์•ผ ๋  ์›€์ง์ž„(margin ๋ฐ padding ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์‹ค์ œ View๋ณด๋‹ค ์กฐ๊ธˆ ๋” ์›€์ง์ด๋„๋ก ์กฐ์ •)์˜ ์ •๋„์ด๋‹ค.

 

 

๋งˆ๋ฌด๋ฆฌ

์ด๋ฒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ํ†ตํ•ด CarouselSlide Component๋ฅผ ๋งŒ๋“ค์–ด๋ณด๋ฉด์„œ, ๋ฆฌ์•กํŠธ ๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์™œ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€์— ๋Œ€ํ•ด์„œ ๋‹ค์‹œ ํ•œ๋ฒˆ ์ƒ๊ฐํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค.

 

ํ”„๋กœ๊ทธ๋žจ์€ ๋‹จ์ˆœํžˆ input๊ณผ output๋งŒ ์ œ๋Œ€๋กœ ๋‚˜์˜ค๊ธฐ๋งŒ ํ•˜๋Š” ๋‹จ์ˆœ ์—ฐ์‚ฐ ์žฅ์น˜๊ฐ€ ์•„๋‹ˆ๋‹ค.

 

ํ”„๋กœ๊ทธ๋žจ์€ ๋‚ด์—์„œ๋Š” ์ˆ˜ ๋งŽ์€ ๊ธฐ๋Šฅ๋“ค์ด ์–ฝํ˜€ ๋‹ค์–‘ํ•œ ์ž‘์—…๋“ค์ด ์ˆ˜ํ–‰๋œ๋‹ค. ๊ทธ ์†์—์„œ ๊ณตํ†ต๋œ ์ง‘ํ•ฉ์˜ ์—ฐ์‚ฐ์„ ํ†ตํ•ด ๋™์ผํ•œ ์—ฐ์‚ฐ ๊ณผ์ •์„ ๋‹จ์ˆœํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ธ๊ฐ€์— ๋Œ€ํ•ด์„œ ๋Š์ž„ ์—†์ด ์ƒ๊ฐํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

 

์ง€๊ธˆ์€ ์•„์ฃผ ์ž‘์€ ํ”„๋กœ์ ํŠธ์ด์ง€๋งŒ ํ–ฅํ›„ ํ˜„์—…์— ๋‚˜๊ฐ€์„œ ๊ทœ๋ชจ๊ฐ€ ์žˆ๋Š” ํ”„๋กœ์ ํŠธ์— ์ฐธ๊ฐ€ํ•  ๋•Œ ํ•œ ๊ฐœ์ธ์œผ๋กœ์„œ ๋‚ด๊ฐ€ ์ด๋Ÿฌํ•œ ๋Œ€๊ทœ๋ชจ์˜ ์ž‘์—…์žฅ์—์„œ ๊ณตํ—Œํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์€ ๊ฑฐ๋Œ€ํ•˜๊ณ  ๋Œ€๋‹จํ•œ ์ผ์ด ์•„๋‹Œ, ๋‹ค์–‘ํ•œ ํ”„๋กœ์„ธ์Šค๋“ค์— ์ ‘๋ชฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ํ•˜๋‚˜์˜ ์ž‘์€ ๋ชจ๋“ˆ์„ ๋งŒ๋“ค์–ด์„œ ๊ฑฐ์‹œ์ ์œผ๋กœ ํ”„๋กœ์ ํŠธ์˜ ํšจ์œจ์„ฑ ์ฆ๋Œ€์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹๊นŒ ๋ผ๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ๋‹ค.

 

์ด๋ฒˆ CarouselSlide Component๋ฅผ ๋งŒ๋“ค๊ณ  ๋ถ„๋ฆฝ์‹œ์ผœ ๋ด„์œผ๋กœ์จ ์ด๋Ÿฌํ•œ ์ ๋“ค์„ ๊นจ๋‹ฌ์„ ์ˆ˜ ์žˆ์—ˆ๋‹ค.

 

๊ด€๋ จ ํฌ์ŠคํŒ…

https://choi95.tistory.com/175

 

Carousel Slide ๊ธฐ๋Šฅ Component๋กœ ๋ถ„๋ฆฝ

Issue ์œ„ Carousel Slide ๊ธฐ๋Šฅ์€ ํ•ด๋‹น Main Page ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ Page ๋‚ด์—์„œ๋„ ์“ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฝํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ์„ ํ™•์ธํ•˜์˜€๋‹ค. Carousel Slide ๊ธฐ๋Šฅ์ด ๋ฆฌ์ŠคํŠธ ํ˜•์‹์—์„œ ์ œ๋Œ€๋กœ ๋™์ž‘ํ•˜๊ธฐ

choi95.tistory.com

https://choi95.tistory.com/176

 

Type ๊ฐ’์— ๋”ฐ๋ผ ์กฐ๊ฑด๋ถ€ ๋žœ๋”๋ง_getDerivedStateFromProps

https://choi95.tistory.com/175 Carousel Slide ๊ธฐ๋Šฅ Component๋กœ ๋ถ„๋ฆฝ Issue ์œ„ Carousel Slide ๊ธฐ๋Šฅ์€ ํ•ด๋‹น Main Page ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ Page ๋‚ด์—์„œ๋„ ์“ฐ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋กœ ์ปดํฌ๋„ŒํŠธ๋กœ ๋ถ„๋ฆฝํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ์„ ํ™•..

choi95.tistory.com

 

๋Œ“๊ธ€
๊ณต์ง€์‚ฌํ•ญ
์ตœ๊ทผ์— ์˜ฌ๋ผ์˜จ ๊ธ€
์ตœ๊ทผ์— ๋‹ฌ๋ฆฐ ๋Œ“๊ธ€
Total
Today
Yesterday
๋งํฌ
TAG
more
ยซ   2025/04   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30
๊ธ€ ๋ณด๊ด€ํ•จ