Giter Club home page Giter Club logo

react-native-redash's Introduction

react-native-redash's People

Contributors

adkenyon avatar christiantakle avatar dependabot[bot] avatar doylemark avatar eleddie avatar felippepuhle avatar gorhom avatar janicduplessis avatar jaulz avatar johan-dutoit avatar jonnyburger avatar jozan avatar jyrno42 avatar ken0x0a avatar marcusstenbeck avatar matt-oakes avatar osdnk avatar owinter86 avatar radko93 avatar scottarnold avatar ssourabh58 avatar sunskyxh avatar wcandillon avatar yasintz 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

react-native-redash's Issues

Friendlier interpolateColor

Hello!
First off, thanks for a super helpful library (and for your contributions to reanimated itself...)

I wrote a version of interpolateColor that more closely matches the RN Animated color interpolations, and allows for hex, shorthand hex, named colors, rgb(r,g,b), and rgba(r,g,b,a) input.

Example:

const backgroundColor = interpolateColor(animVal, {
  inputRange: [0, 1],
  outputRange: ["#ccc", "tomato"],
})

Check it out in action here (pan to change color):
https://snack.expo.io/@computerjazz/interpolatecolor

I know you already have some color interpolation utils but am wondering if it'd be worth it to PR this? I'd rather not publish my own package since you've built up such a handy utility belt already.

Can't import redash in non-typescript project

I'm developing using Expo 33, and I'm in a project that uses flow typing (can't change this).

It'll complain about running into unexpected tokens in a .tsx file, which is natural given that there's no compiler for TypeScript in my project. But I'm surprised that it tries to import the TypeScript files.

If I change this line in package.json like the following then things work.

-   "react-native": "lib/module/index.ts",
+   "react-native": "lib/module/index.js",

loop seems to be going on on the background and doesn't preserve the previous animation value

Hey William

I've tried to implement the mini 5 min loop episode , when I stop the clock the loop is going on and when I start the clock again the loop has no idea what the previous value was and start the animation from some value based on the current state of the loop
I've attempted to store the value of animation when I stop the clock and set it again when I start the clock but that doesn't seem to be working.

I guess I don't get the mechanism here 🤒
is it some kind of miss happening ?

Low FPS onScroll

Hi everyone!

I have a problem with onScroll function (I guess...)

The title animation looks glichy or low FPS. The performance is 60FPS all time, but it looks weird. Only on iOS Expo simulator. On Android works fine. This is the interpolation constant:

const scale = interpolate(y, { inputRange: [-height, 0], outputRange: [10, 1], extrapolateRight: Extrapolate.CLAMP })

And this is the rener function:

renderList = (y) =>{ const AnimatedFlatList = Animated.createAnimatedComponent(FlatList); return( <AnimatedFlatList onScroll={ onScroll({y}) } style={{paddingTop:10}} keyExtractor={this.keyExtractor} data={events} renderItem={({ item }) => <Event data={item} />}/> ) }

ezgif com-resize

Sorry for the GIF quality...

Thank you!

onGestureEvent does not work with LongPressGestureHandler

My code works with TapGestureHandler, but not with LongPressGestureHandler. The source code looks like it would support it, is this wrong?

function Component() {
const state = new Value(State.UNDETERMINED)
const gestureHandler = onGestureEvent({ state })

return (
  <LongPressGestureHandler {...gestureHandler}>
    <Animated.View />
  </LongPressGestureHandler>
)}

preserveOffset jitter with bbc-iplayer

Hi William. I ran into an issue with the bbc-iplayer in your can-it-be-done-in-react-native series where short taps on the gesture handler would result in an in-determinant position. I tried setting the PanGestureHandler to have a minDist of 5 however this did not do anything.

Diving deeper into the redash library I noticed that preserveOffset was setting offset based on Gesture state being GestureState.BEGAN. Changing this to the below meant that the power of the gesture handler could be used to circumvent the jitter and in-determinant state:

export const preserveOffset = (
  value: Animated.Adaptable<number>,
  state: Animated.Adaptable<GestureState>,
) => {
  const previous = new Value(0)
  const offset = new Value(0)

  return block([
    cond(
      eq(state, GestureState.ACTIVE),
      [set(offset, add(offset, sub(value, previous))), set(previous, value)],
      [set(previous, 0)],
    ),
    offset,
  ])
}

Hope this helps someone.

Normalize interpolation functions

Currently, we have interpolate and bInterpolate from redash. I use these functions all the time and they make a lot of sense. However for path and color interpolation, the functions signatures are not symmetric with interpolate and bInterpolate. I would be nice to do some cleanup there.

useValues with Clock

👋

I was looking to replace my useMemoOne calls with the useValues or useNamedValues helper functions, but it looks like it only takes primitive values and returns the animated values. Is there a way to memoize new Clock() variables with this helper function, or is that a feature that could be added somehow? Unless clocks do not need to be memoized and can be recreated in the render calls?

Not sure how this API would adjust, maybe passed a clock type?

const [clock] = useValues([Clock], [])

Thanks for this wonderful library! 👍

ReText component issue on expo 35 sdk

I'm having trouble rendering ReText component. Any suggestion for a work around to render an animated Value as a string?

<ReText text={new Value("hello world")} style={{ color: "blue" }} />

Screenshot_2019-09-25-09-19-24-888

`
{
"main": "node_modules/expo/AppEntry.js",
"scripts": {
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"eject": "expo eject"
},
"dependencies": {
"@expo/vector-icons": "^10.0.5",
"d3": "^5.9.2",
"d3-scale": "^3.0.0",
"d3-shape": "^1.3.5",
"expo": "^35.0.0",
"expo-asset": "^7.0.0",
"expo-constants": "^7.0.0",
"expo-image-picker": "^7.0.0",
"native-base": "^2.12.1",
"react": "16.8.3",
"react-native": "https://github.com/expo/react-native/archive/sdk-35.0.0.tar.gz",
"react-native-animatable": "^1.3.2",
"react-native-calendars": "^1.196.0",
"react-native-gesture-handler": "^1.3.0",
"react-native-reanimated": "^1.1.0",
"react-native-redash": "^5.1.0",
"react-native-signalr": "^1.0.6",
"react-native-svg": "^9.5.1",
"react-navigation": "^4.0.6",
"react-navigation-drawer": "^2.2.2",
"react-navigation-stack": "^1.8.1",
"react-redux": "^6.0.1",
"redux": "^4.0.1",
"redux-axios-middleware": "^4.0.0",
"redux-persist": "^5.10.0",
"rn-snoopy": "^2.0.2",
"svg-path-properties": "^0.4.9"
},
"devDependencies": {
"babel-preset-expo": "^5.0.0"
},
"private": true
}

`

HOW TO UPDATE REDUX STATE AFTER ANIMATION IS DONE

            <>
                <PanGestureHandler {...gestureHandler}>
                    <Animated.View style={[{
                        ...StyleSheet.absoluteFillObject,
                        backgroundColor: colors.dark
                    }, { transform: [{ translateY }] }]}>
                        <PlayerStuff onPress={()=>goDown.setValue(1)} />
                        <Animated.View style={{
                            ...StyleSheet.absoluteFillObject,
                            opacity: overlayOpacity,
                            backgroundColor: colors.lighterDark
                        }} 
                        pointerEvents="none"
                        />
                        <Animated.View style={{
                            opacity,
                            position: 'absolute',
                            top: 0,
                            left: 0,
                            right: 0
                        }}>
                            <MediaStuff
                            onPress={()=>goUp.setValue(1)} 
                            />
                        </Animated.View>
                    </Animated.View>
                </PanGestureHandler>
</>

I used the import { clamp, onGestureEvent, timing as timer, withSpring } from "react-native-redash"; while working on a video called "Spotify Player. Can it be done in react-native?" created by @wcandillon
I am a bit new to React Native animations, and I would like to know how I can update redux state when the player is open or when it gets closed.
Please

Allow initial values for withSpringTransitions

Hi... I'm new to this lib (and react-native animation in general), so excuse if I make any rookie mistake. The withSpringTransition functions presume the initial value is zero. This is generally a great assumption, and basically You can derive any value from this, by treating it as a "progress" delta, but I think It would be nice to override this, by allowing an initial value.

A use case for this could be expanding a view width/height, something like:

const width = withSpringTransition(WINDOW_WIDTH, {initialValue: new Value(elementInitialWidth)});
const height = withSpringTransition(WINDOW_HEIGHT/2, {initialValue: new Value(elementInitialHeight)})

I realize this would lead to starting 2 different Clocks, and I'm not sure if this is the best practice. But from a user point of view, seems like a nice feature to have. Anyway, please let me know what You think about it.

Better docs with live examples

Hello everyone.

Last year react-native-redash helped me a lot, saving countless hours of work. Unfortunately, the documentation is not always easy to understand (IMO, a large README.md file is not the best way to handle it).

I've been thinking about a way to improve it, and since last Saturday I've been working on a new documentation/site:

It's basically using gatsby and react-native-web for live examples (we only have a single live example for now: https://react-native-redash-docs.netlify.com/animations/bInterpolate/).

@wcandillon if you like/agree, I can transfer the ownership to you immediately, so we can keep improving it as needed (I think we should add more live examples, as it's easier to understand what's happening).

Thanks!

Can I disable move right/left for Interacrtable component?

I would like to ask you if there is any way to disable for example left swipe gesture for Interactable component.

I'm implementing this "swipeable" list rows and I would like to achieve only "one directional swipe gesture" lets say swipe right (Buttons are hidden and located only on the left side). However, in my current implemenetation I'm able to drag the row and swipe it to both sides which in my case makes no sense if there isn't anything on the other side.

Enclosing my current implementation of Interactable component

<Interactable
      horizontalOnly={true}
      snapPoints={[
        {
          x: 100,
          damping: 1 - DAMPING,
          tension: TENSION
        },
        {
          x: 0,
          damping: 1 - DAMPING,
          tension: TENSION
        }
      ]}
      animatedValueX={this._deltaX}
    >
      <View style={{ left: 0, right: 0 }}>{children}</View>
</Interactable>

Hope I described it well enough for understanding :(

Thank you so much for any help!

Possible refine of delay() type definition

Hello @wcandillon

I'm new to TypeScript and yesterday during js -> ts conversion I had folllowing problem

delay([set(firstVal, 1), set(another, 1)], durationMs)

The code above was showing some type warnings and I've managed to make it work correctly using following diff:

diff --git a/node_modules/react-native-redash/lib/typescript/AnimationRunners.d.ts b/node_modules/react-native-redash/lib/typescript/AnimationRunners.d.ts
index 88a29ec..7aec241 100644
--- a/node_modules/react-native-redash/lib/typescript/AnimationRunners.d.ts
+++ b/node_modules/react-native-redash/lib/typescript/AnimationRunners.d.ts
@@ -23,7 +23,7 @@ export interface SpringParams {
     config?: SpringConfig;
 }
 export declare const spring: (params: SpringParams) => Animated.Node<number>;
-export declare const delay: (node: Animated.Node<number>, duration: number) => Animated.Node<number>;
+export declare const delay: (node: Animated.Node<number> | Animated.Node<number>[], duration: number) => Animated.Node<number>;
 export interface LoopProps {
     clock?: Animated.Clock;
     easing?: Animated.EasingFunction;

or using block([set(firstVal, 1), set(another, 1)]) node instead of array [].

I wanted to ask you if my patch is correct or there was some other way to keep using array instead of block node.

If my patch is correct, then maybe it would be good to submit a PR?

Thanks!

Issues with Delay Function

Hi @wcandillon,

I'm attempting to create a loading animation in which a series of characters jump up and return down periodically not dissimilar to this animation https://codepen.io/rprom/pen/OPdpQR

I've been unable to recreate this animation using a combination of the loop and delay functions. I have attempted to use the delay for other animations, and am unable to get it to work as expected. When wrapped around a loop function it creates a throttled frame update animation, when wrapped around the clock start it appears to have no impact.

Does anybody have any examples with delay function working as intented?

The code below results in three balls bouncing in unison, rather than having a staggered start. GIF

import { loop, delay } from 'react-native-redash';
import { StyleSheet, View } from 'react-native';
import { useMemoOne } from 'use-memo-one';
import Animated, { Easing } from 'react-native-reanimated';
import PropTypes from 'prop-types';
import React from 'react';

const {
  block, Clock, clockRunning, cond, not, set, startClock, useCode, Value,
} = Animated;


export function LoadingDots({ numberOfBalls = 3, bounceTime = 400, style, ...rest }) {
  const { animations, clocks } = useMemoOne(
    () => ({
      animations: Array(numberOfBalls).fill(0).map(() => new Value(0)),
      clocks: Array(numberOfBalls).fill(0).map(() => new Clock()),
    }),
    []
  );

  useCode(
    block(
      animations.map((animation, index) => block([
        set(
          animation,
          loop({
            clock: clocks[index],
            autoStart: false,
            boomerang: true,
            duration: bounceTime,
            easing: Easing.inOut(Easing.ease),
          }),
        ),
        cond(not(clockRunning(clocks[index])),
          delay(
            startClock(clocks[index]),
            index * bounceTime / numberOfBalls
          )
        ),
      ])
      )
    )
  );

  const translateYs = animations.map(animation =>
    Animated.interpolate(animation, {
      inputRange: [0, 1],
      outputRange: [-20, 0],
    }
    ));

  return (
    <View style={styles.container}>
      {translateYs.map((translateY, index) => (
        <Animated.Text key={index} style={[style, {
          transform: [{ translateY }],
        }]}
        >{'.'}
        </Animated.Text>
      )
      )}
    </View>
  );
}

WithTransition is in a loop

const open = new Value<number>(0);
const transition = withTimingTransition(open, { duration: 400 });
useCode(() => debug('transition', transition), [transition]);

this code console infinte 0 in console

flickery scrollview collapsible header on Android

Hi,

This library is great and I use it constantly.

Thank you very much.

I have encountered an issue regarding an issue when creating an animated header listening to scroll height

The issue I encounter is that on Android scrolling causes the header to flicker between large values due to contentOffset: y changing values unrelated to the scroll.

And issue similar to this facebook/react-native#21801

I use something like this

const [prevYScroll, allowScroll] = useValues([0, 1], []);

const [yScroll, yOffset] = useValues([0, -0.000001], []);

const gpsBarYInterpolate = interpolate(yOffset, {
	inputRange: [ -0.000001, 0.000001 ],
	outputRange: [ 80, 0 ],
	extrapolate: Extrapolate.CLAMP
})

useCode(() => { return block([
				set(yOffset, timing({
					from: yOffset,
					to: clamp(add(yOffset, sub(yScroll, prevYScroll)), -0.000001, 0.000001),
					duration: 100,
					easing: Easing.inOut(Easing.elastic(0))
				})),
				set(prevYScroll, yScroll),
			])}
	,[])

Any help would be greatly appreciated

useTransition() and react-native life cycles

Hi all,

I tried to remove the initial animation coming from useTransition once the component gets rendered for the first time.

I hacked it by introducing a flat to state weather the component has been mounted yet or not.

    const transition = useTransition(
      animatedValue,
      !isMounted ? animatedValue : not(animatedValue),
      animatedValue,
      200,
      Easing.ease,
    );

Basically, if the component is not mounted the transition goes from 1 to 1 resulting in a non visibile effect in the animation. Otherwise, it goes from 1 to 0 and so it performs a transition (based on the animated value).
This works well in modern devices and in production. However, I am getting some issues in debug mode with old phones. I think there might be a cleaner approach.

Are you experiencing something similar? If yes, what is your approach to avoid the initial animation?

Android - onSnapTo throws a.tension (undefined not an object)

I'm making a tappable slider similar to your demo, but on Android when you do a this.cursor.current.snapTo({ index: value }); it throws an error getting the snapAnchor tension.

Snack: https://snack.expo.io/@jkcooper/android-slider

Also the call seems unreliable. On iOS it will make the call and snap (as seen by onSnap updating the state with the new value), but the slider won't move. Some of the time it works, some of the time not.

Let me know if you need any other info

UseTransition() and Reanimated 1.3.0

I am getting a weird behaviour with different animations after updating to react-native-reanimated 1.3.0.

Here my specs:

"react-native-gesture-handler": "^1.4.0",
"react-native-redash": "^8.1.2",
"react-native-reanimated": "1.3.0",
"react-native": "0.61.1",
"react": "16.9.0",

The animation gets triggered every time as shown in the video below:

ezgif com-video-to-gif

Here the code:

    const [isOnFocus, setOnFocus] = useState<0 | 1>(0);
    let animatedValue = isOnFocus || value ? 1 : 0;
    const transition = useTransition(
      animatedValue,
      not(animatedValue),
      animatedValue,
      160,
      Easing.ease,
    );
    const inputRange = [0, 1];
    const fontSize = interpolate(transition, {
      inputRange,
      outputRange: [18, 10],
    });
    const top = interpolate(transition, {
      inputRange,
      outputRange: [20, 5],
    });
 
    return (...); 

It used to work with Reanimated 1.2.0, but I need to upgrade it due to other problems.

Any suggestions? Am I missing something?
Thanks for the help in advance :)

Hex color

Any possibility of adding interpolation for hex colors?
I can help with this.

rgbToHsv() used by interpolateColors not passing correct hue to colorHSV()

The colorHSV function expects the h (hue) value to be a value between 0 and 360. However, the value rgbToHsv outputs for h is a decimal. According to this stackoverflow h needs to be multiplied by 360. Something like this:

const rgbToHsv = (c: RGBColor) => {
  const r = c.r / 255;
  const g = c.g / 255;
  const b = c.b / 255;

  const ma = Math.max(r, g, b);
  const mi = Math.min(r, g, b);
  let h: number = 0;
  const v = ma;

  const d = ma - mi;
  const s = ma === 0 ? 0 : d / ma;
  if (ma === mi) {
    h = 0; // achromatic
  } else {
    switch (ma) {
    case r: h = (g - b) / d + (g < b ? 6 : 0); break;
    case g: h = (b - r) / d + 2; break;
    case b: h = (r - g) / d + 4; break;
    default: // do nothing
    }
    h /= 6;
  }
  return { h: Math.round(h * 360), s, v };
};

patching the rgbToHsv function to the this code appears to have corrected the issue.

Add loop()

It would be nice to easily be able to loop a timing or spring animations with a simple function like in the RN Animated API. Right now this is tedious work to do.

Is there a way to re-render an Interactable component ?

Hi,

I'm using an Interactable Component as a Slider.
So I put a default position for my cursor and I wanted to know if there is a way, when I update my parent component, to reset cursor position to its default position?
Like 'extraData' for flatList?

Thank you for any help !

clamp stucked on edge for while and how to imperatively start spring() animation

Hello! I have two questions:

I've encountered one problem with using clamp() method in spring-based animation. Enclosing a gif:

2019-09-08 10 05 50

It seems like Animated object is always stucked while reaching min/max boundary which makes animation not so smooth. Is there anything I can do with it please? It seems like the more velocity i provide while gesture the longer stuck duration is.

Second question is more specific. I have this switch component which can be seen on gif preview above. Besides swipe gesture I would like to also achieve to start spring(?) animation whenever one of the options is pressed. I've found that there is nothing like snapTo callback within withSpring() function. Do I need to implement custom timing based animation next to spring animation?

In case it would be helpfull I'm enclosing my current spring animation setup:

const [state, translationX, velocityX] = useMemoOne(() => [
    new Value(State.UNDETERMINED),
    new Value(0),
    new Value(0)
  ]);

  const gestureEvent = onGestureEvent({
    state,
    translationX,
    velocityX
  });

  const translateX = useMemoOne(() => {
    return clamp(
      withSpring({
        value: translationX,
        velocity: velocityX,
        state,
        config: {
          damping: 7
        },
        snapPoints: snapPoints
      }),
      snapPoints[0],
      snapPoints[snapPoints.length - 1]
    );
  }, []);

For onPress behaviour I've implemented something like this:

const onOptionPressed = index => {
    setValue(index); // to keep option index for upper component purposes
    translationX.setValue(snapPoints[index]); // I tried to manually set transX
    state.setValue(State.BEGAN); // I tried to set State.BEGAN to simulate(?) pan gesture 
    // I know that setting state to began will not do much as state, same as velocity are 
    // provided by panGestureHandler and are dynamically change during gesture event
  };

Thank you so much!

snapTo not always working

Using the following:

<Interactable
  ref={panel => this.panel = panel}
  verticalOnly={true}
  snapPoints={SNAP_POINTS}
  boundaries={{ top: -300 }}
  initialPosition={{ x: 0, y: Screen.height + 250 }}
  animatedValueY={this._deltaY}
>
  <TouchableHighlight onPress={this.openPlayer}>
 // truncated

Where openPlayer is:

private openPlayer = (): void => {
  if (this.panel) {
    this.panel.snapTo({ index: SNAP_POINTS.indexOf(OPEN_POSITION) })
  }
}

When I press the button to trigger the snap, it seems to only work intermittently. It registers the press, and I can see by logging that the panel ref exists, but sometimes the snap just doesn't happen.

HOW TO UPDATE REDUX STATE AFTER ANIMATION IS DONE

 <> <PanGestureHandler {...gestureHandler}> <Animated.View style={[{ ...StyleSheet.absoluteFillObject, backgroundColor: colors.dark }, { transform: [{ translateY }] }]}> <PlayerStuff onPress={()=>goDown.setValue(1)} /> <Animated.View style={{ ...StyleSheet.absoluteFillObject, opacity: overlayOpacity, backgroundColor: colors.lighterDark }} pointerEvents="none" /> <Animated.View style={{ opacity, position: 'absolute', top: 0, left: 0, right: 0 }}> <MediaStuff onPress={()=>goUp.setValue(1)} /> </Animated.View> </Animated.View> </PanGestureHandler> </>

I used the import { clamp, onGestureEvent, timing as timer, withSpring } from "react-native-redash"; while working on a video called "Spotify Player. Can it be done in react-native?" created by @wcandillon I am a bit new to React Native animations, and I would like to know how I can update redux state when the player is open or when it gets closed.
Please

using interpolatePath throws "outputRange cannot include undefined. (,)"

Hey,

I have two paths

const playPath = 'M11 10 L18 13.74 18 22.28 11 26 M18 13.74 L26 18 26 18 18 22.28'
const pausePath = 'M11 10 L17 10 17 26 11 26 M20 10 L26 10 26 26 20 26'

And I'm trying to use do something

const d = interpolatePath(this.animatedValue, {
  inputRange: [0, 1],
  outputRange: [playPath, pausePath]
});


return (
  <SVG width={100} height={100} viewBox="0 0 36 36">
    <AnimatedPath {...{ d }} fill="green"/>
  </SVG>
)

This throws the following error: outputRange cannot include undefined. (,)

Any ideas?

interpolatePath does not show anything

Hello,

I was trying to interpolate between two simple Bézier curves using the interpolatePath function but when I render the app there is no path visible.
here are my two paths:
const pathA = 'M0 9C0 4.02944 3.99393 0 8.9645 0C30.3249 0 82.8355 0 88 0C94.5 0 107.5 20.5 107.5 25.5C107.5 30.5 93.5 51 88 51C83.6232 51 30.4847 51 8.96353 51C3.99296 51 0 46.9706 0 42V9Z'; const pathB = 'M0 9C0 4.02944 3.99393 0 8.9645 0C30.3249 0 82.8355 0 88 0C94.5 0 68.5 26.5 68.5 31.5C68.5 36.5 93.5 51 88 51C83.6232 51 30.4847 51 8.96353 51C3.99296 51 0 46.9706 0 42V9Z'; c const d = interpolatePath(this._touchX,{ inputRange: [-size/2,size/2], outputRange: [pathA,pathB] });
I even tested the phone slider example but likewise there is no sign of the svg path of the phone.
I tried to debug both codes using reText and it seems like that in both cases the intepolatePath function returns the path without the starting point and starts the path with C for example: C0,9 0,9 0,9

Screen Shot 2019-07-22 at 1 29 40 PM

@wcandillon

Interactable component missing in doc

Hello William!

I've seen on one of your video that you use Interactable from redash, but I'm not seeing it mentionned anywhere in the doc? I think it would be cool to have that component explained in the readme instead of having to dig into the code.

Good job for this great library!

withDecay() reset position if animation is not finished

Hello,

I'm using withDecay() util to simulate a Scrollview behaviour. It works fine, but if the animation is not completely finished and I drag the PanGesture while still translating, the position is reset to the original value. Is there some way to avoid this behaviour and preserve the last X value while translating?

The second question is about setting gesture boundaries, so you can not translate further. In this example, it would be something like [0, -100]. What would be the best implementation? Thanks

This is the current behaviour
https://media.giphy.com/media/J4myqsTmOegFgy1tqS/giphy.gif

AnimatedPath

There's no reference of AnimatedPath in the docs.
Is it just Animated.createAnimatedComponent(Path)??
I can't get it working.

interpolatePath utility method returns "UnexpectedData" path

Hi @wcandillon , thx for the great utils and your videos. It helps me a lot.
But now I've faced with a problem:

I want to interpolate between two shapes (random path data bellow). This paths are the same length:

M4,205.00000000000003C11.12280701754386,202.50000000000003,18.24561403508772,200.00000000000003,25.36842105263158,190C32.49122807017544,179.99999999999997,39.6140350877193,54.99999999999999,46.73684210526316,54.99999999999999C53.859649122807014,54.99999999999999,60.98245614035087,295.00000000000006,68.10526315789473,295.00000000000006C75.22807017543859,295.00000000000006,82.35087719298245,252.5,89.47368421052632,240C96.59649122807018,227.5,103.71929824561403,233.33333333333331,110.84210526315789,219.99999999999997C117.96491228070174,206.66666666666663,125.0877192982456,34.99999999999998,132.21052631578945,34.99999999999998C139.33333333333331,34.99999999999998,146.45614035087718,373.3333333333333,153.57894736842104,380C160.7017543859649,386.6666666666667,167.82456140350877,383.3333333333333,174.94736842105263,390C182.0701754385965,396.66666666666663,189.19298245614033,440,196.3157894736842,440C203.43859649122805,440,210.56140350877192,400,217.68421052631578,400C224.80701754385964,400,231.9298245614035,420,239.05263157894737,420C246.1754385964912,420,253.29824561403507,265,260.4210526315789,265C267.5438596491228,265,274.66666666666663,495,281.7894736842105,495C288.91228070175436,495,296.03508771929825,125,303.1578947368421,125C310.280701754386,125,317.4035087719298,275,324.5263157894737,275C331.64912280701753,275,338.7719298245614,174.16666666666663,345.89473684210526,135C353.01754385964915,95.83333333333326,360.140350877193,39.99999999999998,367.2631578947369,39.99999999999998C374.3859649122807,39.99999999999998,381.50877192982455,485,388.6315789473684,485C395.7543859649123,485,402.8771929824561,260,410,34.99999999999998 L 410 500 L 4 500 Z

M4,5.000000000000004C11.12280701754386,32.5,18.24561403508772,60,25.36842105263158,60C32.49122807017544,60,39.6140350877193,39.99999999999998,46.73684210526316,39.99999999999998C53.859649122807014,39.99999999999998,60.98245614035087,73.33333333333337,68.10526315789473,120C75.22807017543859,166.66666666666669,82.35087719298245,320,89.47368421052632,320C96.59649122807018,320,103.71929824561403,316.6666666666667,110.84210526315789,310C117.96491228070174,303.3333333333333,125.0877192982456,179.99999999999997,132.21052631578945,130C139.33333333333331,79.99999999999996,146.45614035087718,10.000000000000009,153.57894736842104,10.000000000000009C160.7017543859649,10.000000000000009,167.82456140350877,30.000000000000007,174.94736842105263,70C182.0701754385965,109.99999999999994,189.19298245614033,260,196.3157894736842,270C203.43859649122805,280.00000000000006,210.56140350877192,280.83333333333337,217.68421052631578,285.00000000000006C224.80701754385964,289.16666666666674,231.9298245614035,295.00000000000006,239.05263157894737,295.00000000000006C246.1754385964912,295.00000000000006,253.29824561403507,169.99999999999997,260.4210526315789,169.99999999999997C267.5438596491228,169.99999999999997,274.66666666666663,231.66666666666657,281.7894736842105,275C288.91228070175436,318.3333333333333,296.03508771929825,430,303.1578947368421,430C310.280701754386,430,317.4035087719298,240,324.5263157894737,240C331.64912280701753,240,338.7719298245614,285.00000000000006,345.89473684210526,285.00000000000006C353.01754385964915,285.00000000000006,360.140350877193,278.33333333333337,367.2631578947369,265C374.3859649122807,251.66666666666669,381.50877192982455,185,388.6315789473684,185C395.7543859649123,185,402.8771929824561,307.5,410,430 L 410 500 L 4 500 Z

Using your function "interpolatePath(value: Node, { inputRange, outputRange }): path" gives me a crash :
Simulator Screen Shot - iPhone 11 - 2020-01-03 at 15 12 16

I assume that I could do something wrong, but I'm really stuck with this... Any suggestions of what could be wrong?

animatedValueX not being updated for Interactable

First off just want to say I love the react-native videos. Great work.

Testing out this library and trying use the animatedValueX to run an interpolation.

Basic setup is:

constructor(props) {
        super(props);

        this.x = new Animated.Value(0);
        this.x.addListener(console.log);
}

Then in render:

<Interactable
                                    ref={this.cursor}
                                    snapPoints={this.state.snapPoints}
                                    onSnap={this.onSnap}
                                    horizontalOnly
                                    style={{ width: 40 }}
                                    animatedValueX={this.x}
                                    initialPosition={{ x: initialX, y: 0 }}
                                >
{...}
</Interactable>

The display, interaction, snapoints, onSnap, initialPosition all work fine, but for some reason the animatedValueX dosn't get updated. Neither the listener, not an interpolation I have running off it seem to work

Having a quick look through the code it looks like it should be firing off fine, also tried on animatedValueY without success.

Any ideas?

SVG paths with arc don't seem to work

I tried an example with an SVG path that contains arcs and the normalizeSVG function from normalize-svg-path doesn't seem to convert arc into proper bezier curves.

Also ReanimatedPath contains the path values in a denormalized form but we could actually rewrite that into a normalized form again.

Below is a path example to test:

const circle = (r: number, cx: number, cy: number) => `M ${cx - r}, ${cy}
a ${r},${r} 0 1,0 ${r * 2},0
a ${r},${r} 0 1,0 ${-r * 2},0`;

Control animation state

I love the declarative approach reanimated uses do describe an animation. Declarative is cool. But sometimes you need to change the state of animation or even run it after pressing some button in the UI.

I want to open this discussion which aims to find the best solution for mixing declarative and imperative styles to work for better 60fps animations in our applications.

I'm often using some kind of state variable for this.

For example, here is the Input component, which shows a "Cancel" (just like ios default search input does) button on focus.

const UNSET = -1;
const INIT = 0;
const FALSE = 0;
const TRUE = 1;

class Input extends React.Component {
  _inputRef = React.createRef();

  _inputClock = new A.Clock();
  _focusState = new A.Value(UNSET);

  _marginRight = A.cond(
    A.eq(this._focusState, TRUE),
    runTiming(this._inputClock, 8, 84),
    A.cond(
      A.eq(this._focusState, FALSE),
      runTiming(this._inputClock, 84, 8),
      8,
    ),
  );

  _translateX = A.interpolate(this._marginRight, {
    inputRange: [8, 84],
    outputRange: [100, -24],
    extrapolate: A.Extrapolate.CLAMP,
  });

  handleFocus() {
    this._focusState.setValue(TRUE);
  }

  handleBlur(shouldBlur) {
    if (shouldBlur) {
      this._inputRef.current._component.blur();
    }

    this._focusState.setValue(FALSE);
  }

  render() {
    return (
      <View style={styles.inputContainer}>
        <AnimatedTextInput
          ref={this._inputRef}
          onFocus={() => this.handleFocus()}
          onBlur={() => this.handleBlur()}
          style={[styles.input, { marginRight: this._marginRight }]}
        />
        <A.View
          style={[
            styles.cancelButton,
            { transform: [{ translateX: this._translateX }] },
          ]}
        >
          <TouchableOpacity onPress={() => this.handleBlur(true)}>
            <Text style={styles.cancel}>Cancel</Text>
          </TouchableOpacity>
        </A.View>
      </View>
    );
  }
}

It introduces a focusState variable which determinates a state of our input focus and a condition where we trigger some animation after state has been changed.

I wonder if there any other better way to do the same. Or if it's not we should introduce some sort of helper function to do that really quickly and redash is the right place to do it, I think.

Delaying runTiming node flickering

I need to run some timing animations parallel one to the other, I managed to do this pretty easy with multiple runTimings. Now I need to add delay to some of them. My logic tells me to use runDelay with a runTiming inside of it but im getting a flickering effect.

This is one of the animations without the delay (note that there's an opacity and translate animation):

const cardSetup = animSetup(800, 1);
this.opacityCard = runTiming(cardSetup.clock, 0, cardSetup.config);
this.translateCard = bInterpolate(this.opacityCard, 0, -150);

The animSetup function is a helper function which contains this:

const animSetup = (duration, toValue) => {
  return {
    clock: new Clock(),
    config: {
      duration,
      toValue,
      easing: Easing.bezier(0.25, 0.1, 0.25, 1),
    },
  };
}

And it looks like this (works perfectly fine):
runTiming

Now if I add the runDelay function:

const cardSetup = animSetup(800, 1);
this.opacityCard = runDelay(runTiming(cardSetup.clock, 0, cardSetup.config), 100);
this.translateCard = bInterpolate(this.opacityCard, 0, -150);

It looks like this:
runDelayBug

I'm not sure if it is a bug on the runDelay function, a bug on react-native-reanimated or maybe a wrong way to do it.

Any idea how to accomplish this effect?

loop is not working?

well am trying to make a Fade effect , using the loop method as following:

import React from "react";
import { ViewProps } from "react-native";
import Animated from "react-native-reanimated";
import { loop } from "react-native-redash";

const START_VALUE = 0.5;
const DURATION = 500;

export class Fade extends React.Component<ViewProps> {
  private animation: Animated.Value<number>;

  constructor(props: ViewProps) {
    super(props);

    this.animation = new Animated.Value(START_VALUE);
  }

  public componentDidMount() {
    this.start();
  }

  public render() {
    const { children, style } = this.props;
    const animationStyle = {
      backgroundColor: "#dfdfdf",
      opacity: this.animation
    };

    return (
      <Animated.View style={[animationStyle, style]}>{children}</Animated.View>
    );
  }

  private start() {
    Animated.set(
      this.animation,
      loop({
        duration: DURATION,
        autoStart: true,
        boomerang: true
      })
    );
  }
}

am not really sure , if I'm missing something , or there is a bug , also reading theDOCs it recommends using runLoop but I can't find this function exported from the lib.

thank you

Improvements to SVG functions

Here are below some notes from using the SVG functions in a real-world use case.

  • Path normalization could slightly be improved by removing all M commands that are not at the beginning of the path. This happens when concatenating paths together for instance. This can easily be fixed at the user level but since we claim to support any SVG path, it might be useful to be more

  • Implement solveCubicRootForBezier(). This is a tricky one. Not only it would be a very complex algorithm to reimplement in Reanimated (here is a good JS implementation: https://github.com/tab58/minimatrix-polyroots/blob/master/index.js#L133), we would also need to add the root selection (real number between 0 and 1).

parsePath doesn't return an exact match of paths with large curves

Issue:
parsePath doesn't return an exact match of my path which causes getPointAtLength to return inaccurate values.

Versions:
react-native-redash: 8.0.0

Description:

I'm building a line graph similar to revolut's which uses a gestureHandler to navigate it and uses d3 to create the SVG.

In my cursor component, I read the translateX value to map the cursor onto the line graph.

When I compare to svg-path-properties's path properties, I see that it returns a shorter total length than the parsePath function does in redash.

This is the example path with large curves below.

path = "M0,106.2L6.578947368421052,100.8C13.157894736842104,95.40000000000002,26.31578947368421,84.60000000000001,39.473684210526315,90.60000000000001C52.63157894736842,96.60000000000001,65.78947368421052,119.39999999999999,78.94736842105263,109.19999999999999C92.10526315789474,99,105.26315789473684,55.79999999999999,118.42105263157896,56.099999999999994C131.57894736842104,56.4,144.73684210526315,100.2,157.89473684210526,119.10000000000001C171.05263157894737,138,184.21052631578945,132,197.36842105263156,110.7C210.52631578947367,89.39999999999999,223.68421052631575,52.79999999999999,236.8421052631579,58.49999999999999C250,64.19999999999999,263.15789473684214,112.19999999999999,276.3157894736842,129C289.4736842105263,145.79999999999998,302.6315789473684,131.4,315.7894736842105,132.3C328.94736842105266,133.20000000000002,342.10526315789474,149.4,355.2631578947368,156.29999999999998C368.4210526315789,163.20000000000002,381.57894736842104,160.79999999999998,394.7368421052631,136.20000000000002C407.89473684210526,111.60000000000001,421.05263157894734,64.8,434.2105263157894,39C447.3684210526316,13.199999999999998,460.5263157894737,8.399999999999997,473.6842105263158,15.899999999999997C486.8421052631579,23.399999999999995,500,43.199999999999996,513.1578947368421,66.60000000000001C526.3157894736842,90,539.4736842105264,117,552.6315789473684,117C565.7894736842105,117,578.9473684210526,90,592.1052631578947,78C605.2631578947369,66,618.421052631579,69,631.5789473684212,58.5C644.7368421052632,48,657.8947368421053,24,671.0526315789474,12.6C684.2105263157895,1.1999999999999982,697.3684210526316,2.3999999999999964,710.5263157894736,5.999999999999996C723.6842105263158,9.599999999999994,736.8421052631579,15.599999999999994,743.4210526315788,18.599999999999994L750,21.599999999999994"

Here is the code in the cursor component:

export default ({ d, r, borderWidth, borderColor, transX }: CursorProps) => {
  const radius = r + borderWidth / 2;
  const path = parsePath(d);
  const length = interpolate(transX, {
    inputRange: [0, width],
    outputRange: [0, -path.totalLength]
  });
  const { y, x } = getPointAtLength(path, length);
// I divide x by 2 because the graph is width*2 but the cursor moved from 0 to width
  const translateX: any = sub(divide(x, 2), radius);
  const translateY: any = sub(y, radius);
  return (
    <Animated.View
      style={{
        transform: [{ translateX }, { translateY }],
        width: radius * 2,
        height: radius * 2,
        justifyContent: "center",
        alignItems: "center",
        position: "absolute"
      }}
    >
      <View
        style={{
          width: radius * 2,
          height: radius * 2,
          borderRadius: radius,
          borderColor,
          borderWidth,
          backgroundColor: white
        }}
      />
    </Animated.View>
  );
};

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.