Sauter la navigation

[Résolu] How to create post list carousel?

This support ticket is created Il y a 6 années. There's a good chance that you are reading advice that it now obsolete.

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Sun Mon Tue Wed Thu Fri Sat
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

Ce sujet contient 4 réponses, a 1 voix.

Dernière mise à jour par francescoG-3 Il y a 6 années.

Assisté par: Christian Cox.

Auteur
Publications
#1191130

Tell us what you are trying to do? I want to make a posts carousel like as facebook sponsored carousel or facebook user list carousel to send friend requests. With one item scroll on clicking on the left or right arrow, or in automatic scroll, or finger scroll on smartphone and tablet, without sliding page with the items.

Is there any documentation that you are following? I have seen this solution but I don't know if it work https://toolset.com/forums/topic/responsive-carousel-of-three-posts-2/#post-462465
and also I have seen this guide
https://code.tutsplus.com/tutorials/create-the-perfect-carousel-part-1--cms-29481
What is perfect for what I need?

Is there a similar example that we can see? facebook sponsored carousel and facebook user list carousel to send friend requests

What is the link to your site? lien caché

#1191505

Hi,
I think that this guide is perfect for what I nedd https://code.tutsplus.com/tutorials/create-the-perfect-carousel-part-1--cms-29481
But is too difficult for me to write the javascript code, because in the guide there are some string that I don't know if them need to create a new specific function, or include in something exist function, or without function...

I'm trying, but don't happend nothing...

#1191514

So, I have found the correct Js Code:

const { calc, css, physics, pointer, transform, tween, value } = window.popmotion;
const { applyOffset, clamp, nonlinearSpring, pipe } = transform;

function getTotalItemsWidth(items) {
  const { left } = items[0].getBoundingClientRect();
  const { right } = items[items.length - 1].getBoundingClientRect();
  return right - left;
}

function angleIsVertical(angle) {
  const isUp = (
    angle <= -90 + 45 &&
    angle >= -90 - 45
  );
  const isDown = (
    angle <= 90 + 45 &&
    angle >= 90 - 45
  );

  return (isUp || isDown);
}

function carousel(carous) {
  // Select DOM
  const slider = carous.querySelector('.slider');
  const items = slider.querySelectorAll('.item');
  const nextButton = carous.querySelector('.next');
  const prevButton = carous.querySelector('.prev');
  const progressBar = carous.querySelector('.progress-bar');
  
  function checkNavButtonStatus(x) {
    if (x <= minXOffset) {
      nextButton.classList.add('disabled');
    } else {
      nextButton.classList.remove('disabled');

      if (x >= maxXOffset) {
        prevButton.classList.add('disabled');
      } else {
        prevButton.classList.remove('disabled');
      }
    }
  }

  const totalItemsWidth = getTotalItemsWidth(items);
  const maxXOffset = 0;

  let minXOffset = 0;
  let sliderVisibleWidth = 0;
  let clampXOffset;

  function measureCarousel() {
    sliderVisibleWidth = slider.offsetWidth;
    minXOffset = - (totalItemsWidth - sliderVisibleWidth);
    clampXOffset = clamp(minXOffset, maxXOffset);
  }
  
  measureCarousel();

  // Create renderers
  const sliderRenderer = css(slider);
  const progressBarRenderer = css(progressBar);
  
  function updateProgressBar(x) {
    const progress = calc.getProgressFromValue(maxXOffset, minXOffset, x);
    progressBarRenderer.set('scaleX', Math.max(progress, 0));
  }

  const sliderX = value(0, (x) => {
    updateProgressBar(x);
    sliderRenderer.set('x', x);
  });

  let action;
  let touchOrigin = { x: 0, y: 0 };

  // Touch event handling
  function stopTouchScroll() {
    document.removeEventListener('touchend', stopTouchScroll);
    if (action) action.stop();
    
    const currentX = sliderX.get();
    
    if (currentX < minXOffset || currentX > maxXOffset) {
      action = physics({
        from: currentX,
        to: (currentX < minXOffset) ? minXOffset : maxXOffset,
        spring: 800,
        friction: 0.92
      }).output((v) => sliderX.set(v))
        .start();
    } else {
      action = physics({
        from: currentX,
        velocity: sliderX.getVelocity(),
        friction: 0.2
      }).output(pipe(
        clampXOffset,
        (v) => {
          checkNavButtonStatus(v);
          sliderX.set(v);
        }
      )).start();
    }
  }

  function determineDragDirection(e) {
    const touch = e.changedTouches[0];
    const touchLocation = {
      x: touch.pageX,
      y: touch.pageY
    };
    const distance = calc.distance(touchOrigin, touchLocation);

    if (!distance) return;
    document.removeEventListener('touchmove', determineDragDirection);

    const angle = calc.angle(touchOrigin, touchLocation);
    if (angleIsVertical(angle)) return;

    if (action) action.stop();
    action = pointer(e).start();
    
    const elasticity = 5;
    const tugLeft = nonlinearSpring(elasticity, maxXOffset);
    const tugRight = nonlinearSpring(elasticity, minXOffset);
    
    const applySpring = (v) => {
      if (v > maxXOffset) return tugLeft(v);
      if (v < minXOffset) return tugRight(v);
      return v;
    };

    action.output(pipe(
      ({ x }) => x,
      applyOffset(action.x.get(), sliderX.get()),
      applySpring,
      (v) => sliderX.set(v)
    ));
  }

  function startTouchScroll(e) {
    document.addEventListener('touchend', stopTouchScroll);
    if (action) action.stop();
    const touch = e.touches[0];
    touchOrigin = {
      x: touch.pageX,
      y: touch.pageY
    };
    document.addEventListener('touchmove', determineDragDirection);
  }
  
  function onWheel(e) {
    const angle = calc.angle({
      x: e.deltaX,
      y: e.deltaY
    });

    if (angleIsVertical(angle)) return;
    
    e.stopPropagation();
    e.preventDefault();
    
    const newX = clampXOffset(
      sliderX.get() + - e.deltaX // (e.deltaX * factor) can speed or slow scroll
    );
    checkNavButtonStatus(newX);
    sliderX.set(newX);
  }
  
  function findClosestItemOffset(targetX, delta) {
    const { right, width } = items[0].getBoundingClientRect();
    const spacing = items[1].getBoundingClientRect().left - right;
    const totalItems = Math.abs(targetX) / (width + spacing);
    const totalCompleteItems = delta === 1
      ? Math.floor(totalItems)
      : Math.ceil(totalItems);

    return 0 - totalCompleteItems * (width + spacing);
  }
  
  function goto(delta) {
    const currentX = sliderX.get();
    let targetX = currentX + (- sliderVisibleWidth * delta);
    const clampedX = clampXOffset(targetX);

    targetX = (targetX === clampedX)
      ? findClosestItemOffset(targetX, delta)
      : clampedX;
    
    if (action) action.stop();
    action = tween({
      from: currentX,
      to: targetX,
      onUpdate: sliderX
    }).start();
    checkNavButtonStatus(targetX);
  }
  
  function notifyEnd(delta, targetOffset) {
    if (action) action.stop();
    action = physics({
      from: sliderX.get(),
      to: targetOffset,
      velocity: 2000 * delta,
      spring: 300,
      friction: 0.9
    })
      .output((v) => sliderX.set(v))
      .start();
  }
  
  const gotoNext = (e) => !e.target.classList.contains('disabled')
    ? goto(1)
    : notifyEnd(-1, minXOffset);

  const gotoPrev = (e) => !e.target.classList.contains('disabled')
    ? goto(-1)
    : notifyEnd(1, maxXOffset);
  
  function onFocus(e) {
    const { left, right } = e.target.getBoundingClientRect();
    const carouselLeft = carous.getBoundingClientRect().left;

    if (left < carouselLeft) {
      gotoPrev();
    } else if (right > carouselLeft + sliderVisibleWidth) {
      gotoNext();
    }
  }

  carous.addEventListener('touchstart', startTouchScroll);
  carous.addEventListener('wheel', onWheel);
  nextButton.addEventListener('click', gotoNext);
  prevButton.addEventListener('click', gotoPrev);
  slider.addEventListener('focus', onFocus, true);
  window.addEventListener('resize', measureCarousel);
  
  return () => {
    carous.removeEventListener('touchstart', startTouchScroll);
    carous.removeEventListener('wheel', onWheel);
    nextButton.removeEventListener('click', gotoNext);
    prevButton.removeEventListener('click', gotoPrev);
    slider.removeEventListener('focus', onFocus);
    window.removeEventListener('resize', measureCarousel);
  };
}

const destroyCarousel = carousel(document.querySelector('.carous'));

I have added this string in header

<script src="<em><u>lien caché</u></em>"></script>

But the scroll don't work... what is the issue?

#1191519

I have found what I need here lien caché and it work fine!!!

#1191520

My issue is resolved now. Thank you!