UNPKG

react-native-qr-barcode

Version:
169 lines (156 loc) 8.73 kB
'use strict'; import React, { Component, PropTypes } from 'react'; import { View, WebView, Text } from 'react-native'; import qr from 'qr.js'; export class BarCode extends Component { render() { return ( <View style={[{width:this.props.width, height:this.props.height}, this.props.style]}> <WebView source={{html: this._getHtml()}}/> </View> ) } _getHtml() { const IFT = `(function($){JsBarcode=function(image,content,options,validFunction){var merge=function(m1,m2){var newMerge={};for(var k in m1){newMerge[k]=m1[k]}for(var k in m2){newMerge[k]=m2[k]}return newMerge};var validFunctionIfExist=function(valid){if(validFunction){validFunction(valid)}};options=merge(JsBarcode.defaults,options);var canvas=image;if(window.jQuery&&canvas instanceof jQuery){canvas=image.get(0)}if(!(canvas instanceof HTMLCanvasElement)){canvas=document.createElement("canvas")}if(!canvas.getContext){return image}var encoder=new window[options.format](content);if(!encoder.valid()){validFunctionIfExist(false);return this}var binary=encoder.encoded();var _drawBarcodeText=function(text){var x,y;y=options.height;ctx.font=options.fontOptions+" "+options.fontSize+"px "+options.font;ctx.textBaseline="bottom";ctx.textBaseline="top";if(options.textAlign=="left"){x=options.quite;ctx.textAlign="left"}else{if(options.textAlign=="right"){x=canvas.width-options.quite;ctx.textAlign="right"}else{x=canvas.width/2;ctx.textAlign="center"}}ctx.fillText(text,x,y)};var ctx=canvas.getContext("2d");canvas.width=binary.length*options.width+2*options.quite;canvas.height=options.height+(options.displayValue?options.fontSize*1.3:0);ctx.clearRect(0,0,canvas.width,canvas.height);if(options.backgroundColor){ctx.fillStyle=options.backgroundColor;ctx.fillRect(0,0,canvas.width,canvas.height)}ctx.fillStyle=options.lineColor;for(var i=0;i<binary.length;i++){var x=i*options.width+options.quite;if(binary[i]=="1"){ctx.fillRect(x,0,options.width,options.height)}}if(options.displayValue){_drawBarcodeText(content)}uri=canvas.toDataURL("image/png");if(window.jQuery&&image instanceof jQuery){if(!(image.get(0) instanceof HTMLCanvasElement)){image.attr("src",uri)}}else{if(!(image instanceof HTMLCanvasElement)){image.setAttribute("src",uri)}}validFunctionIfExist(true)};JsBarcode.defaults={width:2,height:100,quite:10,format:"CODE128",displayValue:false,fontOptions:"",font:"monospace",textAlign:"center",fontSize:12,backgroundColor:"",lineColor:"#000"};if(window.jQuery){$.fn.JsBarcode=function(content,options,validFunction){JsBarcode(this,content,options,validFunction);return this}}})(window.jQuery);function ITF(ITFNumber){this.ITFNumber=ITFNumber+"";this.valid=function(){return valid(this.ITFNumber)};this.encoded=function(){if(valid(this.ITFNumber)){return encode(this.ITFNumber)}return""};var digitStructure={"0":"00110","1":"10001","2":"01001","3":"11000","4":"00101","5":"10100","6":"01100","7":"00011","8":"10010","9":"01010"};var startBin="1010";var endBin="11101";var regexp=/^([0-9][0-9])+$/;function encode(number){var result="";result+=startBin;for(var i=0;i<number.length;i+=2){result+=calculatePair(number.substr(i,2))}result+=endBin;return result}function calculatePair(twoNumbers){var result="";var number1Struct=digitStructure[twoNumbers[0]];var number2Struct=digitStructure[twoNumbers[1]];for(var i=0;i<5;i++){result+=(number1Struct[i]=="1")?"111":"1";result+=(number2Struct[i]=="1")?"000":"0"}return result}function valid(number){return number.search(regexp)!==-1}};`; return `<!doctype html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body style="height: 100%;width: 100%;margin: 0;padding: 0;overflow: hidden"> <canvas height="${this.props.height}" width="${this.props.width}"></canvas><script> ${IFT} var PIXEL_RATIO = (function () { var ctx = document.createElement("canvas").getContext("2d"), dpr = window.devicePixelRatio || 1, bsr = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1; return dpr / bsr; })(); var canvas = document.querySelector('canvas'); var oldWidth=canvas.width; var oldHeight=canvas.height; canvas.width=oldWidth*PIXEL_RATIO; canvas.height=oldHeight*PIXEL_RATIO; canvas.style.width=oldWidth+'px'; canvas.style.height=oldHeight+'px'; canvas.ontouchstart=function(e){ e.preventDefault(); e.stopImmediatePropagation(); } JsBarcode(canvas, "${this.props.value}",{ width:2, format: "ITF", displayValue: true, fontSize: 28, backgroundColor:'${this.props.bgColor}'}); </script> </body> </html>`; } } BarCode.propTypes = { value: PropTypes.string, bgColor: PropTypes.string, width: PropTypes.number, height: PropTypes.number, style: PropTypes.object } BarCode.defaultProps = { value: '12345678901234567890', bgColor: 'white', width: 225, height: 90 } export class QRCode extends Component { utf16to8 = str => { let out, i, len, c; out = ''; len = str.length; for (i = 0; i < len; i++) { c = str.charCodeAt(i); if ((c >= 0x0001) && (c <= 0x007F)) { out += str.charAt(i); } else if (c > 0x07FF) { out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F)); out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } else { out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F)); out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F)); } } return out; } render() { console.log(this._getHtml()) return ( <View style={[{height: this.props.size, width: this.props.size}, this.props.style]}> <WebView source={{html: this._getHtml()}} /> </View> ); } renderCanvas(canvas) { let ctx = canvas.getContext('2d'); let size = this.size; let fgColor = this.fgColor; let bgColor = this.bgColor; canvas.width = size; canvas.height = size; canvas.style.left = (window.innerWidth - size) / 2 + 'px'; if (window.innerHeight > size) canvas.style.top = (window.innerHeight - size) / 2 + 'px'; ctx.fillStyle = 'red'; ctx.fillRect(0, 0, size, size); let cells = this.cells; let cellWidth = this.size / cells.length; let cellHeight = this.size / cells.length; cells.forEach(function (row, rowIndex) { row.forEach(function (column, columnIndex) { ctx.fillStyle = column ? bgColor : fgColor; let w = Math.ceil((rowIndex + 1) * cellWidth) - Math.floor(rowIndex * cellWidth); let h = Math.ceil((columnIndex + 1) * cellHeight) - Math.floor(columnIndex * cellHeight); ctx.fillRect(Math.round(rowIndex * cellWidth), Math.round(columnIndex * cellHeight), w, h); }); }); } _getHtml = () => { let value = this.utf16to8(this.props.value); let context = { size: this.props.size, bgColor: this.props.bgColor, fgColor: this.props.fgColor, cells: qr(value).modules, }; var contextString = JSON.stringify(context); var renderString = this.renderCanvas.toString(); return `<!doctype html> <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body style="height: 100%;width: 100%;margin: 0;padding: 0;overflow: hidden"> <canvas></canvas> <script> var canvas = document.querySelector('canvas'); (${renderString}).call(${contextString}, canvas); canvas.ontouchstart=function(e){ e.preventDefault(); e.stopImmediatePropagation(); } </script> </body> </html>`; } } QRCode.propTypes = { value: PropTypes.string, fgColor: PropTypes.string, bgColor: PropTypes.string, size: PropTypes.number, style: PropTypes.object } QRCode.defaultProps = { value: '12345678901234567890', fgColor: 'white', bgColor: 'black', size: 128 }