Closed cgo123 closed 2 years ago
Hi, width: null should not be used, but width:'auto' is supported.. do you have an example code to evaluate the issue more in detail?.. If you want to make a tween between 100% to auto you will have to calculate 'auto' in % before making the tween and after tween end set the property to 'auto'
I leave this code making a tween between 10% =>tween=> 100% =>set=> auto
import React from 'react';
import {Pressable, StyleSheet, Text, View} from 'react-native';
import {AutoKillTweens, Elastic, gsap} from 'gsap-rn';
export const SimpleAnimation = () => {
const boxRef = React.createRef();
const tweens = {};
const animate = () => {
tweens.ani1 = gsap.timeline();
tweens.ani1.set(boxRef.current, {style: {width: '10%'}});
tweens.ani1.to(boxRef.current, { duration: 1, style: {width: '80%'}, ease: Elastic.easeInOut,});
tweens.ani1.set(boxRef.current, {style: {width: 'auto'}});
};
return (
<>
<AutoKillTweens tweens={tweens} />
<View ref={boxRef} style={[style.box]} />
<Pressable onPress={animate} style={[style.button, {marginTop: 20}]}>
<Text>Click</Text>
</Pressable>
</>
);
};
export const style = StyleSheet.create({
box: {
padding: 20,
width: '50%',
height: 100,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: 'red',
},
button: {
padding: 20,
justifyContent: 'center',
alignItems: 'center',
width: 'auto',
backgroundColor: '#dddddd',
},
});
Yes, in react-native you can’t mix % with Numbers, if you will do an animation with % just use % value, or if your animation is between 2 Numbers only use numbers, Also, you need to set the initial value before starting the animation, due in ReactNative there is no way to retrieve the current values.
You can use gsap.fromTo(... or gsap.set(... before start your animation, after finish you can use gsap.set to reset value
Some examples
const animate = () => {
AutoKillTweens.kill(tweens);
tweens.ani1 = gsap.timeline();
// set width to 0% and animate to 100%
tweens.ani1.fromTo(boxRef.current, {style:{width:'0%'}}, {duration: 1, style: {width: '100%'}});
// set width to Number (Dimension screen) and animate to 300
tweens.ani1.fromTo(boxRef.current, {style: {width: Dimensions.get('window').width}}, {duration: 1, style: {width: 300}});
// another way to set values before an animation is using .set(), in this case we are resting width to auto
tweens.ani1.set(boxRef.current, {style: {width: 'auto'}});
// set width to 50% before starting next animation
tweens.ani1.set(boxRef.current, {style: {width: '50%'}, delay:1});
// animate to width of 90%
tweens.ani1.to(boxRef.current, {duration:1, style: {width: '90%'}, delay:1});
// reset width to auto
tweens.ani1.set(boxRef.current, {style: {width: 'auto'}});
// NO POSSIBLE: This will not animate because 'auto' is not a real value, so we have to figure out what auto meaning to perform the animation
tweens.ani1.fromTo(boxRef.current, {style:{width:100}}, {style: {width: 'auto'}});
};
I have found a way to animate the height without having to give a fixed value. This has the advantage that the animation does not jump!
const [bodyHeight, setBodyHeight] = useState(0);
useLayoutEffect(() => {
checkBodyHeight();
}, []);
const checkBodyHeight = () => {
setTimeout(() => {
animationViewRef.current?.measure((x, y, width, height, pageX, pageY) => {
if (height > 0) {
setBodyHeight(height);
}
})
}, 0)
}
const playOpenAnimation = () => {
animationTimeLine.set(animationViewRef.current, {
style: {
height: 0,
},
});
animationTimeLine.to(animationViewRef.current, {
style: {
height: bodyHeight,
opacity: 1
},
duration: 1,
ease: Power4.easeOut,
})
animationTimeLine.set(animationViewRef.current, {
style: {
height: 'auto'
},
onComplete: () => {
checkBodyHeight();
}
});
}
const playCloseAnimation = () => {
animationTimeLine.set(animationViewRef.current, {
style: {
height: bodyHeight,
},
});
animationTimeLine.to(animationViewRef.current, {
style: {
height: 0,
opacity: 0
},
duration: 1,
ease: Power4.easeOut,
})
}
{width: null} will not unset the width property, it works like "0".
If you set an element to Width 100% and later want to set it back to Width "auto", then unfortunately this is currently not possible.