Skip to content

Commit

Permalink
feat. Headspace Animation Play Button
Browse files Browse the repository at this point in the history
  • Loading branch information
devym-37 committed Nov 20, 2022
1 parent a9e681d commit f64123c
Show file tree
Hide file tree
Showing 15 changed files with 692 additions and 8 deletions.
16 changes: 14 additions & 2 deletions reanimatedRN/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,12 @@ import MaskedView from "./src/MaskedView";
import WaveView from "./src/WaveView";
import MomoHeader from "./src/MomoHeader";
import Chanel from "./src/ChanelScroll";
import { Headspace } from "./src/Headspace";
import { LoadAssets } from "./src/LoadAssets";

const Stack = createStackNavigator();
const fonts = {};
const assets: number[] = [];

const AppNavigator = () => (
<Stack.Navigator>
Expand Down Expand Up @@ -129,13 +133,21 @@ const AppNavigator = () => (
header: () => null,
}}
/>
<Stack.Screen
name='Headspace'
component={Headspace}
options={{
title: "Headspace",
headerShown: false,
}}
/>
</Stack.Navigator>
);

export default function App() {
return (
<NavigationContainer>
<LoadAssets assets={assets} fonts={fonts}>
<AppNavigator />
</NavigationContainer>
</LoadAssets>
);
}
7 changes: 6 additions & 1 deletion reanimatedRN/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,23 @@
"@react-native-community/masked-view": "^0.1.11",
"@react-navigation/native": "^6.0.13",
"@react-navigation/stack": "^6.3.2",
"@shopify/react-native-skia": "^0.1.159",
"alea": "^1.0.1",
"base-64": "^1.0.0",
"eslint": "^8.26.0",
"expo": "~46.0.16",
"expo-app-loading": "^2.1.0",
"expo-asset": "^8.6.1",
"expo-av": "^13.0.1",
"expo-constants": "^13.2.4",
"expo-font": "^10.2.1",
"expo-gl": "^11.4.0",
"expo-linear-gradient": "^11.4.0",
"expo-status-bar": "^1.4.0",
"expo-three": "^6.2.0",
"faker": "^6.6.6",
"flubber": "^0.4.2",
"moment": "^2.29.4",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-native": "0.70.3",
Expand All @@ -40,7 +45,7 @@
"react-native-web": "0.18.9",
"react-navigation-shared-element": "^3.1.3",
"react-three-fiber": "^6.0.13",
"three": "^0.145.0"
"simplex-noise": "^4.0.1"
},
"devDependencies": {
"@babel/core": "^7.19.6",
Expand Down
74 changes: 74 additions & 0 deletions reanimatedRN/src/Headspace/Background.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type { SkiaValue } from "@shopify/react-native-skia";
import {
Easing,
mix,
vec,
Path,
Skia,
Fill,
useComputedValue,
} from "@shopify/react-native-skia";
import React from "react";
import { Dimensions } from "react-native";

const { width, height } = Dimensions.get("window");
const c = vec(width / 2, height / 2);

const c1 = "#2ab8aa";
const c2 = "#3a9dbb";
const c3 = "#2a7fb8";
const easing = Easing.bezier(0.37, 0, 0.63, 1);
const getProgress = (t: number, durationInFrames = 4000) => {
const p = (t % durationInFrames) / durationInFrames;
const currentIteration = Math.floor(t / durationInFrames);
const isGoingBack = currentIteration % 2 === 0;
const progress = isGoingBack ? 1 - p : p;
return progress;
};

const getCurve = (start: number, h: number) => {
const path = Skia.Path.Make();
path.moveTo(0, start);
path.quadTo(width / 2, start - h, width, start);
path.lineTo(width, height);
path.lineTo(0, height);
path.close();
return path;
};

interface BackgroundProps {
clock: SkiaValue<number>;
}

export const Background = ({ clock }: BackgroundProps) => {
// getCurve(200, 50);
const p1 = useComputedValue(() => {
const progress = getProgress(clock.current, 4100);
return getCurve(
mix(easing(progress), c.y - 300, 200),
mix(easing(progress), 50, 60)
);
}, [clock]);
const p2 = useComputedValue(() => {
const progress = getProgress(clock.current);
return getCurve(
mix(easing(progress), c.y - 150, c.y),
mix(easing(progress), 40, 60)
);
}, [clock]);
const p3 = useComputedValue(() => {
const progress = getProgress(clock.current, 3800);
return getCurve(
mix(easing(progress), c.y + 75, c.y + 225),
mix(easing(progress), 30, 50)
);
}, [clock]);
return (
<>
<Fill color="#60d1b9" />
<Path path={p1} color={c1} />
<Path path={p2} color={c2} />
<Path path={p3} color={c3} />
</>
);
};
91 changes: 91 additions & 0 deletions reanimatedRN/src/Headspace/Headspace.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/* eslint-disable prettier/prettier */
import {
Path,
Skia,
useClockValue,
useComputedValue,
Canvas,
vec,
useTouchHandler,
useTiming,
useValueEffect,
useValue,
runTiming,
Easing,
} from "@shopify/react-native-skia";
import React, { useEffect, useState } from "react";
import { Dimensions } from "react-native";
import { createNoise2D } from "simplex-noise";
import { SafeAreaInsetsContext } from "react-native-safe-area-context";
import alea from "alea";

import { Play } from "./Play";
import { Background } from "./Background";
import { Overlay } from "./Overlay";
import { useContextBridge } from "./useContextBridge";

const C = 0.55228474983079;
const { width, height } = Dimensions.get("window");
const c = vec(width / 2, height / 2);
const r = 60;
const n1 = createNoise2D();
const n2 = createNoise2D();
const n3 = createNoise2D();
const n4 = createNoise2D();

export const Headspace = () => {
const clock = useClockValue();

const progress = useValue(0);
const ContextBridge = useContextBridge(SafeAreaInsetsContext);
const [toggled, setToggled] = useState(false);

const onTouch = useTouchHandler({
onEnd: () => {
setToggled((toggle) => !toggle);
},
});

useEffect(() => {
runTiming(progress, { to: toggled ? 1 : 0 }, { duration: 450, easing: Easing.inOut(Easing.ease) });

if (toggled) {
clock.start();
} else {
clock.stop();
}
}, [clock, progress, toggled]);

const path = useComputedValue(() => {
const A = r * 0.2;
const F = 0.0003;
const d1 = A * n1(clock.current * F, 0);
const d2 = A * n2(clock.current * F, 0);
const d3 = A * n3(clock.current * F, 0);
const d4 = A * n4(clock.current * F, 0);
const p = Skia.Path.Make();
p.moveTo(c.x, c.y - r);
p.cubicTo(c.x + r * C + d1, c.y - r, c.x + r, c.y - r * C - d1, c.x + r, c.y);
p.cubicTo(c.x + r, c.y + r * C + d2, c.x + r * C + d2, c.y + r, c.x, c.y + r);
p.cubicTo(c.x - r * C - d3, c.y + r, c.x - r, c.y + r * C + d3, c.x - r, c.y);
p.cubicTo(c.x - r, c.y - r * C - d4, c.x - r * C - d4, c.y - r, c.x, c.y - r);

const m = Skia.Matrix();
m.translate(c.x, c.y);
m.rotate(clock.current * F);
m.translate(-c.x, -c.y);
p.transform(m);
return p;
}, [clock]);

return (
<Canvas style={{ flex: 1 }} onTouch={onTouch}>
<ContextBridge>
<Background clock={clock} />
<Path path={path} color='#3B3A3A' />
<Play c={c} r={r} progress={progress} />
<Overlay />
</ContextBridge>
</Canvas>
);
};
Loading

0 comments on commit f64123c

Please sign in to comment.