Skip to content
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

Detect strenght of throw / Create a "wheel" effect #275

Closed
QQizi opened this issue Feb 27, 2018 · 8 comments
Closed

Detect strenght of throw / Create a "wheel" effect #275

QQizi opened this issue Feb 27, 2018 · 8 comments
Labels

Comments

@QQizi
Copy link

QQizi commented Feb 27, 2018

Hi everyone,

I'm currently working on an app with a "wheel of fortune" feature.
I'm using react-native-snap-carousel as a horizontal wheel and it's working great.

My question is, is it possible to detect the "power/strenght" of a throw from the user ?
I don't want the user to be able to select there item by throwing the carousel very slowly.

@bd-arc
Copy link
Contributor

bd-arc commented Feb 27, 2018

Hey @QQizi,

There is only one callback in the ScrollResponder component that provides a velocity value directly: onScrollEndDrag(). You use it this way:

<Carousel
  onScrollEndDrag={e => console.log(e.nativeEvent.velocity.x)}
/>

⚠️ This will only work is prop enableMomentum hasn't been set to true, since onScrollEndDrag() is not going to be called for carousels with momentum. If you need it, consider one of the following options (untested).


  1. Implement the relevant negociation methods (probably onResponderGrant(e) and onResponderRelease(e)) from the gesture responder system. As per the doc, you could then use e.nativeEvent.timestamp to calculate velocity.
<Carousel
  onResponderGrant={e => console.log(e.nativeEvent.timestamp)}
  onResponderRelease={e => console.log(e.nativeEvent.timestamp)}
/>
  1. Ditch the plugin and implement a custom PanResponder; its gestureState will give you the velocity value.

@bd-arc bd-arc closed this as completed Feb 27, 2018
@bd-arc
Copy link
Contributor

bd-arc commented Feb 27, 2018

@QQizi By the way, I'm interested in seeing how your "wheel of fortune" looks like ;-)

@QQizi
Copy link
Author

QQizi commented Feb 27, 2018

@bd-arc Thx for your help.
I didn't know PanResponder and managed to use it with this plugin (didn't had to ditch it) and get the velocity of the throw.

Here is the "wheel"

@bd-arc
Copy link
Contributor

bd-arc commented Feb 27, 2018

@QQizi Unfortunately, the link to your gif doesn't seem to work...

Would you mind sharing your implementation with the PanResponder? I think this could really help other people ;-)

By the way, your "wheel" idea has motivated me to check if the following kind of design could be implemented with the carousel:

react-native-snap-carousel wheel
Music Player Interaction, by Asif Adnan Uday

And the answer is yes, with nothing but a few lines of code. I thought I'd share in case someone is interested:

import Carousel, { getInputRangeFromIndexes } from 'react-native-snap-carousel';

const SLIDER_WIDTH = Dimensions.get('window').width;
const SLIDE_WIDTH = SLIDER_WIDTH * 0.75;
const ITEM_HORIZONTAL_MARGIN = SLIDER_WIDTH * 0.04;
const ITEM_WIDTH = SLIDE_WIDTH + ITEM_HORIZONTAL_MARGIN * 2;

function stackScrollInterpolator (index, carouselProps) {
    const range = [2, 1, 0, -1, -2];
    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);
    const outputRange = range;
    return { inputRange, outputRange };
}
function stackAnimatedStyles (index, animatedValue, carouselProps) {
    return {
        opacity: animatedValue.interpolate({
            inputRange: [-2, -1, 0, 1, 2],
            outputRange: [0, 0.8, 1, 0.8, 0]
        }),
        transform: [{
            rotate: animatedValue.interpolate({
                inputRange: [-2, -1, 0, 1, 2],
                outputRange: ['6deg', '3deg', '0deg', '-3deg', '-6deg'],
                extrapolate: 'clamp'
            })
        }, {
            translateY: animatedValue.interpolate({
                inputRange: [-2, -1, 0, 1, 2],
                outputRange: [-10, -5, 0, -5, -10],
                extrapolate: 'clamp'
            })
        }]
    };
}

const myCarousel = (
    <Carousel
      sliderWidth={SLIDER_WIDTH}
      itemWidth={ITEM_WIDTH}
      scrollInterpolator={stackScrollInterpolator}
      slideInterpolatedStyle={stackAnimatedStyles}
      useScrollView={true} // <--- Disable this if you have a bunch of items
    />
);

@QQizi
Copy link
Author

QQizi commented Feb 28, 2018

@bd-arc here's the link

My wheel looks kind of like yours, kudos 👍 ! Your exemple is dope tho !

The panResponder :

componentWillMount(){
  this._panResponder = PanResponder.create({
    onPanResponderMove: (e, gestureState)=>{
      (!this.state.isThrow && Math.abs(gestureState.vx) > 4)?
        this.setState({isThrow : true})
      :false;
    }
  });
}

<Carousel
    {...this._panResponder.panHandlers}
    ref={(c) => { this._carousel = c; }}
    data={this.props.Prices.prices}
    renderItem={this._renderItem}
    activeSlideAlignment={'center'}
    inactiveSlideScale={0.6}
    inactiveSlideShift={0}
    firstItem={2}
    loop={true}
    decelerationRate={100}
    loopClonesPerSide={10}
    sliderWidth={_width}
    enableMomentum={true}
    itemWidth={_itemWidth}
    onSnapToItem={(e)=>{
        (this.state.isThrow)?this._doSomething():false;
    }}
/>

Last question, is there a way to disable the use of the Carousel ? Want the user to not be able to throw again after there throw.

Thx for your help !

@bd-arc
Copy link
Contributor

bd-arc commented Feb 28, 2018

@QQizi Absolutely! The carousel inherits miscellaneous props from ScrollView, including scrollEnabled.

Your wheel looks great; I'd love to see how the custom interpolation I've shared would suit it ;-)

@bd-arc bd-arc changed the title Detect strenght of throw Detect strenght of throw / Create a "wheel" effect Feb 28, 2018
@QQizi
Copy link
Author

QQizi commented Mar 1, 2018

Thx for your help @bd-arc !

I'v tried real quick the interpolation but the "scrollInterpolator" & "slideInterpolatedStyle" did not seem to be triggered. The effect on round slide wouldn't be that obvious anyway.

@bd-arc
Copy link
Contributor

bd-arc commented Mar 1, 2018

The "custom interpolation" feature was implemented in version 3.6.0 of the plugin ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants