Open iamstiil opened 9 years ago
Add a 👍 reaction to this issue if you would like to see this feature added. Do not add +1 comments — They will be deleted.
Thanks for taking a shot at this. I haven't looked in to supporting mousewheel, or providing an API to manipulate the slider position. I'll categorize this as a feature request for now. I'm focusing on releasing the core feature set for Flickity at the moment. I'll come back to this afterwards.
Reclassifying this issue as a feature request. Flickity does not currently support manipulation of the slider position. If you would like to see this feature, please +1 or subscribe to this issue.
+1
+1
(I have a homegrown carousel in place at http://theartificial.nl/ and want to replace it, but mousey-scroll is important to me.)
+1
Got something here ;)
$('.gallery').mousewheel(function(e) {
e.preventDefault();
var flkty = Flickity.data(this);
if (!window.wheeling) {
// console.log('start wheeling!');
if(e.deltaX > 0 || e.deltaY < 0){
flkty.next();
} else if(e.deltaX < 0 || e.deltaY > 0){
flkty.previous();
}
}
clearTimeout(window.wheeling);
window.wheeling = setTimeout(function() {
// console.log('stop wheeling!');
delete window.wheeling;
// reset wheeldelta
window.wheeldelta.x = 0;
window.wheeldelta.y = 0;
}, 250);
window.wheeldelta.x += e.deltaFactor * e.deltaX;
window.wheeldelta.y += e.deltaFactor * e.deltaY;
if(window.wheeldelta.x > 500 || window.wheeldelta.y > 500 || window.wheeldelta.x < -500 || window.wheeldelta.y < -500){
window.wheeldelta.x = 0;
window.wheeldelta.y = 0;
if(e.deltaX > 0 || e.deltaY < 0){
flkty.next();
} else if(e.deltaX < 0 || e.deltaY > 0){
flkty.previous();
}
}
// console.log(window.wheeldelta);
});
Found this approach over here: http://stackoverflow.com/questions/3515446/jquery-mousewheel-detecting-when-the-wheel-stops
+1
I'm presently hacking my way through this, trying to engage Flickity's lovely touch/click behavior for horizontal scrolling. The best discussion about relevant issues seems to be this issue on the jQuery mousewheel plugin: https://github.com/jquery/jquery-mousewheel/issues/36
+1 This feature would make me a very happy human.
+1
Thanks @pavethiran, the approach you are recommending is really interesting, but it only scrolls to the next cell/element. Do you have an idea how to do an actual free mouse scroll with it. Would be so useful, because flickity would cover then almost every possible interaction with the user.
@gerwitz hello. You can try our wheel-indicator to implement wheel support for gallery.
+1
+1
+1
+1
+1 :)
+1
After much searching I found the functionality I was looking for in iDangerous' Swiper: https://github.com/nolimits4web/Swiper - it's also beautifully written and well documented so I'd recommend checking it out :)
If this is still and issue then this might help someone: https://iamsteve.me/blog/entry/enhancing-horizontal-scrolling-with-flickity-js
I have decided to not add this feature. Mouse wheel are most commonly used for vertical scrolling. Flickity is horizontal. Adding this feature would add additional complexity for a small feature. Sorry to say no here!
slider
be a Flickity instance and wheel
be the wheel NPM package
import wheel from 'wheel';
import normalizeWheel from 'normalize-wheel';
wheel.addWheelListener(slider.$element[0], event => { const wheelNormalized = normalizeWheel(event); slider.applyForce(-wheelNormalized.pixelY / 4); slider.startAnimation(); slider.dragEnd(); });
This uses Flickity's internal force, animation and drag functions to perform slider movement and therefore correctly handles slide indexes, freescroll, friction etc.
**Note that this uses the `pixelY` property of the normalized wheel event. So it registers any vertical mouse scrolling as horizontal movement and does nothing with any horizontal mouse scrolling.**
**Also note that the `slider.dragEnd()` call fires the 'dragEnd' event with `undefined` parameters.**
This code example uses NPM packages and arrow functions. If you don't want to use NPM packages or arrow functions, use the following piece of code after loading [MDN's cross browser event listener for wheel events](https://developer.mozilla.org/en-US/docs/Web/Events/wheel#Browser_compatibility) and [Facebook's fixed-data-table normalizeWheel function](https://github.com/facebookarchive/fixed-data-table/blob/master/src/vendor_upstream/dom/normalizeWheel.js#L125) yourself:
```javascript
addWheelListener(slider.$element[0], function (event) {
var wheelNormalized = normalizeWheel(event);
slider.applyForce(-wheelNormalized.pixelY / 4);
slider.startAnimation();
slider.dragEnd();
});
Where slider
again is the Flickity instance.
UPDATE January 18th 2018: Added velocity normalization across browsers
People keep asking for this feature, so I'm re-opening.
Add a 👍 reaction to this issue if you would like to see this feature added. Do not add +1 comments — They will be deleted.
For people who want to "hack in" mousewheel support, this was my approach:
- Install the wheel NPM package which uses MDN's cross browser event listener for wheel events.
- Install the normalize-wheel NPM package which uses Facebook's fixed-data-table mousewheel normalizer to normalize mousewheel delta values across browsers and systems.
- Let
slider
be a Flickity instance andwheel
be the wheel NPM package- Use the following piece of code:
import wheel from 'wheel'; import normalizeWheel from 'normalize-wheel'; wheel.addWheelListener(slider.$element[0], event => { const wheelNormalized = normalizeWheel(event); slider.applyForce(-wheelNormalized.pixelY / 4); slider.startAnimation(); slider.dragEnd(); });
This uses Flickity's internal force, animation and drag functions to perform slider movement and therefore correctly handles slide indexes, freescroll, friction etc.
Note that this uses the
pixelY
property of the normalized wheel event. So it registers any vertical mouse scrolling as horizontal movement and does nothing with any horizontal mouse scrolling.Also note that the
slider.dragEnd()
call fires the 'dragEnd' event withundefined
parameters.This code example uses NPM packages and arrow functions. If you don't want to use NPM packages or arrow functions, use the following piece of code after loading MDN's cross browser event listener for wheel events and Facebook's fixed-data-table normalizeWheel function yourself:
addWheelListener(slider.$element[0], function (event) { var wheelNormalized = normalizeWheel(event); slider.applyForce(-wheelNormalized.pixelY / 4); slider.startAnimation(); slider.dragEnd(); });
Where
slider
again is the Flickity instance.UPDATE January 18th 2018: Added velocity normalization across browsers
Anyway to do this without Jquery? Trying to codepen this and having no luck...
Anyway to do this without Jquery? Trying to codepen this and having no luck...
@joebentaylor, my hack isn't using jQuery if I'm correct. What issue are you encountering?
@LuudJanssen
i was looking for something like this for a full width/height slider, thank you! i did some user tests and found out people using safari on apple laptops were likely to scroll horizontally using the trackpad, here is the workaround I've came with
const wheelNormalized = normalizeWheel(event);
const highestValue = Math.abs(wheelNormalized.pixelY) >= Math.abs(wheelNormalized.pixelX) ?
wheelNormalized.pixelY : wheelNormalized.pixelX * 0.75
this.flkty.applyForce(-highestValue / 8);
this.flkty.startAnimation();
this.flkty.dragEnd();
in addition to your code, it performs a simple check for highest value on x or y axis scroll and use this value, i did not try it on iOs though
Anyway to do this without Jquery? Trying to codepen this and having no luck...
@joebentaylor, my hack isn't using jQuery if I'm correct. What issue are you encountering?
I guess im confused as to what $element
is
After running the code i get this error TypeError: Cannot read property '0' of undefined
@joebentaylor
adding $
before a variable is a naming convention for DOM selectors
if the method is not defined then probably the library is not exectuded the right way
finally you can replace slider.$element[0]
by a simple DOM element query such as document.querySelector('.carousel')
(adapt the code if you have multiple sliders, the original code assume that slider.$element
is an available array, it wasn't in my case either)
@LeoSeyers Im confused as to what element needs to be though, we are replacing slider with our slider name / reference, so whats $element supposed to reference? the slides?
Ive finally got this working, however ive found the bounce to look awful, anybody got a solution to a very smooth finish?
@joebentaylor the bounce is controlled by the friction and the selectedAttraction. Try changing those values to get the result you're looking for. Otherwise you can look for the -wheelNormalized.pixelY / 4
and change the 4
to something that works for you.
@LeoSeyers thanks for the trackpad fix!
Wondering if there was any progress on this feature? Literally the one thing stopping me from using flickity over swiper.
if someone ever comes across this solution after importing flickity as a vue component with vue-flickity, here is the code that worked for me :)
onInit() { const flickity = this.$refs.flickity.flickity() wheel.addWheelListener(flickity.element, event => { const wheelNormalized = normalizeWheel(event) flickity.applyForce(-wheelNormalized.pixelY / 4) flickity.startAnimation() flickity.dragEnd() }) }
Can someone share a codepen with a working exemple of this? I am having trouble implementing it.
Thanks a lot
This is my version for those who use react-flickity. I use @LeoSeyers horizontal code:
useLayoutEffect(() => {
const flickity = slider.current.flkty;
wheel.addWheelListener(flickity.element, event => {
const wheelNormalized = normalizeWheel(event);
const highestValue = Math.abs(wheelNormalized.pixelY) >= Math.abs(wheelNormalized.pixelX) ?
wheelNormalized.pixelY : wheelNormalized.pixelX * 0.75
flickity.applyForce(-highestValue / 8);
flickity.startAnimation();
flickity.dragEnd();
})
}, [slider])
return <Flickity ref={slider}>...</Flickity>
Does anyone have a scroll-like animation?
@joebentaylor this is my solution for a smooth finish, no bouncy:
useLayoutEffect(() => {
const flickity = slider.current.flkty;
let range = {
value: 0,
max: 80,
min: -80,
step: 1,
increase: function(number) {
const threshold = this.max / flickity.slides.length;
if(this.value < this.max) {
this.value += this.step;
}
if(this.value >= threshold) {
flickity.next();
this.value -= threshold;
}
},
decrease: function(number) {
const threshold = this.max / flickity.slides.length;
if(this.value > this.min) {
this.value -= this.step;
}
if(this.value <= threshold) {
flickity.previous();
this.value += threshold;
}
}
};
wheel.addWheelListener(flickity.element, event => {
const wheelNormalized = normalizeWheel(event);
const direction = wheelNormalized.spinX * 100;
direction > 0 ? range.increase(direction) : range.decrease(direction);
flickity.startAnimation();
})
}, [slider])
modify the range max, min if you want it to be slower/faster.
Got something here ;)
$('.gallery').mousewheel(function(e) { e.preventDefault(); var flkty = Flickity.data(this); if (!window.wheeling) { // console.log('start wheeling!'); if(e.deltaX > 0 || e.deltaY < 0){ flkty.next(); } else if(e.deltaX < 0 || e.deltaY > 0){ flkty.previous(); } } clearTimeout(window.wheeling); window.wheeling = setTimeout(function() { // console.log('stop wheeling!'); delete window.wheeling; // reset wheeldelta window.wheeldelta.x = 0; window.wheeldelta.y = 0; }, 250); window.wheeldelta.x += e.deltaFactor * e.deltaX; window.wheeldelta.y += e.deltaFactor * e.deltaY; if(window.wheeldelta.x > 500 || window.wheeldelta.y > 500 || window.wheeldelta.x < -500 || window.wheeldelta.y < -500){ window.wheeldelta.x = 0; window.wheeldelta.y = 0; if(e.deltaX > 0 || e.deltaY < 0){ flkty.next(); } else if(e.deltaX < 0 || e.deltaY > 0){ flkty.previous(); } } // console.log(window.wheeldelta); });
Found this approach over here: http://stackoverflow.com/questions/3515446/jquery-mousewheel-detecting-when-the-wheel-stops
This is a great approach, but you forgot to define the wheeldelta
object, like so:
var wheeldelta = {
x: 0,
y: 0
};
$('.gallery').mousewheel(function(e) {
e.preventDefault();
var flkty = Flickity.data(this);
// ...
Otherwise it'll work but throw a lot of uncaught errors to the console.
I want this feature too. Better experience than dragging when you're on Desktop
Can anyone share a working solution with freescroll instead of flkty.next() and flkty.previous()?
Thanks
@yepececeI I found it was easier and more performant to start from scratch, simply making use of overflow: auto and scroll-snap in CSS. With some scroll-padding, carousels can be made to appear to scroll outside of the content margins as well. Buttons to scroll the carousel left and right took a bit more work.
Came across this recently and it saved my booty https://codepen.io/rniswonger/pen/ExjPryB (thx @rniswonger!)
☝️ this works but is not perfect, it scrolls the page with the slideshow as well, mouse events are not intercepted;
The feature must be in the core in 2022
@desandro any updates on this?
Any news?
I'm experiencing a little problem with one of my sliders.
I am using the jQuery
mousewheel
plugin to support scrolling inside flickity. But somehow on mobile devices occasionally I can't reach the last cell. It always flicks back to the previous one. Could it be a bug or could it be a fault of me?