-
Notifications
You must be signed in to change notification settings - Fork 58
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Breakpoints implementation #70
Comments
Why not do something like this? const breakpoints = {
320: {
slidesPerView: 1,
spaceBetween: 20,
},
480: {
slidesPerView: 1,
spaceBetween: 30,
},
1112: {
slidesPerView: 3,
spaceBetween: 30,
},
1536: {
slidesPerView: 3,
spaceBetween: 0,
}
}
const swiper = new Swiper('.swiper-container');
const swiperResize = () => {
for (const [breakpoint, options] of Object.entries(breakpoints)) {
if (swiper.env.element.$el.offsetWidth <= +breakpoint) {
swiper.options = Object.assign(swiper.options, options)
break
}
}
swiper.updateSize()
}
const swiperResizeListener = _.debounce(swiperResize, 200)
window.addEventListener('resize', swiperResizeListener, { passive: true })
swiper.on('after-destroy', () => window.removeEventListener('resize', swiperResizeListener))
swiperResize() |
What about creating an official plugin for breakpoints? I started a basic implementation which includes a built-in rAF debounce: https://gist.github.com/pryley/3bc6d2f01aa5b68f829a5fbeb19abbd8 A few caveats:
Here is a demo: https://tiny-swiper2-demo-plugin-breakpoints.stackblitz.io |
@pryley That's really great!Would you like to create a PR :) ? Here are some questions I considered about
Btw, would it be better if we provide |
Regarding throttle and debounce, it could be useful to provide these as utils if they are only imported as needed. The debounce implementation was taken from the lodash function and stripped down as much as possible. |
@pryley So, the |
Yes. The resize event is triggered by the window, but the breakpoint size is defined by the swiper width, not the window size. How would you suggest this otherwise? |
@pryley How about adding a new property of |
I'm not sure height breakpoints would be useful. I think you would be more likely to use a breakpoints feature to change the direction of a swiper rather than to determine if a breakpoint is triggered by vertical or horizontal resizing. The reason measuring by width is more practical is because most devices whhich allow you to resize a browser window (i.e. desktop browsers) have landscape screens. What if we simply mirrored the breakpoint functionality of swiperjs? It provides two options:
Swiperjs only measures width on resize, not height (unless using ratios). The breakpoint keys can be either integer units (as pixel values) or ratio strings (i.e. "@0.75"), however I think to keep it minimal only integer units are really necessary. https://swiperjs.com/swiper-api#param-breakpoints I have extracted the debounce functionality into it's own utility function here: https://gist.github.com/pryley/c822c23ec542b6d7b6196de4707c3bdf So using the Debounce utility function and adding a import { Debounce } from '../core/render/timing'
import { Options } from '../core/options'
import { SwiperInstance, SwiperPlugin } from '../core/index'
export type SwiperPluginBreakpointsInstance = {}
export type SwiperPluginBreakpointsOptions = {}
/**
* TinySwiper plugin for breakpoints.
*
* @param {SwiperInstance} instance
* @param {Options}
*/
export default <SwiperPlugin>function SwiperPluginBreakpoints (
instance: SwiperInstance & {
breakpoints?: SwiperPluginBreakpointsInstance
},
options: Options & {
breakpoints?: SwiperPluginBreakpointsOptions,
breakpointsBase?: string,
},
): void {
const isEnabled = Boolean(options.breakpoints)
const breakpoints: SwiperPluginBreakpointsInstance = {
update (): void {
for (const [breakpoint, values] of Object.entries(options.breakpoints)) {
if ('window' === options.breakpointsBase) {
if (window.matchMedia(`(min-width: ${breakpoint}px)`).matches) {
instance.options = Object.assign(instance.options, values)
}
} else if (+breakpoint <= instance.env.element.$el.offsetWidth) {
instance.options = Object.assign(instance.options, values)
}
}
instance.updateSize()
},
}
if (!isEnabled) return
const resizeListener = () => Debounce(breakpoints.update)() // the default timeout is 200ms
instance.on('after-init', () => {
window.addEventListener('resize', resizeListener, { passive: true })
requestAnimationFrame(breakpoints.update)
})
instance.on('before-destroy', () => {
window.removeEventListener('resize', resizeListener)
})
} I think it may be overkill to provide a debounce timeout option, might be better to just provide a sane default. It would be preferable to use I won't submit a pull request as I am not familiar enough with Typescript; you would need to perform the actual implementation. |
@pryley Great, I'll get this done in Oct |
@joe223 Any updates on this? |
Hi @pryley @joshauh46 , sorry for the late reply. |
Hi there, I was looking through the Documentation and couldn't find a breakpoint parameter that Swiper offers. The library is literally unusable on mobile without this parameter.
breakpoints: { 320: { slidesPerView: 1, spaceBetween: 20 }, 480: { slidesPerView: 1, spaceBetween: 30 }, 1112: { slidesPerView: 3, spaceBetween: 30 }, 1536: { slidesPerView: 3, spaceBetween: 0 } }
The text was updated successfully, but these errors were encountered: