root-two / react-native-drawer

React Native Drawer
MIT License
2.54k stars 390 forks source link

What would it take to replace tweenState with Animated? #147

Open faceyspacey opened 8 years ago

faceyspacey commented 8 years ago

The drawer being such a central part of many apps seems to be a key place that should be using Animated.

rt2zz commented 8 years ago

This is doable and desirable. We would need to replace tweenHandler with something like getAnimationStyle:

<Drawer
  getAnimationStyles={(animatedRatio) => {
    return {
      main: {
        opacity: Animated.multiply(animatedRatio, .5)
      }
    }
  }}
//...

Under the hood we would simply replace the two calls to tween with Animated.spring. Also updatePosition would need updating similarly.

rt2zz commented 8 years ago

open to suggestions on the exact api

mvaivre commented 8 years ago

That would be really great to do the switch!

faceyspacey commented 8 years ago

in updatePosition does only tweenHandler need to be replaced? What exactly would we replace it with? a function that returns a call to interpolate? ...ah, I see what you're doing--I never needed to use the tweenHandler prop so I knew nothing about it until now--you're returning interpolations for the various components that could be animated, each of which has multiple style properties that can be animated.

...So basically, if one were to fork this today and get this done (and didn't use tweenHandler) you just need tween() to properly respond to the parameters here:

tween({
      start: this._left,
      end: this.getOpenLeft(),
      duration: this.props.tweenDuration,
      easingType: this.props.tweenEasing,
      onFrame: (tweenValue) => {
        this._left = tweenValue
        this.updatePosition()
      },
      onEnd: () => {
        this._activeTween = null
        this._open = true
        this._prevLeft = this._left
        this.adjustForCaptureGestures()
        this.props.onOpen()
        this.clearInteractionHandle()
      }
})

Looking at it, everything seems easily replaceable with Animated.spring or Animated.timing except onFrame, which I have no idea at the moment what that is.

...Otherwise, my only thoughts are regarding the API. Obviously your initial idea is to replicate the old API so it's backwards compatible. I guess the opposing view is a simpler API. My initial thought was simply returning a single interpolation that handles the main horizontal movement of the drawer. Perhaps that's an easier option baked in. I.e. if you return a function, it's a single interpolation, but if you return a config object, well, the old API where you can control everything will kick in. I don't know all the ins and outs, but something like that where a simpler use case is targeted with the goal of it getting more usage is what I'm envisioning.

faceyspacey commented 8 years ago

....so something like this right?:

function tween() {
   this.animation.addListener(this.props.onFrame);

   Animated.timing(this.animation, {
        toValue: this.getOpenLeft(),
        duration: this.props.tweenDuration,
        easing: this.props.tweenEasing,
   }).start(() => {
        this._activeTween = null
        this._open = true
        this._prevLeft = this._left
        this.adjustForCaptureGestures()
        this.props.onOpen()
        this.animation.removeAllListeners() //new addition
   });
}
rgoldiez commented 7 years ago

@rt2zz - What are your plans/timing for switching to Animated?

rt2zz commented 7 years ago

@rgoldiez I highly desire to, but have not had the time. I see a future for react-native-drawer if we can get this ported to Animated. In the meantime if the performance of Animated is needed I might suggest https://github.com/react-native-community/react-native-side-menu.

The functionality is more limited, but it is a great project and the upside is animated 👍

Open to PR's here to add Animated or maintainer help as well! Also open to collaborating with the side-menu folks.

ippa commented 7 years ago

This makes even more sense now that react-native is focusing on powering more and more of Animated with native code.

See point 2 @ https://github.com/facebook/react-native/wiki/Roadmap

As happy as I am (using it in almost all my projects) with react-native-drawer it doesn't have that 100% native feel.

rgoldiez commented 7 years ago

@rt2zz - I'll get to work on a PR that moves away from tween and to Animated!

rt2zz commented 7 years ago

@rgoldiez nice! let me know how I can support. If some api changes are needed to simplify, I am all ears, I am open to making this a 2.0 with breaking changes

rgoldiez commented 7 years ago

@rt2zz - I've got Animated wired in instead of tween. Seems to be working in the simulator (still have yet to install on a device to test). I'm trying to get some time to test with the different drawer types (static, overlay, displace) - they are all working with a simple scenario.

One question: I personally have been using tweenHandler={Drawer.tweenPresets.parallax} in my app..... and I have Animated doing parallax with type='static' but it's by hardwiring parallax for now. Any thoughts on how to handle the parallax option? Should it be a new prop?

rt2zz commented 7 years ago

@rgoldiez nice! hard to say about parallax, but yes I imagine the tweenHandler functionality will need to go or at least be heavily modified once we switch to Animated. I realize it may not be 100% but mind opening a PR?

rgoldiez commented 7 years ago

@rt2zz - Opened.

rgoldiez commented 7 years ago

@rt2zz - Updated the PR: https://github.com/root-two/react-native-drawer/pull/244

Still work to be done and testing to do. For example, there's a weird bug when useNativeDriver={true} if you try to open the drawer shortly after the app initially loads. Can't figure this one out.