Skip to content
This repository was archived by the owner on Aug 12, 2021. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ Here are the `props` of the the component:
| ---- | ---- | ------------- | ---- |
| `fillColor` | `String` | `null` | The color of the sketch background. Default to null to keep it transparent! *Note: This is different from the `style.backgroundColor` property, as the former will be seen in your exported drawing image, whereas the latter is only used to style the view.* |
| `imageType` | `String` | `png` | The type of image to export. Can be `png` or `jpg`. Default to `png` to get transparency out of the box. |
| `imageData` | `String` | `null` | PNG/JPEG image intepretation encoded with base64 to render on the drawing canvas. |
| `onChange` | `Function` | `() => {}` | Callback function triggered after every change on the drawing. The function takes one argument: the actual base64 representation of your drawing.|
| `onClear` | `Function` | `() => {}` | Callback function triggered after a `clear` has been triggered. |
| `strokeColor` | `String` | `'#000000'` | The stroke color you want to draw with. |
Expand All @@ -80,6 +81,12 @@ The component also has some instance methods:
| `clear()` | `Promise` | Clear the drawing. This method is a Promise mostly to be consistent with `save()`, but you could simply type: `this.sketch.clear();` |
| `save()` | `Promise` | Save the drawing to an image, using the defined props as settings (`imageType`, `fillColor`, etc...). The Promise resolves with an object containing the `path` property of that image. Ex: `this.sketch.save().then(image => console.log(image.path));` |

Here are a few static helper functions for the component:

| Name | Return type | Comment |
| ---- | ----------- | ------- |
| `getImageDataFromFilePath` | `Promise` | Reads a JPEG or PNG file into base64 image data that can be rendered using the `imageData` prop. |

## Examples

The project contains a folder `examples` that contains few demos of how to use `react-native-sketch`. Just copy and paste the code to your React Native application.
Expand Down
1 change: 1 addition & 0 deletions RNSketch/RNSketch.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@
@property (nonatomic, strong) NSString *imageType;
@property (nonatomic, strong) UIColor *strokeColor;
@property (nonatomic, assign) NSInteger strokeThickness;
@property (nonatomic, strong) NSURL *imageData;

@end
10 changes: 9 additions & 1 deletion RNSketch/RNSketch.m
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ - (void)drawCurve

- (void)drawBitmap
{
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0);
UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, UIViewContentModeScaleAspectFit);

// Paint background if fillColor property provided
if (!_image && _fillColor) {
Expand Down Expand Up @@ -192,6 +192,14 @@ - (void)setStrokeColor:(UIColor *)strokeColor
_strokeColor = strokeColor;
}

- (void)setImageData:(NSURL *)imageURLData
{
NSData *imageData = [NSData dataWithContentsOfURL:imageURLData];
_image = [UIImage imageWithData:imageData];
[self drawBitmap];
[self setNeedsDisplay];
}

- (void)setStrokeThickness:(NSInteger)strokeThickness
{
_path.lineWidth = strokeThickness;
Expand Down
1 change: 1 addition & 0 deletions RNSketch/RNSketchManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ @implementation RNSketchManager
RCT_EXPORT_VIEW_PROPERTY(imageType, NSString);
RCT_EXPORT_VIEW_PROPERTY(strokeColor, UIColor);
RCT_EXPORT_VIEW_PROPERTY(strokeThickness, NSInteger);
RCT_EXPORT_VIEW_PROPERTY(imageData, NSURL);

#pragma mark - Lifecycle

Expand Down
37 changes: 33 additions & 4 deletions index.ios.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { NativeModules, requireNativeComponent, View, ViewPropTypes } from 'react-native';
import RNFS from 'react-native-fs';

const SketchManager = NativeModules.RNSketchManager || {};

Expand All @@ -15,6 +16,7 @@ export default class Sketch extends React.Component {
onClear: PropTypes.func,
strokeColor: PropTypes.string,
strokeThickness: PropTypes.number,
imageData: PropTypes.string,
style: viewPropTypes.style,
};

Expand All @@ -25,9 +27,29 @@ export default class Sketch extends React.Component {
onClear: () => {},
strokeColor: '#000000',
strokeThickness: 1,
style: null,
imageData: null,
style: null
};

static getImageDataFromFilePath(filePath) {
const formats = {
"jpg": "image/jpg",
"jpeg": "image/jpg",
"png": "image/png"
}
const fileExtension = filePath.split('.').pop();
const format = formats[fileExtension];

if (!format) {
throw new Error(`Unable to parse file extension .${fileExtension}`)
}

return RNFS.readFile(filePath.path, 'base64')
.then((base64) => {
return `data:${format};base64,${base64}`;
})
}

constructor(props) {
super(props);

Expand All @@ -36,11 +58,17 @@ export default class Sketch extends React.Component {
flex: 1,
backgroundColor: 'transparent',
};

this.state = {
imageData: props.imageData
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found an issue where if the prop is undefined here, removing one <Sketch from the DOM and then rendering a new one later will cause the sketch to contain the old drawing. Adding || null to this initial state causes the issue to go away--RCT will pass the null value inward as nil, but won't pass undefined as a nil to ObjC.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • done by fixing defaultProps

}
}

state = {
imageData: null,
};
componentWillReceiveProps(nextProps) {
this.setState({
imageData: nextProps.imageData
})
}

onChange = (event) => {
const { imageData } = event.nativeEvent;
Expand Down Expand Up @@ -74,6 +102,7 @@ export default class Sketch extends React.Component {
strokeColor={strokeColor}
strokeThickness={strokeThickness}
style={[this.style, this.props.style]}
imageData={this.state.imageData}
/>
);
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
"description": "A react-native component for touch-based drawing",
"main": "index.ios.js",
"dependencies": {
"prop-types": "^15.5.10"
"prop-types": "^15.5.10",
"react-native-fs": "^2.10.14"
},
"devDependencies": {
"babel-eslint": "^7.2.3",
Expand Down