UNPKG

react-native-qrcode-package

Version:

This package include QR code generator and QR code Scanner for React Native.

171 lines (162 loc) 4.2 kB
import React, {useMemo} from 'react'; import Svg, { Defs, G, Path, Rect, Image, ClipPath, LinearGradient, Stop, } from 'react-native-svg'; import generateMatrix from './GenerateMatrix'; import transformMatrixIntoPath from './TransformMatrixIntoPath'; const CLIP_LOGO_ID_BACKGROUND = 'clip-logo-background'; const CLIP_LOGO_BACKGROUND = 'url(#clip-logo-background)'; const CLIP_LOGO_ID = 'clip-logo'; const CLIP_LOGO = 'url(#clip-logo)'; const PRESERVE_ASPECT_RATIO = 'xMidYMid slice'; const STYLE_LINE = 'butt'; const GRADIENT_COLOR = 'url(#grad)'; const renderLogo = ({ sizeQRCode, logo, logoSize, logoBackgroundColor, logoMargin, logoBorderRadius, }) => { const logoPosition = (sizeQRCode - logoSize - logoMargin * 2) / 2; const logoBackgroundSize = logoSize + logoMargin * 2; const logoBackgroundBorderRadius = logoBorderRadius + (logoMargin / logoSize) * logoBorderRadius; return ( <G x={logoPosition} y={logoPosition}> <Defs> <ClipPath id={CLIP_LOGO_ID_BACKGROUND}> <Rect width={logoBackgroundSize} height={logoBackgroundSize} rx={logoBackgroundBorderRadius} ry={logoBackgroundBorderRadius} /> </ClipPath> <ClipPath id={CLIP_LOGO_ID}> <Rect width={logoSize} height={logoSize} rx={logoBorderRadius} ry={logoBorderRadius} /> </ClipPath> </Defs> <G> <Rect width={logoBackgroundSize} height={logoBackgroundSize} fill={logoBackgroundColor} clipPath={CLIP_LOGO_BACKGROUND} /> </G> <G x={logoMargin} y={logoMargin}> <Image width={logoSize} height={logoSize} preserveAspectRatio={PRESERVE_ASPECT_RATIO} href={logo} clipPath={CLIP_LOGO} /> </G> </G> ); }; const GenerateQRCode = ({ jsonObject = {}, sizeQRCode = 150, colorQRCode = 'black', backgroundColorQRCode = 'white', logo, logoSize = sizeQRCode * 0.2, logoBackgroundColor = 'transparent', logoMargin = 2, logoBorderRadius = 0, quietZone = 0, enableLinearGradient = false, gradientDirection = ['0%', '0%', '100%', '100%'], linearGradient = ['rgb(255,0,0)', 'rgb(0,255,255)'], ecl = 'M', getRef, onError, }) => { const qrCodeValue = JSON.stringify(jsonObject); const result = useMemo(() => { try { return transformMatrixIntoPath( generateMatrix(qrCodeValue, ecl), sizeQRCode, ); } catch (error) { if (onError && typeof onError === 'function') { onError(error); } else { // Throw an error when no handler set throw error; } } }, [qrCodeValue, ecl, sizeQRCode, onError]); if (!result) { return null; } const {path, cellSize} = result; return ( <Svg ref={getRef} viewBox={[ -quietZone, -quietZone, sizeQRCode + quietZone * 2, sizeQRCode + quietZone * 2, ].join(' ')} width={sizeQRCode} height={sizeQRCode}> <Defs> <LinearGradient id="grad" x1={gradientDirection[0]} y1={gradientDirection[1]} x2={gradientDirection[2]} y2={gradientDirection[3]}> <Stop offset="0" stopColor={linearGradient[0]} stopOpacity="1" /> <Stop offset="1" stopColor={linearGradient[1]} stopOpacity="1" /> </LinearGradient> </Defs> <G> <Rect x={-quietZone} y={-quietZone} width={sizeQRCode + quietZone * 2} height={sizeQRCode + quietZone * 2} fill={backgroundColorQRCode} /> </G> <G> <Path d={path} strokeLinecap={STYLE_LINE} stroke={enableLinearGradient ? {GRADIENT_COLOR} : colorQRCode} strokeWidth={cellSize} /> </G> {logo && renderLogo({ sizeQRCode, logo, logoSize, logoBackgroundColor, logoMargin, logoBorderRadius, })} </Svg> ); }; export default GenerateQRCode;