React-native-snap-carousel: 3D Cube Animation

Created on 9 May 2019  Â·  8Comments  Â·  Source: meliorence/react-native-snap-carousel

Is this a bug report, a feature request, or a question?

Question

Hello everyone,

image

I was using https://github.com/zehfernandes/react-native-3dcube-navigation library to make instagram's story like cube animation but this library doesn't use FlatList so it has performance issues and also it has some bugs. I thought maybe I can use snap-carousel to implement 3dcube navigation since it looks same as in custom interpolations page.

But when I tried to implement this custom animation. I notice _scrollInterpolator converts -1, 0, 1 to -width, 0, width. So I using "pageX - width" as given below is incorrect. I tried to change them to -1, 0, 1 but I get really weird result.

image

I am new to react native animations. Any help would be appreciated.

  _getTransformsFor = i => {
    let scrollX = this._animatedValue.x;
    let pageX = -width * i;

    let translateX = scrollX.interpolate({
      inputRange: [pageX - width, pageX, pageX + width],
      outputRange: [(-width - 1) / TR_POSITION, 0, (width + 1) / TR_POSITION],
      extrapolate: 'clamp'
    });

    let rotateY = scrollX.interpolate({
      inputRange: [pageX - width, pageX, pageX + width],
      outputRange: ['-60deg', '0deg', '60deg'],
      extrapolate: 'clamp'
    });

    let translateXAfterRotate = scrollX.interpolate({
      inputRange: [pageX - width, pageX, pageX + width],
      inputRange: [
        pageX - width,
        pageX - width + 0.1,
        pageX,
        pageX + width - 0.1,
        pageX + width
      ],
      outputRange: [
        -width - 1,
        (-width - 1) / PESPECTIVE,
        0,
        (width + 1) / PESPECTIVE,
        +width + 1
      ],
      extrapolate: 'clamp'
    });

    let opacity = scrollX.interpolate({
      inputRange: [
        pageX - width,
        pageX - width + 10,
        pageX,
        pageX + width - 250,
        pageX + width
      ],
      outputRange: [0, 0.6, 1, 0.6, 0],
      extrapolate: 'clamp'
    });

    return {
      transform: [
        { perspective: width },
        { translateX },
        { rotateY: rotateY },
        { translateX: translateXAfterRotate }
      ],
      opacity: opacity
    };
  };

Most helpful comment

All 8 comments

What I tried so far

import React, { PureComponent } from 'react';
import Carousel, { getInputRangeFromIndexes } from 'react-native-snap-carousel';
import { Dimensions, Platform, StyleSheet, View } from 'react-native';

const Window = Dimensions.get('window');

const width = Window.width;
const height = Window.height;

const PESPECTIVE = Platform.OS === 'ios' ? 2.38 : 1.7;
const TR_POSITION = Platform.OS === 'ios' ? 2 : 1.5;

const data = [
  { id: 1, color: 'red' },
  { id: 2, color: 'blue' },
  { id: 3, color: 'yellow' },
  { id: 4, color: 'green' },
  { id: 5, color: 'black' },
];

export default class MyCustomCarousel extends PureComponent {

  _scrollInterpolator(index, carouselProps) {
    const range = [1, 0, -1];
    const inputRange = getInputRangeFromIndexes(range, index, carouselProps);
    const outputRange = range;

    return { inputRange, outputRange };
  }

  _animatedStyles(i, scrollX, carouselProps) {
    let pageX = 0;

    let opacity = scrollX.interpolate({
      inputRange: [
        (pageX - width) / width,
        (pageX - width + 10) / width,
        (pageX) / width,
        (pageX + width - 250) / width,
        (pageX + width) / width,
      ],
      outputRange: [0, 0.6, 1, 0.6, 0],
      extrapolate: 'clamp',
    });

    return {
      transform: [
        {
          perspective: width,
        },
        {
          translateX: scrollX.interpolate({
            inputRange: [
              (pageX - width) / width,
              (pageX) / width,
              (pageX + width) / width,
            ],
            outputRange: [
              (-width - 1) / TR_POSITION,
              0,
              (width + 1) / TR_POSITION,
            ],
          }),
        },
        {
          rotateY: scrollX.interpolate({
            inputRange: [-1, 0, 1],
            outputRange: ['-60deg', '0deg', '60deg'],
            extrapolate: 'clamp',
          }),
        },
        {
          translateX: scrollX.interpolate({
            inputRange: [
              (pageX - width) / width,
              (pageX - width + 0.1) / width,
              pageX / width,
              (pageX + width - 0.1) / width,
              (pageX + width) / width,
            ],
            outputRange: [
              (-width - 1),
              ((-width - 1) / PESPECTIVE),
              0,
              ((width + 1) / PESPECTIVE),
              (+width + 1),
            ],
            extrapolate: 'clamp',
          }),
        },
      ],
      opacity: opacity,
    };
  }


  _renderItem({ item, index }) {
    return (
      <View key={index} style={[
        { height, top: 50, backgroundColor: item.color },
      ]}>{item.title}</View>
    );
  }

  render() {
    return (
      <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>


        <Carousel
          firstItem={1}
          containerCustomStyle={{ width }}
          data={data}
          useScrollView={true}
          renderItem={this._renderItem}
          sliderWidth={width}
          itemWidth={width}
          scrollInterpolator={this._scrollInterpolator}
          slideInterpolatedStyle={this._animatedStyles}
        />


      </View>
    );
  }

}

Hi @zek,

Can you please put all this in a Snack example? It will make it easier for us to help you :-)

you make done feature

hey did any one hava an idea how we can do it with a flatlist

Do you need to complete this job?
I am a 3d-cube fullstack developer.
If you hire me I will best

Sent from Mailhttps://go.microsoft.com/fwlink/?LinkId=550986 for Windows 10

From: khalid aoussarnotifications@github.com
Sent: Sunday, December 15, 2019 8:20 PM
To: archriss/react-native-snap-carouselreact-native-snap-carousel@noreply.github.com
Cc: michele jamesleewon961018@hotmail.com; Manualmanual@noreply.github.com
Subject: Re: [archriss/react-native-snap-carousel] 3D Cube Animation (#518)

hey did any one hava an idea how we can do it with a flatlist

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHubhttps://github.com/archriss/react-native-snap-carousel/issues/518?email_source=notifications&email_token=ANZADAT3JYPCRHSTWGITNN3QYYOJRA5CNFSM4HL43KXKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEG4X4XY#issuecomment-565804639, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ANZADAQGCNK5J2ALA2OE7WTQYYOJRANCNFSM4HL43KXA.

I'm having a similar issue where the selected item just disappears. Below is my _slideInterpolatedStyle. If perspective is removed, everything seems to work fine... Any clue on how I could fix this?

_slideInterpolatedStyle = (index, animatedValue, carouselProps) => ({
    opacity: animatedValue.interpolate({
      inputRange: [-1, 0, 1],
      outputRange: [0.5, 1, 0.5],
      extrapolate: 'clamp',
    }),
    transform: [
      {
        perspective: animatedValue.interpolate({
          inputRange: [-1, 0, 1],
          outputRange: [-1500, 0, -1500],
          extrapolate: 'clamp',
        }),
      },
      {
        translateX: animatedValue.interpolate({
          inputRange: [-3, -2, -1, 0, 1, 2, 3],
          outputRange: [110, 50, 0, 0, 0, -50, -110],
          extrapolate: 'clamp',
        }),
      },
    ],
  });
Was this page helpful?
0 / 5 - 0 ratings