Слайдер карточек в виджете

XenForo Слайдер карточек в виджете

Совместимость с XenForo
  1. 2.2.x
Переходим в виджеты admin.php?widgets выбираем добавить виджет HTML и прописываем код:
Код:
<main>
    <div class="scroll-wrapper">
        <div class="scroll-filler"></div>
        <div class="scroll">
            <div class="scroll-inner">
                <a href="#" class="scroll-item">
                    <h2>I made a slider</h2>
                    <span class="scroll-item-date">5 Jun 2020</span>
                </a>
                <a href="#" class="scroll-item red">
                    <h2>I don't know how to make a slider</h2>
                    <span class="scroll-item-date">4 Jun 2020</span>
                </a>
                <a href="#" class="scroll-item">
                    <h2>I want to make a slider</h2>
                    <span class="scroll-item-date">3 Jun 2020</span>
                </a>
                <a href="#" class="scroll-item bees">
                    <h2>bees</h2>
                    <span class="scroll-item-date">bees</span>
                </a>
                <a href="#" class="scroll-item red">
                    <h2>---------</h2>
                    <span class="scroll-item-date">---------</span>
                </a>
                <a href="#" class="scroll-item">
                    <h2>тест</h2>
                    <span class="scroll-item-date">тест</span>
                </a>
                <a href="#" class="scroll-item blue"></a>
                <div class="scroll-item ghost">
                    <h2>No more items</h2>
                    <span class="scroll-item-date">For real</span>
                </div>
            </div>
        </div>
    </div>
    <div class="scroll-position-wrapper">
        <button class="scroll-btn prev" onclick="prevBtn()" disabled></button>
        <div class="scroll-position">
            <div class="scroll-position-inner"></div>
        </div>
        <button class="scroll-btn next" onclick="nextBtn()"></button>
    </div>
</main>
<style>
main {
  background-color: white;
  border-radius: 16px;
  overflow: hidden;
  padding: 30px 20px 20px;
  box-shadow: 0 6px 20px 0 rgba(202, 208, 216, 0.15);
  display: flex;
  flex-direction: column;
}
::-webkit-scrollbar {
  display: none;
  width: 0;
  background: transparent;
  height: 0;
  -webkit-appearance: none;
}
.scroll {
  padding: 20px 20px 40px;
  white-space: nowrap;
  position: sticky;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
.scroll-wrapper {
  height: -webkit-fit-content;
  height: -moz-fit-content;
  height: fit-content;
  margin-left: -20px;
  margin-right: -20px;
  position: relative;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: none;
}
.scroll-filler {
  width: 100%;
  height: 100%;
  position: absolute;
}
.scroll-inner {
  width: -webkit-fit-content;
  width: -moz-fit-content;
  width: fit-content;
  display: flex;
  align-items: stretch;
}
.scroll-item {
  width: 160px;
  border-radius: 16px;
  background-image: linear-gradient(130deg, #9457e2, #5029bb);
  transform: perspective(400px);
  box-shadow: 0 8px 20px 0 rgba(108, 79, 197, 0.44);
  padding: 20px 30px;
  vertical-align: top;
  color: white;
  text-decoration: none;
  white-space: normal;
  display: flex;
  flex-direction: column;
}
.scroll-item.red {
  background-image: linear-gradient(130deg, #ff8063, #e34040);
  box-shadow: 0 8px 20px 0 rgba(213, 65, 51, 0.45);
}
.scroll-item.bees {
  background-image: linear-gradient(130deg, #ffe561, #ffd24c);
  box-shadow: 0 8px 20px 0 rgba(227, 169, 55, 0.45);
  color: #333;
}
.scroll-item.blue {
  background-image: linear-gradient(130deg, #1cffb7, #0075ff);
  box-shadow: 0 8px 20px 0 rgba(107, 187, 255, 0.45);
}
.scroll-item.ghost {
  background-image: none;
  box-shadow: none;
  border: 1px dashed #eaeaea;
  color: #bdbdbd;
  cursor: default;
}
.scroll-item:not(:last-child) {
  margin-right: 0;
}
.scroll-item h2 {
  font-size: 1.15em;
  font-weight: 600;
  line-height: 1.5;
  margin: 0 0 30px;
}
.scroll-item .scroll-item-date {
  font-size: 0.8em;
  letter-spacing: 0.02em;
  opacity: 0.8;
  display: block;
  margin-top: auto;
}
.scroll-position {
  height: 1px;
  background-color: #f1f1f1;
  flex: 1;
  margin: 0 5px;
}
.scroll-position-wrapper {
  width: 100%;
  margin-top: -10px;
  display: flex;
  align-items: center;
}
.scroll-position-inner {
  height: 1px;
  background-color: #d0d0d0;
}
.scroll-btn {
  display: block;
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none;
  border: none;
  background: none;
  width: 26px;
  height: 26px;
  background-color: white;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23aaa' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='9 18 15 12 9 6'%3E%3C/polyline%3E%3C/svg%3E");
  background-position: center;
  background-size: 20px;
  z-index: 9;
  cursor: pointer;
  opacity: 0.6;
  color: rgba(179, 179, 179, 0.7);
  transition-duration: 0.3s;
}
.scroll-btn:hover {
  opacity: 1;
}
.scroll-btn.prev {
  transform: scaleX(-1);
}
.scroll-btn[disabled] {
  opacity: 0;
  pointer-events: none;
}
</style>
<script src='https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.0/gsap.min.js'></script>
<script>
const wrapper = document.querySelector('.scroll-wrapper');
const el = document.querySelector('.scroll');
const filler = document.querySelector('.scroll-filler');
const position = document.querySelector('.scroll-position-inner');
const inner = document.querySelector('.scroll-inner');
const btns = {prev: document.querySelector('.scroll-btn.prev'), next: document.querySelector('.scroll-btn.next')};

const lerp = (a, b, n) => {
  return (1 - n) * a + n * b
}

const padding = 20;

let scrollNow = 0;

filler.style.width = inner.offsetWidth + padding*2 + 'px';
position.style.width = wrapper.offsetWidth / (inner.offsetWidth + padding*2) * 100 + '%';

const offset = 150;
const angle = 25;
const z = 15;

function render() {
  let now = lerp(scrollNow, wrapper.scrollLeft, .15);
  gsap.set(el, {x: -now});
  gsap.set(position, {x: now / wrapper.offsetWidth * 100 + '%'});

  document.querySelectorAll('.scroll-item').forEach(item => {
    let elPos = item.offsetLeft + item.offsetWidth / 2 - scrollNow;

    if (elPos > wrapper.offsetWidth - offset) {
      let q = (wrapper.offsetWidth - elPos) / offset;
      gsap.set(item, {rotateY: -(angle - q * angle), z: z - z * q})
    } else if (elPos < offset) {
      let q = elPos / offset;
      gsap.set(item, {rotateY: angle - q * angle, z: z - z * q})
    } else {
      gsap.set(item, {rotateY: 0, z: 0});
    }
  });

  scrollNow = now;

  if (wrapper.scrollLeft === 0) btns.prev.disabled = true
  else if (inner.offsetWidth - wrapper.scrollLeft === wrapper.offsetWidth - padding*2) btns.next.disabled = true
  else {btns.prev.disabled = false; btns.next.disabled = false;}
  requestAnimationFrame(render);
}

render();

function nextBtn() {
  wrapper.scrollLeft += document.querySelector('.scroll-item').offsetWidth*2 - 20;
}
function prevBtn() {
  wrapper.scrollLeft -= document.querySelector('.scroll-item').offsetWidth*2 - 20;
}
</script>
Получаем такой результат:
  • dsf33 (2).gif
    dsf33 (2).gif
    759.6 КБ · Просмотры: 3



Слайдер карточек в виджете
Слайдер карточек в виджете
Просмотры
12
Первый выпуск
Обновление
Рейтинг
0.00 звёзд Оценок: 0
  • Теги Теги
    xenforo
  • Ещё ресурсы от Groot

    Поделиться этим ресурсом

    Назад
    Верх