Comment créer un effet de navigation 2D glissable sans utiliser de plugins?

Oct 13 2020

Je voudrais créer un curseur de navigation déplaçable similaire à Noël bizarre . Comment voir le curseur: -

  • Aller à http://christmas.rogue.studio/
  • Cliquez sur le bouton "Envoyer une carte de Noël"
  • Cliquez sur n'importe quelle image pour ouvrir la fenêtre contextuelle et le curseur se trouve à l'intérieur de la fenêtre contextuelle.

Actuellement, dans ma mise en œuvre, chaque fois que je clique sur une image, la fenêtre contextuelle apparaît mais ma 1ère image est en haut à cause de la plus élevée z-index. Ce que je veux en fait, c'est que chaque fois que les utilisateurs cliquent sur une image, cette image particulière doit être accompagnée du z-index le plus élevé et le reste des autres images suivra le z-index selon cette image particulière z-index comme dans l'exemple de site Web (http://christmas.rogue.studio/ ).

De plus, je suis coincé avec le concept de bouton précédent: chaque fois que je clique sur le bouton précédent, cela ajoute une classe de sortie d'animation mais la configuration de la fonction zindex ne fonctionne pas correctement. La fonctionnalité du bouton suivant fonctionne correctement. un merci spécial à Reyno. J'ai eu de l'aide de lui pour la fonctionnalité du bouton suivant.

Voici l'exemple de travail https://codepen.io/mukul6996/pen/bGeEZaR

Ci-dessous mon code.

fichier index.html

<div class="gallery-wrapper">
    <div class="gallery-row">
        <div class="item">
            <a href="#" class="item-link">
                <img src="https://images.unsplash.com/photo-1602642753381-030eacbf4a58?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2434&q=80" />
            </a>
        </div>
        <div class="item">
            <a href="#" class="item-link">
                <img src="https://images.unsplash.com/photo-1602609741544-de5fc39b88ab?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80" />
            </a>
        </div>

        <div class="item">
            <a href="#" class="item-link">
                <img src="https://images.unsplash.com/photo-1602608646744-6a03235141c9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2434&q=80" />
            </a>
        </div>
        <div class="item">
            <a href="#" class="item-link">
                <img src="https://images.unsplash.com/photo-1602607878796-baf56d8dfc8a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2200&q=80" />
            </a>
        </div>
        <div class="item">
            <a href="#" class="item-link">
                <img src="https://images.unsplash.com/photo-1602653077972-0a5a38f9a466?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2458&q=80" />
            </a>
        </div>
    </div>


    <!-- Gallery Popup -->
    <div class="gallery-popup">
        <a href="javascript:void(0)" class="close-link">x</a>
        <div class="collection">
            <div class="post">
                <img src="https://images.unsplash.com/photo-1602642753381-030eacbf4a58?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2434&q=80" />
            </div>
            <div class="post">
                <img src="https://images.unsplash.com/photo-1602609741544-de5fc39b88ab?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=334&q=80" />
            </div>
            <div class="post">
                <img src="https://images.unsplash.com/photo-1602608646744-6a03235141c9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2434&q=80" />
            </div>
            <div class="post">
                <img src="https://images.unsplash.com/photo-1602607878796-baf56d8dfc8a?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2200&q=80" />
            </div>
            <div class="post">
                <img src="https://images.unsplash.com/photo-1602653077972-0a5a38f9a466?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2458&q=80" />
            </div>
        </div>

        <div class="button-holder">
            <button class="prev-btn">Previous</button>
            <button class="next-btn">Next</button>
        </div>
    </div>
    <!-- End of Gallery Popup -->
</div>

fichier style.css

 * {
        margin: 0;
        padding: 0;
        box-sizing: border-box;
    }
    
    body {
        overflow-x: hidden !important;
    }
    
    .gallery-popup {
        display: none;
        position: fixed;
        top: 0;
        left: 0;
        background: rgba(0, 0, 0, 0.8);
        width: 100%;
        height: 100%;
    }
    
    .collection {
        max-width: 300px;
        margin: 0 auto;
        perspective: 1500px;
        position: absolute;
        left: 50%;
        top: 120px;
        transform: translateX(-50%);
        width: 100%;
    }
    
    .post {
        position: absolute;
        left: 0;
        top: 0;
        width: 300px;
        height: 400px;
        background: orangered;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 4rem;
        transform-style: preserve-3d;
        transition: transform 0.25s cubic-bezier(0.57, 0.09, 0.105, 1.005);
    }
    
    .post img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
    
    .animate {
        transform: translate3d(350px, 25px, -400px);
    }
    
    .animate-out {
        transform: translate3d(350px, 15px, -100px);
    }
    
    .button-holder {
        position: absolute;
        bottom: 50px;
        width: 100%;
        text-align: center;
    }
    
    .button-holder button {
        margin: 5px;
        width: 70px;
        height: 30px;
        border-radius: 0;
        border: none;
        background: orangered;
        color: #fff;
    }
    
    .close-link {
        color: #fff;
        position: absolute;
        right: 15px;
        top: 15px;
        width: 35px;
        height: 35px;
        border-radius: 50%;
        line-height: 34px;
        text-align: center;
        text-decoration: none;
        font-size: 18px;
        font-family: 'Arial';
        background: orangered;
    }
    
    .gallery-row {
        display: flex;
        flex-wrap: wrap;
        padding: 15px;
        margin-left: -10px;
        margin-right: -10px;
    }
    
    .gallery-row .item {
        padding: 10px;
        flex: 0 0 25%;
        max-width: 25%;
    }
    
    .gallery-row .item img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

fichier main.js

$(function() { var galleryWrapper = $('.gallery-wrapper');

        galleryWrapper.each(function() {
            var $this = $(this),
                galleryPopup = $this.find('.gallery-popup'), prevBtn = $this.find('.prev-btn'),
                nextBtn = $this.find('.next-btn'), posts = $this.find('.post'),
                current = 0


            // -------- Opening popup by clicking on any item-link
            // --------------------------------------------

            $this.find('.item-link').on('click', function(event) { event.preventDefault(); galleryPopup.fadeIn(); $('body, html').css('overflow', 'hidden');
            });

            // -------- Closing popup by clicking on close-link
            // --------------------------------------------

            $this.find('.close-link').on('click', function(event) { event.preventDefault(); galleryPopup.fadeOut(); $('body, html').css('overflow', 'initial');
            })

            // -------- Popup slider script
            // --------------------------------------------

            function setZIndex() {
                for (let i = 0; i < posts.length; i++) {
                    const post = posts[i];
                    const {
                        zIndex
                    } = post.style;

                    post.style.zIndex = zIndex ? (Number(zIndex) + 1) % posts.length : posts.length - i - 1;
                }
            }

            nextBtn.on('click', function() {
                const post = posts[current];
                post.classList.add('animate');

                setTimeout(function() {
                    post.classList.remove('animate');
                    setZIndex();
                }, 300);

                current = (current + 1) % posts.length;
            });

            prevBtn.on('click', function() {
                const post = posts[current];
                post.classList.add('animate-out');

                setTimeout(function() {
                    post.classList.remove('animate-out');
                    setZIndex();
                }, 300);

                current = (current - 1) % posts.length;
            });

            setZIndex();
        });
    });

Réponses

1 Reyno Oct 13 2020 at 12:29

Vous pouvez utiliser du CSS pour créer une transition 3D. Tout ce que vous avez à faire est de définir le z-index et le timing corrects pour créer la meilleure animation.

Ce n'est qu'un petit concept que j'avais traîné mais il vous montre comment obtenir cet effet.

const btn = document.querySelector("button");
const posts = document.querySelectorAll(".post");
let current = 0;

const setZIndex = () => {
  for(let i = 0; i < posts.length; i++) {
    const post = posts[i];
    const { zIndex } = post.style;
    
    post.style.zIndex = zIndex ? (Number(zIndex) + 1) % posts.length : posts.length - i - 1;
  }
}

btn.addEventListener("click", () => {
    const post = posts[current];
    post.classList.add("animate");
    
    setTimeout(() => {
      post.classList.remove("animate");
      setZIndex();
    }, 500);
    
    current = (current + 1) % posts.length;
});

setZIndex();
.collection {
  position: fixed;
  top: 25%;
  left: 0;
  right: 0;
  margin: 0 auto;
  width: 75%;
  perspective: 1500px;
}

.post {
  position: absolute;
  left: 0;
  top: 0;
  width: 100px;
  height: 200px;
  background: orangered;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 4rem;
  transform-style: preserve-3d;
  transition: transform 0.25s cubic-bezier(0.57, 0.09, 0.105, 1.005);
}

.animate {
  transform: translate3d(300px, -25px, 500px);
}
<div class="collection">
  <div class="post">1</div>
  <div class="post">2</div>
  <div class="post">3</div>
  <div class="post">4</div>
  <div class="post">5</div>
</div>

<button>Next</button>