Карусель (слайдер) с flexbox и реагирует - PullRequest
0 голосов
/ 05 февраля 2019

Я пытаюсь создать Карусель (псевдоним Slider) с flexbox и React (без JQuery, библиотек или манипуляций с DOM).

Чтобы переупорядочить элементы, я использую свойствоorder flexbox.Однако это свойство не поддерживает какой-либо эффект перехода, поэтому для его создания я пытаюсь сделать то же, что и в этой статье: https://blog.envylabs.com/the-order-property-flexbox-carousels-87a168567820 (используя transform)

Тем не менее, у меня много проблем с отзывчивостью, различными шагами (например, переместите 3 слайда на 3 вместо одного), эффектом перехода ...

Буду признателен, если кто-нибудь сможет мне помочьчтобы решить эту глючную ситуацию ... у меня теперь много времени болит голова ...

Я добавил свой код в stackblitz:

Также добавляю сюдакод:

carousel.js

import React, { Component } from 'react'

import './carousel.scss'

const STEP = 1

export default class Carousel extends Component {
  constructor(props) {
    super(props)
    this.next = this.next.bind(this)
    this.prev = this.prev.bind(this)
    this.resetSet = this.resetSet.bind(this)
    this.state = { ref: 0, isSet: true, isReversing: false }
  }

  getOrder(index) {
    const { items } = this.props
    const { ref } = this.state
    const order = index - ref

    if (order >= 0) {
      return order
    }

    return items.length - order
  }

  resetSet() {
    setTimeout(() => {
      this.setState({ isSet: true })
    }, 50)
  }

  next() {
    const { ref } = this.state
    const { items } = this.props
    const newRef = ref + STEP

    if (newRef < items.length) {
      this.setState({
        ref: newRef,
        isSet: false,
        isReversing: false,
      }, this.resetSet)
    }
  }

  prev() {
    const { ref } = this.state
    const newRef = ref - STEP

    if (newRef >= 0) {
      this.setState({
        ref: newRef,
        isSet: false,
        isReversing: true,
      }, this.resetSet)
    }
  }

  render() {
    const { title, items } = this.props
    const { isSet, isReversing } = this.state
    const classSet = isSet ? 'is-set' : ''
    const classReversing = isReversing ? 'is-reversing' : ''

    return (
      <>
        {title && <h2 className="carousel-title">{title}</h2>}
        <div className="carousel-wrapper" role="listbox">
          <div
            role="button"
            onClick={this.prev}
            tabIndex={0}
            className="arrow"
          >
          ⬅️
          </div>
          <div className={`carousel ${classSet} ${classReversing}`}>
            {items.map((item, index) => (
              <div
                key={item}
                style={{ order: this.getOrder(index) }}
                className="item"
              >{item}</div>
            ))}
          </div>
          <div
            className="arrow"
            role="button"
            onClick={this.next}
            tabIndex={0}
          >
          ➡️
          </div>
        </div>
      </>
    )
  }
}

carousel.scss

.carousel-title {
  font-family: 'PT_Serif-Web-BoldItalic';
  font-size: 20px;
  display: grid;
  width: 100%;
  align-items: center;
  text-align: center;
  grid-template-columns: minmax(20px, 1fr) auto minmax(20px, 1fr);
  grid-gap: 20px;

  &:before,
  &:after {
      content: '';
      border-top: 1px solid;
  }
}

.carousel-wrapper {
  width: 100%;
  display: flex;
  justify-content: center;

  .widget {
    margin: 0 10px;
  }

  .arrow {
    cursor: pointer;
    align-self: center;
    margin: 40px;
  }

  .carousel {
    display: flex;
    flex-direction: row;
    max-width: 750px;
    overflow: hidden;
    transform: translateX(100%);

    &.is-reversing {
      transform: translateX(-100%)
    }

    &.is-set {
      transform: none;
      transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1);
    }

    @media(max-width: 1049px){
      width: 500px;
    }
    @media(max-width: 800px){
      width: 240px;
    }
  }
}

.item {
  background-color: #f6f6f6;
  display: flex;
  font-size: 30px;
  justify-content: center;
  align-items: center;
  min-width: 230px;
  height: 400px;
  margin: 10px
}

body {
  overflow: hidden
}

Пример использования:

  • <Carousel title="My carousel" items={[1,2,3,4,5,6,7,8,9]} />

Большое вам спасибо за помощь!

1 Ответ

0 голосов
/ 05 февраля 2019

Хорошо

Итак, вот что я нашел:

1-й: Вы переходите на 100%: так что, если покажете 3 элемента, все три элемента будут скользить, мне удалось справитьсяэто вручную, изменяя 100% до 250px (возможно, есть лучший способ, но это идея).

transform: translateX(250px);

&.is-reversing {
  transform: translateX(250px)
}

Во-вторых: ваш getOrder вернул

items.length - order

вместо

items.length + order

вот так

getOrder(index) {
    const { items } = this.props
    const { ref } = this.state
    const order = index - ref

    if (order >= 0) {
      return order;
    }
    else{
        return items.length + order;
    }

}

Тогда для слайдов у NEXT не было результата, когда ссылка была больше items.length

if (newRef <= items.length) {
  this.setState({
    ref: newRef,
    isSet: false,
    isReversing: false,
  }, this.resetSet)
}else{
  this.setState(
    {
      ref: 1,
      isSet: false,
      isReversing: false
    },
    this.resetSet
  );
}

иВаш слайд PREV должен работать следующим образом:

if (newRef >= 0) {
  this.setState({
    ref: newRef,
    isSet: false,
    isReversing: true,
  }, this.resetSet)
}else{
  this.setState(
    {
      ref: 8,
      isSet: false,
      isReversing: true
    },
    this.resetSet
  );
}

, как вы можете видеть, я добавил некоторые вещи, такие как 250px и "8", которые можно добавить, например, 250px - это ширина элемента, а 8 - последний индексмассив.

также я понял, что ваш переход всегда скользит влево.Я могу смотреть дальше, как только у меня будет время, но сейчас это то, что мне удалось сделать,

Надеюсь, это поможет, Не уверен, что я хорошо объяснил, но я старался изо всех сил.

повеселиться

https://stackblitz.com/edit/carousel-pov-rvftku

Редактировать: добавлена ​​вилка карусели на стеке блиц

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...