react native reanimated动画文本样式

umuewwlo  于 2023-06-24  发布在  React
关注(0)|答案(2)|浏览(88)

因此,我正在熟悉reanimated 2,为此我正在构建一个简单的todo应用程序,因此每当我检查单个todo(一个简单的切换状态,完成或!完成),我改变文本样式为line-through,使它看起来完成,现在为了添加一些动画,我试图合并reanimated到它,但不成功,所以有人能指导我如何实现我想要的吗?

const TodoItem = ({ todo }) => {
  const { toggleTodo } = useTodoStore((state) => state);
  const progress = useSharedValue('none');

  useEffect(() => {
    progress.value = withTiming(todo.completed ? 'line-through' : 'none', {
        duration: 1000,
        easing: Easing.linear,
    })
  }, [todo.completed]);

  const textReanimatedStyle = useAnimatedStyle(() => ({
    textDecorationLine: progress.value, // ts error: Type 'string' is not assignable to type 'number | "none" | "underline" | "line-through" | "underline line-through" | undefined'.
  }), []);

  const toggleTodoHandler = () => {
    toggleTodo(todo.id);
  };

  return (
    <Animated.View
      style={styles.container}
      entering={FadeIn}
      exiting={FadeOut}
      layout={Layout.delay(300)}>
      <View style={styles.innerContainer}>
        <TouchableOpacity
          style={styles.checkboxContainer}
          activeOpacity={0.6}
          onPress={toggleTodoHandler}>
          {todo.completed ? (
            <Ionicon name="checkmark" size={20} color={'gray'} />
          ) : null}
        </TouchableOpacity>
        <Animated.Text
          numberOfLines={2}
          style={[
            styles.text,
            textReanimatedStyle,
          ]}>
          {todo.text}
        </Animated.Text>
      </View>
    </Animated.View>
  );
};

现在,每当我切换完成或不,它抛出错误说:

Invalid RCTTextDecorationLineType 'noneNaN'. should be one of: (
  "line-through",
  none,
  underline,
  "underline line-through"
)
sqougxex

sqougxex1#

我不确定这是你想要的。但我所做的是可以处理状态变化也没有复活。
还有一种替代方法。检查此答案https://stackoverflow.com/a/65262789/8743951

const textState = useSharedValue('none');
  const [todo, setTodo] = useState<{ text: string; completed: boolean }>({ text: 'complete this', completed: false });

  const textReanimatedStyle = useAnimatedStyle(() => {
    if (textState.value === 'checked') {
      return {
        textDecorationLine: 'line-through',
      };
    }

    return {
      textDecorationLine: 'none',
    };
  }, []);

  const toggleTodoHandler = (): void => {
    textState.value = todo.completed ? 'none' : 'checked';
    setTodo({ ...todo, completed: !todo.completed });
  };

  return (
    <Animated.View style={styles.container} entering={FadeIn} exiting={FadeOut} layout={Layout.delay(300)}>
      <View style={styles.innerContainer}>
        <TouchableOpacity style={styles.checkboxContainer} activeOpacity={0.6} onPress={toggleTodoHandler}>
          {todo.completed ? <Ionicon name="checkmark" size={20} color="gray" /> : null}
        </TouchableOpacity>
        <Animated.Text numberOfLines={2} style={[styles.text, textReanimatedStyle]}>
          {todo.text}
        </Animated.Text>
      </View>
    </Animated.View>
  );
myzjeezk

myzjeezk2#

一般来说,一个概念存在问题。动画不断改变值,所以基本上它不能将none更改为line-through,因为之间没有值。动画是做什么的?例如,您需要将Y位置从0更改为200。仅将最终Y动画位置设置为200,库将开始为您取景。因此,它会根据您的帧速率(和其他设置,如定时曲线)从0到200连续更改位置,以获得平滑的动画。因此,它将以某种方式(例如)进行更改:0, 1, 2, 3, 4 ... 200。但它不能连续改变一个非数值。

相关问题