swiper icon indicating copy to clipboard operation
swiper copied to clipboard

Active bullet is not centered when using custom value on dynamicMainBullets

Open zecka opened this issue 1 year ago • 3 comments

Check that this is really a bug

  • [X] I confirm

Reproduction link

https://stackblitz.com/edit/swiper-demo-4-pagination-dynamic-bullets-onb81qfr?file=index.html

Bug description

When using dynamicBullet with a custom dynamicMainBullets value the active bullet is not centered

var swiper = new Swiper('.swiper-container', {
        pagination: {
          el: '.swiper-pagination',
          dynamicBullets: true,
          dynamicMainBullets: 5,
        },
});

Followings issues are closed but seems to be related to the same bug https://github.com/nolimits4web/swiper/issues/5304 https://github.com/nolimits4web/swiper/issues/5250

Expected Behavior

image

Actual Behavior

image

Swiper version

11.1.5

Platform/Target and Browser Versions

macOs Chrome

Validations

  • [X] Follow our Code of Conduct
  • [X] Read the docs.
  • [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
  • [X] Make sure this is a Swiper issue and not a framework-specific issue

Would you like to open a PR for this bug?

  • [ ] I'm willing to open a PR

zecka avatar Dec 20 '24 08:12 zecka

can i work on this issue??

devjs2705 avatar Dec 20 '24 15:12 devjs2705

any updates here? running in the same problem and currently solving it by writing a complete custom bullet implementation, which feels hacky and ugly at the same time 🐙

mindray87 avatar Mar 06 '25 15:03 mindray87

In case someone need the proper patching for bullet centering + variable active bullet width. Here is my solution which works in any browser, for dynamicMainBullets: 3 (like on Amazon PrimeVideo main slider):

Javascript

const swiper = new Swiper('.swiper', {
    loop: true,
    pagination: {
        el: '.swiper-pagination',
        dynamicMainBullets: 3,
    },
    navigation: {
        nextEl: '.swiper-button-next',
        prevEl: '.swiper-button-prev',
    },
    on: {
        paginationUpdate: function (swiper, pEl) {
            let mainBullets = this.originalParams.pagination.dynamicMainBullets,
                slidesQ = $(".swiper-pagination-bullet", pEl).length,
                $Prev, $Next
            if (this.realIndex >= mainBullets && this.realIndex < slidesQ - mainBullets) {
                $Prev = $(":nth-child(" + (this.realIndex - 1) + ")", pEl)
                $Next = $(":nth-child(" + (this.realIndex + 3) + ")", pEl)
                $(pEl).children().removeClass("swiper-pagination-bullet-active-prev swiper-pagination-bullet-active-next")
                $(pEl).children().css("left", parseInt( 16 * (mainBullets - this.realIndex - 1)   + "px"))
            } else {
                if (this.realIndex < mainBullets) {
                    $Next = $(":nth-child(" + (mainBullets + 2) + ")", pEl)
                    $(pEl).children().css("left", "0px")
                } else {
                    $Prev = $(":nth-child(" + (slidesQ - mainBullets - 1) + ")", pEl)
                    $(pEl).children().css("left", parseInt( 16 * (mainBullets - slidesQ + 2)   + "px"))
                }
            }
            if ($Prev) $Prev.addClass("swiper-pagination-bullet-active-prev")
            if ($Next) $Next.addClass("swiper-pagination-bullet-active-next")
        }
    }
});

And CSS

.swiper-pagination-bullet {
    position: relative;
    transition: all .2s;
}
.swiper-pagination-bullet-active {
    width: var(--swiper-pagination-active-bullet-size, var(--swiper-pagination-bullet-size));
}
.swiper-horizontal > .swiper-pagination-bullets, .swiper-pagination-bullets.swiper-pagination-horizontal {
    left: 50%;
    transform: translateX(-50%);
    width: calc(4* var(--swiper-pagination-bullet-size) + var(--swiper-pagination-active-bullet-size) + 10* var(--swiper-pagination-bullet-horizontal-gap));
    white-space: nowrap;
    overflow: hidden;
}
.swiper-pagination-bullet-active-prev, .swiper-pagination-bullet-active-next {
    transform: scale(0.5);
}
:root {
    --swiper-pagination-bullet-size: 8px;
    --swiper-pagination-active-bullet-size: 16px;
    --swiper-pagination-bullet-border-radius: 10000px;
    --swiper-pagination-bullet-horizontal-gap: 4px;
    --swiper-pagination-bullet-inactive-color: #fff;
    --swiper-pagination-bullet-inactive-opacity: 1;
}

Hope this would be helpful for someone :blush:

arriterx avatar Apr 22 '25 15:04 arriterx