wcandillon / react-native-redash

The React Native Reanimated and Gesture Handler Toolbelt
https://wcandillon.gitbook.io/redash/
MIT License
1.97k stars 117 forks source link

interpolateColor issue #307

Open ogulcankarayel5 opened 4 years ago

ogulcankarayel5 commented 4 years ago

I've been watching react native fashion tutorial and I've stucked in this section.

const { scrollHandler, x, y } = useScrollHandler();
  const backgroundColor=interpolateColor(x,{
    inputRange:[0,width,width*2,width*3],
    outputRange:["#BFEAF5","#BEECC4","#FFE4D9","#FFDDDD"]

  })

After implementing this in style all my backgrounds are white. How can I fix this ?

MartinSchnit commented 4 years ago

Same problem for me !

Hope there is a solution

ahoopen commented 4 years ago

I had the same issue. The problem for me was the wrong way the scrollHandler was set on the Animated.ScrollView. So do this, {...scrollHandler} instead of {...{scrollHandler} }

<Animated.ScrollView
          {...scrollHandler}
/>
ogulcankarayel5 commented 4 years ago

Many thanks to you

Bensigo commented 4 years ago

I still have a white background

MartinSchnit commented 4 years ago

I still have a white background

same... :(

Bensigo commented 4 years ago

I had the same issue. The problem for me was the wrong way the scrollHandler was set on the Animated.ScrollView. So do this, {...scrollHandler} instead of {...{scrollHandler} }

<Animated.ScrollView
          {...scrollHandler}
/>

this does not work

Bensigo commented 4 years ago

I have to do it this way for it to work

    const x = new Animated.Value(0)
    const backgroundColor = x.interpolate({
        inputRange: [0, width, width * 2],
        outputRange: ["#BFEAF5", "#BEECC4", "#FFE4D9"]

    })
 <Animated.ScrollView
   onScroll={Animated.event(
                        [{nativeEvent: {contentOffset: {x}}}]//
                    )}
.....
ahoopen commented 4 years ago

Its important that the Animated import is from "react-native-reanimated" instead of "react-native". And also don't forget to remove the backgroundColor on slider in your styles. And ofcourse you have to set the backgroundColor on the Animated.ScrollView

<Animated.View style={[styles.slider, { backgroundColor }]}>

Hope this helps :)

Bensigo commented 4 years ago

Its important that the Animated import is from "react-native-reanimated" instead of "react-native". And also don't forget to remove the backgroundColor on slider in your styles. And ofcourse you have to set the backgroundColor on the Animated.ScrollView

<Animated.View style={[styles.slider, { backgroundColor }]}>

Hope this helps :)

this does't work.

Bensigo commented 4 years ago

TS2769: No overload matches this call.   Overload 1 of 2, '(props: Readonly<AnimateProps<ViewStyle, ViewProps>>): View', gave the following error.     Type 'AnimatedNode<number>' is not assignable to type 'false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | RecursiveArray<false | AnimateStyle<ViewStyle> | RegisteredStyle<...> | null | undefined> | readonly (false | ... 3 more ... | undefined)[] | null | undefined'.       Type 'AnimatedNode<number>' is missing the following properties from type 'readonly (false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | null | undefined)[]': length, concat, join, slice, and 18 more.   Overload 2 of 2, '(props: AnimateProps<ViewStyle, ViewProps>, context?: any): View', gave the following error.     Type 'AnimatedNode<number>' is not assignable to type 'false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | RecursiveArray<false | AnimateStyle<ViewStyle> | RegisteredStyle<...> | null | undefined> | readonly (false | ... 3 more ... | undefined)[] | null | undefined'.       Type 'AnimatedNode<number>' is not assignable to type 'readonly (false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | null | undefined)[]'. you get this if using typescript

ahoopen commented 4 years ago

TS2769: No overload matches this call.   Overload 1 of 2, '(props: Readonly<AnimateProps<ViewStyle, ViewProps>>): View', gave the following error.     Type 'AnimatedNode<number>' is not assignable to type 'false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | RecursiveArray<false | AnimateStyle<ViewStyle> | RegisteredStyle<...> | null | undefined> | readonly (false | ... 3 more ... | undefined)[] | null | undefined'.       Type 'AnimatedNode<number>' is missing the following properties from type 'readonly (false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | null | undefined)[]': length, concat, join, slice, and 18 more.   Overload 2 of 2, '(props: AnimateProps<ViewStyle, ViewProps>, context?: any): View', gave the following error.     Type 'AnimatedNode<number>' is not assignable to type 'false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | RecursiveArray<false | AnimateStyle<ViewStyle> | RegisteredStyle<...> | null | undefined> | readonly (false | ... 3 more ... | undefined)[] | null | undefined'.       Type 'AnimatedNode<number>' is not assignable to type 'readonly (false | AnimateStyle<ViewStyle> | RegisteredStyle<AnimateStyle<ViewStyle>> | null | undefined)[]'. you get this if using typescript

Perhaps this might help you.

import { View, StyleSheet, Dimensions } from "react-native";
import Animated from "react-native-reanimated";
import { interpolateColor, useScrollHandler } from "react-native-redash";

const SLIDE_HEIGHT = 0.61 * height;
const BORDER_RADIUS = 75;
const { width } = Dimensions.get("window");
const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: "white",
    },
    slider: {
        height: SLIDE_HEIGHT,
        borderBottomRightRadius: BORDER_RADIUS,
    },
    footer: {
        flex: 1,
    },
    footerContent: {
        flex: 1,
        flexDirection: "row",
        backgroundColor: "white",
        borderTopLeftRadius: BORDER_RADIUS,
    },
});

export const Onboarding = () => {
    const { scrollHandler, x } = useScrollHandler();
    const backgroundColor = interpolateColor(x, {
        inputRange: slides.map((_, i) => i * width),
        outputRange: slides.map(slide => slide.color),
    });

  return (
        <View style={styles.container}>
            <Animated.View style={[styles.slider, { backgroundColor }]}>
                <Animated.ScrollView
                    ref={scroll}
                    horizontal
                    snapToInterval={width}
                    decelerationRate="fast"
                    showsHorizontalScrollIndicator={false}
                    bounces={false}
                    {...scrollHandler}
                >
                    { your slides here }
                </Animated.ScrollView>
            </Animated.View>
            <View style={styles.footer}>
                <Animated.View
                    style={{
                        ...StyleSheet.absoluteFillObject,
                        backgroundColor,
                    }}
                />
               <View><Text>footer</Text></View>
            </View>
        </View>
    );
};
MartinSchnit commented 4 years ago

Hi all, i have a problem with my app.

Everything work fine, but when i scroll, the background dont change his color...

Here is my code :

import React from 'react';
import { View, Text, StyleSheet, Dimensions } from 'react-native';
import Animated, { Easing } from 'react-native-reanimated';
import { useValue, onScrollEvent, interpolateColor, useScrollHandler } from 'react-native-redash';

import Slide, { SLIDE_HEIGHT } from './Slide';
const { width, height } = Dimensions.get('window');

const slides = [
    { title: "Relaxed", color: '#BFEAF5', subtitle: 'subtitle 1', description: 'Description'},
    { title: "Playful", color: '#BEECC4', subtitle: 'subtitle 1', description: 'Description'},
    { title: "Excentric", color: '#FFE4D9', subtitle: 'subtitle 1', description: 'Description'},
    { title: "Funky", color: '#FFDDDD', subtitle: 'subtitle 1', description: 'Description'},
];

const OnBoarding = () => {
    // const x = useValue(0);
    // TODO
    const { scrollHandler, x, y } = useScrollHandler();
    const backgroundColor = interpolateColor(x, {
        inputRange: slides.map((_, i) => i*width),
        outputRange: slides.map(slide => slide.color),
    });
    // console.log(x);
    // console.log(backgroundColor);
    return (
        <View style={styles.container}>
            <Animated.View style={[styles.slider, { backgroundColor }]}>
                <Animated.ScrollView 
                    horizontal 
                    snapToInterval={width} 
                    decelerationRate="fast" 
                    showsHorizontalScrollIndicator={false} 
                    bounces={false}
                    // scrollEventThrottle={1}
                    // onScroll={() => onScrollEvent({ x })}
                    {...{scrollHandler}}
                >
                    {slides.map(({title}, index) => (
                        <Slide key={index} right={!!(index%2)} {...{title}} />
                    )) }
                </Animated.ScrollView>
            </Animated.View>
            <View style={styles.footer}>
                <Animated.View style={{...StyleSheet.absoluteFillObject, backgroundColor}} />
                <View style={styles.footerContent}>
                    {/* {slides.map(({ subtitle, description }, index) => (
                        <Subslide 
                            key={index} 
                            last={index === index.length-1} 
                            {...{ subtitle, description, x }} 
                        />
                    ))} */}
                </View>
            </View>
        </View>
    )
};

const styles = StyleSheet.create({
    container: {
        flex: 1,
        backgroundColor: 'white'
    },
    slider: {
        height: SLIDE_HEIGHT,
        // backgroundColor: 'cyan',
        borderBottomRightRadius: 75
    },
    footer: {
        flex: 1,
    },
    footerContent: { 
        flex: 1,
        backgroundColor: 'white',
        borderTopLeftRadius: 75 
    }
});

export default OnBoarding;

This must be a noob error but i cant find it...

Thanks for your time <3

a-eid commented 4 years ago

could u please share a re-producable example on expo snack ?

chj-damon commented 4 years ago

does it mean that interpolateColor can only be used as backgroundColor? what about color?

a-eid commented 4 years ago

It works fine with either color or backgroundColor

anhquan291 commented 4 years ago

Hi guys,Cannot get it works with expo sdk38, reanimated 1.9.0. Any suggestion please? Thanks in advance

anhquan291 commented 4 years ago

I have to do it this way for it to work

    const x = new Animated.Value(0)
    const backgroundColor = x.interpolate({
        inputRange: [0, width, width * 2],
        outputRange: ["#BFEAF5", "#BEECC4", "#FFE4D9"]

    })
 <Animated.ScrollView
   onScroll={Animated.event(
                        [{nativeEvent: {contentOffset: {x}}}]//
                    )}
.....

This works for me with the Animated from react-native. Thank you. You saved my day

a-eid commented 4 years ago

@anhquan291 please share your non working code || make a reproducible example ( on expo snack )

MateuszPalosz commented 3 years ago

@Bensigo

Types of property 'backgroundColor' are incompatible.
Type 'AnimatedNode<number>' is not assignable to type 'number | ColorValue | undefined'.

Workaround can look like this (it's not great, but works):

 const backgroundColor = interpolateColor(x, {
    inputRange: [0, width, width * 2, width * 3],
    outputRange: ["#bfeaf5", "#beecc4", "#ffe4d9", "#ffdddd"],
  }) as any;

or

const backgroundColor = (interpolateColor(x, {
    inputRange: [0, width, width * 2, width * 3],
    outputRange: ["#bfeaf5", "#beecc4", "#ffe4d9", "#ffdddd"],
  }) as unknown) as number | ColorValue;
dioseb commented 2 years ago

Using {Animated} from 'react-native' like suggested by @anhquan291 worked.

Here's my code :

const x = new Animated.Value(0); const backgroundColor = x.interpolate({ inputRange: slides.map((_, i) => i * width), outputRange: slides.map((slide) => slide.color), });