Skip to content

Instantly share code, notes, and snippets.

@dohooo
Last active August 1, 2023 04:26
Show Gist options
  • Save dohooo/bfda3d320201eb54b42c04b681c26a89 to your computer and use it in GitHub Desktop.
Save dohooo/bfda3d320201eb54b42c04b681c26a89 to your computer and use it in GitHub Desktop.
import { useEffect, type FC } from "react";
import { Button, Dimensions, ScrollView, Text, View } from "react-native";
import type { SharedValue } from "react-native-reanimated";
import { Easing, Extrapolate, interpolate, useDerivedValue, useSharedValue, withDecay, withDelay, withRepeat, withTiming } from "react-native-reanimated";
import { SafeAreaView } from "react-native-safe-area-context";
import { Blur, Canvas, DisplacementMap, Fill, FractalNoise, Group, LinearGradient, Rect, RoundedRect, Shadow, Turbulence, Vertices, vec } from "@shopify/react-native-skia";
const { width } = Dimensions.get("window");
const posCount = 12;
const posGap = width / (posCount - 2);
const posArr = Array.from({ length: posCount }).map((_, i) => [i * posGap, 0]);
const height = width / 1.58;
const lineWidth = 20;
const AnimatedLine: FC<{
index: number
x: number
y: number
animVal: SharedValue<number>
}> = ({ index, x, y, animVal }) => {
const animatedGap = 50 / posCount;
const startInput = animatedGap * index;
const endInput = animatedGap * (index + 1);
const animatedX = useDerivedValue(() => {
return interpolate(
animVal.value,
[-100, -80, -50, -20, 0],
[x + 50, x + 50, x, x + 50, x + 50],
);
}, [x, animVal]);
const animatedOpacity = useDerivedValue(() => {
const animatedGap = 50 / posCount * 2;
const startInput = animatedGap * index;
const endInput = animatedGap * (index + 1);
return interpolate(
animVal.value,
[-endInput, -startInput, -startInput, -endInput],
[0.2, 1, 1, 0.2],
Extrapolate.CLAMP,
);
}, [x, animVal]);
const animatedWidth = useDerivedValue(() => {
const width = lineWidth + (posCount - index) - index * 1;
return interpolate(
animVal.value,
[-endInput, -startInput, -startInput, -endInput],
[width * 0.9, width, width, width * 0.9],
Extrapolate.CLAMP,
);
}, [x, animVal, index]);
return (
<Rect
x={animatedX}
y={y - (width / 2)}
width={animatedWidth}
height={width * 2}
opacity={animatedOpacity}
transform={[{ rotate: Math.PI / 12 + 1.2 * index / 40 }]}
>
<LinearGradient
start={vec(0, width)}
end={vec(width, 0)}
positions={[0, 0.5, 0.65, 0.7, 0.9, 1]}
colors={["#000", "rgba(15,104,82,1)", "rgba(15,104,82,1)", "#39738046", "#193355", "#193355"]}
/>
</Rect>
);
};
const AnimatedMask: FC<{
animVal: SharedValue<number>
}> = ({ animVal }) => {
const animatedBlur = useDerivedValue(() => {
return interpolate(
animVal.value,
[-100, -50, 0],
[5, 3, 5],
Extrapolate.CLAMP,
);
}, []);
return (
<Blur blur={animatedBlur} mode={"decal"}/>
);
};
const AnimationExample = () => {
const animVal = useSharedValue(0);
useEffect(() => {
animVal.value = withRepeat(
withTiming(
animVal.value > -50 ? -100 : 0,
{ duration: 10 * 1000, easing: Easing.linear },
), 0, true);
}, []);
return (
<ScrollView style={{ backgroundColor: "black", flex: 1 }}>
<Canvas style={{ width, height }}>
<Group>
<Rect x={0} y={0} width={width} height={width}>
<LinearGradient
start={vec(width, 0)}
end={vec(0, width)}
positions={[0, 0.4, 0.5, 0.9, 1]}
colors={["#193355", "#193355", "#397380", "#0F6852"]}
/>
</Rect>
{
posArr.map(([x, y], i) => (
<AnimatedLine
key={i}
x={x}
index={i}
animVal={animVal}
y={y - (width / 2)}
/>
))
}
<Vertices
vertices={[vec(width * 1.1, height * 0.15), vec(width * 1.1, height * 1.1), vec(-width * 0.1, height * 1.1)]}
colors={["#000000b2", "#000", "#000000b2"]}
>
<Shadow dx={-20} dy={-20} blur={30} color="#000" />
<Blur blur={10} />
</Vertices>
<Rect
x={0}
y={height * 0.6}
width={width * 0.25}
height={height * 0.4}
transform={[{ rotate: Math.PI / 12 }]}
color={"rgba(15,104,82,1)"}
>
<Shadow dx={-10} dy={-10} blur={20} color="#0000007d" />
<Blur blur={20} />
</Rect>
<AnimatedMask animVal={animVal}/>
</Group>
<Rect x={0} y={0} width={width} height={width}>
<Turbulence
freqX={2.3}
freqY={2.3}
octaves={1}
/>
</Rect>
<Rect
x={-20}
y={height - 20}
width={width}
height={20}
color={"black"}
>
<Blur blur={20} />
</Rect>
</Canvas>
<Text style={{ alignSelf: "center", marginTop: -28, paddingHorizontal: 12, color: "white", fontSize: 24, fontWeight: "700" }}>VA-11 Hall-A- 在赛博酒吧里寻求生机</Text>
</ScrollView>
);
};
export default AnimationExample;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment