Created
January 24, 2023 20:40
-
-
Save RaphBlanchet/4598ef4ff0ec43df79246755c169580a to your computer and use it in GitHub Desktop.
React-Native Skewed Background using react-native-svg
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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