diff --git a/example/src/App.tsx b/example/src/App.tsx index 49a8c42..cf976cb 100644 --- a/example/src/App.tsx +++ b/example/src/App.tsx @@ -6,27 +6,27 @@ import { QrCodeSvg } from 'react-native-qr-svg'; export default function App() { return ( - + - 👋 + 👋 } contentStyle={styles.box} /> - + - 💻 + 💻 } dotColor="#ffffff" @@ -34,6 +34,9 @@ export default function App() { contentStyle={styles.box} /> + + + ); } @@ -41,7 +44,6 @@ export default function App() { const styles = StyleSheet.create({ container: { flex: 1, - flexDirection: 'row', alignItems: 'center', justifyContent: 'center', }, @@ -49,11 +51,14 @@ const styles = StyleSheet.create({ alignItems: 'center', justifyContent: 'center', }, - firstQr: { - marginRight: 15, + icon: { + fontSize: 20, }, - secondQr: { + qr: { padding: 15, + }, + firstQr: {}, + secondQr: { backgroundColor: '#000000', }, }); diff --git a/src/getCornets.ts b/src/getCornets.ts index e7ae996..c83e111 100644 --- a/src/getCornets.ts +++ b/src/getCornets.ts @@ -3,28 +3,35 @@ * @param x * @param y * @param cellSize + * @param padding */ -export default function getCorners(x: number, y: number, cellSize: number) { +export default function getCorners( + x: number, + y: number, + cellSize: number, + padding: number +) { // q4 0 0 0 q1 // 0 0 0 0 0 // 0 0 0 0 0 // 0 0 0 0 0 // q3 0 0 0 q2 const q1 = { - x: x + cellSize, - y: y, + x: x + cellSize - padding, + y: y + padding, }; const q2 = { - x: x + cellSize, - y: y + cellSize, + x: x + cellSize - padding, + y: y + cellSize - padding, }; const q3 = { - x: x, - y: y + cellSize, + x: x + padding, + y: y + cellSize - padding, }; const q4 = { - x: x, - y: y, + x: x + padding, + y: y + padding, }; - return { q1, q2, q3, q4 }; + const center = { x: x + cellSize / 2, y: y + cellSize / 2 }; + return { q1, q2, q3, q4, center }; } diff --git a/src/index.tsx b/src/index.tsx index 301f3ec..4ba9a9c 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,12 +1,12 @@ -import React, { useCallback, useMemo } from 'react'; +import React, { useMemo } from 'react'; import { createMatrix } from './createMatrix'; -import Svg, { Path, G, Rect, Circle } from 'react-native-svg'; -import type { RectProps, PathProps, CircleProps } from 'react-native-svg'; -import { StyleSheet, View } from 'react-native'; +import type { CircleProps, PathProps, RectProps } from 'react-native-svg'; +import Svg, { G, Path, Rect } from 'react-native-svg'; import type { StyleProp, ViewStyle } from 'react-native'; +import { StyleSheet, View } from 'react-native'; import type { QRCodeErrorCorrectionLevel } from 'qrcode'; import type { Neighbors } from './types'; -import getCorners from './getCornets'; +import renderFigure from './renderFigure'; export type QrCodeSvgProps = { value: string; @@ -21,6 +21,7 @@ export type QrCodeSvgProps = { contentStyle?: StyleProp; figureCircleProps?: CircleProps; figurePathProps?: PathProps; + padding?: number; }; export function QrCodeSvg({ @@ -36,21 +37,22 @@ export function QrCodeSvg({ contentStyle, figureCircleProps, figurePathProps, + padding = 0.05, }: QrCodeSvgProps) { const originalMatrix = useMemo( () => createMatrix(value, errorCorrectionLevel), [errorCorrectionLevel, value] ); - const matrixCellSize = round(frameSize / originalMatrix.length); // Ex. 3.141592653589793 -> 3.1 + const cell = round(frameSize / originalMatrix.length); // Ex. 3.141592653589793 -> 3.1 const matrixRowLength = originalMatrix[0]?.length ?? 0; const roundedContentCells = (matrixRowLength - contentCells) % 2 === 0 ? contentCells : contentCells + 1; - const contentSize = matrixCellSize * roundedContentCells; + const contentSize = cell * roundedContentCells; const contentStartIndex = (matrixRowLength - roundedContentCells) / 2; const contentEndIndex = contentStartIndex + roundedContentCells - 1; - const contentXY = contentStartIndex * matrixCellSize; + const contentXY = contentStartIndex * cell; const matrix = useMemo( () => @@ -69,95 +71,40 @@ export function QrCodeSvg({ [content, contentEndIndex, contentStartIndex, originalMatrix] ); - const renderFigure = useCallback( - (x: number, y: number, neighbors: Neighbors) => { - const { q1, q2, q3, q4 } = getCorners(x, y, matrixCellSize); - if ( - !( - neighbors.top || - neighbors.right || - neighbors.bottom || - neighbors.left - ) - ) { - return ( - - ); - } - // q4 0 d1 0 q1 - // 0 0 0 0 0 - // d4 0 0 0 d2 - // 0 0 0 0 0 - // q3 0 d3 0 q2 - const d1 = { - x: x + matrixCellSize / 2, - y: y, - }; - const d2 = { - x: x + matrixCellSize, - y: y + matrixCellSize / 2, - }; - const d1d2 = - neighbors.top || neighbors.right - ? `L${q1.x} ${q1.y} L${d2.x} ${d2.y}` - : `Q${q1.x} ${q1.y} ${d2.x} ${d2.y}`; - const d3 = { - x: x + matrixCellSize / 2, - y: y + matrixCellSize, - }; - const d2d3 = - neighbors.right || neighbors.bottom - ? `L${q2.x} ${q2.y} L${d3.x} ${d3.y}` - : `Q${q2.x} ${q2.y} ${d3.x} ${d3.y}`; - const d4 = { - x: x, - y: y + matrixCellSize / 2, - }; - const d3d4 = - neighbors.bottom || neighbors.left - ? `L${q3.x} ${q3.y} L${d4.x} ${d4.y}` - : `Q${q3.x} ${q3.y} ${d4.x} ${d4.y}`; - const d4d1 = - neighbors.left || neighbors.top - ? `L${q4.x} ${q4.y} L${d1.x} ${d1.y}` - : `Q${q4.x} ${q4.y} ${d1.x} ${d1.y}`; - const d = `M${d1.x} ${d1.y} ${d1d2} ${d2d3} ${d3d4} ${d4d1}`; - - return ; - }, - [dotColor, figureCircleProps, figurePathProps, matrixCellSize] + const paths = useMemo( + () => + matrix.flatMap((row, i) => + row.flatMap((_, j) => { + if (!row?.[j]) { + return []; + } + const neighbors: Neighbors = { + top: Boolean(matrix[i - 1]?.[j]), + bottom: Boolean(matrix[i + 1]?.[j]), + left: Boolean(row[j - 1]), + right: Boolean(row[j + 1]), + }; + const x = j * cell; + const y = i * cell; + return [renderFigure(x, y, neighbors, cell, padding)]; + }) + ), + [matrix, padding, cell] ); + const dPath = paths + .filter((_) => _.type === 'path') + .map((_) => _.d) + .join(); + const dCircle = paths + .filter((_) => _.type === 'circle') + .map((_) => _.d) + .join(); return ( - {matrix.map((row, i) => - row.map((_, j) => { - if (!row?.[j]) { - return null; - } - const neighbors: Neighbors = { - top: Boolean(matrix[i - 1]?.[j]), - bottom: Boolean(matrix[i + 1]?.[j]), - left: Boolean(row[j - 1]), - right: Boolean(row[j + 1]), - }; - const x = j * matrixCellSize; - const y = i * matrixCellSize; - const key = `${i}${j}`; - return ( - - {renderFigure(x, y, neighbors)} - - ); - }) - )} + + {content && (