diff --git a/src/Cropper/Cropper.page.tsx b/src/Cropper/Cropper.page.tsx index 7d5298a..891c5e7 100644 --- a/src/Cropper/Cropper.page.tsx +++ b/src/Cropper/Cropper.page.tsx @@ -1,29 +1,35 @@ import React, { Component } from 'react'; -import { Animated, PanResponder, PanResponderInstance, PanResponderGestureState, ImageCropData } from 'react-native'; +import { Animated, PanResponder, PanResponderInstance, PanResponderGestureState, ImageCropData, ImageResizeMode } from 'react-native'; // @ts-ignore; 'react-native-image-rotate' does not have typescript support import RNImageRotate from '@wili/react-native-image-rotate'; import ImageEditor from '@react-native-community/image-editor'; import { Q } from '../constants'; import Cropper from './Cropper'; import { getCropperLimits } from '../utils'; +import { StyleType } from '../Main'; type CropperPageProps = { footerComponent: JSX.Element; + headerComponent: JSX.Element; onDone: (croppedImageUri: string) => void; onError: (err: Error) => void; onCancel: () => void; imageUri: string; imageWidth: number; imageHeight: number; + imageResizeMode: ImageResizeMode; TOP_VALUE: number; LEFT_VALUE: number; BOTTOM_VALUE: number; RIGHT_VALUE: number; initialRotation: number; NOT_SELECTED_AREA_OPACITY: number; + NOT_SELECTED_AREA_BACKGROUND_COLOR?: string; BORDER_WIDTH: number; COMPONENT_WIDTH: number; COMPONENT_HEIGHT: number; + style: StyleType; + disableBoxPan?: boolean; }; interface ExtendedAnimatedValue extends Animated.Value { @@ -138,7 +144,7 @@ class CropperPage extends Component { const topRightPanResponder = this.initCornerPanResponder('topPosition', 'rightPosition'); const rectanglePosition = new Animated.ValueXY({ x: LEFT_VALUE, y: TOP_VALUE }) as ExtendedAnimatedValueXY; - const rectanglePanResponder = this.initRectanglePanResponder(); + const rectanglePanResponder = props.disableBoxPan ? {} : this.initRectanglePanResponder(); this.state = { topOuterPosition, @@ -192,6 +198,8 @@ class CropperPage extends Component { W = this.props.COMPONENT_WIDTH; H = this.props.COMPONENT_HEIGHT - Q; + outerBackgroundColor = this.props.NOT_SELECTED_AREA_BACKGROUND_COLOR || `rgba(0, 0, 0, ${this.props.NOT_SELECTED_AREA_OPACITY})`; + onCancel = () => { this.props.onCancel(); }; @@ -203,7 +211,7 @@ class CropperPage extends Component { left: this.state.LEFT_LIMIT, height: Animated.add(this.props.BORDER_WIDTH - this.state.TOP_LIMIT, this.state.topPosition.y), width: this.W, - backgroundColor: `rgba(0, 0, 0, ${this.props.NOT_SELECTED_AREA_OPACITY})`, + backgroundColor: this.outerBackgroundColor, }; }; @@ -214,7 +222,7 @@ class CropperPage extends Component { left: this.state.LEFT_LIMIT, height: Animated.add(-this.props.BORDER_WIDTH, Animated.add(this.state.bottomPosition.y, Animated.multiply(-1, this.state.topPosition.y))), width: Animated.add(this.props.BORDER_WIDTH - this.state.LEFT_LIMIT, this.state.leftPosition.x), - backgroundColor: `rgba(0, 0, 0, ${this.props.NOT_SELECTED_AREA_OPACITY})`, + backgroundColor: this.outerBackgroundColor, }; }; @@ -225,7 +233,7 @@ class CropperPage extends Component { left: this.state.LEFT_LIMIT, height: Animated.add(this.props.COMPONENT_HEIGHT - this.state.BOTTOM_LIMIT, Animated.multiply(-1, this.state.bottomPosition.y)), width: this.W, - backgroundColor: `rgba(0, 0, 0, ${this.props.NOT_SELECTED_AREA_OPACITY})`, + backgroundColor: this.outerBackgroundColor, }; }; @@ -236,7 +244,7 @@ class CropperPage extends Component { left: this.state.rightPosition.x, height: Animated.add(-this.props.BORDER_WIDTH, Animated.add(this.state.bottomPosition.y, Animated.multiply(-1, this.state.topPosition.y))), right: this.state.RIGHT_LIMIT, - backgroundColor: `rgba(0, 0, 0, ${this.props.NOT_SELECTED_AREA_OPACITY})`, + backgroundColor: this.outerBackgroundColor, }; }; @@ -335,7 +343,7 @@ class CropperPage extends Component { left: this.state.LEFT_LIMIT + DIFF, bottom: this.state.BOTTOM_LIMIT - DIFF, right: this.state.RIGHT_LIMIT + DIFF, - resizeMode: 'stretch', + resizeMode: this.props.imageResizeMode, transform: [{ rotate: `${this.state.rotation.toString()}deg` }], }; }; @@ -693,7 +701,7 @@ class CropperPage extends Component { (rotatedUri: string) => { // ImageEditor.cropImage(rotatedUri, cropData) - .then(croppedUri => { + .then((croppedUri) => { this.props.onDone(croppedUri); }) .catch((err: Error) => { @@ -710,8 +718,10 @@ class CropperPage extends Component { render() { return ( { bottomRightPanResponder={this.state.bottomRightPanResponder} topRightPanResponder={this.state.topRightPanResponder} rectanglePanResponder={this.state.rectanglePanResponder} - topOuterRef={ref => (this.topOuter = ref)} - leftOuterRef={ref => (this.leftOuter = ref)} - bottomOuterRef={ref => (this.bottomOuter = ref)} - rightOuterRef={ref => (this.rightOuter = ref)} + topOuterRef={(ref) => (this.topOuter = ref)} + leftOuterRef={(ref) => (this.leftOuter = ref)} + bottomOuterRef={(ref) => (this.bottomOuter = ref)} + rightOuterRef={(ref) => (this.rightOuter = ref)} COMPONENT_WIDTH={this.props.COMPONENT_WIDTH} COMPONENT_HEIGHT={this.props.COMPONENT_HEIGHT} W={this.W} diff --git a/src/Cropper/Cropper.style.ts b/src/Cropper/Cropper.style.ts index 2cdc69d..34e0d5c 100644 --- a/src/Cropper/Cropper.style.ts +++ b/src/Cropper/Cropper.style.ts @@ -8,7 +8,6 @@ export default function getStyles(COMPONENT_WIDTH: number, COMPONENT_HEIGHT: num flexDirection: 'column', alignItems: 'center', justifyContent: 'center', - backgroundColor: 'black', }, secondContainer: { position: 'absolute', @@ -17,6 +16,12 @@ export default function getStyles(COMPONENT_WIDTH: number, COMPONENT_HEIGHT: num width: COMPONENT_WIDTH, height: COMPONENT_HEIGHT, }, + headerContainer: { + position: 'absolute', + top: 20, + left: 10, + right: 10, + }, footerContainer: { position: 'absolute', top: COMPONENT_HEIGHT - Q, @@ -29,8 +34,6 @@ export default function getStyles(COMPONENT_WIDTH: number, COMPONENT_HEIGHT: num }, gridColumn: { flex: 1, - borderWidth: 1, - borderColor: 'rgba(255, 255, 255, 0.5)', }, animation: { position: 'absolute', @@ -92,7 +95,6 @@ export default function getStyles(COMPONENT_WIDTH: number, COMPONENT_HEIGHT: num borderDesign: { width: 30, height: 30, - borderColor: 'white', }, icon: { paddingRight: 10, diff --git a/src/Cropper/Cropper.tsx b/src/Cropper/Cropper.tsx index 307a124..1595160 100644 --- a/src/Cropper/Cropper.tsx +++ b/src/Cropper/Cropper.tsx @@ -1,9 +1,11 @@ import React from 'react'; import { View, Animated, Image, PanResponderInstance } from 'react-native'; +import { StyleType } from '../Main'; import getStyles from './Cropper.style'; interface CropperProps { imageUri: string; + headerComponent: JSX.Element; footerComponent: JSX.Element; getTopOuterStyle: () => object; getLeftOuterStyle: () => object; @@ -43,12 +45,17 @@ interface CropperProps { COMPONENT_HEIGHT: number; W: number; H: number; + style: StyleType; } -const Cropper: React.FC = props => { +const Cropper: React.FC = (props) => { const styles = getStyles(props.COMPONENT_WIDTH, props.COMPONENT_HEIGHT, props.W); + const gridColumn = { ...styles.gridColumn, ...props.style.grid.column }; + const borderDesign = { ...styles.borderDesign, ...props.style.grid.border }; + return ( - + + {React.cloneElement(props.headerComponent)} @@ -67,8 +74,14 @@ const Cropper: React.FC = props => { // @ts-ignore */} {/* - // @ts-ignore */ /* eslint-disable-line */ /* eslint-disable-next-line prettier/prettier */} - + // @ts-ignore */ + /* eslint-disable-line */ + /* eslint-disable-next-line prettier/prettier */} + {/* // @ts-ignore */} @@ -80,45 +93,51 @@ const Cropper: React.FC = props => { {/* eslint-disable-next-line prettier/prettier */} - + {/* eslint-disable-next-line prettier/prettier */} - + - - + + - - + + - - + + - - + + - - - + + + - - + + - - + + - + void; onError: (err: Error) => void; @@ -11,25 +18,32 @@ export type AmazingCropperProps = { imageUri: string; imageWidth: number; imageHeight: number; + imageResizeMode: ImageResizeMode; TOP_VALUE?: number; LEFT_VALUE?: number; BOTTOM_VALUE?: number; RIGHT_VALUE?: number; initialRotation?: number; NOT_SELECTED_AREA_OPACITY?: number; + NOT_SELECTED_AREA_BACKGROUND_COLOR?: string; BORDER_WIDTH?: number; COMPONENT_WIDTH?: number; COMPONENT_HEIGHT?: number; + style?: StyleType; + disableBoxPan?: boolean; } & typeof defaultProps; +/// new key change const defaultProps = { footerComponent: , + headerComponent: <>, onDone: (_croppedImageUri: string) => {}, onError: (_err: Error) => {}, onCancel: () => {}, imageUri: '', imageWidth: 1280, imageHeight: 747, + imageResizeMode: 'stretch', TOP_VALUE: 0, LEFT_VALUE: 0, BOTTOM_VALUE: 0, @@ -39,6 +53,11 @@ const defaultProps = { BORDER_WIDTH: 50, COMPONENT_WIDTH: SCREEN_WIDTH, COMPONENT_HEIGHT: SCREEN_HEIGHT, + style: { + container: { backgroundColor: '#000' }, + grid: { border: { borderColor: '#FFF' }, column: { borderWidth: 1, borderColor: 'rgba(255, 255, 255, 0.5)' } }, + }, + disableBoxPan: false, }; class Main extends Component { @@ -47,6 +66,7 @@ class Main extends Component { render() { return ( { imageUri={this.props.imageUri} imageWidth={this.props.imageWidth} imageHeight={this.props.imageHeight} + imageResizeMode={this.props.imageResizeMode} TOP_VALUE={this.props.TOP_VALUE} LEFT_VALUE={this.props.LEFT_VALUE} BOTTOM_VALUE={this.props.BOTTOM_VALUE} RIGHT_VALUE={this.props.RIGHT_VALUE} initialRotation={this.props.initialRotation} NOT_SELECTED_AREA_OPACITY={this.props.NOT_SELECTED_AREA_OPACITY} + NOT_SELECTED_AREA_BACKGROUND_COLOR={this.props.NOT_SELECTED_AREA_BACKGROUND_COLOR} BORDER_WIDTH={this.props.BORDER_WIDTH} COMPONENT_WIDTH={this.props.COMPONENT_WIDTH} COMPONENT_HEIGHT={this.props.COMPONENT_HEIGHT} + style={this.props.style} + disableBoxPan={this.props.disableBoxPan} /> ); }