React-Native Animated.spring callback is being delay - javascript

I am setting a simple layout on my react-native app with a list of products in which on can click and open a booking flow. When you click on a product, the whole app is sliding to the left, and the product page is sliding from the right to the left.
When I click back from the product page, I am sliding back the app and the product to the right. But because the product page is part of the booking flow, i am suppose to unmount the BookingFlow component by setting a state to false.
Problem is there is a delay in the callback of the animation so it takes 400ms for the BookingFlow component to be unmounted.
I use the callback from Animated.parallel in order to do so:
closeProduct () {
Animated.parallel([
Animated.spring(this.props.translateXApp, {
toValue: 0,
duration: 140,
bounciness: 0,
speed: 14,
easing: Easing.ease,
useNativeDriver: true
}),
Animated.spring(this.translateXProduct, {
toValue: width,
duration: 140,
bounciness: 0,
speed: 14,
easing: Easing.ease,
useNativeDriver: true
})
]).start(() => {
this.props.closeBookingFlow()
})
}
On my app.js here is my code:
<Animated.View style={[styles.translateXView,{transform: [{translateX: this.translateXApp},{scale:this.scallApp}]}]}>
<Application
openCategory={this.openCategory.bind(this)}
openProduct={this.openProduct.bind(this)}
/>
</Animated.View>
{
this.state.showBookingFlow == true?
<BookingFlow
closeBookingFlow = {this.closeBookingFlow.bind(this)}
onRef={ref => (this.bookingFlowRef = ref)}
translateXApp = {this.translateXApp}
/>
:null
}
I found a trick in order to avoid this issue but it is not very proper. I use a timeout outside of the animation which is waiting 400ms.
setTimeout(function(){
that.props.closeBookingFlow()
}, 400);
Is there a way to avoid the delay in the animated callback?
Thanks guys.

I figured out that i needed to add those 2 values to my springs animations:
restSpeedThreshold: 100, restDisplacementThreshold: 40

Related

use gsap scrollTrigger in react

I am trying to imply some animations in an image while scrolling , the image will grow while scrolling down and return to normal when scrolling up . The reference : codepen.
This is my react code :
<ArticleWrapper ref={ref}>
<img id='grow' className='image' src={Img} alt='Image' />
</ArticleWrapper>
I have tried to implement this but it didnt work when I scroll :
const ref = useRef(null);
useEffect(() => {
const element = ref.current;
scrollTrigger: {
trigger: "#grow",
scrub: 1.5,
start: "top center",
end: "+=400",
ease: "power1.out"
},
{
duration: 1,
scale: 1
}
);
}, []);
Any idea how to do that ?

The scroll trigger end of gsap does not work properly

Hi I use gsap and bootstrap
Each version is gsap 3.9.1 and bootstrap 5.1.3
My problem is that the end of the scroll trigger does not work properly.
const navbarani = gsap.from('.navbar', {
yPercent: -100,
paused: true,
duration: 0.5
}).progress(1)
ScrollTrigger.create({
start: 'top top',
end: 'bottom',
onUpdate: (self) => {
self.direction === -1 ? navbarani.play() : navbarani.reverse()
}
})
If I change end: 'bottom' to end: 999999 it works properly, but
I can't use end: 999999 because I want the scroll to work only when it's at the top.
What I don't understand is that if i erase the bootstrap from the cdn, end: 'bottom' works well.
That's why I think bootstrap and gsap scroll trigger's end cause conflict.
This is the code that I experimented with.
<template>
<div class="navbar">I'm navbar</div>
<div class="blank" />
</template>
<script>
import { onMounted } from 'vue'
import { gsap } from 'gsap'
import { ScrollTrigger } from 'gsap/ScrollTrigger'
gsap.registerPlugin(ScrollTrigger)
export default {
setup () {
onMounted(() => {
const navbarani = gsap.from('.navbar', {
yPercent: -100,
paused: true,
duration: 0.5
}).progress(1)
ScrollTrigger.create({
start: 'top top',
end: 'bottom',
onUpdate: (self) => {
self.direction === -1 ? navbarani.play() : navbarani.reverse()
}
})
})
}
}
</script>
<style>
.navbar {
position: fixed;
}
.blank {
height: 150vh;
}
</style>
I wonder if this collision only occurs to me or if the version is wrong.
If you don't have enough explanation, please let me know. I'll add an explanation.
Thank you for your help.

How to move plane icon with framer motion?

I have a react paper plane icon that I would like to make a cool effect by making it travel around the HTML document reaching the final position which is the menu button at the top.
This is how my react component called NavPlane looks like:
import React, { Component, useEffect } from "react";
import { useCycle } from "framer-motion";
import { FaPaperPlane } from "react-icons/fa";
import { motion } from "framer-motion";
const PlaneVariants = {
animationOne: {
x: 370,
y: 250,
transition: { ease: [0.17, 0.67, 0.83, 0.67] },
},
animationTwo: {
x: 140,
y: 150,
transition: { duration: 1.0 },
},
animationThree: {
x: 170,
y: 200,
transition: { duration: 1.0 },
},
};
export default function NavPlane() {
const [animation, cycleAnimation] = useCycle(
"animationOne",
"animationTwo",
"animationThree"
);
useEffect(() => {
setTimeout(() => {
cycleAnimation();
}, 1000);
}, []);
return (
<motion.div
className="text-2xl text-gray-600"
variants={PlaneVariants}
animate={animation}
>
<FaPaperPlane />
</motion.div>
);
}
cycleAnimation() was supposed to cycle through 3 animations but only cycling through the first two. The 3rd is only applied when making some change to the code and updating it.
The final goal is to have a movement that goes from right corner of the page to middle, does a knot movement and then travels to the top of the page.
Any ideas how to make it cycle through as many animation variants as I want?
cycleAnimation only advances one step. Initially it will start "animationOne". Once you call cycleAnimation() after 1 second, "animationTwo" will start. You need another timer if you want to play "animationThree"
useEffect(() => {
setTimeout(cycleAnimation, 1000); // start "animationTwo" after 1 second
setTimeout(cycleAnimation, 2000); // start "animationThree" after 2 seconds
}, []);

React-motion rendering on every animation

I'm getting really bad performance using React-Motion (https://github.com/chenglou/react-motion). I'm animating the height of a dropdown from a table row from 0 to 260.
constructor() {
this.state = {
opened: false
}
this.handleRowClick = this.handleRowClick.bind(this)
}
handleRowClick() {
this.setState({
opened: !this.state.opened
})
}
render() {
<Motion style={{height: spring(this.state.opened ? 260 : 0, {stiffness: 140, damping: 30})}}>
{(height) =>
<div onClick={this.handleRowClick}>
<div style={height}>
...stuff goes here
</div>
</div>
}
</Motion>
}
The animation is working as expected, but upon logging the height every time it renders all of this in the span of ~5 seconds (which is WAY too long):
Maybe I misread something in the docs, but is there a way to avoid lag on the animation?
You'll need to apply the transition styles to a div and render a component inside it which implements shouldComponentUpdate (eg. with React.PureComponent) to prevent it from rerendering when not needed.
render () {
<Motion
style={{
height: spring(
this.state.opened ? 260 : 0,
{ stiffness: 140, damping: 30 }
)
}}
>
{(height) =>
<div style={height}>
<YourComponent />
</div>
}
</Motion>
}
And MyComponent might be something like class MyComponent extends React.PureComponent or using a HOC like pure from recompose. This way MyComponent will only update when it's props changes.

React Native SectionList scroll to section

I just changed my ListView to React Native's new SectionList and now the app crashes when I attempt to use the scrollTo function, stating that it's undefined. I tried looking up new/alternative functions that may help, but none of them seem to be working.
What's the proper protocol for programmatically scrolling to a specific section with the new SectionList?
Links I've been consulting thus far:
https://github.com/facebook/react-native/issues/13151
https://facebook.github.io/react-native/releases/0.43/docs/virtualizedlist.html#scrolltoend
My current attempt:
var params = {animated:true,offset:Platform.OS == "ios" ? 244 : 264}
_mainListView.scrollToOffset(params)
<SectionList
ref={(sectionList) => { this.sectionList = sectionList }} .../>
this.sectionList.scrollToLocation(
{
sectionIndex: sectionIndex,
itemIndex: itemIndex
}
);
This is what I used to get it working using a mix of this post and https://snack.expo.io/HJp9mEQkG
This is how I scroll to end
listRef.current?.scrollToLocation({
animated: true,
sectionIndex: sections.length - 1,
itemIndex: sections[sections.length - 1].data.length - 1,
})
This is how I scroll to top
listRef.current?.scrollToLocation({
animated: true,
sectionIndex: 0,
itemIndex: 0,
})
scrollToSection = (sectionIndex,itemIndex = 1 ) => {
this.refs.foo.scrollToLocation({
sectionIndex: sectionIndex,
itemIndex: itemIndex
});
}
sectionList:
<SectionList
ref = "foo",
//something
/>
For me workaround is
list.current?.getScrollResponder()?.scrollTo({ x: 0, y: 0, animated: false })

Categories

Resources