@oguzhnatly/react-native-custom-qr-codes 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/build.yml +32 -0
- package/.github/workflows/publish.yml +69 -0
- package/CONTRIBUTING.md +14 -0
- package/LICENSE +21 -0
- package/README.md +181 -0
- package/index.d.ts +32 -0
- package/index.js +1 -0
- package/lib/QRCode.js +529 -0
- package/lib/QRCodeGenerator.js +1862 -0
- package/lib/styles/codeStyles/circle.js +31 -0
- package/lib/styles/codeStyles/diamond.js +35 -0
- package/lib/styles/codeStyles/dot.js +31 -0
- package/lib/styles/codeStyles/index.js +36 -0
- package/lib/styles/codeStyles/ninja.js +132 -0
- package/lib/styles/codeStyles/sharp.js +118 -0
- package/lib/styles/codeStyles/square.js +32 -0
- package/lib/styles/index.js +45 -0
- package/lib/styles/innerEyeStyles/circle.js +31 -0
- package/lib/styles/innerEyeStyles/diamond.js +35 -0
- package/lib/styles/innerEyeStyles/index.js +31 -0
- package/lib/styles/innerEyeStyles/none.js +8 -0
- package/lib/styles/innerEyeStyles/square.js +32 -0
- package/lib/styles/outerEyeStyles/circle.js +31 -0
- package/lib/styles/outerEyeStyles/diamond.js +35 -0
- package/lib/styles/outerEyeStyles/index.js +30 -0
- package/lib/styles/outerEyeStyles/none.js +8 -0
- package/lib/styles/outerEyeStyles/square.js +32 -0
- package/package.json +39 -0
package/lib/QRCode.js
ADDED
|
@@ -0,0 +1,529 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
QRCode.js
|
|
4
|
+
|
|
5
|
+
This is a Customisable QR Code Component for React Native Applications.
|
|
6
|
+
|
|
7
|
+
--Geoff Natin 08/7/17 21:49
|
|
8
|
+
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { Image, View } from "react-native";
|
|
12
|
+
//-----------------------------Imports-----------------------------------
|
|
13
|
+
import React, { PureComponent } from "react";
|
|
14
|
+
import Svg, {
|
|
15
|
+
ClipPath,
|
|
16
|
+
Defs,
|
|
17
|
+
LinearGradient,
|
|
18
|
+
Rect,
|
|
19
|
+
Stop,
|
|
20
|
+
} from "react-native-svg";
|
|
21
|
+
|
|
22
|
+
import PropTypes from "prop-types";
|
|
23
|
+
import { drawPiece } from "./styles";
|
|
24
|
+
import { generateQRCode } from "./QRCodeGenerator.js";
|
|
25
|
+
import styled from "../../styled-components";
|
|
26
|
+
|
|
27
|
+
//-----------------------------Component---------------------------------
|
|
28
|
+
export default class QRCode extends PureComponent {
|
|
29
|
+
//-----------------------Properties---------------------
|
|
30
|
+
static propTypes = {
|
|
31
|
+
content: PropTypes.string,
|
|
32
|
+
size: PropTypes.number,
|
|
33
|
+
padding: PropTypes.number,
|
|
34
|
+
color: PropTypes.string,
|
|
35
|
+
linearGradient: PropTypes.arrayOf(PropTypes.string),
|
|
36
|
+
gradientDirection: PropTypes.arrayOf(PropTypes.number),
|
|
37
|
+
backgroundColor: PropTypes.string,
|
|
38
|
+
innerEyeStyle: PropTypes.oneOf([
|
|
39
|
+
"circle",
|
|
40
|
+
"circles",
|
|
41
|
+
"diamond",
|
|
42
|
+
"rounded",
|
|
43
|
+
"square",
|
|
44
|
+
]),
|
|
45
|
+
outerEyeStyle: PropTypes.oneOf([
|
|
46
|
+
"circle",
|
|
47
|
+
"circles",
|
|
48
|
+
"diamond",
|
|
49
|
+
"rounded",
|
|
50
|
+
"square",
|
|
51
|
+
]),
|
|
52
|
+
codeStyle: PropTypes.oneOf([
|
|
53
|
+
"circle",
|
|
54
|
+
"diamond",
|
|
55
|
+
"dot",
|
|
56
|
+
"ninja",
|
|
57
|
+
"sharp",
|
|
58
|
+
"square",
|
|
59
|
+
]),
|
|
60
|
+
logo: PropTypes.oneOfType([Image.propTypes.source, PropTypes.string]),
|
|
61
|
+
backgroundImage: Image.propTypes.source,
|
|
62
|
+
logoSize: PropTypes.number,
|
|
63
|
+
ecl: PropTypes.oneOf(["L", "M", "Q", "H"]),
|
|
64
|
+
svg: PropTypes.any,
|
|
65
|
+
isRTL: PropTypes.bool,
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
static defaultProps = {
|
|
69
|
+
content: "No Content",
|
|
70
|
+
size: 250,
|
|
71
|
+
padding: 0,
|
|
72
|
+
color: "black",
|
|
73
|
+
gradientDirection: [0, 0, 170, 0],
|
|
74
|
+
backgroundColor: "transparent",
|
|
75
|
+
codeStyle: "square",
|
|
76
|
+
outerEyeStyle: "square",
|
|
77
|
+
innerEyeStyle: "square",
|
|
78
|
+
logoSize: 100,
|
|
79
|
+
ecl: "H",
|
|
80
|
+
isRTL: false,
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
//-----------------------Methods-----------------------
|
|
84
|
+
|
|
85
|
+
//Returns an array of SVG Elements that represent the pieces of the QR Code
|
|
86
|
+
getPieces() {
|
|
87
|
+
var qr = generateQRCode(this.props);
|
|
88
|
+
|
|
89
|
+
var modules = qr.qrcode.modules;
|
|
90
|
+
|
|
91
|
+
var size = this.props.size;
|
|
92
|
+
var length = modules.length;
|
|
93
|
+
var xsize = size / length;
|
|
94
|
+
var ysize = size / length;
|
|
95
|
+
var logoX = this.props.size / 2 - this.props.logoSize / 2;
|
|
96
|
+
var logoY = this.props.size / 2 - this.props.logoSize / 2;
|
|
97
|
+
var logoSize = this.props.logoSize;
|
|
98
|
+
|
|
99
|
+
var pieces = [];
|
|
100
|
+
var nonPieces = [];
|
|
101
|
+
|
|
102
|
+
this.length = length;
|
|
103
|
+
this.ratio = xsize;
|
|
104
|
+
|
|
105
|
+
//Add the SVG element of each piece in the body of the QR Code
|
|
106
|
+
for (var y = 0; y < length; y++) {
|
|
107
|
+
for (var x = 0; x < length; x++) {
|
|
108
|
+
var module = modules[x][y];
|
|
109
|
+
var px = x * xsize;
|
|
110
|
+
var py = y * ysize;
|
|
111
|
+
|
|
112
|
+
//TODO: Add function to compute if pieces overlap with circular logos (more complex. Must see if tl or br is inside the radius from the centre of the circle (pythagoras theorem?))
|
|
113
|
+
var overlapsWithLogo =
|
|
114
|
+
(px > logoX &&
|
|
115
|
+
px < logoX + logoSize &&
|
|
116
|
+
py > logoY &&
|
|
117
|
+
py < logoY + logoSize) || //Piece's top left is inside the logo area
|
|
118
|
+
(px + xsize > logoX &&
|
|
119
|
+
px + xsize < logoX + logoSize &&
|
|
120
|
+
py + ysize > logoY &&
|
|
121
|
+
py + ysize < logoY + logoSize); //Piece's bottom right is inside the logo area
|
|
122
|
+
|
|
123
|
+
if (!this.props.logo || (this.props.logo && !overlapsWithLogo)) {
|
|
124
|
+
if (module) {
|
|
125
|
+
pieces.push(this.getPiece(x, y, modules));
|
|
126
|
+
} else {
|
|
127
|
+
nonPieces.push(this.getPiece(x, y, modules));
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (this.props.backgroundImage) {
|
|
134
|
+
return (
|
|
135
|
+
<View
|
|
136
|
+
style={{
|
|
137
|
+
backgroundColor: "transparent",
|
|
138
|
+
margin: 0,
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
<Image
|
|
142
|
+
source={this.props.backgroundImage}
|
|
143
|
+
style={{
|
|
144
|
+
position: "absolute",
|
|
145
|
+
top: 0,
|
|
146
|
+
left: 0,
|
|
147
|
+
height: this.props.logoSize,
|
|
148
|
+
width: this.props.logoSize,
|
|
149
|
+
}}
|
|
150
|
+
/>
|
|
151
|
+
{this.displayLogo()}
|
|
152
|
+
<Svg
|
|
153
|
+
style={{
|
|
154
|
+
backgroundColor: "transparent",
|
|
155
|
+
height: this.props.logoSize,
|
|
156
|
+
width: this.props.logoSize,
|
|
157
|
+
}}
|
|
158
|
+
>
|
|
159
|
+
<Defs>
|
|
160
|
+
<ClipPath id="clip">{nonPieces}</ClipPath>
|
|
161
|
+
</Defs>
|
|
162
|
+
<Rect
|
|
163
|
+
clipPath="url(#clip)"
|
|
164
|
+
fill="transparent"
|
|
165
|
+
x={0}
|
|
166
|
+
y={0}
|
|
167
|
+
height="100%"
|
|
168
|
+
width="100%"
|
|
169
|
+
/>
|
|
170
|
+
</Svg>
|
|
171
|
+
</View>
|
|
172
|
+
);
|
|
173
|
+
} else if (this.props.linearGradient) {
|
|
174
|
+
return (
|
|
175
|
+
<View>
|
|
176
|
+
<Svg
|
|
177
|
+
style={{
|
|
178
|
+
backgroundColor: this.props.backgroundColor,
|
|
179
|
+
height: this.props.size,
|
|
180
|
+
width: this.props.size,
|
|
181
|
+
}}
|
|
182
|
+
>
|
|
183
|
+
<Defs>
|
|
184
|
+
<ClipPath id="clip">{pieces}</ClipPath>
|
|
185
|
+
<LinearGradient
|
|
186
|
+
id="grad"
|
|
187
|
+
x1={this.props.gradientDirection[0]}
|
|
188
|
+
y1={this.props.gradientDirection[1]}
|
|
189
|
+
x2={this.props.gradientDirection[2]}
|
|
190
|
+
y2={this.props.gradientDirection[3]}
|
|
191
|
+
>
|
|
192
|
+
<Stop
|
|
193
|
+
offset="0"
|
|
194
|
+
stopColor={this.props.linearGradient[0]}
|
|
195
|
+
stopOpacity="1"
|
|
196
|
+
/>
|
|
197
|
+
<Stop
|
|
198
|
+
offset="1"
|
|
199
|
+
stopColor={this.props.linearGradient[1]}
|
|
200
|
+
stopOpacity="1"
|
|
201
|
+
/>
|
|
202
|
+
</LinearGradient>
|
|
203
|
+
</Defs>
|
|
204
|
+
<Rect
|
|
205
|
+
clipPath="url(#clip)"
|
|
206
|
+
fill="transparent"
|
|
207
|
+
x={0}
|
|
208
|
+
y={0}
|
|
209
|
+
height="100%"
|
|
210
|
+
width="100%"
|
|
211
|
+
fill="url(#grad)"
|
|
212
|
+
/>
|
|
213
|
+
</Svg>
|
|
214
|
+
{this.displayLogo()}
|
|
215
|
+
</View>
|
|
216
|
+
);
|
|
217
|
+
} else {
|
|
218
|
+
return (
|
|
219
|
+
<View>
|
|
220
|
+
<Svg
|
|
221
|
+
style={{
|
|
222
|
+
backgroundColor: this.props.backgroundColor,
|
|
223
|
+
height: this.props.size,
|
|
224
|
+
width: this.props.size,
|
|
225
|
+
}}
|
|
226
|
+
>
|
|
227
|
+
<Defs>
|
|
228
|
+
<ClipPath id="clip">{pieces}</ClipPath>
|
|
229
|
+
</Defs>
|
|
230
|
+
<Rect
|
|
231
|
+
clipPath="url(#clip)"
|
|
232
|
+
fill="transparent"
|
|
233
|
+
x={0}
|
|
234
|
+
y={0}
|
|
235
|
+
height="100%"
|
|
236
|
+
width="100%"
|
|
237
|
+
fill={this.props.color}
|
|
238
|
+
/>
|
|
239
|
+
</Svg>
|
|
240
|
+
{this.displayLogo()}
|
|
241
|
+
</View>
|
|
242
|
+
);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
//Renders the logo on top of the QR Code if there is one
|
|
247
|
+
displayLogo() {
|
|
248
|
+
if (this.props.logo && !this.props.svg) {
|
|
249
|
+
return (
|
|
250
|
+
<Image
|
|
251
|
+
source={this.props.logo}
|
|
252
|
+
style={{
|
|
253
|
+
width: this.props.logoSize,
|
|
254
|
+
height: this.props.logoSize,
|
|
255
|
+
position: "absolute",
|
|
256
|
+
left: this.props.size / 2 - this.props.logoSize / 2,
|
|
257
|
+
top: this.props.size / 2 - this.props.logoSize / 2,
|
|
258
|
+
borderRadius: 20,
|
|
259
|
+
}}
|
|
260
|
+
/>
|
|
261
|
+
);
|
|
262
|
+
} else {
|
|
263
|
+
return <View />;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
//Returns an SVG Element that represents the piece of the QR code at modules[x][y]
|
|
268
|
+
getPiece(x, y, modules) {
|
|
269
|
+
//Find out which piece type it is
|
|
270
|
+
var pieceProps = this.getPieceProperties(x, y, modules);
|
|
271
|
+
return drawPiece(x, y, modules, pieceProps, this.props);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
//Returns an object with orientation and pieceType representation of the piece type. (See https://github.com/mpaolino/qrlib/tree/master/qrlib/static)
|
|
275
|
+
getPieceProperties(x, y, modules) {
|
|
276
|
+
var mod_matrix = {};
|
|
277
|
+
mod_matrix.topLeft = x != 0 && y != 0 && modules[x - 1][y - 1];
|
|
278
|
+
mod_matrix.top = y != 0 && modules[x][y - 1];
|
|
279
|
+
mod_matrix.topRight =
|
|
280
|
+
x != modules.length - 1 && y != 0 && modules[x + 1][y - 1];
|
|
281
|
+
mod_matrix.left = x != 0 && modules[x - 1][y];
|
|
282
|
+
mod_matrix.right = x != modules.length - 1 && modules[x + 1][y];
|
|
283
|
+
mod_matrix.bottomLeft =
|
|
284
|
+
x != 0 && y != modules.length - 1 && modules[x - 1][y + 1];
|
|
285
|
+
mod_matrix.bottom = y != modules.length - 1 && modules[x][y + 1];
|
|
286
|
+
mod_matrix.bottomRight =
|
|
287
|
+
x != modules.length - 1 &&
|
|
288
|
+
y != modules.length - 1 &&
|
|
289
|
+
modules[x + 1][y + 1];
|
|
290
|
+
|
|
291
|
+
// (surroundingCount holds the number of pieces above or to the side of this piece)
|
|
292
|
+
var surroundingCount = 0;
|
|
293
|
+
if (mod_matrix.top) {
|
|
294
|
+
surroundingCount++;
|
|
295
|
+
}
|
|
296
|
+
if (mod_matrix.left) {
|
|
297
|
+
surroundingCount++;
|
|
298
|
+
}
|
|
299
|
+
if (mod_matrix.right) {
|
|
300
|
+
surroundingCount++;
|
|
301
|
+
}
|
|
302
|
+
if (mod_matrix.bottom) {
|
|
303
|
+
surroundingCount++;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
var pieceProperties = {};
|
|
307
|
+
var orientation = 0;
|
|
308
|
+
|
|
309
|
+
//Determine what the piece properties are from its surrounding pieces.
|
|
310
|
+
// (surroundingCount holds the number of pieces above or to the side of this piece)
|
|
311
|
+
// (See https://github.com/mpaolino/qrlib/tree/master/qrlib/static)
|
|
312
|
+
switch (surroundingCount) {
|
|
313
|
+
case 0:
|
|
314
|
+
pieceProperties.pieceType = "1a";
|
|
315
|
+
if (mod_matrix.right) {
|
|
316
|
+
orientation = 90;
|
|
317
|
+
} else if (mod_matrix.bottom) {
|
|
318
|
+
orientation = 180;
|
|
319
|
+
} else if (mod_matrix.left) {
|
|
320
|
+
orientation = 270;
|
|
321
|
+
}
|
|
322
|
+
pieceProperties.orientation = orientation;
|
|
323
|
+
return pieceProperties;
|
|
324
|
+
case 1:
|
|
325
|
+
pieceProperties.pieceType = "2b";
|
|
326
|
+
pieceProperties.orientation = 0;
|
|
327
|
+
return pieceProperties;
|
|
328
|
+
case 2:
|
|
329
|
+
if (
|
|
330
|
+
(mod_matrix.top && mod_matrix.bottom) ||
|
|
331
|
+
(mod_matrix.left && mod_matrix.right)
|
|
332
|
+
) {
|
|
333
|
+
var orientation = mod_matrix.top && mod_matrix.bottom ? 0 : 90;
|
|
334
|
+
pieceProperties.pieceType = "1b3b";
|
|
335
|
+
pieceProperties.orientation = orientation;
|
|
336
|
+
return pieceProperties;
|
|
337
|
+
} else {
|
|
338
|
+
var orientation = 0;
|
|
339
|
+
if (mod_matrix.top && mod_matrix.right) {
|
|
340
|
+
pieceProperties.orientation = 90;
|
|
341
|
+
pieceProperties.pieceType = mod_matrix.topRight ? "2a1b1a" : "2a1b";
|
|
342
|
+
return pieceProperties;
|
|
343
|
+
} else if (mod_matrix.right && mod_matrix.bottom) {
|
|
344
|
+
pieceProperties.orientation = 180;
|
|
345
|
+
pieceProperties.pieceType = mod_matrix.bottomRight
|
|
346
|
+
? "2a1b1a"
|
|
347
|
+
: "2a1b";
|
|
348
|
+
return pieceProperties;
|
|
349
|
+
} else if (mod_matrix.left && mod_matrix.bottom) {
|
|
350
|
+
pieceProperties.orientation = 270;
|
|
351
|
+
pieceProperties.pieceType = mod_matrix.bottomLeft
|
|
352
|
+
? "2a1b1a"
|
|
353
|
+
: "2a1b";
|
|
354
|
+
return pieceProperties;
|
|
355
|
+
} else {
|
|
356
|
+
pieceProperties.pieceType = mod_matrix.topLeft ? "2a1b1a" : "2a1b";
|
|
357
|
+
return pieceProperties;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
case 3:
|
|
361
|
+
pieceProperties.pieceType = "2a1b2c";
|
|
362
|
+
var orientation = 0;
|
|
363
|
+
if (mod_matrix.top && mod_matrix.right && mod_matrix.bottom) {
|
|
364
|
+
orientation = 90;
|
|
365
|
+
} else if (mod_matrix.right && mod_matrix.bottom && mod_matrix.left) {
|
|
366
|
+
orientation = 180;
|
|
367
|
+
} else if (mod_matrix.bottom && mod_matrix.left && mod_matrix.top) {
|
|
368
|
+
orientation = 270;
|
|
369
|
+
}
|
|
370
|
+
pieceProperties.orientation = orientation;
|
|
371
|
+
return pieceProperties;
|
|
372
|
+
case 4:
|
|
373
|
+
pieceProperties.pieceType = "2a1b2c3b";
|
|
374
|
+
pieceProperties.orientation = 0;
|
|
375
|
+
return pieceProperties;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
//---------------------Rendering-----------------------
|
|
380
|
+
|
|
381
|
+
render() {
|
|
382
|
+
let pieces = this.getPieces();
|
|
383
|
+
let eyeSize = 7 * this.ratio;
|
|
384
|
+
let eyeCoords = [
|
|
385
|
+
[0, 0], // top left
|
|
386
|
+
[0, this.props.size - eyeSize], // bottom left
|
|
387
|
+
[this.props.size - eyeSize, 0], // top right
|
|
388
|
+
];
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
<View>
|
|
392
|
+
<QRView size={this.props.size}>
|
|
393
|
+
{pieces}
|
|
394
|
+
{eyeCoords.map((eyeCoord, index) => (
|
|
395
|
+
<Eyes
|
|
396
|
+
key={index}
|
|
397
|
+
outerEyeStyle={this.props.outerEyeStyle}
|
|
398
|
+
innerEyeStyle={this.props.innerEyeStyle}
|
|
399
|
+
size={eyeSize}
|
|
400
|
+
color={this.props.color}
|
|
401
|
+
x={
|
|
402
|
+
this.props.isRTL
|
|
403
|
+
? this.props.size - eyeCoord[0] - eyeSize
|
|
404
|
+
: eyeCoord[0]
|
|
405
|
+
}
|
|
406
|
+
y={eyeCoord[1]}
|
|
407
|
+
ratio={this.ratio}
|
|
408
|
+
/>
|
|
409
|
+
))}
|
|
410
|
+
</QRView>
|
|
411
|
+
<View
|
|
412
|
+
style={{
|
|
413
|
+
position: "absolute",
|
|
414
|
+
top: 0,
|
|
415
|
+
left: 0,
|
|
416
|
+
right: 0,
|
|
417
|
+
bottom: 0,
|
|
418
|
+
justifyContent: "center",
|
|
419
|
+
alignItems: "center",
|
|
420
|
+
}}
|
|
421
|
+
>
|
|
422
|
+
<View
|
|
423
|
+
style={{
|
|
424
|
+
position: "absolute",
|
|
425
|
+
backgroundColor: this.props.logo,
|
|
426
|
+
height: 60,
|
|
427
|
+
width: 60,
|
|
428
|
+
borderRadius: 20,
|
|
429
|
+
}}
|
|
430
|
+
/>
|
|
431
|
+
{this.props.svg}
|
|
432
|
+
</View>
|
|
433
|
+
</View>
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
class Eyes extends React.Component {
|
|
439
|
+
constructor(props) {
|
|
440
|
+
super(props);
|
|
441
|
+
this.size = this.props.size;
|
|
442
|
+
this.ratio = this.props.ratio;
|
|
443
|
+
|
|
444
|
+
/* XY coordinates (right-to-bottom) */
|
|
445
|
+
this.x = this.props.x;
|
|
446
|
+
this.y = this.props.y;
|
|
447
|
+
|
|
448
|
+
this.outerEyeStyle = this.drawEyeStyle(this.props.outerEyeStyle, "outer");
|
|
449
|
+
this.innerEyeStyle = this.drawEyeStyle(this.props.innerEyeStyle, "inner");
|
|
450
|
+
|
|
451
|
+
this.color = this.props.color;
|
|
452
|
+
|
|
453
|
+
/* innerEye variables */
|
|
454
|
+
this.inSize = 3 * this.ratio;
|
|
455
|
+
this.inX = this.ratio;
|
|
456
|
+
this.inY = this.ratio;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
drawEyeStyle(style, type) {
|
|
460
|
+
if (type === "outer") {
|
|
461
|
+
return ["diamond", "circles"].includes(style) ? null : style;
|
|
462
|
+
}
|
|
463
|
+
return ["diamond", "circles"].includes(style) ? null : style;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
render() {
|
|
467
|
+
return (
|
|
468
|
+
<Container size={this.size}>
|
|
469
|
+
<EyeShape
|
|
470
|
+
type={this.outerEyeStyle}
|
|
471
|
+
size={this.size}
|
|
472
|
+
leftCornerX={this.x}
|
|
473
|
+
leftCornerY={this.y}
|
|
474
|
+
color={this.color}
|
|
475
|
+
border
|
|
476
|
+
borderWidth={this.ratio}
|
|
477
|
+
>
|
|
478
|
+
<EyeShape
|
|
479
|
+
type={this.innerEyeStyle}
|
|
480
|
+
size={this.inSize}
|
|
481
|
+
leftCornerX={this.inX}
|
|
482
|
+
leftCornerY={this.inY}
|
|
483
|
+
color={this.color}
|
|
484
|
+
borderWidth={this.ratio}
|
|
485
|
+
/>
|
|
486
|
+
</EyeShape>
|
|
487
|
+
</Container>
|
|
488
|
+
);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
const EyeShape = styled.View`
|
|
493
|
+
height: ${(props) => props.size}px;
|
|
494
|
+
width: ${(props) => props.size}px;
|
|
495
|
+
background-color: ${(props) =>
|
|
496
|
+
props.border || !props.type ? "transparent" : props.color};
|
|
497
|
+
top: ${(props) => props.leftCornerY}px;
|
|
498
|
+
left: ${(props) => props.leftCornerX}px;
|
|
499
|
+
border-radius: ${(props) => {
|
|
500
|
+
switch (props.type) {
|
|
501
|
+
case "circle":
|
|
502
|
+
return props.size;
|
|
503
|
+
case "rounded":
|
|
504
|
+
return props.size / 5;
|
|
505
|
+
default:
|
|
506
|
+
return 0;
|
|
507
|
+
}
|
|
508
|
+
}}px;
|
|
509
|
+
border-color: ${(props) =>
|
|
510
|
+
props.border && props.type ? props.color : "transparent"};
|
|
511
|
+
border-width: ${(props) => {
|
|
512
|
+
if (!props.border) {
|
|
513
|
+
return 0;
|
|
514
|
+
}
|
|
515
|
+
return props.borderWidth;
|
|
516
|
+
}}px;
|
|
517
|
+
`;
|
|
518
|
+
|
|
519
|
+
const Container = styled.View`
|
|
520
|
+
position: absolute;
|
|
521
|
+
height: ${(props) => props.size}px;
|
|
522
|
+
width: ${(props) => props.size}px;
|
|
523
|
+
`;
|
|
524
|
+
|
|
525
|
+
const QRView = styled.View`
|
|
526
|
+
position: relative;
|
|
527
|
+
height: ${(props) => props.size}px;
|
|
528
|
+
width: ${(props) => props.size}px;
|
|
529
|
+
`;
|