基于React Native Animated API实现缩放时View/Text左对齐的问题咨询
解决方案
方案1:使用transformOrigin属性(推荐,RN 0.62+ 支持)
React Native 从0.62版本开始支持transformOrigin样式属性,可以直接指定变换的原点,你只需要给执行缩放的Animated.View新增该属性,将原点设置为左侧即可,无需额外计算偏移量。
修改后的核心代码如下:
<Animated.View style={{ transform: [ { scale: scale.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5], }), }, ], transformOrigin: 'left', // 新增这一行,指定变换原点为左侧 backgroundColor: 'yellow', }} onLayout={(e) => console.log({ view: e.nativeEvent.layout })}> <Text onLayout={(e) => console.log({ text: e.nativeEvent.layout })}> Label </Text> </Animated.View>
这个方案实现最简单,性能也和原来的动画一致,支持原生驱动。
方案2:旧版本RN兼容方案(手动偏移补偿)
如果你的项目RN版本低于0.62不支持transformOrigin,可以通过提前获取标签初始宽度,手动添加横向偏移补偿的方式实现左对齐:
- 新增state存储标签的初始宽度
- 在
onLayout回调中获取初始宽度并保存 - 在transform中新增
translateX的插值计算,抵消缩放带来的左侧偏移
完整代码如下:
import React from 'react'; import { View, Text, TextInput, Animated } from 'react-native'; export const F = (): JSX.Element => { const scale = React.useRef(new Animated.Value(0.0)).current; const [labelWidth, setLabelWidth] = React.useState(0); React.useEffect(() => { const animation = Animated.timing(scale, { toValue: 1.0, duration: 1000, useNativeDriver: true, }); animation.start(); }, []); return ( <View style={{ backgroundColor: 'red' }}> <Animated.View style={{ transform: [ { scale: scale.interpolate({ inputRange: [0, 1], outputRange: [1, 0.5], }), }, { // 偏移量计算公式:初始宽度 * (1 - 缩放比例) / 2 translateX: scale.interpolate({ inputRange: [0, 1], outputRange: [0, -labelWidth * (1 - 0.5) / 2], }) } ], backgroundColor: 'yellow', }} onLayout={(e) => { // 只需要获取一次初始宽度即可,无需动画过程中更新 if (labelWidth === 0) { setLabelWidth(e.nativeEvent.layout.width); } }}> <Text onLayout={(e) => console.log({ text: e.nativeEvent.layout })}> Label </Text> </Animated.View> <TextInput style={{ backgroundColor: 'blue' }} /> </View> ); };
这个方案的原理是:默认以中心为原点缩放时,视图缩小后左侧会多出初始宽度*(1-缩放比例)/2的空白,我们通过向左平移同等距离抵消这个空白,就能保持全程左对齐。
内容的提问来源于stack exchange,提问作者Bertrand Caron
相关产品推荐
相关产品推荐

