
Security News
Feross on TBPN: How North Korea Hijacked Axios
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.
@benjeau/react-native-draw
Advanced tools
Cross-platform React Native drawing component based on SVG
npm install @benjeau/react-native-draw
# or
yarn add @benjeau/react-native-draw
Also, you need to install react-native-gesture-handler and react-native-svg, and follow their installation instructions.
Supporting components, such as CanvasControls, ColorPicker and BrushProperties components, are available as a separate package, @benjeau/react-native-draw-extras
All the following examples are also available in the example Expo application
Here's the most simple example:
import React from 'react';
import { Canvas } from '@benjeau/react-native-draw';
export default () => <Canvas />;
Here's a more complex example:
import React, { useRef } from 'react';
import { Button } from 'react-native';
import { Canvas, CanvasRef } from '@benjeau/react-native-draw';
export default () => {
const canvasRef = useRef<CanvasRef>(null);
const handleUndo = () => {
canvasRef.current?.undo();
};
const handleClear = () => {
canvasRef.current?.clear();
};
return (
<>
<Canvas
ref={canvasRef}
height={600}
color="red"
thickness={20}
opacity={0.6}
style={{ backgroundColor: 'black' }}
/>
<Button title="Undo" onPress={handleUndo} />
<Button title="Clear" onPress={handleClear} />
</>
);
};
@BenJeau/react-native-draw-extrasThis uses the @benjeau/react-native-draw-extras npm package for the color picker and the bottom buttons/brush preview.
As this package does not depend on
@BenJeau/react-native-draw-extras, it is completely optional and you can build your own supporting UI, just like the previous example
import React, { useRef, useState } from 'react';
import { Animated, StyleSheet, View } from 'react-native';
import {
BrushProperties,
Canvas,
CanvasControls,
CanvasRef,
DEFAULT_COLORS,
DrawingTool,
} from '@benjeau/react-native-draw';
export default () => {
const canvasRef = useRef<CanvasRef>(null);
const [color, setColor] = useState(DEFAULT_COLORS[0][0][0]);
const [thickness, setThickness] = useState(5);
const [opacity, setOpacity] = useState(1);
const [tool, setTool] = useState(DrawingTool.Brush);
const [visibleBrushProperties, setVisibleBrushProperties] = useState(false);
const handleUndo = () => {
canvasRef.current?.undo();
};
const handleClear = () => {
canvasRef.current?.clear();
};
const handleToggleEraser = () => {
setTool((prev) =>
prev === DrawingTool.Brush ? DrawingTool.Eraser : DrawingTool.Brush
);
};
const [overlayOpacity] = useState(new Animated.Value(0));
const handleToggleBrushProperties = () => {
if (!visibleBrushProperties) {
setVisibleBrushProperties(true);
Animated.timing(overlayOpacity, {
toValue: 1,
duration: 200,
useNativeDriver: true,
}).start();
} else {
Animated.timing(overlayOpacity, {
toValue: 0,
duration: 200,
useNativeDriver: true,
}).start(() => {
setVisibleBrushProperties(false);
});
}
};
return (
<>
<Canvas
ref={canvasRef}
height={600}
color={color}
thickness={thickness}
opacity={opacity}
tool={tool}
style={{
borderBottomWidth: StyleSheet.hairlineWidth,
borderColor: '#ccc',
}}
/>
<View>
<CanvasControls
onUndo={handleUndo}
onClear={handleClear}
onToggleEraser={handleToggleEraser}
onToggleBrushProperties={handleToggleBrushProperties}
tool={tool}
color={color}
opacity={opacity}
thickness={thickness}
/>
{visibleBrushProperties && (
<BrushProperties
color={color}
thickness={thickness}
opacity={opacity}
onColorChange={setColor}
onThicknessChange={setThickness}
onOpacityChange={setOpacity}
style={{
position: 'absolute',
bottom: 80,
left: 0,
right: 0,
padding: 10,
backgroundColor: '#f2f2f2',
borderTopEndRadius: 10,
borderTopStartRadius: 10,
borderWidth: StyleSheet.hairlineWidth,
borderBottomWidth: 0,
borderTopColor: '#ccc',
opacity: overlayOpacity,
}}
/>
)}
</View>
</>
);
};
| name | description | type | default |
|---|---|---|---|
color | Color of the brush strokes | string | - (required) |
thickness | Thickness of the brush strokes | number | - (required) |
opacity | Opacity of the brush strokes | number | - (required) |
initialPaths | Paths to be already drawn | PathType[] | [] |
height | Height of the canvas | number | height of the window - 80 |
width | Width of the canvas | number | width of the window |
style | Override the style of the container of the canvas | StyleProp | - |
onPathsChange | Callback function when paths change | (paths: PathType[]) => any | - |
simplifyOptions | SVG simplification options | SimplifyOptions | see below |
eraserSize | Width of eraser (to compensate for path simplification) | number | 5 |
tool | Initial tool of the canvas | brush or eraser | brush |
combineWithLatestPath | Combine current path with the last path if it's the same color, thickness, and opacity | boolean | false |
enabled | Allows for the canvas to be drawn on, put to false if you want to disable/lock the canvas | boolean | true |
| name | description | type | default |
|---|---|---|---|
simplifyPaths | Enable SVG path simplification on paths, except the one currently being drawn | boolean | true |
simplifyCurrentPath | Enable SVG path simplification on the stroke being drawn | boolean | false |
amount | Amount of simplification to apply | number | 10 |
roundPoints | Ignore fractional part in the points. Improves performance | boolean | true |
| name | description | type |
|---|---|---|
undo | Undo last brush stroke | () => void |
clear | Removes all brush strokes | () => void |
getPaths | Get brush strokes data | () => PathType[] |
addPath | Append a path to the current drawing paths | (path: PathType) => void |
getSvg | Get SVG path string of the drawing | () => string |
If you cannot draw on the canvas, make sure you have followed the extra steps of react-native-gesture-handler
createSVGPath() is available to create the string representation of an SVG path.See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
FAQs
Cross-platform React Native drawing component
The npm package @benjeau/react-native-draw receives a total of 414 weekly downloads. As such, @benjeau/react-native-draw popularity was classified as not popular.
We found that @benjeau/react-native-draw demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.

Security News
OpenSSF has issued a high-severity advisory warning open source developers of an active Slack-based campaign using impersonation to deliver malware.

Research
/Security News
Malicious packages published to npm, PyPI, Go Modules, crates.io, and Packagist impersonate developer tooling to fetch staged malware, steal credentials and wallets, and enable remote access.