New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@benjeau/react-native-draw

Package Overview
Dependencies
Maintainers
1
Versions
16
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@benjeau/react-native-draw

Cross-platform React Native drawing component

latest
Source
npmnpm
Version
0.8.3
Version published
Weekly downloads
475
7.71%
Maintainers
1
Weekly downloads
 
Created
Source

@benjeau/react-native-draw

NPM badge CircleCI Status Platform badge

Cross-platform React Native drawing component based on SVG

Installation

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.

Extras

Supporting components, such as CanvasControls, ColorPicker and BrushProperties components, are available as a separate package, @benjeau/react-native-draw-extras

Usage

All the following examples are also available in the example Expo application

Simple example

Here's the most simple example:

import React from 'react';
import { Canvas } from '@benjeau/react-native-draw';

export default () => <Canvas />;

https://user-images.githubusercontent.com/22248828/152838002-3bf01ff0-8c8d-43ec-abdf-4f856d200bc5.mp4

Complex example

Here's a more complex example:

Complex example - Code snippet
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} />
    </>
  );
};

https://user-images.githubusercontent.com/22248828/152837975-a51bdcf5-9a62-4aa2-8e5e-26c1d52fcf79.mp4

Example with @BenJeau/react-native-draw-extras

This 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

Extras example - Code snippet
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>
    </>
  );
};

https://user-images.githubusercontent.com/22248828/152837922-757d3a13-1d35-409a-936a-b38ea9248262.mp4

Props

Canvas

namedescriptiontypedefault
colorColor of the brush strokesstring- (required)
thicknessThickness of the brush strokesnumber- (required)
opacityOpacity of the brush strokesnumber- (required)
initialPathsPaths to be already drawnPathType[][]
heightHeight of the canvasnumberheight of the window - 80
widthWidth of the canvasnumberwidth of the window
styleOverride the style of the container of the canvasStyleProp-
onPathsChangeCallback function when paths change(paths: PathType[]) => any-
simplifyOptionsSVG simplification optionsSimplifyOptionssee below
eraserSizeWidth of eraser (to compensate for path simplification)number5
toolInitial tool of the canvasbrush or eraserbrush
combineWithLatestPathCombine current path with the last path if it's the same color, thickness, and opacitybooleanfalse
enabledAllows for the canvas to be drawn on, put to false if you want to disable/lock the canvasbooleantrue

SimplifyOptions

namedescriptiontypedefault
simplifyPathsEnable SVG path simplification on paths, except the one currently being drawnbooleantrue
simplifyCurrentPathEnable SVG path simplification on the stroke being drawnbooleanfalse
amountAmount of simplification to applynumber10
roundPointsIgnore fractional part in the points. Improves performancebooleantrue

Ref functions

namedescriptiontype
undoUndo last brush stroke() => void
clearRemoves all brush strokes() => void
getPathsGet brush strokes data() => PathType[]
addPathAppend a path to the current drawing paths(path: PathType) => void
getSvgGet SVG path string of the drawing() => string

Troubleshooting

If you cannot draw on the canvas, make sure you have followed the extra steps of react-native-gesture-handler

Helper functions

  • If you need to create an SVG path, createSVGPath() is available to create the string representation of an SVG path.

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT

Keywords

react-native-component

FAQs

Package last updated on 18 May 2022

Did you know?

Socket

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.

Install

Related posts