Skip to content

Instantly share code, notes, and snippets.

@RaphBlanchet
Created January 24, 2023 20:40
Show Gist options
  • Save RaphBlanchet/4598ef4ff0ec43df79246755c169580a to your computer and use it in GitHub Desktop.
Save RaphBlanchet/4598ef4ff0ec43df79246755c169580a to your computer and use it in GitHub Desktop.
React-Native Skewed Background using react-native-svg
type Props = {
targetSize: [number, number];
color?: string;
angle?: number;
style?: ViewStyle;
};
const SkewedBackground: React.FC<Props> = ({
targetSize,
color: _color,
angle: _angle,
style: _style,
}) => {
const color = _color ?? //Define a default color;
const angle = _angle ?? // Define a default angle;
const [targetWidth, targetHeight] = targetSize;
// This is the offset on the X axis of the top left corner
// compared to the bottom left corner
const xTranslation = targetHeight / Math.tan((90 - angle) * (Math.PI / 180));
const totalWidth = targetWidth + xTranslation;
const style: ViewStyle = {
position: "absolute",
top: 0,
left: -(xTranslation / 2),
width: totalWidth,
height: targetHeight,
..._style,
};
return (
<Svg
width={totalWidth}
height={targetHeight}
viewBox={`0 0 ${totalWidth} ${targetHeight}`}
style={style}>
<Path
d={`M${xTranslation} 0 0 ${targetHeight}h${targetWidth}l${xTranslation}-${targetHeight}z`}
fill={color}
/>
</Svg>
);
};
SkewedBackground.defaultProps = {
color: undefined,
angle: 15,
style: undefined,
};
export default SkewedBackground;
type SkewedViewProps = ViewProps & {
color?: string;
angle?: number;
backgroundStyle?: ViewStyle;
};
export const SkewedBackgroundView: React.FC<SkewedViewProps> = ({
color,
angle,
backgroundStyle,
children,
...props
}) => {
// useComponentSize() is a custom hook I made to ease the `onLayout` usage
const [size, onLayout] = useComponentSize();
return (
<View {...props} onLayout={onLayout}>
<SkewedBackground targetSize={size} angle={angle} color={color} style={backgroundStyle} />
{children}
</View>
);
};
SkewedBackgroundView.defaultProps = {
color: undefined,
angle: undefined,
backgroundStyle: undefined,
};
import { useState } from "react";
import { LayoutChangeEvent } from "react-native";
type Size = [number, number];
export function useComponentSize(): [Size, (layout: LayoutChangeEvent) => void] {
const [layoutSize, setLayoutSize] = useState<Size>([0, 0]);
const onLayout = (layout: LayoutChangeEvent) => {
setLayoutSize([layout.nativeEvent.layout.width, layout.nativeEvent.layout.height]);
};
return [layoutSize, onLayout];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment