ReScript bindings for
@react-native-community/image-editor.
Exposed as ReactNativeImageEditor module.
@rescript-react-native/image-editor X.y.* means it's compatible with
@react-native-community/image-editor X.y.*
When
@react-native-community/image-editor
is properly installed & configured by following their installation instructions,
you can install the bindings:
npm install @rescript-react-native/image-editor
# or
yarn add @rescript-react-native/image-editor@rescript-react-native/image-editor should be added to bs-dependencies in your
bsconfig.json:
{
//...
"bs-dependencies": [
"@rescript/react",
"rescript-react-native",
// ...
+ "@rescript-react-native/image-editor"
],
//...
}cropImage takes arguments of type source and cropData and, if the image is
successfully cropped, returns path of the resulting image as a string, wrapped
in a Promise. If a remote image cannot be downloaded or an image cannot be
cropped, the Promise will be rejected.
cropImage: (source, cropData) => Js.Promise.t(string)To convert a ReactNative.Packager.required object into source.
fromRequired: ReactNative.Packager.required => sourceTo convert a URI given as a string into source.
fromUriSource: string => sourceAn abstract type created using the fromRequired and
fromUriSource methods.
An abstract type created using the constructor of the same name which takes
named arguments x and y of type int.
offset: (~x: int, ~y: int) => offsetAn abstract type created using the constructor of the same name which takes
named arguments width and height of type int.
size: (~width: int, ~height: int) => sizeAn abstract type created using the constructor of the same name which takes
named arguments offset (of type offset) and size (of type size) and
optional arguments displaySize (of type size) and resizeMode (one of
polymorphic variants `contain, `cover, `stretch).
cropData: (
~offset: offset,
~size: size,
~displaySize: size=?,
~resizeMode=[ | `contain | `cover | `stretch]=?,
unit
) => cropDataopen ReactNative;
// hardcoding actual image dimensions
let imageWidth = 3396.;
let imageHeight = 2388.;
let windowWidth = Dimensions.get(`window)##width;
let windowHeight = Dimensions.get(`window)##height;
let displayWidth = windowWidth *. 0.9;
let displayHeight = windowWidth *. 0.9 *. imageHeight /. imageWidth;
let styles =
Style.(
StyleSheet.create({
"container":
style(
~width=windowWidth->dp,
~height=windowHeight->dp,
~flexDirection=`column,
~alignItems=`center,
~justifyContent=`center,
(),
),
"frame":
style(
~width=displayWidth->dp,
~height=displayHeight->dp,
~alignItems=`center,
~justifyContent=`center,
~borderWidth=StyleSheet.hairlineWidth,
(),
),
})
);
type state = {
path: option(string),
imageLoaded: bool,
};
type action =
| SetPath(option(string))
| SetImageLoaded;
let imageUri = "https://images.unsplash.com/photo-1520453803296-c39eabe2dab4";
let uri = ReactNativeImageEditor.fromUriSource(imageUri);
let handleCropImage = (cropData, send, handler) =>
Js.Promise.(
ReactNativeImageEditor.cropImage(uri, cropData)
|> then_(successURI => resolve(send(handler(successURI))))
|> catch(err => resolve(Js.Console.warn(err)))
|> ignore
);
[@react.component]
let make = () => {
let (state, dispatch) =
React.useReducer(
(state, action) =>
switch (action) {
| SetPath(p) => {...state, path: p}
| SetImageLoaded => {...state, imageLoaded: true}
},
{path: None, imageLoaded: false},
);
let size =
ReactNativeImageEditor.size(
~width=(imageWidth *. 0.5)->floor->truncate,
~height=(imageHeight *. 0.5)->floor->truncate,
);
let cropData = offset =>
ReactNativeImageEditor.cropData(
~offset,
~size,
~resizeMode=`cover,
(),
);
<View style=styles##container>
<Text>
"Click on a quadrant of the image to crop it."->React.string
</Text>
<View style=styles##frame>
<TouchableOpacity
onPress={e =>
handleCropImage(
ReactNativeImageEditor.offset(
~x=
{e##nativeEvent##locationX /. displayWidth < 0.5
? 0 : (0.5 *. imageWidth)->floor->truncate},
~y=
{e##nativeEvent##locationY /. displayHeight < 0.5
? 0 : (0.5 *. imageHeight)->floor->truncate},
)
->cropData,
dispatch,
link =>
SetPath(Some(link))
)
}>
<Image
source={Image.Source.fromUriSource(
Image.uriSource(
~uri=
Belt.Option.getWithDefault(
state.path,
imageUri,
),
~width=displayWidth,
~height=
if (state.imageLoaded) {
displayHeight;
} else {
0.;
},
(),
),
)}
resizeMode=`contain
onLoadEnd={() => dispatch(SetImageLoaded)}
/>
</TouchableOpacity>
{state.imageLoaded
? React.null
: <Text> "Please wait while image is loaded."->React.string </Text>}
</View>
<Button title="Reset Image" onPress={_ => dispatch(SetPath(None))} />
</View>;
};Check the changelog for more informations about recent releases.
Read the contribution guidelines before contributing.
We want this community to be friendly and respectful to each other. Please read our full code of conduct so that you can understand what actions will and will not be tolerated.