Swiper 5 ile 3d tekerleği simüle eden özel efekt


9

Sonsuz bir şekilde dönen bir 3d tekerleği simüle eden 12 maddeden oluşan bir atlıkarınca yapmam gerekiyor. Açık olmak gerekirse, tam olarak bu etkiyi yaratmam gerekiyor:

https://codepen.io/SitePoint/pen/yXWXaw ( burada bulundu )

ancak bu ekleme özellikleriyle (özellikle masaüstü ve mobil cihazlarda):

  1. slaytlar tokatlamak adım adım takip etmek gerekir, yani slaytlar kaydırma sırasında hareket etmelidir (Swiper gibi).
  2. Hızlı bir kaydırma ile birçok kaydı momentumla kaydırmalıdır (Swiper'ın yaptığı gibi freeScroll).
  3. Tekerlek (Swiper ile yaptığı gibi ön slayta oturur dönen durdurur Sonra zaman freeModeStickyve centeredSlides) o kullanıcıdan seçilmiş kişi olduğunu.
  4. Her zaman bir slayt değişikliği (olay gibi slideChanged) (Swiper yaptığı gibi ) bir geri arama gerekir .

Tüm bu nedenlerden dolayı Swiper 5.3.0'ın iyi bir başlangıç ​​noktası olacağını düşündüm .

Çeşitli geçici çözümü denedim, daha iyi olanı bu kurulumda, ancak loop: truekorkunç bir geçici çözüm ve sorunlara neden oluyor (yorumları kontrol edin):

  var swiper = new Swiper(el_class, {
    slidesPerView: 1.5,
    spaceBetween: 25,
    centeredSlides: true,
    grabCursor: true,
    speed: 550,
    loop: true, // <== repeat infinitely the 12 items. with fast scroll at the end of a cycle it waits a while before render the next cycle. Awful
    loopAdditionalSlides: 10, 

    // Free mode
    freeMode: true, // <== free scrolling. Good
    freeModeMomentumRatio: 1,
    freeModeMomentumVelocityRatio: 1.5,
    freeModeMomentumBounceRatio: 1,
    freeModeMinimumVelocity: 0.02,
    freeModeSticky: true, // <== snap to the slides. Good

    // Touch Resistance
    resistanceRatio: 0.85,

    // Prevent blurry texts
    roundLengths: true,

  });

Kesinlikle doğru yol değil.

Ben doğru yolu özel bir Swiper geliştirmektir düşünüyorum effect(gibi yerleşik cubeEffect, coverflowEffect, ...) o kullanmadan, tekerleği simüle loop:truenedenleri konularında söyledi. Örneğin, burada bir adam kendi özel efektini yaratır ve daha sonra effectSwiper özelliğine ayarlar : https://codepen.io/paralleluniv3rse/pen/yGQjMv

...
effect: "myCustomTransition",
...

İhtiyacım olan 3d tekerlek gibi özel bir efekt nasıl geliştirilir?


Bu etki ile bir başlangıç ​​noktası olarak çalışmanın en yararlı yol olup olmadığını merak ediyorum: swiperjs.com/demos/240-effect-coverflow.html . Gösteriyi tekrarlamak için kaydırıcının sağ tarafına geri dönmesine rağmen "geçmiş slaytları" negatif bir x ekseninde hareket ettirmeyi merak ediyorum ...
Phlume

1
@Phlume Zaten coverflowEffectbaşlangıç ​​noktası olarak çalışmayı ve parametrelerini "hacklemeyi" denedim ama bu sadece bir çözüm ve ilk kodlama etkisini elde edemiyorum. Slaytlar dairesel bir yüzeye yerleştirilmez.
Fred K

Üzgünüm, ne yapmak istediğinizi açıklayabilir misiniz? Önceki / sonraki düğmelere tıklamadan karuselin eğrilebilir olmasını ister misiniz ?
Mukyuu

1
@Mukyuu Güncel soru sorusu ayrıntılarla
Fred K

Yanıtlar:


2

Sanırım istediğin bu: https://codepen.io/mukyuu/pen/GRgPYqG .

Swiper 5 ve snap kullanmadığı sürece koşullarınızı neredeyse yerine getirdi.

  1. Tokatlamanın yönü ile döner.
  2. Hızlı bir kaydırma ile, birçok kaydı momentumla kaydırmalıdır (Swiper'ın yaptığı gibi).
  3. Daha sonra tekerlek dönmeyi bıraktığında, bir slayda yapışır (Swiper'ın yaptığı gibi).
  4. In ontouchfonksiyonu geri arama var.

HTML:

<div class="carousel" id="wrapper">
    <figure>
    <img src="https://source.unsplash.com/7mUXaBBrhoA/800x533" alt="">
    <img src="https://source.unsplash.com/bjhrzvzZeq4/800x533" alt="">
        <img src="https://source.unsplash.com/EbuaKnSm8Zw/800x533" alt="">
        <img src="https://source.unsplash.com/kG38b7CFzTY/800x533" alt="">
        <img src="https://source.unsplash.com/nvzvOPQW0gc/800x533" alt="">
        <img src="https://source.unsplash.com/mCg0ZgD7BgU/800x533" alt="">
    <img src="https://source.unsplash.com/1FWICvPQdkY/800x533" alt="">
        <img src="https://source.unsplash.com/VkwRmha1_tI/800x533" alt="">
    </figure>
</div>

S (CSS):

body {
    margin: 0;
    font-family: 'Roboto';
    font-size: 16px;

    display: flex;
    flex-direction: column;
    height: 100vh;
    justify-content: center;
}

// Carousel configuration parameters
$n: 8;
$item-width: 400px;
$item-separation: 80px;
$viewer-distance: 500px;

// Derived variables
$theta: 2 * 3.141592653589793 / $n; 
$apothem: 482.842712474619px;

.carousel {
    padding: 20px;

    perspective: $viewer-distance;
    overflow: hidden;

    display: flex;
    flex-direction: column;
    align-items: center;
    > * {
        flex: 0 0 auto;
    }

    figure {
        cursor: grab;
        margin: 0;

        width: $item-width;
        transform-style: preserve-3d;
        transition: transform 0.5s;
        transform-origin: 50% 50% (-$apothem);

        img {
            width: 100%;
            box-sizing: border-box;
            padding: 0 $item-separation / 2;

            opacity: 0.9;

            &:not(:first-of-type) {
                position: absolute;
                left: 0;
                top: 0;
                transform-origin: 50% 50% (-$apothem);
            }

            @for $i from 2 through $n {
                &:nth-child(#{$i}) {
                    transform: rotateY(#{($i - 1) * $theta}rad);
                }
            }
        }
    }

    nav {
        display: flex;
        justify-content: center;
        margin: 20px 0 0;

        button {
            flex: 0 0 auto;
            margin: 0 5px;

            cursor: pointer;

            color: #333;
            background: none;
            border: 1px solid;
            letter-spacing: 1px;
            padding: 5px 10px;
        }
    }
}

JS:

var
    carousel = document.querySelector('.carousel'),
    figure = carousel.querySelector('figure'),
    nav = carousel.querySelector('nav'),
    numImages = figure.childElementCount,
    theta =  2 * Math.PI / numImages,
    currImage = 0
;

// add touch detect:
function ontouch(el, callback){
 // Modified from http://www.javascriptkit.com/javatutors/touchevents3.shtml
    var touchsurface = el,
    dir,
    swipeType,
    startX,
    startY,
    distX,
    distY,
    threshold = 150, //required min distance traveled to be considered swipe
    restraint = 100, // maximum distance allowed at the same time in perpendicular direction
    allowedTime = 500, // maximum time allowed to travel that distance
    elapsedTime,
    startTime,
    handletouch = callback || function(evt, dir, phase, swipetype, distance){}

    touchsurface.addEventListener('touchstart', function(e){
        var touchobj = e.changedTouches[0]
        dir = 'none'
        swipeType = 'none'
        dist = 0
        startX = touchobj.pageX
        startY = touchobj.pageY
        startTime = new Date().getTime() // record time when finger first makes contact with surface
        handletouch(e, 'none', 'start', swipeType, 0) // fire callback function with params dir="none", phase="start", swipetype="none" etc
        e.preventDefault()

    }, false)

    touchsurface.addEventListener('touchmove', function(e){
        var touchobj = e.changedTouches[0]
        distX = touchobj.pageX - startX // get horizontal dist traveled by finger while in contact with surface
        distY = touchobj.pageY - startY // get vertical dist traveled by finger while in contact with surface
        if (Math.abs(distX) > Math.abs(distY)){ // if distance traveled horizontally is greater than vertically, consider this a horizontal movement
            dir = (distX < 0)? 'left' : 'right'
            handletouch(e, dir, 'move', swipeType, distX) // fire callback function with params dir="left|right", phase="move", swipetype="none" etc
        }
        else{ // else consider this a vertical movement
            dir = (distY < 0)? 'up' : 'down'
            handletouch(e, dir, 'move', swipeType, distY) // fire callback function with params dir="up|down", phase="move", swipetype="none" etc
        }
        e.preventDefault() // prevent scrolling when inside DIV
    }, false)

    touchsurface.addEventListener('touchend', function(e){
        var touchobj = e.changedTouches[0]
        elapsedTime = new Date().getTime() - startTime // get time elapsed
        if (elapsedTime <= allowedTime){ // first condition for awipe met
            if (Math.abs(distX) >= threshold && Math.abs(distY) <= restraint){ // 2nd condition for horizontal swipe met
                swipeType = dir // set swipeType to either "left" or "right"
            }
            else if (Math.abs(distY) >= threshold && Math.abs(distX) <= restraint){ // 2nd condition for vertical swipe met
                swipeType = dir // set swipeType to either "top" or "down"
            }
        }
        // Fire callback function with params dir="left|right|up|down", phase="end", swipetype=dir etc:
        handletouch(e, dir, 'end', swipeType, (dir =='left' || dir =='right')? distX : distY)
        e.preventDefault()
    }, false)
}
function DoSomething(dir, distance) {
  //modifiy this function for wheel rotation (prev/next) images
  var momentum = 100; // modify this value for how much momentum expected to switch to next/prev images
  switch (dir){
    case 'left':
    case 'right':
      currImage+= Math.round(distance/momentum);
      break;
  }
    figure.style.transform = `rotateY(${currImage * -theta}rad)`;
}
document.getElementById('wrapper').ondragstart = function() { return false; }; // prevent image dragged on mouse drag
window.addEventListener('load', function() {
  var dir, phase, el = document.getElementById('wrapper'),
    position = {
      X: 0,
      Y: 0
    };

  el.onmousedown = function(down) {
    position.X = down.clientX;
    position.Y = down.clientY;
  };

  el.onmouseup = function(up) {
    distX = up.clientX - position.X; // get horizontal dist traveled by finger while in contact with surface
    distY = position.Y - up.clientY; // get vertical dist traveled by finger while in contact with surface
    if (Math.abs(distX) > Math.abs(distY)) { // if distance traveled horizontally is greater than vertically, consider this a horizontal movement
      dir = (distX < 0) ? 'left' : 'right';
      distance = distX;
    } else { // else consider this a vertical movement
      dir = (distY < 0) ? 'down' : 'up';
      distance = distY;
    }
    dir = (distance == 0) ? 'none' : dir;
    DoSomething(dir, distance); // simulate touch from mouse control
  }; 
  ontouch(el, function(evt, dir, phase, swipetype, distance){
 // evt: contains original Event object
 // dir: contains "none", "left", "right", "top", or "down"
 // phase: contains "start", "move", or "end"
 // swipetype: contains "none", "left", "right", "top", or "down"
 // distance: distance traveled either horizontally or vertically, depending on dir value

 if ( phase == 'end' && (dir =='left' || dir == 'right') ) // on succesful swipe
   DoSomething(dir, distance);
})
}, false)

Android 9 ve Windows 10 tarayıcılarda test edilmiştir.


3
uhhh .. Soldan sağa
kaydırıyorum

2
Bu arada cevabınız için çok teşekkürler, ancak birçok gereksinime cevap vermiyor: 1) @Tschallacka tarafından belirtildiği gibi tersine döner. 2) slaytlar kaydırmayı izlemez, slaytlar kaydırırken kaydırmayı hareket ettirmelidir (Swiper'ın yaptığı gibi). 3) Hızlı bir kaydırma ile birçok kaydı momentumla kaydırmalıdır (Swiper'ın yaptığı gibi). 4) Daha sonra tekerlek dönmeyi durdurduğunda bir slayda oturur (Swiper'ın yaptığı gibi). 5)slideChanged (Swiper'ın yaptığı gibi) etkinlikte geri aramaya ihtiyacım var. Tüm bu nedenlerden dolayı Swiper'ın iyi bir başlangıç ​​noktası olacağını düşündüm ...
Fred K

Kayıt edilmiş. Dönüşleri tersine değiştirdim ve biraz momentum ekledim, Swiperjs ile neler yapabileceğimi görmeye çalışacağım. Bir şeyin daha fazla iyileştirmeye ihtiyacı olup olmadığını söyle.
Mukyuu
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.