Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add svg icons example #1651

Merged
merged 3 commits into from
Jun 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions example/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ PODS:
- RNScreens (3.17.0):
- React-Core
- React-RCTImage
- RNSVG (13.9.0):
- React-Core
- SocketRocket (0.6.0)
- Yoga (1.14.0)
- YogaKit (1.18.1):
Expand Down Expand Up @@ -524,6 +526,7 @@ DEPENDENCIES:
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNSVG (from `../node_modules/react-native-svg`)
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`)

SPEC REPOS:
Expand Down Expand Up @@ -621,6 +624,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-reanimated"
RNScreens:
:path: "../node_modules/react-native-screens"
RNSVG:
:path: "../node_modules/react-native-svg"
Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga"

Expand Down Expand Up @@ -676,6 +681,7 @@ SPEC CHECKSUMS:
RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
RNReanimated: b1220a0e5168745283ff5d53bfc7d2144b2cee1b
RNScreens: 0df01424e9e0ed7827200d6ed1087ddd06c493f9
RNSVG: 53c661b76829783cdaf9b7a57258f3d3b4c28315
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
Yoga: d56980c8914db0b51692f55533409e844b66133c
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
Expand Down
2 changes: 2 additions & 0 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"android-reverse-tcp": "adb devices | grep '\t' | awk '{print $1}' | sed 's/\\s//g' | xargs -I {} adb -s {} reverse tcp:8081 tcp:8081"
},
"dependencies": {
"@react-navigation/bottom-tabs": "^6.5.7",
"@react-navigation/elements": "^1.3.6",
"@react-navigation/native": "6.0.13",
"@react-navigation/native-stack": "6.9.0",
Expand All @@ -32,6 +33,7 @@
"react-native-reanimated": "3.1.0",
"react-native-safe-area-context": "4.3.4",
"react-native-screens": "3.17.0",
"react-native-svg": "^13.9.0",
"react-native-web": "^0.18.0",
"simplex-noise": "^3.0.1"
},
Expand Down
27 changes: 27 additions & 0 deletions example/src/Examples/API/Icons/SvgIcons/GithubIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* eslint-disable max-len */
import * as React from "react";
import Svg, { Path } from "react-native-svg";
export const Github = () => (
<Svg width={48} height={48}>
<Path
fill="#fff"
d="M41 24c0 9.4-7.6 17-17 17S7 33.4 7 24 14.6 7 24 7s17 7.6 17 17z"
/>
<Path
fill="#455a64"
d="M21 41v-5.5c0-.3.2-.5.5-.5s.5.2.5.5V41h2v-6.5c0-.3.2-.5.5-.5s.5.2.5.5V41h2v-5.5c0-.3.2-.5.5-.5s.5.2.5.5V41h1.8c.2-.3.2-.6.2-1.1V36c0-2.2-1.9-5.2-4.3-5.2h-2.5c-2.3 0-4.3 3.1-4.3 5.2v3.9c0 .4.1.8.2 1.1H21zm19.1-14.6s-1.3-.4-2.4-.4h-.1c-1.1 0-2.9.3-2.9.3-.1 0-.1 0-.1-.1s0-.1.1-.1 2-.3 3.1-.3 2.4.4 2.5.4c.1 0 .1.1.1.2-.2-.1-.2 0-.3 0zm-.3.8s-1.4-.4-2.6-.4c-.9 0-3 .2-3.1.2-.1 0-.1 0-.1-.1s0-.1.1-.1 2.2-.2 3.1-.2c1.3 0 2.6.4 2.6.4.1 0 .1.1.1.2 0-.1 0 0-.1 0zm-32-.8c-.1 0-.1 0-.1-.1s0-.1.1-.2c.8-.2 2.4-.5 3.3-.5.8 0 3.5.2 3.6.2.1 0 .1.1.1.1 0 .1-.1.1-.1.1s-2.7-.2-3.5-.2c-1.1.2-2.6.4-3.4.6zm.4 1.5s-.1 0-.1-.1v-.2c.1 0 1.4-.8 2.9-1 1.3-.2 4 .1 4.2.1.1 0 .1.1.1.1 0 .1-.1.1-.1.1s-2.8-.3-4.1-.1c-1.5.3-2.9 1.1-2.9 1.1z"
/>
<Path
fill="#455a64"
d="M14.2 23.5c0-4.4 4.6-8.5 10.3-8.5 5.7 0 10.3 4 10.3 8.5S31.5 31 24.5 31s-10.3-3.1-10.3-7.5z"
/>
<Path
fill="#455a64"
d="M28.6 16.3s1.7-2.3 4.8-2.3c1.2 1.2.4 4.8 0 5.8l-4.8-3.5zm-8.2 0S18.7 14 15.6 14c-1.2 1.2-.4 4.8 0 5.8l4.8-3.5zm-.3 19.6h-2.8c-1.2 0-2.3-.5-2.8-1.5-.6-1.1-1.1-2.3-2.6-3.3-.3-.2-.1-.4.4-.4.5.1 1.4.2 2.1 1.1.7.9 1.5 2 2.8 2 1.3 0 2.7 0 3.5-.9l-.6 3z"
/>
<Path
fill="#00bcd4"
d="M24 4C13 4 4 13 4 24s9 20 20 20 20-9 20-20S35 4 24 4zm0 36c-8.8 0-16-7.2-16-16S15.2 8 24 8s16 7.2 16 16-7.2 16-16 16z"
/>
</Svg>
);
27 changes: 27 additions & 0 deletions example/src/Examples/API/Icons/SvgIcons/OctocatIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/* eslint-disable max-len */
import * as React from "react";
import Svg, { Path } from "react-native-svg";
export const Octocat = () => (
<Svg width={48} height={48}>
<Path
fill="#455A64"
d="M40.3 15.7c.6-1.7 1.2-5-.4-8.7-4.5 0-8.3 3.2-8.9 3.8-2.2-.5-4.6-.7-7-.7-2.5 0-4.9.3-7.2.8C13.7 7.7 9.6 7 8 7c0 0-.9 1.8-.9 5 0 2 .5 3.2.8 3.8C5.5 18.3 4 21.7 4 26.1c0 11.2 7.1 15 20 15s20-3.8 20-15c0-4.6-1.4-8-3.7-10.4z"
/>
<Path
fill="#FFCCBC"
d="M24 39c-8.2 0-15-1.4-15-9 0-2.9 1.6-4.5 2.7-5.5 2.5-2.2 6.7-1.2 12.3-1.2 4.1 0 7.6-.7 10.4.2 2.8.9 4.6 3.5 4.6 6.3 0 7.9-4 9.2-15 9.2z"
/>
<Path
fill="#D84315"
d="M25 34c0 .6-.4 1-1 1s-1-.4-1-1 .4-1 1-1 1 .4 1 1zm1.5 2.5c.2-.2.2-.5 0-.7s-.5-.2-.7 0c-.9.9-2.6.9-3.5 0-.2-.2-.5-.2-.7 0s-.2.5 0 .7c.7.7 1.5 1 2.5 1s1.7-.4 2.4-1z"
/>
<Path
fill="#FFF"
d="M19 29.5c0 2.5-1.3 4.5-3 4.5s-3-2-3-4.5 1.3-4.5 3-4.5 3 2 3 4.5zM32 25c-1.7 0-3 2-3 4.5s1.3 4.5 3 4.5 3-2 3-4.5-1.3-4.5-3-4.5z"
/>
<Path
fill="#6D4C41"
d="M34 30c0 1.7-.9 3-2 3s-2-1.3-2-3c0-.2 0-.5.1-.7.1.4.5.7.9.7.6 0 1-.4 1-1s-.4-1-1-1c-.2 0-.4.1-.6.2.4-.7.9-1.2 1.6-1.2 1.1 0 2 1.3 2 3zm-18-3c-.7 0-1.2.5-1.6 1.2.2-.1.4-.2.6-.2.6 0 1 .4 1 1s-.4 1-1 1c-.4 0-.8-.3-.9-.7 0 .2-.1.5-.1.7 0 1.7.9 3 2 3s2-1.3 2-3-.9-3-2-3z"
/>
</Svg>
);
20 changes: 20 additions & 0 deletions example/src/Examples/API/Icons/SvgIcons/StackExchangeIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import * as React from "react";
import Svg, { Path } from "react-native-svg";
export const StackExchange = () => (
<Svg width={48} height={48}>
<Path fill="#33afec" d="M6 13v7h25.2l6.4-7H6z" />
<Path fill="#0084d7" d="M6 22v7h17.1l6.3-7H6z" />
<Path fill="#0262b8" d="M6 31v2c0 3.3 2.7 6 6 6h2l7.3-8H6z" />
<Path fill="#0084d7" d="M42 13h-4.4l-6.4 7H42v-7z" />
<Path fill="#027ad4" d="M42 22H29.4l-6.3 7H42v-7z" />
<Path
fill="#0553a4"
d="M21.3 31 14 39h13v7l7-7h2c3.3 0 6-2.7 6-6v-2H21.3z"
/>
<Path fill="#33afec" d="M42 11V9c0-.3 0-.6-.1-.8L39.4 11H42z" />
<Path
fill="#54daff"
d="M36 3H12C8.7 3 6 5.7 6 9v2h33.4L42 8.2C41.5 5.3 39 3 36 3z"
/>
</Svg>
);
32 changes: 32 additions & 0 deletions example/src/Examples/API/Icons/SvgIcons/StackOverflowIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/* eslint-disable max-len */
import * as React from "react";
import Svg, { Path } from "react-native-svg";
export const StackOverflow = () => (
<Svg width={48} height={48}>
<Path
fill="#727d86"
d="M32 28.5V39H12V28.5a.5.5 0 0 0-.5-.5h-2a.5.5 0 0 0-.5.5V41a1 1 0 0 0 1 1h24a1 1 0 0 0 1-1V28.5a.5.5 0 0 0-.5-.5h-2a.5.5 0 0 0-.5.5z"
/>
<Path fill="#727d86" d="M15 34h14v3H15z" />
<Path
fill="#89776b"
d="M15.081 28.26 29 29.758l-.321 2.983-13.92-1.498.322-2.983z"
/>
<Path
fill="#e36001"
d="m36.871 6 2.133 13.835-2.966.457-2.133-13.835L36.871 6z"
/>
<Path
fill="#cc661c"
d="m28.47 8.237 6.831 12.218-2.619 1.465-6.831-12.219 2.619-1.464z"
/>
<Path
fill="#b66c36"
d="M20.501 14.551 32 22.533l-1.711 2.465-11.499-7.982 1.711-2.465z"
/>
<Path
fill="#9f7151"
d="m16.899 21.218 13.173 4.739-1.016 2.824-13.173-4.739 1.016-2.824z"
/>
</Svg>
);
137 changes: 137 additions & 0 deletions example/src/Examples/API/Icons/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React, { createContext, useContext, useMemo } from "react";
import { Text, View } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import type { SkPicture } from "@shopify/react-native-skia";
import {
Canvas,
Rect,
SkiaPictureView,
Skia,
useSVG,
} from "@shopify/react-native-skia";

import { Octocat } from "./SvgIcons/OctocatIcon";
import { StackExchange } from "./SvgIcons/StackExchangeIcon";
import { StackOverflow } from "./SvgIcons/StackOverflowIcon";
import { Github } from "./SvgIcons/GithubIcon";

const useSVGPicture = (module: number) => {
const svg = useSVG(module);
return useMemo(() => {
if (!svg) {
return null;
}
const recorder = Skia.PictureRecorder();
const canvas = recorder.beginRecording(Skia.XYWHRect(0, 0, 48, 48));
canvas.drawSvg(svg);
console.log("finishRecordingAsPicture");
return recorder.finishRecordingAsPicture();
}, [svg]);
};

const useLoadSVGs = () => {
const github = useSVGPicture(require("../../../assets/icons8-github.svg"));
const octocat = useSVGPicture(require("../../../assets/icons8-octocat.svg"));
const stackExchange = useSVGPicture(
require("../../../assets/icons8-stack-exchange.svg")
);
const overflow = useSVGPicture(
require("../../../assets/icons8-stack-overflow.svg")
);
if (github && octocat && stackExchange && overflow) {
return {
github,
octocat,
stackExchange,
overflow,
};
} else {
return null;
}
};

interface SVGAssets {
github: SkPicture;
octocat: SkPicture;
stackExchange: SkPicture;
overflow: SkPicture;
}

const SVGContext = createContext<SVGAssets | null>(null);

const useSVGs = () => {
const svgs = useContext(SVGContext);
if (!svgs) {
throw new Error("No SVGs available");
}
return svgs;
};

interface IconProps {
icon: SkPicture;
size?: number;
}

const style = { width: 48, height: 48 };

const Icon = ({ icon }: IconProps) => {
return <SkiaPictureView picture={icon} style={style} />;
};

const Screen = () => {
const { github, octocat, stackExchange, overflow } = useSVGs();
return (
<View
style={{
flex: 1,
flexDirection: "row",
alignItems: "center",
backgroundColor: "#EFFFE0",
}}
>
<View style={{ flex: 1, alignItems: "center" }}>
<Text>React Native Skia Picture</Text>
<Icon icon={github} />
<Icon icon={octocat} />
<Icon icon={stackExchange} />
<Icon icon={overflow} />
<Text>React Native Skia Canvas</Text>
<Canvas style={{ width: 50, height: 50 }}>
<Rect x={0} y={0} width={50} height={50} color="red" />
</Canvas>
<Text>React Native View</Text>
<View style={{ backgroundColor: "orange", width: 50, height: 50 }} />
</View>
<View style={{ flex: 1, alignItems: "center" }}>
<Text>React Native SVG</Text>
<Github />
<Octocat />
<StackExchange />
<StackOverflow />
<Text>React Native View</Text>
<View style={{ backgroundColor: "orange", width: 50, height: 50 }} />
</View>
</View>
);
};

const HomeScreen = () => <Screen />;

const SettingsScreen = () => <Screen />;

const Tab = createBottomTabNavigator();

export const IconsExample = () => {
const assets = useLoadSVGs();
if (!assets) {
return null;
}
return (
<SVGContext.Provider value={assets}>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Settings" component={SettingsScreen} />
</Tab.Navigator>
</SVGContext.Provider>
);
};
4 changes: 4 additions & 0 deletions example/src/Examples/API/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ export const examples = [
screen: "PathEffect",
title: "⭐️ Path Effect",
},
{
screen: "IconsExample",
title: "📱 Icons",
},
{
screen: "Transform",
title: "🔄 Transformations",
Expand Down
1 change: 1 addition & 0 deletions example/src/Examples/API/Routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ export type Routes = {
PictureView: undefined;
OnLayout: undefined;
Snapshot: undefined;
IconsExample: undefined;
};
8 changes: 8 additions & 0 deletions example/src/Examples/API/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { Touch } from "./Touch";
import { PictureViewExample } from "./PictureView";
import { OnLayoutDemo } from "./OnLayout";
import { Snapshot } from "./Snapshot";
import { IconsExample } from "./Icons";

const Stack = createNativeStackNavigator<Routes>();
export const API = () => {
Expand Down Expand Up @@ -56,6 +57,13 @@ export const API = () => {
title: "📺 View Snapshot",
}}
/>
<Stack.Screen
name="IconsExample"
component={IconsExample}
options={{
title: "📱 Icons",
}}
/>
<Stack.Screen
name="ColorFilter"
component={ColorFilter}
Expand Down
1 change: 1 addition & 0 deletions example/src/assets/icons8-github.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions example/src/assets/icons8-octocat.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions example/src/assets/icons8-stack-exchange.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions example/src/assets/icons8-stack-overflow.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions example/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export type StackParamList = {
Animation: undefined;
Reanimated: undefined;
Performance: undefined;
SVGComparison: undefined;
};