diff --git a/index.js b/index.js
index 2eb7f03..7a19564 100644
--- a/index.js
+++ b/index.js
@@ -1,134 +1,144 @@
-import React from 'react';
-import { Animated, StyleSheet, View } from 'react-native';
-import PropTypes from 'prop-types';
+import React, { useEffect, useState } from "react";
+import { Animated, StyleSheet, View } from "react-native";
+import PropTypes from "prop-types";
const styles = StyleSheet.create({
container: {
- alignItems: 'center',
- justifyContent: 'center',
+ alignItems: "center",
+ justifyContent: "center",
...StyleSheet.absoluteFillObject,
},
finder: {
- alignItems: 'center',
- justifyContent: 'center',
+ alignItems: "center",
+ justifyContent: "center",
},
topLeftEdge: {
- position: 'absolute',
+ position: "absolute",
top: 0,
left: 0,
},
topRightEdge: {
- position: 'absolute',
+ position: "absolute",
top: 0,
right: 0,
},
bottomLeftEdge: {
- position: 'absolute',
+ position: "absolute",
bottom: 0,
left: 0,
},
bottomRightEdge: {
- position: 'absolute',
+ position: "absolute",
bottom: 0,
right: 0,
},
maskOuter: {
- position: 'absolute',
+ position: "absolute",
top: 0,
left: 0,
- width: '100%',
- height: '100%',
- alignItems: 'center',
- justifyContent: 'space-around',
+ width: "100%",
+ height: "100%",
+ alignItems: "center",
+ justifyContent: "space-around",
},
maskInner: {
- backgroundColor: 'transparent',
+ backgroundColor: "transparent",
},
maskRow: {
- width: '100%',
+ width: "100%",
},
maskCenter: {
- display: 'flex',
- flexDirection: 'row',
+ display: "flex",
+ flexDirection: "row",
},
animatedLine: {
- position: 'absolute',
+ position: "absolute",
elevation: 4,
zIndex: 0,
},
});
-class BarcodeMask extends React.Component {
- constructor(props) {
- super(props);
- this.state = {
- edgeRadiusOffset: props.edgeRadius ? -Math.abs(props.edgeRadius / 3) : 0
- };
- }
+const BarcodeMask = ({
+ width = 280,
+ height = 230,
+ edgeWidth = 20,
+ edgeHeight = 20,
+ edgeColor = "#FFF",
+ edgeBorderWidth = 4,
+ edgeRadius,
+ backgroundColor = "rgb(0, 0, 0)",
+ outerMaskOpacity = 0.6,
+ showAnimatedLine = true,
+ animatedLineColor = "#FFF",
+ animatedLineHeight = 2,
+ animatedLineWidth = "85%",
+ lineAnimationDuration = 5000,
+ animatedLineOrientation = "horizontal",
+ useNativeDriver = true,
+ onLayoutMeasured,
+}) => {
+ const edgeRadiusOffset = edgeRadius ? -Math.abs(edgeRadius / 3) : 0;
- componentDidMount() {
- this._startLineAnimation();
- }
+ const [
+ { top, left, lineTravelWindowDistance, finderLayout },
+ setLayout,
+ ] = useState({
+ top: new Animated.Value(0),
+ left: new Animated.Value(0),
+ lineTravelWindowDistance: 0,
+ finderLayout: null,
+ });
- componentWillUnmount() {
- if (this.animation) {
- this.animation.stop();
- }
- }
+ useEffect(() => {
+ let animation = null;
- _startLineAnimation = () => {
- const intervalId = setInterval(() => {
- const { finderLayout, intervalId } = this.state;
- if (finderLayout && finderLayout.height > 0) {
- this._animateLoop();
- clearInterval(intervalId);
- }
- }, 500);
- this.setState({
- intervalId,
- });
- };
-
- _animateLoop = () => {
- const {
- animatedLineOrientation,
- lineAnimationDuration,
- useNativeDriver
- } = this.props;
- const { lineTravelWindowDistance } = this.state;
- const isHorizontal = animatedLineOrientation !== 'vertical';
- const propertyToChange = isHorizontal ? 'top' : 'left';
+ const isHorizontal = animatedLineOrientation !== "vertical";
+ const propertyToChange = isHorizontal ? top : left;
const startValue = -lineTravelWindowDistance;
const endValue = lineTravelWindowDistance;
- this.animation = Animated.loop(
- Animated.sequence([
- Animated.timing(this.state[propertyToChange], {
- toValue: endValue,
- duration: lineAnimationDuration,
- useNativeDriver
- }),
- Animated.timing(this.state[propertyToChange], {
- toValue: startValue,
- duration: lineAnimationDuration,
- useNativeDriver
- })
- ])
- );
- this.animation.start();
- }
- _applyMaskFrameStyle = () => {
- const { backgroundColor, outerMaskOpacity } = this.props;
+ if (finderLayout && finderLayout.height > 0) {
+ animation = Animated.loop(
+ Animated.sequence([
+ Animated.timing(propertyToChange, {
+ toValue: endValue,
+ duration: lineAnimationDuration,
+ useNativeDriver,
+ }),
+ Animated.timing(propertyToChange, {
+ toValue: startValue,
+ duration: lineAnimationDuration,
+ useNativeDriver,
+ }),
+ ])
+ );
+ animation.start();
+ }
+
+ return function cleanup() {
+ if (animation) {
+ animation.stop();
+ }
+ };
+ }, [
+ finderLayout,
+ animatedLineOrientation,
+ top,
+ left,
+ lineTravelWindowDistance,
+ lineAnimationDuration,
+ useNativeDriver,
+ ]);
+
+ const _applyMaskFrameStyle = () => {
return { backgroundColor, opacity: outerMaskOpacity, flex: 1 };
};
- _renderEdge = (edgePosition) => {
- const { edgeWidth, edgeHeight, edgeColor, edgeBorderWidth, edgeRadius } = this.props;
- const { edgeRadiusOffset } = this.state;
+ const _renderEdge = (edgePosition) => {
const defaultStyle = {
- width: edgeWidth,
- height: edgeHeight,
- borderColor: edgeColor
+ width: edgeWidth,
+ height: edgeHeight,
+ borderColor: edgeColor,
};
const edgeBorderStyle = {
topRight: {
@@ -143,14 +153,14 @@ class BarcodeMask extends React.Component {
borderTopWidth: edgeBorderWidth,
borderTopLeftRadius: edgeRadius,
top: edgeRadiusOffset,
- left: edgeRadiusOffset
+ left: edgeRadiusOffset,
},
bottomRight: {
borderRightWidth: edgeBorderWidth,
borderBottomWidth: edgeBorderWidth,
borderBottomRightRadius: edgeRadius,
bottom: edgeRadiusOffset,
- right: edgeRadiusOffset
+ right: edgeRadiusOffset,
},
bottomLeft: {
borderLeftWidth: edgeBorderWidth,
@@ -160,92 +170,91 @@ class BarcodeMask extends React.Component {
left: edgeRadiusOffset,
},
};
- return ;
+ return (
+
+ );
};
- _calculateLineTravelWindowDistance({ layout, isHorizontalOrientation }) {
- return (((isHorizontalOrientation ? layout.height : layout.width) - 10)/2);
- }
+ const _calculateLineTravelWindowDistance = ({
+ layout,
+ isHorizontalOrientation,
+ }) => {
+ return ((isHorizontalOrientation ? layout.height : layout.width) - 10) / 2;
+ };
- _onFinderLayoutMeasured = ({ nativeEvent }) => {
- const { animatedLineOrientation, onLayoutMeasured } = this.props;
+ const _onFinderLayoutMeasured = ({ nativeEvent }) => {
const { layout } = nativeEvent;
- const isHorizontal = animatedLineOrientation !== 'vertical';
- const travelDistance = this._calculateLineTravelWindowDistance({
- layout,
- isHorizontalOrientation: isHorizontal,
+ const isHorizontal = animatedLineOrientation !== "vertical";
+ const travelDistance = _calculateLineTravelWindowDistance({
+ layout,
+ isHorizontalOrientation: isHorizontal,
+ });
+ setLayout({
+ top: new Animated.Value(-travelDistance),
+ left: new Animated.Value(-travelDistance),
+ lineTravelWindowDistance: travelDistance,
+ finderLayout: layout,
});
- this.setState({
- top: new Animated.Value(-travelDistance),
- left: new Animated.Value(-travelDistance),
- lineTravelWindowDistance: travelDistance,
- finderLayout: layout,
- })
if (onLayoutMeasured) {
- onLayoutMeasured(nativeEvent);
+ onLayoutMeasured(nativeEvent);
}
- }
+ };
- render() {
- const {
- width,
- height,
- showAnimatedLine,
- animatedLineColor,
- animatedLineWidth,
- animatedLineHeight,
- animatedLineOrientation,
- edgeBorderWidth
- } = this.props;
- const animatedLineStyle = {
- backgroundColor: animatedLineColor,
- height: animatedLineHeight,
- maxHeight: height,
- width: animatedLineWidth,
- maxWidth: width,
- margin: edgeBorderWidth
- };
- const { finderLayout, top, left } = this.state;
- if (finderLayout && animatedLineOrientation !== 'vertical') {
- animatedLineStyle.transform = [{
- translateY: top
- }]
- } else if (finderLayout) {
- animatedLineStyle.transform = [{
- translateX: left
- }]
- }
+ const animatedLineStyle = {
+ backgroundColor: animatedLineColor,
+ height: animatedLineHeight,
+ maxHeight: height,
+ width: animatedLineWidth,
+ maxWidth: width,
+ margin: edgeBorderWidth,
+ };
- return (
-
-
- {this._renderEdge('topLeft')}
- {this._renderEdge('topRight')}
- {this._renderEdge('bottomLeft')}
- {this._renderEdge('bottomRight')}
- {showAnimatedLine && (
-
- )}
-
-
-
-
-
-
-
-
-
-
-
- );
+ if (finderLayout && animatedLineOrientation !== "vertical") {
+ animatedLineStyle.transform = [
+ {
+ translateY: top,
+ },
+ ];
+ } else if (finderLayout) {
+ animatedLineStyle.transform = [
+ {
+ translateX: left,
+ },
+ ];
}
-}
+ return (
+
+
+ {_renderEdge("topLeft")}
+ {_renderEdge("topRight")}
+ {_renderEdge("bottomLeft")}
+ {_renderEdge("bottomRight")}
+ {showAnimatedLine && (
+
+ )}
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
const propTypes = {
width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
@@ -261,31 +270,15 @@ const propTypes = {
animatedLineColor: PropTypes.string,
animatedLineHeight: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
animatedLineWidth: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
- lineAnimationDuration: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+ lineAnimationDuration: PropTypes.oneOfType([
+ PropTypes.string,
+ PropTypes.number,
+ ]),
animatedLineOrientation: PropTypes.string,
useNativeDriver: PropTypes.bool,
- onLayoutMeasured: PropTypes.func
-};
-
-const defaultProps = {
- width: 280,
- height: 230,
- edgeWidth: 20,
- edgeHeight: 20,
- edgeColor: '#FFF',
- edgeBorderWidth: 4,
- backgroundColor: 'rgb(0, 0, 0)',
- outerMaskOpacity: 0.6,
- showAnimatedLine: true,
- animatedLineColor: '#FFF',
- animatedLineHeight: 2,
- animatedLineWidth: '85%',
- lineAnimationDuration: 5000,
- animatedLineOrientation: 'horizontal',
- useNativeDriver: true
+ onLayoutMeasured: PropTypes.func,
};
BarcodeMask.propTypes = propTypes;
-BarcodeMask.defaultProps = defaultProps;
export default BarcodeMask;