Code Monkey home page Code Monkey logo

embla-carousel's People

Contributors

anzbert avatar davidjerleke avatar dependabot-preview[bot] avatar dependabot[bot] avatar hamidrezahanafi avatar horseeyephil avatar javiergonzalezgenially avatar joshuacrewe avatar liammartens avatar lucasmarinifalbo avatar meirroth avatar mujahidfa avatar nikrowell avatar nwidynski avatar openscript avatar pipisasa avatar ranno-lauri avatar rojadesign avatar romellem avatar ronit-gurjar avatar ruijdacd avatar sadeghbarati avatar sarussss avatar silllli avatar smultar avatar th-km avatar tlo-johnson avatar wopian avatar xiel avatar zaaakher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

embla-carousel's Issues

Scroll Progress (set)

๐Ÿ‘‰ Feature Specification

// set scroll progress
// accepts a number from 0 - 1 representing % scrolled of scrollable distance
// scroll to target is smooth

embla.scrollToProgress(0.5)

As discussed in issue #21.

Special thanks

@xiel for this feature request.

Only dispatch dragStart event if mouse is actually dragging

It would be great if the dragStart event would not fire when the mouse goes down but rather when the cursor actually starts moving. Currently, dragStart and dragEnd will be fired if I only click/touch the slider without moving the cursor.

This would be useful to me because I am currently listening to both click events on items and dragStart/dragEnd Events and change styles accordingly. This leads to the item click having weird effects as it first transitions to the "drag" styles and back before the click event is fired.

I am currently using embla-carousel-react but I think this is something that concerns all variants of embla.

Let me know if you need an example.

Great Work by the way! ๐Ÿ˜Š

Example of using multiple slides and making it responsive

Hi David,

I noticed that in 2.4.0 you introduced the containScroll option, which allows me to use that in combination with slidesToScroll to display multiple slides at once. I was wondering if you had any recommendations on how to make the carousel responsive when used in this way.

For example, I want to show a different number of slides depending on the size of the window...

  • Desktop: slidesToScroll: 3
  • Tablet: slidesToScroll: 2
  • Phone: slidesToScroll: 1

One idea I had was to detect changes to the windows size and then fire the changeOptions() method to update the slidesToScroll option.

Is that the right approach, or would you recommend something else?

Vue 3 wrapper

Feature description

Create an Embla Carousel Vue wrapper - A component that allows Vue users to consume Embla Carousel.

Release

Released with v7.0.0-rc05. Documentation will be released with stable v7 but until then you can check out usage instructions below:

Vue wrapper

Start by installing the Embla Carousel npm package and add it to your dependencies.

npm install embla-carousel-vue --save

The component structure

Embla Carousel provides the handy emblaCarouselVue function for seamless integration with Vue. A minimal setup requires an overflow wrapper and a scroll container. Start by adding the following structure to your carousel:

<template>
  <div class="embla" ref="emblaNode">
    <div class="embla__container">
      <div class="embla__slide">Slide 1</div>
      <div class="embla__slide">Slide 2</div>
      <div class="embla__slide">Slide 3</div>
    </div>
  </div>
</template>

<script>
  import emblaCarouselVue from 'embla-carousel-vue'

  export default {
    setup() {
      const [emblaNode] = emblaCarouselVue()
      return { emblaNode }
    },
  }
</script>

Styling the carousel

The emblaCarouselVue function gives us an emblaNode to attach to our wrapping element with the classname embla, which is needed to cover the scroll overflow. The element with the container classname is the scroll body that scrolls the slides. Continue by adding the following CSS to these elements:

<style scoped>
  .embla {
    overflow: hidden;
  }
  .embla__container {
    display: flex;
  }
  .embla__slide {
    position: relative;
    flex: 0 0 100%;
  }
</style>

Accessing the carousel API

The emblaCarouselVue function takes the Embla Carousel options as the first argument. Additionally, you can access the API with an onMounted like demonstrated below:

<template>
  <div class="embla" ref="emblaNode">
    <div class="embla__container">
      <div class="embla__slide">Slide 1</div>
      <div class="embla__slide">Slide 2</div>
      <div class="embla__slide">Slide 3</div>
    </div>
  </div>
</template>

<script>
  import { onMounted } from 'vue'
  import emblaCarouselVue from 'embla-carousel-vue'

  export default {
    setup() {
      const [emblaNode, emblaApi] = emblaCarouselVue({ loop: false })

      onMounted(() => {
        if (emblaApi.value) {
          // Embla API is ready
        }
      })

      return { emblaNode, emblaApi }
    },
  }
</script>

Adding plugins

The emblaCarouselVue function also accepts plugins as the second argument. Note that plugins need to be passed in an array like so:

<template>
  <div class="embla" ref="emblaNode">
    <div class="embla__container">
      <div class="embla__slide">Slide 1</div>
      <div class="embla__slide">Slide 2</div>
      <div class="embla__slide">Slide 3</div>
    </div>
  </div>
</template>

<script>
  import emblaCarouselVue from 'embla-carousel-vue'
  import Autoplay from 'embla-carousel-autoplay'

  export default {
    setup() {
      const [emblaNode] = emblaCarouselVue({ loop: false }, [Autoplay()])
      return { emblaNode }
    },
  }
</script>

Congratulations! You just created your first Embla Carousel component.

Add option for Y-axis

๐Ÿ‘‰ Feature Specification

// accepts an axis option with 'x' and 'y' as possible values
const options = { axis: 'y' }
const embla = EmblaCarousel(emblaNode, options)

Special thanks

To all guys sending me private emails instead of opening an issue about this.

This has been implemented and will be released with version 3.

Add support for wheel event scrolling

When using touchpad on an MacBook, you can use two-finger gestures for scrolling. As far as I understand, these values are available through "wheel" events in javascript.

It would be very nice to have support for horizontal scrolling using touchpad in Embla Carousel if possible.

Here is a fiddle that demonstrates the values received: https://jsfiddle.net/64p5r459/2/

Snappoints on showing multiple slides

Currently I am implementing Embla Carousel in a project where we have multiple slides in the viewport at once, this basically means 2.5 slides are always visible.

When we containScroll and align start the items the snappoints for slide 4 and 5 are the same so it feels there should be one less snappoint for these settings.

I've setup a sandbox forked from one of the other issues to explain this issue: https://codesandbox.io/s/embla-carousel-loop-false-xdpsb?fontsize=14

Add a Settle event

๐Ÿ‘‰ Feature Specification

// Embla should fire an event when the carousel has stopped scrolling.

embla.on('settle', () => {
  console.log('The carousel has stopped scrolling.')
})

Special thanks

@horgen for this feature request.

Initialize embla after certain width, and destroy below certain width

Hello, i have a problem with initializing Embla carousel after 992px and destroying it below that value.

My js code:

const initBrandsEmbla = () => {
  const brandsEmbla = document.querySelector('.embla__brands');

  if (brandsEmbla !== null) {
    const settings = {
      draggable: false,
      loop: true,
      align: 'start',
      startIndex: 1,
    };

    const embla = EmblaCarousel(brandsEmbla, settings);
    const autoPlayer = autoPlay(embla, 1000);

    const checkEmbla = () => {
      if (window.matchMedia('(max-width: 992px)').matches) {
        // I want to reinitialize it here
        // something like embla.recover() would be helpful
        autoPlayer.play();
      } else {
        embla.destroy();
      }
    }

    checkEmbla();

    // On embla resize, check the width and initialize carousel, or destroy it
    embla.on('resize', () => {
      checkEmbla();
    });
  }
}

window.addEventListener('load', () => {
  initBrandsEmbla();
});

The problem is: it works when i load the window that has width lower than 992, it also works as intended (the carousel stops) when i resize that window above 992px, but when i go back below 992px, the carousel doesn't recover or reinitialize no matter what i do.
I tried many things, but nothing worked so far.

When i try something like that:

const initBrandsEmbla = () => {
  const brandsEmbla = document.querySelector('.embla__brands');

  if (brandsEmbla !== null) {
    const settings = {
      draggable: false,
      loop: true,
      align: 'start',
      startIndex: 1,
    };

    let embla;
    let autoPlayer;

    const checkEmbla = () => {
      if (window.matchMedia('(max-width: 992px)').matches) {
        // I want to reinitialize it here
        embla = EmblaCarousel(brandsEmbla, settings);
        autoPlayer = autoPlay(embla, 1000).play();
      } else {
        embla.destroy();
      }
    }

    checkEmbla();

    // On embla resize, check the width and initialize carousel, or destroy it
    window.addEventListener('resize', () => {
      checkEmbla();
    });
  }
}

window.addEventListener('load', () => {
  initBrandsEmbla();
});

Then it doesn't stop on the desktop, i've ran out of ideas :/

Do you know the solution by any chance?

[Feat]: Add a fade plugin

Love the carousel and was able to get it working right away. The one thing that I need that it doesn't provide is a way to have a scroll option for single/multiple slides and a fade option to handle next/previous transition when it's just showing a single slide at a time.

Is that something that has been requested before?

Setting up multiple carousels on same page

Possible / how to do something like this?

import EmblaCarousel from 'embla-carousel';

var elements = document.querySelectorAll("li.carouselparent");

for (var i= 0; i < elements.length; i++) {
  const emblaNode = document.querySelector('.embla');
  const options = { loop: true };
  const embla = EmblaCarousel(emblaNode, options);
}

Trying to display multiple slides, scroll by one slide only

I can use CSS to quickly change Embla so that instead of showing a single slide, it shows more (e.g. width:25%), however when using scrollNext and scrollPrev, it still scrolls by 100%, for the full number of slides.

This means that for several clicks on next/prev button, there are no slides showing. I really like Embla and don't want to have to implement a different solution, but I have no idea where to even start changing the TS to make it perform as expected. Do you have any plans to update to allow the functionality I'm after?

Is there anyway to use this just with plain javascript?

Hi guys....
I'm just a rookie dev... in fact, I'm just code my portfolio with plane html, css and javascript and well, I thought this can be more easy to implement.

I just wonder if there anyway to use this without typescript or anyway more simple?

Another css units in embla__container translate3d() animation

Hello, is it possible to have an option of selecting another css unit for the transform animation?
I mean: .embla__container is using translate3d(%, 0, 0) for the animations, but from what i've tested on my website, the performance would be better if i used translate3d(px, 0, 0) instead of % value.

Would you consider adding this feature to the Embla Carousel?

Thank you.

1 slide is not displayed

When I have 2 slides, the carousel works as expected.

If I have just 1 slide the slide does not show and it is with left: 100%.

I found that the reason is the option loop: true.

Since we are populating the slides dynamically, can the lib disable the loop if the slide is just one?

Unnecessary scroll under certain conditions

Hi! I ran into a nasty bug with unnecessary scroll under certain conditions:

  • loop: true
  • draggable: false
  • slidesToScroll: more than 1 (for example 4)
  • slides count: more than slidesToScroll but not completely divisible by slidesToScroll (for example 5)

In this case after initial load when we scroll to next and try to click link on the first slide we see unnecessary scroll.

Here's a demonstration of what I'm talking about: https://codesandbox.io/s/embla-carousel-containscroll-mec6x

As I figured out it is because click on the link fires focus event and Embla considers that this is not the current slide and does scroll.

Add contributors to README

Add all contributors to README to show appreciation for their great efforts ๐Ÿ’ช๐Ÿปโญ๏ธ!

Scroll By

๐Ÿ‘‰ Specification (implemented)

// adds to current scroll progress
// accepts a number from 0 - 1 representing % to add to the current scroll progress
// scroll to target is smooth

embla.scrollBy(0.5)

As discussed here and here in issue #21.

Special thanks

@xiel for this feature request.

Please react with --> ๐Ÿ‘ if you want this to be implemented.

Make Drag Threshold configurable

As already mentioned in #22, I think it would be desirable to make the threshold at which the slider starts to react to the hand/cursor movement configurable.

That might look like this:

const embla = EmblaCarousel(emblaNode, {
  dragThreshold: 5,
  ...
})

With the value being the amount of pixels the hand/cursor has to move until the silder will follow its movement.

Apparently there already is a drag threshold already built in and I'm sure that the default value will be enough for most devs but depending on what kind of device the slider is used on, it could be quite useful (I'm thinking mostly about touch screens here).

Jeff

TypeErrorCannot read property '0' of undefined

Hey! Let me first say, loving the library so far. Very easy to get a really nice carousel with 0 config :) So thanks for the nice defaults.

I just got this error reported in my error tracking, and it leads to embla-carousel/lib/index.

Environment:

Chrome Mobile Version 77.0.3865
Android Version 8.0.0

TypeError: Cannot read property '0' of undefined
 at ./node_modules/embla-carousel/lib/index.js(read:1589:46)
 at ./node_modules/embla-carousel/lib/index.js(apply:1417:29)
 at ./node_modules/logrocket/dist/build.umd.js(HTMLElement.o:2857:31)

chrome_2019-10-11_22-49-17

So that's

./node_modules/embla-carousel/lib/index.js in read on line 1589:46
1586 | function read(evt, axis) {
1587 | var isMouse = state.isMouse;
1588 | var c = coords[axis];
1589 | var value = isMouse ? evt[c] : evt.touches[0][c];
1590 | return pointValue.setNumber(value);
1591 | }
1592 | ย 
1593 | function down(evt) {
1594 | state.isMouse = !!evt.type.match(/mouse/);

./node_modules/embla-carousel/lib/index.js in apply on line 1417:29
1413 | var resist = !params.loop && reachedLimit ? 2 : 1;
1414 | target.addNumber(diff / resist);
1415 | evt.preventDefault();
1416 | } else {
1417 | var X = pointer.read(evt, 'x').get();
1418 | var Y = pointer.read(evt, 'y').get();
1419 | var diffX = Math.abs(X - startX.get());
1420 | var diffY = Math.abs(Y - startY.get());
1421 | state.preventScroll = diffX > diffY;
1422 | if (!state.preventScroll && !state.preventClick) up();

If you need some copy and paste friendly text.

Not really sure how to go from here! I was going to default value to 0 if evt.touches is not defined although that is just a hack :)

Thanks!

Bug with two 50 % slides when containScroll = true

Hi!

First of all, let me say that I really like embla-carousel. Thank you for sharing your awesome work!!

There's one little bug I discovered when I have two slides with width: 50% and containScroll is set to true. It doesn't appear if I have only one slide with width: 100% or three slides with width: 33.33%.

Here's a demonstration of what I'm talking about: https://codesandbox.io/s/embla-carousel-loop-true-xgg95

It's actually easy to fix by setting the width to 49.99 % but as this is only a workaround, I wanted to report the issue.

Once again, thanks for your efforts!

Percentage alignment options

Hi @davidcetinkaya - thanks for your work on this - love your vision for a lightweight and flexible carousel!

I'm working on a project where it would be useful to specify the align option as a percentage from the left edge (let me know if helpful to have a visual / example of my use case). Is this something you could see being added to Embla?

Add methods about previous and next slides in the API?

Hello again, I was checking the example on CodeSandbox.

I wanted to customize the example to hide the "Previous" button when the first slide is shown and if the "loop" mode is off.

I have seen I can grab the current index position with selectedIndex() and the total number of slides using groupedIndexes() but it's not very obvious and the concept of "grouped slides" is a bit confusing.

Maybe embla object could expose some convenient methods or properties like isFirstSlide(), isLastSlide(), hasPreviousSlide() and hasNextSlide() to make the task more convenient?

Or maybe there is a better approach, I may be missing something.

Thank you for your attention!

Scroll Progress (get)

๐Ÿ‘‰ Conclusion / Feature Specification

The discussion in this issue has resulted in a decision to implement the following API method:

// get scroll progress
// returns a number representing % scrolled of scrollable distance.
// 0 is start position and 1 is end position

embla.scrollProgress()

Example Usage

embla.on('scroll', () => {
  console.log(`Current progress is: ${embla.scrollProgress() * 100}%`)
}

CodeSandbox

See example usage.

Special thanks

@xiel for discussing this and sharing your thoughts and ideas.
@welteki for the nice demonstration.

Resize/Reinit Trigger of Some kind

I actually see that you're currently tracking a similar request in the react version. https://github.com/davidcetinkaya/embla-carousel-react/issues/10

My issue is comparable, but just in a vanilla environment where I am encountering image load issues not correctly drawing the slideshow/allowing me to access it. However doing a simple browser resize appears to resolve it, so if there were an event on the api where we could refresh the slideshow init (similar to the settimeout fix on flickity for anyone familiar with forcing an update on that slideshow...). I realize in an ideal world we wouldn't need these functions and the slideshows would init perfectly but that isn't the case for me.

I'm getting around this by preloading all my images in the background before mounting the slideshow + a combination of index switching but it's not terribly elegant, it does however work. The usecase is a little harder to replicate because I am also creating multiple slideshows on the page via color variant selects (for an ecom experience)

Blank Carousel when looping with 2 slides (inactive browser tab)

Hello,

when trying to create an automated slideshow with two slides and loop: true, I stumbled upon an interesting edge case. I used setInterval() to call scrollNext() every few seconds. After I switched tabs and came back later (one or two minutes is enough), the embla carousel was blank and the source code had a weird transform value:

<div class="embla__container" style="transform: translate3d(-5.72608e+10%, 0px, 0px);">

It can be reproduced here: https://codesandbox.io/s/embla-carousel-align-start-vllyp

I think this only happens in quite specific conditions - e.g. I was only able to reproduce this with two slides. I worked around the problem by using the Page Visibility API and only calling scrollNext() if the page is visible, but I thought it might be worth reporting the issue.

Create an option to block excessive scrolling

Hi @davidjerleke!

Embla currently has ways to remove the leading and trailing blanks from the Slider (containsScroll: true), but still allow for excessive scrolling. It would be interesting to add an option to block this scroll and stop it when it reaches the end or beginning of the Slider. I would like to know what you think of this idea

Below is the example of the "excessive scroll" I am referring to

Captura de Tela (21)

Add RTL Support

Hi @davidcetinkaya - May I know if there's a future plan for RTL support or if there is a workaround for now, please let me know. Thank you!

Improve carousel behavior when slide content width is inferior to container's one

Hi ! First of all, thanks for this great library.

I am actually working on an infinite looping carousel with dynamic content (meaning various slides number). I ran into a bothering problem when it comes to having a carousel containing less slides than needed to properly loop without layout breaking.

If the number of slides times the width of a slide is inferior to the width of the container plus half the width of a slide, embla does not manage to find a nice solution to display items.

It should imho, either not init embla and leave the layout as it is or clone items to fit container's width.

You can see what I mean with the examples below :

Blank space before last slide

when align is start, the last slide automatically adds a blank. Is there any way to lock the last slide on the edge of the container?

blank-space

Can't get Embla working in Angular

Hi, I found your lib after looking at many carousel libraries. I like yours because it's clean and light weight.

I've made an Angular wrapper around it and it works for static content. But I can't seem to get it working with content that's dynamically generated from an api request. Using the ngFor loop to generate the slides Embla returns empty node array and nothing works.

I guess it's only for static content? or am I doing something wrong?

Check if embla exists in ES6

Hello, i have a problem with checking if element exists and initializing the Embla carousel.

I want to do something like: If element exists on the page, then initialize it with Embla carousel, because when i do it without checking the element first, then on another subpage, i get an error saying "Error: No root element provided ๐Ÿ˜ข"

My code looks like that:

import EmblaCarousel from 'embla-carousel';

const testimonials = document.querySelector('.embla__testimonials');

const checkTestimonials = () => {
  return EmblaCarousel(testimonials, {
    align: 'center',
    containerSelector: '*',
    slidesToScroll: 1,
    containScroll: false,
    draggable: true,
    dragFree: false,
    loop: false,
    speed: 10,
    startIndex: 0,
    selectedClass: 'is-selected',
    draggableClass: 'is-draggable',
    draggingClass: 'is-dragging',
  });
}

if (testimonials.length) {
  checkTestimonials();
}

The code above doesn't work, it checks correctly for the element, but does not initialize the carousel, and i need to initialize it always after checking the element first :/

Does anyone know how i can solve it?
Thanks!

Only works after a screen refresh (Vue framework)

Embla only seems to work after the page is refreshed in some way such as a resize.
When the page loads at first, embla appears to be unresponsive, as if it does not exist.
I noticed the 'is-dragging' classes are being applied meaning embla is loaded and working but the transforms don't get applied until I resize the page.
In hindsight, it might be a vue issue, but I wanted to get your thoughts first before filing a vue issue.

The Slider is skipping other items

Hello, when users swipe hard enough it looks like its skipping other slides, how can we limit it to only one slide per swipe? slidesToScroll: 1 doesn't seem to do anything

const wrap = document.querySelector('.js-home-slider');
  const viewPort = wrap.querySelector('.js-home-slider-viewport');
  const dots = wrap.querySelector('.js-home-slider-dots');
  const homesliderStart = EmblaCarousel(viewPort, {
    loop: true,
    draggable: true,
    dragFree: false,
    speed: 10,
    startIndex: 0,
    slidesToScroll: 1,
  });

Improve the documentation by providing a full example of code?

Hello again David @davidjerleke,
As mentioned in Best of JavaScript issue (michaelrambeau/bestofjs#237), I think you could improve the documentation by providing a full example of markup and JavaScript code.

You could use something like https://codepen.io and embed the "pen" directly in the demo page.

I'm asking because it took me some time to realize that I have to bind by myself the "Next" and "Previous" buttons to Embla methods.

Thank you for your attention!

Wrong option in README

Wrong option name is showing in README:

Wrong

const options = {
  container: '*' // Should be containerSelector: '*'
}

Correct

const options = {
  containerSelector: '*'
}

Question: where is CSS?

Hi,

Sorry, I am puzzled, but where is CSS code located in your project? E.g., I see that, for example, <style id="/src/css/radio.css:-css" type="text/css">.radio {... is generated by your script, but I could not locate that in the source code. To be honest, I really like your project, but your code has almost 0 comments, the overall structure is quite confusing, therefore I am not able to do anything with your code (help with adding new features, etc). Thanks.

[Feat]: Build an Angular wrapper

Create an Embla Carousel Angular npm package - A wrapper component that allows Angular users to consume Embla Carousel like the React implementation.

Please react with --> ๐Ÿ‘ if you want this to be implemented.

  • This will be merged with #627.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.