Карусель анимации css3 ведет себя странно - PullRequest
0 голосов
/ 10 января 2020

Я создал эту вертикальную карусель из 3 предметов, и мне нужно исправить переход.

Мой текущий проект можно посмотреть здесь: http://hotelfjordgaarden.dk.test.vjm.dk/

I хочу создать переход из этого пера (обычный переход карусели смахивания / затухания): https://codepen.io/marcusmichaels/pen/yGGoLM

Если бы кто-нибудь мог помочь мне решить эту проблему, я был бы очень рад!

Заранее спасибо!

Мой HTML:

    <div class="container">
    <div class="frontpage__content__carousel">
        <div class="frontpage__content__carousel__list">
            <div class="frontpage__content__carousel__list__item" data-href="//google.com">
                <a href="//google.com">
                    <p class="h1">
                        Heading
                    </p>
                    <p class="sub">
                        Subheading
                    </p>
                </a>
            </div>
            <div class="frontpage__content__carousel__list__item" data-href="//google.com">
                <a href="//google.com">
                    <p class="h1">
                        Heading
                    </p>
                    <p class="sub">
                        Subheading
                    </p>
                </a>
            </div>
            <div class="frontpage__content__carousel__list__item" data-href="//google.com">
                <a href="//google.com">
                    <p class="h1">
                        Heading
                    </p>
                    <p class="sub">
                        Subheading
                    </p>
                </a>
            </div>
            <div class="frontpage__content__carousel__list__item" data-href="//google.com">
                <a href="//google.com">
                    <p class="h1">
                        Heading
                    </p>
                    <p class="sub">
                        Subheading
                    </p>
                </a>
            </div>
            <div class="frontpage__content__carousel__list__item" data-href="//google.com">
                <a href="//google.com">
                    <p class="h1">
                        Heading
                    </p>
                    <p class="sub">
                        Subheading
                    </p>
                </a>
            </div>
        </div>
        <div class="frontpage__content__carousel__navigation">
            <div class="prev icon" id="jsGoToPrev"></div>
            <div class="next icon" id="jsGoToNext"></div>
        </div>
    </div>
</div>

Мой SASS:

.frontpage {
    width: 100%;
    overscroll-behavior: none;

    .header {
        background: white;
        display: flex;
        width: 100%;
        justify-content: center;
        align-items: center;
        height: 138px;
    }

    .frontpage__content {
        width: 100%;
        height: 100%;
        display: flex;
        text-align: center;
        align-items: center;
        background-size: cover;
        background-position: center;
        background-repeat: no-repeat;
        position: relative;
        overflow: hidden;

        @media only screen and (max-width: @screen-sm-max) {
            > div {
                width: 100%;
                margin-left: auto;
                margin-right: auto;
            }
        }


        &::before {
            content: '';
            display: block;
            position: absolute;
            top: 0;
            right: 0;
            bottom: 0;
            left: 0;
            background-color: #8fa2a6;
            z-index: -2;
        }

        &__video {
            position: absolute;
            left: 0;
            top: 0;
            bottom: 0;
            right: 0;
            z-index: -1;
            opacity: 0.4;
        }

        // carousel wrapper
        &__carousel {
            overflow: hidden;

            & * {
                box-sizing: border-box;
            }

            // carousel
            &__list {
                overflow: hidden;
                transform-style: preserve-3d;

                &__item {
                    // disable user selection
                    -webkit-touch-callout: none;
                    -webkit-user-select: none;
                    -khtml-user-select: none;
                    -moz-user-select: none;
                    -ms-user-select: none;
                    user-select: none;

                    opacity: 0;
                    position: absolute;
                    top: 0;
                    left: 0;
                    transition: transform .5s, top .5s, z-index .5s;
                    width: 100%;
                    z-index: -100;
                    margin: auto;

                    a {

                        .h1 {
                            font-size: 18px;
                            color: white;
                            text-transform: uppercase;
                            margin: 0;
                        }

                        .sub {
                            font-size: 14px;
                            font-weight: 500;
                            color: white;
                            margin: 0;
                        }
                    }

                    &.prev {
                        transform: translateY(-100%);
                        z-index: 800;
                        opacity: 0.5;
                    }

                    &.next {
                        transform: translateY(420%);
                        @media only screen and (min-width: @screen-lg) {
                            transform: translateY(500%);
                        }
                        z-index: 800;
                        opacity: 0.5;
                    }

                    &.active {
                        opacity: 1;
                        position: relative;
                        z-index: 900;
                        padding: 40px 0;
                        margin: 20px 0;
                        border: 1px solid rgba(255, 255, 255, 0.4);
                        border-left: none;
                        border-right: none;

                        a {
                            .h1 {
                                font-size: 18px;
                            }

                            .sub {
                                font-size: 16px;
                            }
                        }
                    }
                }
            }

            &__navigation {
                -webkit-touch-callout: none;
                -webkit-user-select: none;
                -khtml-user-select: none;
                -moz-user-select: none;
                -ms-user-select: none;
                user-select: none;
                display: none;
                position: relative;

                .icon {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    width: 40px;
                    height: 40px;
                    font-size: 20px;
                    border-radius: 50%;
                    border: 2px solid rgba(white, 0.5);
                    color: rgba(white, 0.5);
                    font-weight: 400;
                    font-family: 'Font Awesome 5 Pro';
                    position: fixed;
                    left: 60px;
                    cursor: pointer;
                }

                .prev {
                    top: 40%;

                    &::before {
                        content: '\f176';
                    }
                }

                .next {
                    top: 70%;

                    &::before {
                        content: '\f175';
                    }
                }
            }
        }
    }

    // tablet portrait
    @media only screen and (min-width: @screen-sm) {
        height: 100vh;

        .frontpage__content__carousel__list__item {
            a {
                .h1 {
                    font-size: 30px;
                }

                .sub {
                    font-size: 10px;
                }
            }


            &.active {
                a {
                    .h1 {
                        font-size: 40px;
                    }

                    .sub {
                        font-size: 24px;
                    }
                }
            }
        }
    }

    // tablet landscape
    @media only screen and (min-width: @screen-md) {
        .frontpage__content__carousel__list__item {
            a {
                .h1 {
                    font-size: 30px;
                }

                .sub {
                    font-size: 10px;
                }
            }


            &.active {
                a {
                    .h1 {
                        font-size: 40px;
                    }

                    .sub {
                        font-size: 24px;
                    }
                }
            }
        }
    }

    // desktop
    @media only screen and (min-width: @screen-lg) {
        .frontpage__content__carousel__navigation {
            display: block;
        }
        .frontpage__content__carousel__list__item {
            a {
                .h1 {
                    font-size: 30px;
                }

                .sub {
                    font-size: 10px;
                }
            }


            &.active {
                a {
                    .h1 {
                        font-size: 60px;
                    }

                    .sub {
                        font-size: 30px;
                    }
                }
            }
        }
    }
}

Мой Javascript:

if ($('.frontpage__content').length > 0) {
    $(document).ready(function () {
        adjustFrontpageContentHeight();
    });

    $(window).resize(function () {
        adjustFrontpageContentHeight();
    });

    function adjustFrontpageContentHeight() {
        var $windowHeight = $(window).height();
        var $headerHeight = $('.header').height();

        $('.frontpage__content').height($windowHeight - $headerHeight);
    }

    (function ($) {

        var carousel      = $('.frontpage__content__carousel');
        var list          = $('.frontpage__content__carousel__list');
        var items         = $('.frontpage__content__carousel__list__item');
        var totalItems    = items.length;
        var slide         = 0;
        var moving        = true;
        var itemClassName = 'frontpage__content__carousel__list__item';

        function getElements() {
            var prev   = $('.frontpage__content__carousel__list__item.prev');
            var active = $('.frontpage__content__carousel__list__item.active');
            var next   = $('.frontpage__content__carousel__list__item.next');

            var beforePrev;
            if (prev.prev().length > 0) {
                beforePrev = prev.prev();
            } else if (prev.data('index') == 0) {
                beforePrev = $('[data-index=' + (totalItems - 1) + ']')
            } else {
                beforePrev = $('[data-index=' + (prev.data('index') - 1) + ']');
            }

            var afterNext;
            if (next.next().length > 0) {
                afterNext = next.next();
            } else {
                afterNext = $('[data-index=' + (next.data('index') + 1) + ']');
            }

            return {
                beforePrev: beforePrev,
                prev      : prev,
                active    : active,
                next      : next,
                afterNext : afterNext,
            }
        }

        function setInitialClasses() {
            items[totalItems - 1].className = itemClassName + ' prev';
            items[0].className              = itemClassName + ' active';
            items[1].className              = itemClassName + ' next';
        }

        function goToPrev() {
            if (!moving) {
                // if first slide, set as last slide, else -1
                if (slide === 0) {
                    slide = (totalItems - 1);
                } else {
                    slide--;
                }

                goToSlide(slide);
                //prependPrev();
            }
        }

        function goToNext() {
            if (!moving) {
                // if last slide, reset to 0, else +1
                if (slide === (totalItems - 1)) {
                    slide = 0;
                } else {
                    slide++;
                }
                goToSlide(slide);
                //appendNext();
            }
        }

        function goToSlide(slide) {
            if (!moving) {
                disableInteraction();

                // Update the "old" adjacent slides with "new" ones
                var newPrevious = slide - 1,
                    newNext     = slide + 1,
                    oldPrevious = slide - 2,
                    oldNext     = slide + 2;

                // Checks and updates if the new slides are out of bounds
                if (newPrevious <= 0) {
                    oldPrevious = (totalItems - 1);
                } else if (newNext >= (totalItems - 1)) {
                    oldNext = 0;
                }
                // Checks and updates if slide is at the beginning/end
                if (slide === 0) {
                    newPrevious = (totalItems - 1);
                    oldPrevious = (totalItems - 2);
                    oldNext     = (slide + 1);
                } else if (slide === (totalItems - 1)) {
                    newPrevious = (slide - 1);
                    newNext     = 0;
                    oldNext     = 1;
                }
                items.each(function() {
                    $(this).removeClass('active prev next');
                });

                // Add new classes
                items[newPrevious].className = itemClassName + " prev";
                items[slide].className       = itemClassName + " active";
                items[newNext].className     = itemClassName + " next";
            }
        }

        function disableInteraction() {
            moving = true;
            // set timeout to same as transition length
            setTimeout(function () {
                moving = false;
            }, 500);
        }

        function setEventListeners() {
            // click listeners
            $('body').on('click', '#jsGoToPrev', function () {
                goToPrev();
            });
            $('body').on('click', '#jsGoToNext', function () {
                goToNext();
            });
            $('body').on('click', '.frontpage__content__carousel__list__item.prev', function () {
                goToPrev();
            });
            $('body').on('click', '.frontpage__content__carousel__list__item.next', function () {
                goToNext();
            });
            $('body').on('click', '.frontpage__content__carousel__list__item.active', function () {
                if (!moving) {
                    window.location.href = $(this).data('href');
                }
            });

            // mousewheel scroll listener
            $('body').on('wheel', carousel.selector, function (e) {
                if (e.originalEvent.deltaY < 0) {
                    goToPrev();
                } else if (e.originalEvent.deltaY > 0) {
                    goToNext();
                }
            });

            // touch scroll listener
            var ts;
            var te;
            $('body').on('touchstart', function (e) {
                ts = e.originalEvent.touches[0].clientY;
            });

            $('body').on('touchend', function (e) {
                te = e.originalEvent.changedTouches[0].clientY;
                if (ts > te+5) {
                    goToNext();
                } else if (ts < te-5) {
                    goToPrev();
                }
            });
        }

        function prependPrev() {
            list.prepend(getElements().prev);
        }

        function appendNext() {
            list.append(getElements().next);
        }

        function initCarousel() {

            // nullify links href after load - this is due to SEO
            items.each(function () {
                $(this).find('a').attr('href', 'javascript:void(0)');
            });
            setInitialClasses();
            setEventListeners();
            prependPrev();

            moving = false;
        }

        $(document).ready(function () {
            initCarousel();
        });
    })(jQuery);
}

1 Ответ

0 голосов
/ 20 января 2020

То, что я, в конце концов, завелся, таково: заставьте мою карусель DIV / контейнер переполняться: скрыто, чтобы внутри могли быть предметы, которые скрыты из-за переполнения. Затем я использую jQuery для прокрутки моего div, когда щелкает неактивный элемент. Весь скрипт для страницы здесь:

if ($('.frontpage__content').length > 0) {
    $('.frontpage__content__carousel__list__item ').click(function (e) {
        if (!$(this).hasClass('active')) {
            e.preventDefault();
            var direction = 'up';
            if ($(this).index() >= $('.frontpage__content__carousel__list__item.active').index()) {
                direction = 'down';
            }

            $('.frontpage__content__carousel__list__item').removeClass('active');
            $(this).addClass('active');

            var _this     = this;
            var scrollTop = 0;

            var items = $('.frontpage__content__carousel__list__item');
            items.each(function (index, item) {
                if ($(this).is($(_this).prev()) || $(_this).index() == 0) {
                    return false;
                }

                scrollTop += $(this).height();
            });

            $('.frontpage__content__carousel__list').stop().animate({
                'scrollTop': scrollTop
            });
        }
    });

    function goToPrev() {
        $('.frontpage__content__carousel__list__item.active').prev().trigger('click');
    }

    function goToNext() {
        $('.frontpage__content__carousel__list__item.active').next().trigger('click');
    }

    $('#jsGoToPrev').click(function () {
        goToPrev();
    });

    $('#jsGoToNext').click(function () {
        goToNext();
    });

    $(window).resize(function () {
        adjustFrontpageContentHeight();
    });

    function adjustFrontpageContentHeight() {
        var $windowHeight = $(window).height();
        var $headerHeight = $('.header').height();

        $('.frontpage__content').height($windowHeight - $headerHeight);
    }

    var moving = false;
    // mousewheel scroll listener
    $('body').on('wheel', '.frontpage__content__carousel', function (e) {
        if (!moving) {
            moving = true;
            setTimeout(function () {
                moving = false;
            }, 250);

            if (e.originalEvent.deltaY < 0) {
                goToPrev();
            } else if (e.originalEvent.deltaY > 0) {
                goToNext();
            }
        }

    });

    // touch scroll listener
    var ts;
    var te;
    $('body').on('touchstart', '.frontpage__content__carousel', function (e) {
        ts = e.originalEvent.touches[0].clientY;
    });

    $('body').on('touchend', '.frontpage__content__carousel', function (e) {
        te = e.originalEvent.changedTouches[0].clientY;
        if (ts > te + 5) {
            goToNext();
        } else if (ts < te - 5) {
            goToPrev();
        }
    });

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