react-native 踩坑
AI不会取代人类,被取代的是不会使用AI 的人
0%~100% 是动画运动的时长,通过约定多1/4的时间Y轴的位置,来控制动画的停留。
/* 通过间隔做 暂停 */
@keyframes ad_move {
0% {
transform: translateY(0px);
}
25%{
transform: translateY(0px);
}
50%{
transform: translateY(calc(var(--y)/2));
}
75%{
transform: translateY(calc(var(--y)/2));
}
100% {
transform: translateY(var(--y));
}
}
好消息是,写完啦。
坏消息是👇
那translate 总支持吧。
于是,我迅速安装了animejs,并自信的写了两种方式
animeRef.current = anime({
targets: el,
// translateY: [0, -2 * height],
translateY: [
{ value: 0, duration: 1000, delay: 750, easing: 'linear' },
{ value: -height, duration: 1000, delay: 1750, easing: 'linear' },
{ value: -2 * height, duration: 1000, delay: 2750, easing: 'linear' },
],
// keyframes: [
// { translateY: 0 },
// { translateY: 0 },
// { translateY: -height },
// { translateY: -height },
// { translateY: -2 * height }
// ],
duration: 8000,
loop: true,
easing: 'linear'
})
😭,结果被告知
Native 的组件(如 View、Text)并非 DOM 元素,且其样式系统与 Web 的 CSS 有本质差异。
Anime.js 是一个基于浏览器 DOM 和 CSS 的 Web 动画库
好吧,从控制台看,我看着是div呀。
😭,只得老老实实的使用 react-native-reanimated
,在短时间内实现我的需求,是有点费事儿的。
最近流行一句:不会被取代的人是,会使用AI的人。
于是,deepseek 两秒帮我写完了。
import { View, Text } from 'components/ui';
import React from 'react';
import { useEffect, useMemo } from 'react';
import { useWindowDimensions, ViewProps } from 'react-native';
import Animated, {
useSharedValue,
withTiming,
withDelay,
withSequence,
Easing,
withRepeat
} from 'react-native-reanimated';
const height = 64
const MyView = React.forwardRef(
(props: ViewProps, ref: React.LegacyRef<View>) => {
const { width } = useWindowDimensions();
const height = 64
return (
<View ref={ref} {...props}>
<View style={{ height: `${height}px` }} className='bg-pink-600 w-full'>
<Text>山上有樱名为良,树本无形只待春</Text>
</View>
<View style={{ height: `${height}px` }} className='bg-pink-200'>
<Text>山上有樱名为良,树本无形只待春</Text>
</View>
<View style={{ height: `${height}px` }} className='bg-pink-600'>
<Text>山上有樱名为良,树本无形只待春</Text>
</View>
<View style={{ height: `${height}px` }} className='bg-pink-200'>
<Text>山上有樱名为良,树本无形只待春</Text>
</View>
</View>
);
}
);
const AnimatedView = Animated.createAnimatedComponent(MyView);
export function Test2() {
const { width } = useWindowDimensions();
const sharedValue = useSharedValue(0);
useEffect(() => {
if (!height) return;
// 定义动画的总距离
const totalDistance = -2 * height;
// 定义每 1/2 的距离
const halfDistance = totalDistance / 2;
// 使用 withSequence 实现分段动画
const animation = withSequence(
// 暂停 2 秒
withDelay(2000, withTiming(0, { duration: 0 })), // 保持当前位置
// 第一段动画:运动 1/2
withTiming(halfDistance, {
duration: 2000, // 4 秒完成 1/2 的距离
easing: Easing.linear,
}),
// 暂停 2 秒
withDelay(2000, withTiming(halfDistance, { duration: 0 })), // 保持当前位置
// 第二段动画:运动剩余的 1/2
withTiming(totalDistance, {
duration: 2000, // 4 秒完成剩余的 1/2 的距离
easing: Easing.linear,
})
);
// 使用 withRepeat 实现循环
sharedValue.value = withRepeat(animation, -1, false);
}, [height, sharedValue]);
return (
<View className='w-full'>
<View style={{ height: `${height}px`, overflow: 'hidden' }} className='w-full'>
<AnimatedView style={{ transform: [{ translateY: sharedValue }] }} />
</View>
</View>
);
}