-
Notifications
You must be signed in to change notification settings - Fork 13
/
index.html
272 lines (239 loc) · 79.6 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
<!DOCTYPE html><html data-reactid=".1c0hi1r0074" data-react-checksum="402388454"><head data-reactid=".1c0hi1r0074.0"><meta charset="utf-8" data-reactid=".1c0hi1r0074.0.0"><title data-reactid=".1c0hi1r0074.0.1">Building SVG Icons with React</title><meta name="viewport" content="width=device-width,initial-scale=1" data-reactid=".1c0hi1r0074.0.2"><meta name="description" content="How to Create Mathematically-Generated Graphics Using JavaScript and React" data-reactid=".1c0hi1r0074.0.3"><meta name="keywords" content="react, svg, icon, icons, tutorial" data-reactid=".1c0hi1r0074.0.4"><style data-reactid=".1c0hi1r0074.0.5">body{margin:0}img{max-width:100%}svg{max-height:100%}body{font-family:SF UI Text,Roboto,Helvetica Neue,Helvetica,sans-serif;line-height:1.5;font-size:100%}h1,h2,h3,h4,h5,h6{font-family:SF UI Display,Roboto,Helvetica Neue,Helvetica,sans-serif;font-weight:700;line-height:1.25;margin-top:1em;margin-bottom:.5em}dl,ol,p,ul{font-size:1pc;font-size:1rem;margin-top:0;margin-bottom:1pc;margin-bottom:1rem}code,pre,samp{font-family:Source Code Pro,Consolas,monospace;font-size:87.5%}pre{margin-top:0;margin-bottom:1pc;margin-bottom:1rem;overflow-x:scroll}h1{font-size:2pc;font-size:2rem}h2{font-size:24px;font-size:1.5rem}h3{font-size:20px;font-size:1.25rem}h4{font-size:1pc;font-size:1rem}h5{font-size:14px;font-size:.875rem}h6{font-size:9pt;font-size:.75rem}body{color:#172c36;background-color:#fff}a{color:#007bbd;text-decoration:none}a:hover{text-decoration:underline}code,pre{background-color:transparent;border-radius:3px}hr{border:0;border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#000;border-bottom-color:rgba(0,0,0,.125)}.btn{font-family:inherit;font-size:14px;font-size:.875rem;font-weight:700;cursor:pointer;display:inline-block;line-height:18px;line-height:1.125rem;padding:8px 1pc;padding:.5rem 1rem;margin:0;height:auto;border:1px solid transparent;vertical-align:middle;-webkit-appearance:none;color:inherit;background-color:transparent}.btn,.btn:hover{text-decoration:none}.btn:hover{border:1px solid #000;border:1px solid rgba(0,0,0,.0625);box-shadow:inset 0 0 0 20rem #000;box-shadow:inset 0 0 0 20rem rgba(0,0,0,.0625)}.btn:focus{outline:0;border-color:#000;border-color:rgba(0,0,0,.125);box-shadow:0 0 0 3px #000;box-shadow:0 0 0 3px rgba(0,0,0,.25)}.btn.is-active,.btn:active{box-shadow:inset 0 0 0 20rem rgba(0,0,0,.125),inset 0 3px 4px 0 rgba(0,0,0,.25),0 0 1px #000;box-shadow:inset 0 0 0 20rem rgba(0,0,0,.125),inset 0 3px 4px 0 rgba(0,0,0,.25),0 0 1px rgba(0,0,0,.125)}.btn.is-disabled,.btn:disabled{opacity:.5}.btn-primary{color:#fff;background-color:#007bbd;border-radius:3px}.btn-outline,.btn-outline:hover{border-color:currentcolor;border-radius:3px}::-moz-focus-inner{border:0;padding:0}.h1{font-size:2pc;font-size:2rem}.h2{font-size:24px;font-size:1.5rem}.h3{font-size:20px;font-size:1.25rem}.h4{font-size:1pc;font-size:1rem}.h5{font-size:14px;font-size:.875rem}.h6{font-size:9pt;font-size:.75rem}.bold{font-weight:700}.regular{font-weight:400}.italic{font-style:italic}.caps{text-transform:uppercase;letter-spacing:.2em}.left-align{text-align:left}.center{text-align:center}.right-align{text-align:right}.justify{text-align:justify}.nowrap{white-space:nowrap}.break-word{word-wrap:break-word}.truncate{max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.list-reset{list-style:none;padding-left:0}.inline{display:inline}.block{display:block}.inline-block{display:inline-block}.table{display:table}.table-cell{display:table-cell}.overflow-hidden{overflow:hidden}.overflow-scroll{overflow:scroll}.overflow-auto{overflow:auto}.clearfix:after,.clearfix:before{content:" ";display:table}.clearfix:after{clear:both}.left{float:left}.right{float:right}.fit{max-width:100%}.border-box{box-sizing:border-box}.m0{margin:0}.mt0{margin-top:0}.mr0{margin-right:0}.mb0{margin-bottom:0}.ml0{margin-left:0}.m1{margin:8px;margin:.5rem}.mt1{margin-top:8px;margin-top:.5rem}.mr1{margin-right:8px;margin-right:.5rem}.mb1{margin-bottom:8px;margin-bottom:.5rem}.ml1{margin-left:8px;margin-left:.5rem}.m2{margin:1pc;margin:1rem}.mt2{margin-top:1pc;margin-top:1rem}.mr2{margin-right:1pc;margin-right:1rem}.mb2{margin-bottom:1pc;margin-bottom:1rem}.ml2{margin-left:1pc;margin-left:1rem}.m3{margin:2pc;margin:2rem}.mt3{margin-top:2pc;margin-top:2rem}.mr3{margin-right:2pc;margin-right:2rem}.mb3{margin-bottom:2pc;margin-bottom:2rem}.ml3{margin-left:2pc;margin-left:2rem}.m4{margin:4pc;margin:4rem}.mt4{margin-top:4pc;margin-top:4rem}.mr4{margin-right:4pc;margin-right:4rem}.mb4{margin-bottom:4pc;margin-bottom:4rem}.ml4{margin-left:4pc;margin-left:4rem}.mxn1{margin-left:-8px;margin-left:-.5rem;margin-right:-8px;margin-right:-.5rem}.mxn2{margin-left:-1pc;margin-left:-1rem;margin-right:-1pc;margin-right:-1rem}.mxn3{margin-left:-2pc;margin-left:-2rem;margin-right:-2pc;margin-right:-2rem}.mxn4{margin-left:-4pc;margin-left:-4rem;margin-right:-4pc;margin-right:-4rem}.mx-auto{margin-left:auto;margin-right:auto}.p1{padding:8px;padding:.5rem}.py1{padding-top:8px;padding-top:.5rem;padding-bottom:8px;padding-bottom:.5rem}.px1{padding-left:8px;padding-left:.5rem;padding-right:8px;padding-right:.5rem}.p2{padding:1pc;padding:1rem}.py2{padding-top:1pc;padding-top:1rem;padding-bottom:1pc;padding-bottom:1rem}.px2{padding-left:1pc;padding-left:1rem;padding-right:1pc;padding-right:1rem}.p3{padding:2pc;padding:2rem}.py3{padding-top:2pc;padding-top:2rem;padding-bottom:2pc;padding-bottom:2rem}.px3{padding-left:2pc;padding-left:2rem;padding-right:2pc;padding-right:2rem}.p4{padding:4pc;padding:4rem}.py4{padding-top:4pc;padding-top:4rem;padding-bottom:4pc;padding-bottom:4rem}.px4{padding-left:4pc;padding-left:4rem;padding-right:4pc;padding-right:4rem}.container{max-width:8in;max-width:48rem;margin-left:auto;margin-right:auto}.col{float:left}.col,.col-right{box-sizing:border-box}.col-right{float:right}.col-1{width:8.33333%}.col-2{width:16.66667%}.col-3{width:25%}.col-4{width:33.33333%}.col-5{width:41.66667%}.col-6{width:50%}.col-7{width:58.33333%}.col-8{width:66.66667%}.col-9{width:75%}.col-10{width:83.33333%}.col-11{width:91.66667%}.col-12{width:100%}@media (min-width:40em){.sm-col{float:left;box-sizing:border-box}.sm-col-right{float:right;box-sizing:border-box}.sm-col-1{width:8.33333%}.sm-col-2{width:16.66667%}.sm-col-3{width:25%}.sm-col-4{width:33.33333%}.sm-col-5{width:41.66667%}.sm-col-6{width:50%}.sm-col-7{width:58.33333%}.sm-col-8{width:66.66667%}.sm-col-9{width:75%}.sm-col-10{width:83.33333%}.sm-col-11{width:91.66667%}.sm-col-12{width:100%}}@media (min-width:52em){.md-col{float:left;box-sizing:border-box}.md-col-right{float:right;box-sizing:border-box}.md-col-1{width:8.33333%}.md-col-2{width:16.66667%}.md-col-3{width:25%}.md-col-4{width:33.33333%}.md-col-5{width:41.66667%}.md-col-6{width:50%}.md-col-7{width:58.33333%}.md-col-8{width:66.66667%}.md-col-9{width:75%}.md-col-10{width:83.33333%}.md-col-11{width:91.66667%}.md-col-12{width:100%}}@media (min-width:64em){.lg-col{float:left;box-sizing:border-box}.lg-col-right{float:right;box-sizing:border-box}.lg-col-1{width:8.33333%}.lg-col-2{width:16.66667%}.lg-col-3{width:25%}.lg-col-4{width:33.33333%}.lg-col-5{width:41.66667%}.lg-col-6{width:50%}.lg-col-7{width:58.33333%}.lg-col-8{width:66.66667%}.lg-col-9{width:75%}.lg-col-10{width:83.33333%}.lg-col-11{width:91.66667%}.lg-col-12{width:100%}}.flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.flex-column{-webkit-box-orient:vertical;-webkit-box-direction:normal;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column}.flex-wrap{-webkit-flex-wrap:wrap;-ms-flex-wrap:wrap;flex-wrap:wrap}.flex-center{-webkit-box-align:center;-webkit-align-items:center;-ms-flex-align:center;align-items:center}.flex-baseline{-webkit-box-align:baseline;-webkit-align-items:baseline;-ms-flex-align:baseline;align-items:baseline}.flex-stretch{-webkit-box-align:stretch;-webkit-align-items:stretch;-ms-flex-align:stretch;align-items:stretch}.flex-start{-webkit-box-align:start;-webkit-align-items:flex-start;-ms-flex-align:start;align-items:flex-start}.flex-end{-webkit-box-align:end;-webkit-align-items:flex-end;-ms-flex-align:end;align-items:flex-end}.flex-justify{-webkit-box-pack:justify;-webkit-justify-content:space-between;-ms-flex-pack:justify;justify-content:space-between}.flex-first{-webkit-box-ordinal-group:0;-webkit-order:-1;-ms-flex-order:-1;order:-1}.flex-last{-webkit-box-ordinal-group:1025;-webkit-order:1024;-ms-flex-order:1024;order:1024}.flex-auto{-webkit-box-flex:1;-webkit-flex:1 1 auto;-ms-flex:1 1 auto;flex:1 1 auto}.flex-grow{-webkit-box-flex:1;-webkit-flex:1 0 auto;-ms-flex:1 0 auto;flex:1 0 auto}.flex-none{-webkit-box-flex:0;-webkit-flex:none;-ms-flex:none;flex:none}.flex>div{box-sizing:border-box}@media (min-width:40em){.sm-flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.sm-flex>div{box-sizing:border-box}}@media (min-width:52em){.md-flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.md-flex>div{box-sizing:border-box}}@media (min-width:64em){.lg-flex{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}.lg-flex>div{box-sizing:border-box}}.border{border:1px solid #000;border-color:rgba(0,0,0,.125)}.border-top{border-top-style:solid;border-top-width:1px;border-top-color:#000;border-top-color:rgba(0,0,0,.125)}.border-right{border-right-style:solid;border-right-width:1px;border-right-color:#000;border-right-color:rgba(0,0,0,.125)}.border-bottom{border-bottom-style:solid;border-bottom-width:1px;border-bottom-color:#000;border-bottom-color:rgba(0,0,0,.125)}.border-left{border-left-style:solid;border-left-width:1px;border-left-color:#000;border-left-color:rgba(0,0,0,.125)}.rounded{border-radius:3px}.circle{border-radius:50%}.rounded-top{border-radius:3px 3px 0 0}.rounded-right{border-radius:0 3px 3px 0}.rounded-bottom{border-radius:0 0 3px 3px}.rounded-left{border-radius:3px 0 0 3px}.not-rounded{border-radius:0}.black{color:#111}.gray{color:#aaa}.silver{color:#ddd}.white{color:#fff}.aqua{color:#7fdbff}.blue{color:#007bbd}.navy{color:#001f3f}.teal{color:#39cccc}.green{color:#00a865}.olive{color:#3d9970}.lime{color:#01ff70}.yellow{color:#ffdc00}.orange{color:#ff851b}.red{color:#ff6200}.fuchsia{color:#f012be}.purple{color:#b10dc9}.maroon{color:#85144b}.color-inherit{color:inherit}.muted{opacity:.5}.bg-black{background-color:#111}.bg-gray{background-color:#aaa}.bg-silver{background-color:#ddd}.bg-white{background-color:#fff}.bg-aqua{background-color:#7fdbff}.bg-blue{background-color:#007bbd}.bg-navy{background-color:#001f3f}.bg-teal{background-color:#39cccc}.bg-green{background-color:#00a865}.bg-olive{background-color:#3d9970}.bg-lime{background-color:#01ff70}.bg-yellow{background-color:#ffdc00}.bg-orange{background-color:#ff851b}.bg-red{background-color:#ff6200}.bg-fuchsia{background-color:#f012be}.bg-purple{background-color:#b10dc9}.bg-maroon{background-color:#85144b}.bg-darken-1{background-color:#000;background-color:rgba(0,0,0,.0625)}.bg-darken-2{background-color:#000;background-color:rgba(0,0,0,.125)}.bg-darken-3{background-color:#000;background-color:rgba(0,0,0,.25)}.bg-darken-4{background-color:#000;background-color:rgba(0,0,0,.5)}.prose{font-family:Georgia,serif;font-size:1pc;font-size:1rem}.prose dl,.prose ol,.prose p,.prose ul{font-size:inherit}.prose p:first-child{font-size:20px;font-size:1.25rem}.prose img{height:auto}.prose figcaption{font-family:SF UI Text,Roboto,Helvetica Neue,Helvetica,sans-serif;font-size:14px;font-size:.875rem}@media (min-width:40em){.prose,.serif{font-size:1.25rem}.prose p:first-child{font-size:1.5rem}}h1 a,h2 a,h3 a,h4 a,h5 a,h6 a{color:inherit;text-decoration:none}h1 a:hover,h2 a:hover,h3 a:hover,h4 a:hover,h5 a:hover,h6 a:hover{text-decoration:underline}pre{padding:0 24px;padding:0 1.5rem;border-left:4px solid #000;border-left:4px solid rgba(0,0,0,.0625)}.caps{letter-spacing:.1em}.sans{font-family:SF UI Text,Roboto,Helvetica Neue,Helvetica,sans-serif}.serif{font-family:Georgia,serif}.compact{font-family:SF Compact Text,Roboto,Helvetica Neue,Helvetica,sans-serif}.icon{position:relative;top:.125em}.btn:hover{box-shadow:inset 0 99999px #7fdbff;box-shadow:inset 0 99999px rgba(127,219,255,.0625)}.btn-link:hover{text-decoration:underline;box-shadow:none}.btn-narrow{padding-left:8px;padding-left:.5rem;padding-right:8px;padding-right:.5rem}.slate{color:#172c36}.brightblue{color:#33b8ff}.bg-slate{background-color:#172c36}.bg-brightblue{background-color:#33b8ff}input[type=range]{vertical-align:middle;background-color:transparent;padding-top:8px;padding-top:.5rem;padding-bottom:8px;padding-bottom:.5rem}input[type=range]::-webkit-slider-thumb{position:relative;width:8px;width:.5rem;height:20px;height:1.25rem;cursor:pointer;margin-top:-8px;margin-top:-.5rem}input[type=range]::-webkit-slider-thumb:before{content:'';display:block;position:absolute;top:-8px;top:-.5rem;left:-14px;left:-.875rem;width:36px;width:2.25rem;height:36px;height:2.25rem;opacity:0}input[type=range]::-moz-range-thumb{width:8px;width:.5rem;height:20px;height:1.25rem;cursor:pointer}input[type=range]::-webkit-slider-runnable-track{height:4px;height:.25rem;cursor:pointer}input[type=range]::-moz-range-track{height:4px;height:.25rem;cursor:pointer}.range-light{color:inherit;background-color:transparent;-webkit-appearance:none}.range-light::-webkit-slider-thumb{-webkit-appearance:none;border-radius:3px;background-color:currentcolor}.range-light::-moz-range-thumb{border-radius:3px;border-color:transparent;border-width:0;background-color:currentcolor}.range-light::-webkit-slider-runnable-track{border-radius:3px;background-color:#000;background-color:rgba(0,0,0,.25)}.range-light::-moz-range-track{border-radius:3px;background-color:#000;background-color:rgba(0,0,0,.25)}.range-light:focus{outline:0}.range-light:focus::-webkit-slider-thumb{outline:0;border:0;box-shadow:0 0 1px 2px currentcolor}.range-light:focus::-moz-range-thumb{outline:0;border:0;box-shadow:0 0 0 3px #000;box-shadow:0 0 0 3px rgba(0,0,0,.25)}.hljs{-webkit-text-size-adjust:none}.diff .hljs-header,.hljs-comment,.hljs-javadoc{color:#aaa;font-style:italic}.css .rule .hljs-keyword,.hljs-keyword,.hljs-request,.hljs-status,.hljs-subst,.hljs-winutils,.nginx .hljs-title{color:#111;font-weight:700}.hljs-hexcolor,.hljs-number,.ruby .hljs-constant{color:#3d9970}.hljs-dartdoc,.hljs-phpdoc,.hljs-string,.hljs-tag .hljs-value,.tex .hljs-formula{color:#ff6200}.hljs-id,.hljs-title,.scss .hljs-preprocessor{color:#ff6200;font-weight:700}.hljs-list .hljs-keyword,.hljs-subst{font-weight:400}.hljs-class .hljs-title,.hljs-type,.tex .hljs-command,.vhdl .hljs-literal{color:#001f3f;font-weight:700}.django .hljs-tag .hljs-keyword,.hljs-rules .hljs-property,.hljs-tag,.hljs-tag .hljs-title{color:#001f3f;font-weight:400}.hljs-attribute,.hljs-regexp,.hljs-variable,.lisp .hljs-body{color:#3d9970}.clojure .hljs-keyword,.hljs-prompt,.hljs-symbol,.lisp .hljs-keyword,.ruby .hljs-symbol .hljs-string,.scheme .hljs-keyword,.tex .hljs-special{color:#b10dc9}.hljs-built_in{color:#001f3f}.hljs-cdata,.hljs-doctype,.hljs-pi,.hljs-pragma,.hljs-preprocessor,.hljs-shebang{color:#aaa;font-weight:700}.hljs-deletion{background:#f012be}.hljs-addition{background:#01ff70}.diff .hljs-change{background:#001f3f}.hljs-chunk{color:#ddd}svg{max-width:100%;height:auto;max-height:100%}.prose pre{font-size:75%}</style></head><body class="p3 container" data-reactid=".1c0hi1r0074.1"><div class="mb2 center" data-reactid=".1c0hi1r0074.1.0"><svg viewBox="0 0 320 320" width="320" height="320" fill="currentcolor" data-reactid=".1c0hi1r0074.1.0.0"><path d="M 140.26588221812182 0 L 179.73411778187818 0 L 189.33840332223883 53.98463276250162 A 110 110 0 0 1 214.21880114527625 64.29043097804175 L 259.1829564855475 32.908786505852305 L 287.0912134941477 60.81704351445251 L 255.70956902195826 105.78119885472377 A 110 110 0 0 1 266.01536723749837 130.66159667776117 L 320 140.26588221812182 L 320 179.73411778187818 L 266.01536723749837 189.33840332223883 A 110 110 0 0 1 255.70956902195826 214.21880114527625 L 287.0912134941477 259.1829564855475 L 259.1829564855475 287.0912134941477 L 214.21880114527625 255.70956902195826 A 110 110 0 0 1 189.33840332223883 266.01536723749837 L 179.73411778187818 320 L 140.26588221812182 320 L 130.6615966777612 266.01536723749837 A 110 110 0 0 1 105.78119885472375 255.70956902195826 L 60.81704351445251 287.0912134941477 L 32.908786505852305 259.1829564855475 L 64.29043097804175 214.21880114527625 A 110 110 0 0 1 53.98463276250163 189.3384033222389 L 0 179.7341177818782 L 0 140.26588221812185 L 53.98463276250159 130.66159667776125 A 110 110 0 0 1 64.29043097804177 105.78119885472373 L 32.90878650585226 60.81704351445251 L 60.817043514452465 32.908786505852305 L 105.78119885472374 64.29043097804175 A 110 110 0 0 1 130.66159667776117 53.98463276250162 M 160 100 A 60 60 0 0 0 160 220 A 60 60 0 0 0 160 100" data-reactid=".1c0hi1r0074.1.0.0.0"></path><g data-reactid=".1c0hi1r0074.1.0.0.1"><circle style="fill:none;stroke:#FF4136;stroke-width:1;opacity:0.75;" cx="160" cy="160" r="160" data-reactid=".1c0hi1r0074.1.0.0.1.0"></circle><circle style="fill:none;stroke:#FF4136;stroke-width:1;opacity:0.75;" cx="160" cy="160" r="110" data-reactid=".1c0hi1r0074.1.0.0.1.1"></circle><circle style="fill:none;stroke:#FF4136;stroke-width:1;opacity:0.75;" cx="160" cy="160" r="60" data-reactid=".1c0hi1r0074.1.0.0.1.2"></circle><path d="M 160 160 L 160 0 M 160 160 L 273.1370849898476 46.862915010152406 M 160 160 L 320 160 M 160 160 L 273.1370849898476 273.1370849898476 M 160 160 L 160 320 M 160 160 L 46.862915010152406 273.1370849898476 M 160 160 L 0 160.00000000000003 M 160 160 L 46.86291501015236 46.862915010152406" style="fill:none;stroke:#FF4136;stroke-width:1;opacity:0.75;" data-reactid=".1c0hi1r0074.1.0.0.1.3"></path><path d="M 176.0027654484939 102.17343605227362 L 202.67404119598376 5.795829472729622 M 189.57389153378705 107.79478053347732 L 238.86371075676544 20.786081422606173 M 212.2052194665227 130.42610846621295 L 299.2139185773938 81.13628924323457 M 217.82656394772638 143.9972345515061 L 314.2041705272704 117.32595880401625 M 217.82656394772638 176.0027654484939 L 314.2041705272704 202.67404119598376 M 212.2052194665227 189.57389153378705 L 299.2139185773938 238.86371075676544 M 189.57389153378705 212.2052194665227 L 238.86371075676544 299.2139185773938 M 176.0027654484939 217.82656394772638 L 202.67404119598376 314.2041705272704 M 143.9972345515061 217.82656394772638 L 117.32595880401627 314.2041705272704 M 130.42610846621295 212.2052194665227 L 81.13628924323456 299.2139185773938 M 107.79478053347732 189.57389153378705 L 20.786081422606173 238.86371075676547 M 102.17343605227362 176.00276544849393 L 5.79582947272965 202.67404119598382 M 102.17343605227359 143.99723455150612 L 5.795829472729594 117.32595880401635 M 107.79478053347732 130.42610846621295 L 20.786081422606202 81.13628924323451 M 130.42610846621295 107.79478053347732 L 81.13628924323453 20.786081422606173 M 143.9972345515061 102.17343605227362 L 117.32595880401624 5.795829472729622" style="fill:none;stroke:#FF4136;stroke-width:1;opacity:0.25;" data-reactid=".1c0hi1r0074.1.0.0.1.4"></path></g></svg></div><header class="py3 sm-flex flex-wrap flex-center" data-reactid=".1c0hi1r0074.1.1"><div class="flex-auto mxn1" data-reactid=".1c0hi1r0074.1.1.0"><div class="" data-reactid=".1c0hi1r0074.1.1.0.0"><a href="http://jxnblk.com" class="h5 bold caps compact px1 color-inherit" data-reactid=".1c0hi1r0074.1.1.0.0.0">Jxnblk</a></div><h1 class="m0" data-reactid=".1c0hi1r0074.1.1.0.1"><a class="inline-block px1" data-reactid=".1c0hi1r0074.1.1.0.1.0">Building SVG Icons with React</a></h1><p class="h3 m0 px1" data-reactid=".1c0hi1r0074.1.1.0.2">How to Create Mathematically-Generated Graphics Using JavaScript and React</p></div><div class="mxn1" data-reactid=".1c0hi1r0074.1.1.1"><a href="#live-demo" class="btn btn-narrow btn-link" data-reactid=".1c0hi1r0074.1.1.1.$0">View Demo</a><a href="//github.com/jxnblk/react-icons" class="btn btn-narrow btn-link" data-reactid=".1c0hi1r0074.1.1.1.$1">GitHub</a></div></header><div class="right-align py3" data-reactid=".1c0hi1r0074.1.2"><div class="inline-block" data-reactid=".1c0hi1r0074.1.2.0"><a href="https://twitter.com/share" class="twitter-share-button" data-text="Building SVG icons with React" data-via="jxnblk" data-size="large" data-reactid=".1c0hi1r0074.1.2.0.0">Tweet</a><script data-reactid=".1c0hi1r0074.1.2.0.1">!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?"http":"https";if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document, "script", "twitter-wjs");</script></div></div><div class="prose" data-reactid=".1c0hi1r0074.1.3"><p data-reactid=".1c0hi1r0074.1.3.0">While traditional graphics applications like Adobe Illustrator work well for certain tasks, they fall short when used to create pixel perfect, mathematically-derived graphics. Anyone who’s attempted to create data visualizations with such software might have encountered these limitations. And while JavaScript libraries like D3 have helped out tremendously, certain types of illustrations and icons can still be difficult to create, and tools like Illustrator leave a lot of room for error.</p><div class="center py2 mb2" data-reactid=".1c0hi1r0074.1.3.1"><svg viewBox="0 0 128 128" width="128" height="128" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1.0"><path d="M 56.106352887248725 0 L 71.89364711275128 0 L 75.73536132889554 21.593853105000647 A 44 44 0 0 1 85.6875204581105 25.716172391216702 L 103.673182594219 13.163514602340923 L 114.83648539765908 24.326817405781 L 102.2838276087833 42.31247954188951 A 44 44 0 0 1 106.40614689499935 52.26463867110447 L 128 56.106352887248725 L 128 71.89364711275128 L 106.40614689499935 75.73536132889554 A 44 44 0 0 1 102.2838276087833 85.6875204581105 L 114.83648539765908 103.673182594219 L 103.673182594219 114.83648539765908 L 85.6875204581105 102.2838276087833 A 44 44 0 0 1 75.73536132889554 106.40614689499935 L 71.89364711275128 128 L 56.106352887248725 128 L 52.26463867110448 106.40614689499935 A 44 44 0 0 1 42.3124795418895 102.2838276087833 L 24.326817405781 114.83648539765908 L 13.163514602340923 103.673182594219 L 25.716172391216702 85.6875204581105 A 44 44 0 0 1 21.593853105000655 75.73536132889555 L 0 71.8936471127513 L 0 56.10635288724874 L 21.59385310500064 52.26463867110449 A 44 44 0 0 1 25.716172391216702 42.31247954188949 L 13.16351460234091 24.326817405781004 L 24.326817405780986 13.163514602340921 L 42.312479541889495 25.716172391216702 A 44 44 0 0 1 52.264638671104464 21.593853105000647 M 64 40 A 24 24 0 0 0 64 88 A 24 24 0 0 0 64 40" data-reactid=".1c0hi1r0074.1.3.1.0.0"></path></svg></div><p data-reactid=".1c0hi1r0074.1.3.2">Take a settings cog icon as an example. It relies on radial symmetry and is based on three concentric circles, where lines from each tooth must intersect at points not easily determined within a two dimensional grid. Creating something like this in graphics software would require using transformations every time an adjustment was made. Luckily, some basic math can help out, and JavaScript excels at making these sorts of calculations.</p><p data-reactid=".1c0hi1r0074.1.3.3">Although most of this could be achieved with plain JavaScript and other templating engines, using a library like React provides high cohesion between the SVG code and the math involved, keeps things encapsulated into a single requirable component, and provides an easy way to render static markup.</p><p class="h5" data-reactid=".1c0hi1r0074.1.3.4">Note: this tutorial focuses on using React as a stand-alone exploratory design tool, rather than as a way to implement SVG icons within a React application.</p><h2 id="making-a-cog-icon" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.5"><a href="#making-a-cog-icon" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.5.0">Making a Cog Icon</a></h2><figure class="center mb3" data-reactid=".1c0hi1r0074.1.3.6"><img src="http://jxnblk.s3.amazonaws.com/assets/images/cog-sketch-bw.jpg" alt="Cog icon sketch" width="320" class="fit" data-reactid=".1c0hi1r0074.1.3.6.0"><figcaption data-reactid=".1c0hi1r0074.1.3.6.1">Icon sketch made using a salt shaker, Sixpoint can, and a quarter</figcaption></figure><p data-reactid=".1c0hi1r0074.1.3.7">Looking at this sketch, there are some properties that can be handled with JavaScript variables:</p><ul data-reactid=".1c0hi1r0074.1.3.8"><li data-reactid=".1c0hi1r0074.1.3.8.0">Overall dimensions</li><li data-reactid=".1c0hi1r0074.1.3.8.1">The radii for the three concentric circles</li><li data-reactid=".1c0hi1r0074.1.3.8.2">The number of flat-edged, splayed teeth around the outside</li><li data-reactid=".1c0hi1r0074.1.3.8.3">The angle of each tooth</li><li data-reactid=".1c0hi1r0074.1.3.8.4">Fill color for the SVG</li></ul><h2 id="initial-setup" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.9"><a href="#initial-setup" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.9.0">Initial Setup</a></h2><p data-reactid=".1c0hi1r0074.1.3.a"><span data-reactid=".1c0hi1r0074.1.3.a.0">To get started, you should have </span><a href="https://nodejs.org/" target="_blank" data-reactid=".1c0hi1r0074.1.3.a.1">Node.js</a><span data-reactid=".1c0hi1r0074.1.3.a.2"> installed as well as a basic understanding of using npm and JavaScript modules. Initialize a new npm package and install react and react-tools</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.b">
<span class="hljs-built_in">npm</span> init</pre><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.c">
npm i --<span class="hljs-built_in">save</span>-<span class="hljs-built_in">dev</span> react react-tools</pre><p data-reactid=".1c0hi1r0074.1.3.d"><span data-reactid=".1c0hi1r0074.1.3.d.0">Now create a </span><code data-reactid=".1c0hi1r0074.1.3.d.1">build.js</code><span data-reactid=".1c0hi1r0074.1.3.d.2"> script which will be used to render the static SVG.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.e">
<span class="hljs-keyword">var</span> fs = <span class="hljs-built_in">require</span>(<span class="hljs-string">'fs'</span>)
<span class="hljs-keyword">var</span> React = <span class="hljs-built_in">require</span>(<span class="hljs-string">'react'</span>)
<span class="hljs-keyword">var</span> Cog = <span class="hljs-built_in">require</span>(<span class="hljs-string">'./Cog'</span>)
<span class="hljs-keyword">var</span> build = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name, props</span>) </span>{
<span class="hljs-keyword">var</span> svg = React.renderToStaticMarkup(React.createElement(Cog, props))
fs.writeFileSync(<span class="hljs-string">'icons/'</span> + name + <span class="hljs-string">'.svg'</span>, svg)
}
build(<span class="hljs-string">'cog-icon'</span>, {})
</pre><p data-reactid=".1c0hi1r0074.1.3.f"><span data-reactid=".1c0hi1r0074.1.3.f.0">This build script imports the Cog component, renders it to static markup, and saves the file in the </span><code data-reactid=".1c0hi1r0074.1.3.f.1">icons</code><span data-reactid=".1c0hi1r0074.1.3.f.2"> directory.</span></p><p data-reactid=".1c0hi1r0074.1.3.g">Go ahead and make a new directory for the icons.</p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.h">
<span class="hljs-built_in">mkdir</span> icons</pre><p data-reactid=".1c0hi1r0074.1.3.i"><span data-reactid=".1c0hi1r0074.1.3.i.0">Next create a </span><code data-reactid=".1c0hi1r0074.1.3.i.1">src</code><span data-reactid=".1c0hi1r0074.1.3.i.2"> folder and a new </span><code data-reactid=".1c0hi1r0074.1.3.i.3">Cog.jsx</code><span data-reactid=".1c0hi1r0074.1.3.i.4"> file.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.j">
var React = require(<span class="hljs-string">'react'</span>)
var Cog = React.createClass({
getDefaultProps: function() {
<span class="hljs-keyword">return</span> {
<span class="hljs-built_in">size</span>: <span class="hljs-number">64</span>,
<span class="hljs-built_in">fill</span>: <span class="hljs-string">'currentcolor'</span>
}
},
render: function() {
var <span class="hljs-built_in">size</span> = <span class="hljs-keyword">this</span>.props.<span class="hljs-built_in">size</span>
var <span class="hljs-built_in">fill</span> = <span class="hljs-keyword">this</span>.props.<span class="hljs-built_in">fill</span>
var viewBox = [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-built_in">size</span>, <span class="hljs-built_in">size</span>].<span class="hljs-built_in">join</span>(<span class="hljs-string">' '</span>)
var pathData = [
<span class="hljs-string">''</span>
].<span class="hljs-built_in">join</span>(<span class="hljs-string">' '</span>)
<span class="hljs-keyword">return</span> (
<svg xmlns=<span class="hljs-string">"http://www.w3.org/svg/2000"</span>
viewBox={viewBox}
<span class="hljs-variable">width</span>={<span class="hljs-built_in">size</span>}
<span class="hljs-variable">height</span>={<span class="hljs-built_in">size</span>}
<span class="hljs-built_in">fill</span>={<span class="hljs-built_in">fill</span>}>
<path d={pathData} />
</svg>
)
}
});
module.exports = Cog
</pre><p data-reactid=".1c0hi1r0074.1.3.k"><span data-reactid=".1c0hi1r0074.1.3.k.0">Next add some scripts to </span><code data-reactid=".1c0hi1r0074.1.3.k.1">package.json</code><span data-reactid=".1c0hi1r0074.1.3.k.2">.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.l">
<span class="hljs-string">"scripts"</span>: {
<span class="hljs-string">"build"</span>: <span class="hljs-string">"node build"</span>,
<span class="hljs-string">"jsx"</span>: <span class="hljs-string">"jsx -x jsx src ."</span>,
<span class="hljs-string">"watch:jsx"</span>: <span class="hljs-string">"jsx -w -x jsx src ."</span>
}
</pre><p data-reactid=".1c0hi1r0074.1.3.m"><span data-reactid=".1c0hi1r0074.1.3.m.0">Run the following scripts to compile </span><code data-reactid=".1c0hi1r0074.1.3.m.1">Cog.jsx</code><span data-reactid=".1c0hi1r0074.1.3.m.2"> to plain JavaScript, and to create an SVG named </span><code data-reactid=".1c0hi1r0074.1.3.m.3">cog-icon.svg</code></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.n">
npm <span class="hljs-command">run</span> jsx</pre><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.o">
npm <span class="hljs-command">run</span> build</pre><h2 id="the-xmlns-attribute-in-react" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.p"><a href="#the-xmlns-attribute-in-react" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.p.0">The xmlns Attribute in React</a></h2><p data-reactid=".1c0hi1r0074.1.3.q"><span data-reactid=".1c0hi1r0074.1.3.q.0">At the time of this writing, React strips the xmlns attribute from the SVG. When using the SVG inline in HTML, this shouldn’t be a problem, but when using it as an image, the attribute is needed. To get around this limitation, add a wrapping SVG tag in </span><code data-reactid=".1c0hi1r0074.1.3.q.1">build.js</code><span data-reactid=".1c0hi1r0074.1.3.q.2">.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.r">
var build = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(name, props)</span> {</span>
<span class="hljs-transposed_variable">props.</span><span class="hljs-built_in">size</span> = <span class="hljs-transposed_variable">props.</span><span class="hljs-built_in">size</span> || <span class="hljs-number">64</span>
var <span class="hljs-built_in">size</span> = <span class="hljs-transposed_variable">props.</span><span class="hljs-built_in">size</span>
var viewBox = <span class="hljs-matrix">[<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, size, size].</span>join(<span class="hljs-string">' '</span>)
var svg = <span class="hljs-matrix">[
<span class="hljs-string">'<svg xmlns="</span>http://www.w3.org/<span class="hljs-number">2000</span>/svg<span class="hljs-string">" '</span>,
<span class="hljs-string">'viewBox="</span><span class="hljs-string">', viewBox, '</span><span class="hljs-string">" '</span>,
<span class="hljs-string">'width="</span><span class="hljs-string">', size, '</span><span class="hljs-string">" '</span>,
<span class="hljs-string">'height="</span><span class="hljs-string">', size, '</span><span class="hljs-string">" '</span>,
<span class="hljs-string">'>'</span>,
React.renderToStaticMarkup(React.createElement(Icon, props)),
<span class="hljs-string">'</svg>'</span>
].</span>join(<span class="hljs-string">''</span>)
<span class="hljs-transposed_variable">fs.</span>writeFileSync(<span class="hljs-string">'icons/'</span> + name + <span class="hljs-string">'.svg'</span>, svg)
}
</pre><p data-reactid=".1c0hi1r0074.1.3.s"><span data-reactid=".1c0hi1r0074.1.3.s.0">After making these changes, run </span><code data-reactid=".1c0hi1r0074.1.3.s.1">npm run build</code><span data-reactid=".1c0hi1r0074.1.3.s.2"> to rebuild the SVG. Open the SVG file in a browser to see the icon as it progresses. At this point, it should appear blank, but you can open web inspector to ensure that the SVG wrapper is there.</span></p><h2 id="watching-changes" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.t"><a href="#watching-changes" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.t.0">Watching Changes</a></h2><p data-reactid=".1c0hi1r0074.1.3.u">To watch changes as the icon is developed, run the watch:jsx command to transpile the jsx file to js.</p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.v">
npm <span class="hljs-command">run</span> watch:jsx</pre><p data-reactid=".1c0hi1r0074.1.3.w">For each change you’ll need to rerun the build script. While you can also set up watching for the build script, this is beyond the scope of the tutorial.</p><h2 id="default-props" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.x"><a href="#default-props" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.x.0">Default Props</a></h2><p data-reactid=".1c0hi1r0074.1.3.y"><span data-reactid=".1c0hi1r0074.1.3.y.0">To allow for adjustments to be made from the build script, the icon will use React props. Define some defaults in </span><code data-reactid=".1c0hi1r0074.1.3.y.1">Cog.jsx</code><span data-reactid=".1c0hi1r0074.1.3.y.2">.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.z">
<span class="hljs-tag">getDefaultProps</span>: <span class="hljs-tag">function</span>() {
<span class="hljs-tag">return</span> {
<span class="hljs-attribute">size</span>: <span class="hljs-number">64</span>,
<span class="hljs-attribute">d1</span>: <span class="hljs-number">1</span>,
<span class="hljs-attribute">d2</span>: .<span class="hljs-number">6875</span>,
<span class="hljs-attribute">d3</span>: .<span class="hljs-number">375</span>,
<span class="hljs-attribute">teeth</span>: <span class="hljs-number">8</span>,
<span class="hljs-attribute">splay</span>: <span class="hljs-number">0.375</span>,
<span class="hljs-attribute">fill</span>: <span class="hljs-string">'currentcolor'</span>
}
},
</pre><p data-reactid=".1c0hi1r0074.1.3.10"><span data-reactid=".1c0hi1r0074.1.3.10.0">The width and height of the square-shaped icon will be handled with the </span><code data-reactid=".1c0hi1r0074.1.3.10.1">size</code><span data-reactid=".1c0hi1r0074.1.3.10.2"> prop. The diameters </span><code data-reactid=".1c0hi1r0074.1.3.10.3">d1</code><span data-reactid=".1c0hi1r0074.1.3.10.4">, </span><code data-reactid=".1c0hi1r0074.1.3.10.5">d2</code><span data-reactid=".1c0hi1r0074.1.3.10.6">, and </span><code data-reactid=".1c0hi1r0074.1.3.10.7">d3</code><span data-reactid=".1c0hi1r0074.1.3.10.8"> represent ratios of the size for each concentric circle. The number of teeth on the cog will be handled with the </span><code data-reactid=".1c0hi1r0074.1.3.10.9">teeth</code><span data-reactid=".1c0hi1r0074.1.3.10.a"> prop. The </span><code data-reactid=".1c0hi1r0074.1.3.10.b">splay</code><span data-reactid=".1c0hi1r0074.1.3.10.c"> prop represents the angle for the side of each tooth and will be explained later. And the </span><code data-reactid=".1c0hi1r0074.1.3.10.d">fill</code><span data-reactid=".1c0hi1r0074.1.3.10.e"> prop is set to </span><code data-reactid=".1c0hi1r0074.1.3.10.f">currentcolor</code><span data-reactid=".1c0hi1r0074.1.3.10.g"> to inherit color when used inline in HTML.</span></p><h2 id="defining-radii-and-other-values" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.11"><a href="#defining-radii-and-other-values" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.11.0">Defining Radii and Other Values</a></h2><p data-reactid=".1c0hi1r0074.1.3.12">Within the render function, use these props to define other values that will be used to create the icon.</p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.13">
<span class="hljs-attribute">render</span>: <span class="hljs-string">function() {</span>
<span class="kotlin"> <span class="hljs-variable"><span class="hljs-keyword">var</span> size</span> = this.props.size
<span class="hljs-variable"><span class="hljs-keyword">var</span> fill</span> = this.props.fill
<span class="hljs-comment">// Center</span>
<span class="hljs-variable"><span class="hljs-keyword">var</span> c</span> = size / <span class="hljs-number">2</span>
<span class="hljs-comment">// Radii</span>
<span class="hljs-variable"><span class="hljs-keyword">var</span> r1</span> = this.props.d1 * size / <span class="hljs-number">2</span>
<span class="hljs-variable"><span class="hljs-keyword">var</span> r2</span> = this.props.d2 * size / <span class="hljs-number">2</span>
<span class="hljs-variable"><span class="hljs-keyword">var</span> r3</span> = this.props.d3 * size / <span class="hljs-number">2</span>
<span class="hljs-comment">// Angle</span>
<span class="hljs-variable"><span class="hljs-keyword">var</span> angle</span> = <span class="hljs-number">360</span> / this.props.teeth
<span class="hljs-variable"><span class="hljs-keyword">var</span> offset</span> = <span class="hljs-number">90</span>
<span class="hljs-variable"><span class="hljs-keyword">var</span> viewBox</span> = [<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, size, size].join(' ')
<span class="hljs-comment">// ...</span>
}
</span></pre><p data-reactid=".1c0hi1r0074.1.3.14"><span data-reactid=".1c0hi1r0074.1.3.14.0">The center of the icon is defined as </span><code data-reactid=".1c0hi1r0074.1.3.14.1">c</code><span data-reactid=".1c0hi1r0074.1.3.14.2">. The angle for each tooth is calculated based on the number of teeth. And </span><code data-reactid=".1c0hi1r0074.1.3.14.3">offset</code><span data-reactid=".1c0hi1r0074.1.3.14.4"> is used to rotate the icon 90° to ensure that the first tooth is at the top.</span></p><h2 id="path-data" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.15"><a href="#path-data" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.15.0">Path Data</a></h2><p data-reactid=".1c0hi1r0074.1.3.16"><span data-reactid=".1c0hi1r0074.1.3.16.0">The </span><code data-reactid=".1c0hi1r0074.1.3.16.1">pathData</code><span data-reactid=".1c0hi1r0074.1.3.16.2"> variable will be used for the path element’s </span><code data-reactid=".1c0hi1r0074.1.3.16.3">d</code><span data-reactid=".1c0hi1r0074.1.3.16.4"> attribute. The value for this attribute is a string of commands used to draw a line. Letters represent different commands and numbers represent positions in the x/y coordinate system. Uppercase letters are used for absolute coordinates, while lowercase is used for relative coordinates. This tutorial only uses absolute coordinates, so each letter must be uppercase. Only three commands will be used to create the icon: Move </span><code data-reactid=".1c0hi1r0074.1.3.16.5">M</code><span data-reactid=".1c0hi1r0074.1.3.16.6">, Line To </span><code data-reactid=".1c0hi1r0074.1.3.16.7">L</code><span data-reactid=".1c0hi1r0074.1.3.16.8">, and Arc </span><code data-reactid=".1c0hi1r0074.1.3.16.9">A</code><span data-reactid=".1c0hi1r0074.1.3.16.a">. To read more about the SVG path element, see this </span><a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths" target="_blank" data-reactid=".1c0hi1r0074.1.3.16.b">MDN tutorial</a><span data-reactid=".1c0hi1r0074.1.3.16.c">.</span></p><p data-reactid=".1c0hi1r0074.1.3.17"><span data-reactid=".1c0hi1r0074.1.3.17.0">The </span><code data-reactid=".1c0hi1r0074.1.3.17.1">pathData</code><span data-reactid=".1c0hi1r0074.1.3.17.2"> variable is constructed with an array followed by the </span><code data-reactid=".1c0hi1r0074.1.3.17.3">.join()</code><span data-reactid=".1c0hi1r0074.1.3.17.4"> method. This is to more easily combine path commands and numbers and ensure that the values have a space between each one.</span></p><p data-reactid=".1c0hi1r0074.1.3.18">To demonstrate how the path commands work, the following should create a rectangle based on the coordinates given.</p><div class="center" data-reactid=".1c0hi1r0074.1.3.19"><svg viewBox="0 0 64 64" width="64" height="64" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.19.0"><path d="M 2 2 L 62 2 L 62 62 L 2 62 L 2 2" data-reactid=".1c0hi1r0074.1.3.19.0.0"></path></svg></div><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.1a">
<span class="hljs-tag">var</span> pathData = [
<span class="hljs-string">'M'</span>, <span class="hljs-number">2</span>, <span class="hljs-number">2</span>, <span class="hljs-comment">// Move to 2,2</span>
<span class="hljs-string">'L'</span>, <span class="hljs-number">62</span>, <span class="hljs-number">2</span>, <span class="hljs-comment">// Draw a line to 62,2</span>
<span class="hljs-string">'L'</span>, <span class="hljs-number">62</span>, <span class="hljs-number">62</span>, <span class="hljs-comment">// Draw a line to 62,62</span>
<span class="hljs-string">'L'</span>, <span class="hljs-number">2</span>, <span class="hljs-number">62</span>, <span class="hljs-comment">// Draw a line to 2,62</span>
<span class="hljs-string">'L'</span>, <span class="hljs-number">2</span>, <span class="hljs-number">2</span>, <span class="hljs-comment">// Draw a line to 2,2</span>
].<span class="hljs-function"><span class="hljs-title">join</span><span class="hljs-params">(<span class="hljs-string">' '</span>)</span></span>
</pre><h2 id="building-teeth" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.1b"><a href="#building-teeth" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.1b.0">Building Teeth</a></h2><p data-reactid=".1c0hi1r0074.1.3.1c"><span data-reactid=".1c0hi1r0074.1.3.1c.0">To create teeth around the outer circle based on the number given in the </span><code data-reactid=".1c0hi1r0074.1.3.1c.1">teeth</code><span data-reactid=".1c0hi1r0074.1.3.1c.2"> prop, a function will be used to return the values for each point. To calculate the x/y coordinates for each point around the outer circle, add the following functions.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.1d">
<span class="hljs-keyword">var</span> rad = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">a</span>) </span>{
<span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.PI * a / <span class="hljs-number">180</span>
}
<span class="hljs-keyword">var</span> rx = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">r, a</span>) </span>{
<span class="hljs-keyword">return</span> c + r * <span class="hljs-built_in">Math</span>.cos(rad(a))
}
<span class="hljs-keyword">var</span> ry = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">r, a</span>) </span>{
<span class="hljs-keyword">return</span> c + r * <span class="hljs-built_in">Math</span>.sin(rad(a))
}
</pre><p data-reactid=".1c0hi1r0074.1.3.1e"><span data-reactid=".1c0hi1r0074.1.3.1e.0">The </span><code data-reactid=".1c0hi1r0074.1.3.1e.1">rad</code><span data-reactid=".1c0hi1r0074.1.3.1e.2"> function converts degrees to radians for convenience and since the </span><code data-reactid=".1c0hi1r0074.1.3.1e.3">Math.cos</code><span data-reactid=".1c0hi1r0074.1.3.1e.4">, </span><code data-reactid=".1c0hi1r0074.1.3.1e.5">Math.sin</code><span data-reactid=".1c0hi1r0074.1.3.1e.6">, and </span><code data-reactid=".1c0hi1r0074.1.3.1e.7">Math.tan</code><span data-reactid=".1c0hi1r0074.1.3.1e.8"> functions all require radians. The </span><code data-reactid=".1c0hi1r0074.1.3.1e.9">rx</code><span data-reactid=".1c0hi1r0074.1.3.1e.a"> and </span><code data-reactid=".1c0hi1r0074.1.3.1e.b">ry</code><span data-reactid=".1c0hi1r0074.1.3.1e.c"> functions calculate the x and y coordinates respectively based on the radius and angle.</span></p><figure class="center mb3" data-reactid=".1c0hi1r0074.1.3.1f"><svg viewBox="0 0 256 256" width="256" height="256" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1f.0"><circle cx="128" cy="128" r="126" style="fill:none;stroke:currentcolor;" data-reactid=".1c0hi1r0074.1.3.1f.0.0"></circle><path d="M 128 128 L 128 2 M 128 128 L 237.11920087683927 65" style="fill:none;stroke:currentcolor;" data-reactid=".1c0hi1r0074.1.3.1f.0.1"></path><circle cx="237.11920087683927" cy="65" r="6" style="fill:#7FDBFF;opacity:0.75;" data-reactid=".1c0hi1r0074.1.3.1f.0.2"></circle></svg><figcaption data-reactid=".1c0hi1r0074.1.3.1f.1"><span data-reactid=".1c0hi1r0074.1.3.1f.1.0">The </span><code data-reactid=".1c0hi1r0074.1.3.1f.1.1">rx</code><span data-reactid=".1c0hi1r0074.1.3.1f.1.2"> and </span><code data-reactid=".1c0hi1r0074.1.3.1f.1.3">ry</code><span data-reactid=".1c0hi1r0074.1.3.1f.1.4"> functions being used to find coordinates along a circle</span></figcaption></figure><p data-reactid=".1c0hi1r0074.1.3.1g"><span data-reactid=".1c0hi1r0074.1.3.1g.0">Start with a polygon to see how the </span><code data-reactid=".1c0hi1r0074.1.3.1g.1">teeth</code><span data-reactid=".1c0hi1r0074.1.3.1g.2"> prop can be adjusted to create different numbers of points.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.1h">
<span class="hljs-keyword">var</span> num = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(n)</span> </span>{
<span class="hljs-keyword">return</span> (n < <span class="hljs-number">0.0000001</span>) ? <span class="hljs-number">0</span> : n
}
<span class="hljs-keyword">var</span> drawTeeth = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">(n)</span> </span>{
<span class="hljs-keyword">var</span> d = []
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">var</span> i = <span class="hljs-number">0</span>; i < n; i++) {
<span class="hljs-keyword">var</span> a = angle * i - offset
<span class="hljs-keyword">var</span> line = [
(i === <span class="hljs-number">0</span>) ? <span class="hljs-string">'M'</span> : <span class="hljs-string">'L'</span>,
num(rx(r1, a)),
num(ry(r1, a)),
].join(<span class="hljs-string">' '</span>)
d.push(line)
}
<span class="hljs-keyword">return</span> d.join(<span class="hljs-string">' '</span>)
}
<span class="hljs-keyword">var</span> pathData = [
drawTeeth(<span class="hljs-keyword">this</span>.props.teeth)
].join(<span class="hljs-string">' '</span>)
</pre><figure class="center py2" data-reactid=".1c0hi1r0074.1.3.1i"><svg viewBox="0 0 128 128" width="128" height="128" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1i.0"><path d="M 64 0 L 109.25483399593904 18.745166004060962 L 128 64 L 109.25483399593904 109.25483399593904 L 64 128 L 18.745166004060962 109.25483399593904 L 0 64.00000000000001 L 18.74516600406095 18.745166004060962" data-reactid=".1c0hi1r0074.1.3.1i.0.0"></path></svg><svg viewBox="0 0 128 128" width="128" height="128" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1i.1"><path d="M 64 0 L 114.03721487795391 24.096652681041057 L 126.3953863796367 78.24133977320413 L 91.76855930352373 121.66200754575482 L 36.231440696476255 121.66200754575482 L 1.6046136203632884 78.24133977320413 L 13.962785122046085 24.096652681041064" data-reactid=".1c0hi1r0074.1.3.1i.1.0"></path></svg><svg viewBox="0 0 128 128" width="128" height="128" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1i.2"><path d="M 64 0 L 119.42562584220408 32 L 119.42562584220408 96 L 64 128 L 8.574374157795923 96 L 8.57437415779593 31.999999999999993" data-reactid=".1c0hi1r0074.1.3.1i.2.0"></path></svg><svg viewBox="0 0 128 128" width="128" height="128" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1i.3"><path d="M 64 0 L 124.86761704288983 44.22291236000336 L 101.61825614671828 115.77708763999664 L 26.381743853281726 115.77708763999664 L 3.132382957110174 44.22291236000335" data-reactid=".1c0hi1r0074.1.3.1i.3.0"></path></svg><figcaption data-reactid=".1c0hi1r0074.1.3.1i.4">Polygons with 8, 7, 6, and 5 points</figcaption></figure><p data-reactid=".1c0hi1r0074.1.3.1j"><span data-reactid=".1c0hi1r0074.1.3.1j.0">Passing the number of teeth to the </span><code data-reactid=".1c0hi1r0074.1.3.1j.1">drawTeeth</code><span data-reactid=".1c0hi1r0074.1.3.1j.2"> function, it loops through and calculates each angle with the offset defined above. Using a ternary operator, it either moves to the first point or draws a line to subsequent points. The x and y coordinates are calculated with the </span><code data-reactid=".1c0hi1r0074.1.3.1j.3">rx</code><span data-reactid=".1c0hi1r0074.1.3.1j.4"> and </span><code data-reactid=".1c0hi1r0074.1.3.1j.5">ry</code><span data-reactid=".1c0hi1r0074.1.3.1j.6"> functions. Then each command is pushed to the </span><code data-reactid=".1c0hi1r0074.1.3.1j.7">d</code><span data-reactid=".1c0hi1r0074.1.3.1j.8"> array, and it is return as a string.</span></p><p data-reactid=".1c0hi1r0074.1.3.1k"><span data-reactid=".1c0hi1r0074.1.3.1k.0">Since Math functions are calculating numbers that are being converted to strings for the </span><code data-reactid=".1c0hi1r0074.1.3.1k.1">d</code><span data-reactid=".1c0hi1r0074.1.3.1k.2"> attribute, JavaScript will convert extremely small numbers to scientific notation. To prevent this from happening, the </span><code data-reactid=".1c0hi1r0074.1.3.1k.3">num</code><span data-reactid=".1c0hi1r0074.1.3.1k.4"> function is used to return </span><code data-reactid=".1c0hi1r0074.1.3.1k.5">0</code><span data-reactid=".1c0hi1r0074.1.3.1k.6"> for small numbers.</span></p><h2 id="shaping-the-teeth" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.1l"><a href="#shaping-the-teeth" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.1l.0">Shaping the Teeth</a></h2><p data-reactid=".1c0hi1r0074.1.3.1m"><span data-reactid=".1c0hi1r0074.1.3.1m.0">Now that the function to loop through the number of teeth is set up, change the commands in the </span><code data-reactid=".1c0hi1r0074.1.3.1m.1">line</code><span data-reactid=".1c0hi1r0074.1.3.1m.2"> array to draw lines to the inner circle of the cog.</span></p><div class="center" data-reactid=".1c0hi1r0074.1.3.1n"><svg viewBox="0 0 256 256" width="256" height="256" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1n.0"><path d="M 128 0 L 137.19850476755352 40.48207320759195 A 88 88 0 0 1 183.3801944123857 59.61115539178657 L 218.50966799187808 37.490332008121925 L 196.38884460821345 72.61980558761431 A 88 88 0 0 1 215.51792679240805 118.8014952324465 L 256 128 L 215.51792679240805 137.19850476755352 A 88 88 0 0 1 196.38884460821345 183.3801944123857 L 218.50966799187808 218.50966799187808 L 183.3801944123857 196.38884460821345 A 88 88 0 0 1 137.19850476755352 215.51792679240805 L 128 256 L 118.80149523244651 215.51792679240805 A 88 88 0 0 1 72.61980558761432 196.38884460821345 L 37.490332008121925 218.50966799187808 L 59.61115539178658 183.38019441238572 A 88 88 0 0 1 40.48207320759195 137.19850476755352 L 0 128.00000000000003 L 40.48207320759194 118.80149523244653 A 88 88 0 0 1 59.61115539178657 72.61980558761428 L 37.4903320081219 37.490332008121925 L 72.61980558761434 59.61115539178654 A 88 88 0 0 1 118.8014952324465 40.48207320759194" data-reactid=".1c0hi1r0074.1.3.1n.0.0"></path></svg></div><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.1o">
var drawTeeth = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-title">n</span>) {</span>
var d = []
<span class="hljs-keyword">for</span> (var i = <span class="hljs-number">0</span>; i < n; i++) {
var <span class="hljs-operator">a</span> = angle * i - <span class="hljs-built_in">offset</span>
var a1 = <span class="hljs-operator">a</span> + <span class="hljs-number">6</span>
var a2 = <span class="hljs-operator">a</span> + angle - <span class="hljs-number">6</span>
var <span class="hljs-built_in">line</span> = [
(i === <span class="hljs-number">0</span>) ? <span class="hljs-string">'M'</span> : <span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r1, <span class="hljs-operator">a</span>)),
<span class="hljs-built_in">num</span>(ry(r1, <span class="hljs-operator">a</span>)),
<span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r2, a1)),
<span class="hljs-built_in">num</span>(ry(r2, a1)),
<span class="hljs-string">'A'</span>, r2, r2,
<span class="hljs-string">'0 0 1'</span>,
<span class="hljs-built_in">num</span>(rx(r2, a2)),
<span class="hljs-built_in">num</span>(ry(r2, a2)),
].join(<span class="hljs-string">' '</span>)
d.push(<span class="hljs-built_in">line</span>)
}
<span class="hljs-constant">return</span> d.join(<span class="hljs-string">' '</span>)
}
</pre><h2 id="the-arc-command" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.1p"><a href="#the-arc-command" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.1p.0">The Arc Command</a></h2><p data-reactid=".1c0hi1r0074.1.3.1q"><span data-reactid=".1c0hi1r0074.1.3.1q.0">Here the Arc </span><code data-reactid=".1c0hi1r0074.1.3.1q.1">A</code><span data-reactid=".1c0hi1r0074.1.3.1q.2"> command is being used to draw part of the inner circle. The first two values in the Arc command represent the x and y radii. The next three values are booleans representing the </span><code data-reactid=".1c0hi1r0074.1.3.1q.3">x-axis-rotation</code><span data-reactid=".1c0hi1r0074.1.3.1q.4">, </span><code data-reactid=".1c0hi1r0074.1.3.1q.5">large-arc-flag</code><span data-reactid=".1c0hi1r0074.1.3.1q.6">, and the </span><code data-reactid=".1c0hi1r0074.1.3.1q.7">sweep-flag</code><span data-reactid=".1c0hi1r0074.1.3.1q.8">. The </span><code data-reactid=".1c0hi1r0074.1.3.1q.9">sweep-flag</code><span data-reactid=".1c0hi1r0074.1.3.1q.a"> value is set to </span><code data-reactid=".1c0hi1r0074.1.3.1q.b">1</code><span data-reactid=".1c0hi1r0074.1.3.1q.c"> (true) to ensure the arc curves in the right direction. The last two values are the x and y coordinates for where the arc should end. To read more about the Arc command see this </span><a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths#Arcs" target="_blank" data-reactid=".1c0hi1r0074.1.3.1q.d">MDN tutorial</a><span data-reactid=".1c0hi1r0074.1.3.1q.e">.</span></p><p data-reactid=".1c0hi1r0074.1.3.1r">Currently, this function arbitrarily adds and subtracts 6° to the angle to create the teeth. Add the following to the render function to calculate the angles based on the number of teeth.</p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.1s">
var ta = angle / <span class="hljs-number">4</span>
var tw = Math.<span class="hljs-built_in">tan</span>(rad(ta)) * r1
var tx = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-title">a</span>, <span class="hljs-title">w</span>) {</span>
<span class="hljs-constant">return</span> Math.<span class="hljs-built_in">sin</span>(rad(<span class="hljs-operator">a</span>)) * w
}
var ty = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-title">a</span>, <span class="hljs-title">w</span>) {</span>
<span class="hljs-constant">return</span> Math.<span class="hljs-built_in">cos</span>(rad(<span class="hljs-operator">a</span>)) * w
}
var drawTeeth = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-title">n</span>) {</span>
var d = []
<span class="hljs-keyword">for</span> (var i = <span class="hljs-number">0</span>; i < n; i++) {
var <span class="hljs-operator">a</span> = angle * i - <span class="hljs-built_in">offset</span>
var a1 = <span class="hljs-operator">a</span> + ta
var a2 = <span class="hljs-operator">a</span> + angle - ta
var <span class="hljs-built_in">line</span> = [
(i === <span class="hljs-number">0</span>) ? <span class="hljs-string">'M'</span> : <span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r1, <span class="hljs-operator">a</span>) + tx(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-built_in">num</span>(ry(r1, <span class="hljs-operator">a</span>) - ty(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r1, <span class="hljs-operator">a</span>) - tx(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-built_in">num</span>(ry(r1, <span class="hljs-operator">a</span>) + ty(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r2, a1)),
<span class="hljs-built_in">num</span>(ry(r2, a1)),
<span class="hljs-string">'A'</span>, r2, r2,
<span class="hljs-string">'0 0 1'</span>,
<span class="hljs-built_in">num</span>(rx(r2, a2)),
<span class="hljs-built_in">num</span>(ry(r2, a2)),
].join(<span class="hljs-string">' '</span>)
d.push(<span class="hljs-built_in">line</span>)
}
<span class="hljs-constant">return</span> d.join(<span class="hljs-string">' '</span>)
}
</pre><p data-reactid=".1c0hi1r0074.1.3.1t"><span data-reactid=".1c0hi1r0074.1.3.1t.0">The tooth angle </span><code data-reactid=".1c0hi1r0074.1.3.1t.1">ta</code><span data-reactid=".1c0hi1r0074.1.3.1t.2"> is one-fourth of the angle for each tooth. The tooth width </span><code data-reactid=".1c0hi1r0074.1.3.1t.3">tw</code><span data-reactid=".1c0hi1r0074.1.3.1t.4"> is based on that angle. The </span><code data-reactid=".1c0hi1r0074.1.3.1t.5">tx</code><span data-reactid=".1c0hi1r0074.1.3.1t.6"> and </span><code data-reactid=".1c0hi1r0074.1.3.1t.7">ty</code><span data-reactid=".1c0hi1r0074.1.3.1t.8"> functions are used to calculate the x and y coordinates based on angle and distance. These functions and values are added to the line array to offset points for the corners of the teeth and the points at which they intersect the inner circle.</span></p><pre class="display-none" data-reactid=".1c0hi1r0074.1.3.1u">
right triangle diagram</pre><div class="center" data-reactid=".1c0hi1r0074.1.3.1v"><svg viewBox="0 0 256 256" width="256" height="256" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.1v.0"><path d="M 102.53921697540378 0 L 153.46078302459622 0 L 145.1679483374193 41.69089532451572 A 88 88 0 0 1 176.890180505725 54.83067411737602 L 200.50617566086675 19.4868396771106 L 236.5131603228894 55.493824339133255 L 201.16932588262398 79.109819494275 A 88 88 0 0 1 214.30910467548426 110.83205166258071 L 256 102.53921697540378 L 256 153.46078302459622 L 214.30910467548426 145.1679483374193 A 88 88 0 0 1 201.16932588262398 176.890180505725 L 236.5131603228894 200.50617566086675 L 200.50617566086675 236.5131603228894 L 176.890180505725 201.16932588262398 A 88 88 0 0 1 145.1679483374193 214.30910467548426 L 153.46078302459622 256 L 102.53921697540378 256 L 110.83205166258074 214.3091046754843 A 88 88 0 0 1 79.109819494275 201.16932588262398 L 55.493824339133255 236.5131603228894 L 19.4868396771106 200.50617566086675 L 54.830674117376006 176.890180505725 A 88 88 0 0 1 41.69089532451572 145.1679483374193 L 0 153.46078302459625 L 0 102.5392169754038 L 41.69089532451571 110.83205166258074 A 88 88 0 0 1 54.83067411737602 79.109819494275 L 19.48683967711057 55.493824339133255 L 55.493824339133226 19.486839677110595 L 79.10981949427494 54.83067411737606 A 88 88 0 0 1 110.83205166258068 41.690895324515736" data-reactid=".1c0hi1r0074.1.3.1v.0.0"></path></svg></div><h2 id="splayed-teeth" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.1w"><a href="#splayed-teeth" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.1w.0">Splayed Teeth</a></h2><p data-reactid=".1c0hi1r0074.1.3.1x"><span data-reactid=".1c0hi1r0074.1.3.1x.0">The icon is starting to take shape, but the sides of each tooth are based on angles from the center. To splay the sides of the teeth in the other direction, edit the </span><code data-reactid=".1c0hi1r0074.1.3.1x.1">tw</code><span data-reactid=".1c0hi1r0074.1.3.1x.2"> variable as shown below.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.1y">
<span class="hljs-keyword">var</span> <span class="hljs-keyword">ta</span> = angle / 4
<span class="hljs-keyword">var</span> splay = this.props.splay * <span class="hljs-keyword">ta</span>
<span class="hljs-keyword">var</span> <span class="hljs-keyword">tw</span> = Math.<span class="hljs-literal">tan</span>(rad(<span class="hljs-keyword">ta</span> - splay)) * r1
</pre><p data-reactid=".1c0hi1r0074.1.3.1z">Splay, defined earlier in default props, represents a ratio of the tooth angle. Since it’s a prop, adjustments to this angle can be made from the build script. For the tooth width, the splay angle is subtracted from the tooth angle.</p><p data-reactid=".1c0hi1r0074.1.3.20"><span data-reactid=".1c0hi1r0074.1.3.20.0">For the </span><code data-reactid=".1c0hi1r0074.1.3.20.1">drawTeeth</code><span data-reactid=".1c0hi1r0074.1.3.20.2"> function, splay is added and subtracted from the angles at which the side of the tooth should intersect the inner circle.</span></p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.21">
var drawTeeth = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-title">n</span>) {</span>
var d = []
<span class="hljs-keyword">for</span> (var i = <span class="hljs-number">0</span>; i < n; i++) {
var <span class="hljs-operator">a</span> = angle * i - <span class="hljs-built_in">offset</span>
var a1 = <span class="hljs-operator">a</span> + ta + splay
var a2 = <span class="hljs-operator">a</span> + angle - ta - splay
var <span class="hljs-built_in">line</span> = [
(i === <span class="hljs-number">0</span>) ? <span class="hljs-string">'M'</span> : <span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r1, <span class="hljs-operator">a</span>) + tx(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-built_in">num</span>(ry(r1, <span class="hljs-operator">a</span>) - ty(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r1, <span class="hljs-operator">a</span>) - tx(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-built_in">num</span>(ry(r1, <span class="hljs-operator">a</span>) + ty(<span class="hljs-operator">a</span>, tw)),
<span class="hljs-string">'L'</span>,
<span class="hljs-built_in">num</span>(rx(r2, a1)),
<span class="hljs-built_in">num</span>(ry(r2, a1)),
<span class="hljs-string">'A'</span>, r2, r2,
<span class="hljs-string">'0 0 1'</span>,
<span class="hljs-built_in">num</span>(rx(r2, a2)),
<span class="hljs-built_in">num</span>(ry(r2, a2)),
].join(<span class="hljs-string">' '</span>)
d.push(<span class="hljs-built_in">line</span>)
}
<span class="hljs-constant">return</span> d.join(<span class="hljs-string">' '</span>)
}
</pre><div class="center" data-reactid=".1c0hi1r0074.1.3.22"><svg viewBox="0 0 256 256" width="256" height="256" fill="currentcolor" data-reactid=".1c0hi1r0074.1.3.22.0"><path d="M 112.21270577449745 0 L 143.78729422550256 0 L 151.47072265779107 43.187706210001295 A 88 88 0 0 1 171.375040916221 51.432344782433404 L 207.346365188438 26.327029204681846 L 229.67297079531815 48.653634811562 L 204.5676552175666 84.62495908377902 A 88 88 0 0 1 212.8122937899987 104.52927734220894 L 256 112.21270577449745 L 256 143.78729422550256 L 212.8122937899987 151.47072265779107 A 88 88 0 0 1 204.5676552175666 171.375040916221 L 229.67297079531815 207.346365188438 L 207.346365188438 229.67297079531815 L 171.375040916221 204.5676552175666 A 88 88 0 0 1 151.47072265779107 212.8122937899987 L 143.78729422550256 256 L 112.21270577449745 256 L 104.52927734220896 212.8122937899987 A 88 88 0 0 1 84.624959083779 204.5676552175666 L 48.653634811562 229.67297079531815 L 26.327029204681846 207.346365188438 L 51.432344782433404 171.375040916221 A 88 88 0 0 1 43.18770621000131 151.4707226577911 L 0 143.7872942255026 L 0 112.21270577449748 L 43.18770621000128 104.52927734220899 A 88 88 0 0 1 51.432344782433404 84.62495908377898 L 26.32702920468182 48.65363481156201 L 48.65363481156197 26.327029204681843 L 84.62495908377899 51.432344782433404 A 88 88 0 0 1 104.52927734220893 43.187706210001295" data-reactid=".1c0hi1r0074.1.3.22.0.0"></path></svg></div><h2 id="adding-a-hole" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.3.23"><a href="#adding-a-hole" style="color:inherit;" data-reactid=".1c0hi1r0074.1.3.23.0">Adding a Hole</a></h2><p data-reactid=".1c0hi1r0074.1.3.24">Now all that’s left is to add the hole in the center. To create a circle that subtracts (or punches) from the outer shape, use two Arc commands to draw a circle in a counterclockwise direction. With the path element, intersecting shapes subtract from each other when they are drawn in opposite directions.</p><pre style="white-space:pre;" data-reactid=".1c0hi1r0074.1.3.25">
<span class="hljs-keyword">var</span> hole = <span class="hljs-function"><span class="hljs-keyword">function</span><span class="hljs-params">()</span> </span>{
<span class="hljs-keyword">return</span> [
<span class="hljs-string">'M'</span>, c, c - r3,
<span class="hljs-string">'A'</span>, r3, r3,
<span class="hljs-string">'0 0 0'</span>,
c, c + r3,
<span class="hljs-string">'A'</span>, r3, r3,
<span class="hljs-string">'0 0 0'</span>,
c, c - r3,
].join(<span class="hljs-string">' '</span>)
}
<span class="hljs-keyword">var</span> pathData = [
drawTeeth(<span class="hljs-keyword">this</span>.props.teeth),
hole()
].join(<span class="hljs-string">' '</span>)
</pre><p data-reactid=".1c0hi1r0074.1.3.26"><span data-reactid=".1c0hi1r0074.1.3.26.0">Now you should have an adjustable cog icon similar to the one below. View the complete source code for the cog icon on </span><a href="https://github.com/jxnblk/react-icons/blob/master/src/Cog.jsx" data-reactid=".1c0hi1r0074.1.3.26.1">GitHub</a><span data-reactid=".1c0hi1r0074.1.3.26.2">. Hopefully you can see how with just a little bit of math, React can be a powerful tool for creating flexible and precise SVG graphics.</span></p></div><div class="py3" data-reactid=".1c0hi1r0074.1.4"><h2 id="live-demo" style="padding-top:2rem;" data-reactid=".1c0hi1r0074.1.4.0"><a href="#live-demo" style="color:inherit;" data-reactid=".1c0hi1r0074.1.4.0.0">Live Demo</a></h2><div data-reactid=".1c0hi1r0074.1.4.1"><div class="center mb2" data-reactid=".1c0hi1r0074.1.4.1.0"><svg viewBox="0 0 512 512" width="512" height="512" fill="currentcolor" data-reactid=".1c0hi1r0074.1.4.1.0.0"><path d="M 224.4254115489949 0 L 287.5745884510051 0 L 302.94144531558214 86.37541242000259 A 176 176 0 0 1 342.750081832442 102.86468956486681 L 414.692730376876 52.65405840936369 L 459.3459415906363 97.307269623124 L 409.1353104351332 169.24991816755804 A 176 176 0 0 1 425.6245875799974 209.05855468441789 L 512 224.4254115489949 L 512 287.5745884510051 L 425.6245875799974 302.94144531558214 A 176 176 0 0 1 409.1353104351332 342.750081832442 L 459.3459415906363 414.692730376876 L 414.692730376876 459.3459415906363 L 342.750081832442 409.1353104351332 A 176 176 0 0 1 302.94144531558214 425.6245875799974 L 287.5745884510051 512 L 224.4254115489949 512 L 209.0585546844179 425.6245875799974 A 176 176 0 0 1 169.249918167558 409.1353104351332 L 97.307269623124 459.3459415906363 L 52.65405840936369 414.692730376876 L 102.86468956486681 342.750081832442 A 176 176 0 0 1 86.37541242000262 302.9414453155822 L 0 287.5745884510052 L 0 224.42541154899496 L 86.37541242000256 209.05855468441797 A 176 176 0 0 1 102.86468956486681 169.24991816755795 L 52.65405840936364 97.30726962312401 L 97.30726962312394 52.654058409363685 L 169.24991816755798 102.86468956486681 A 176 176 0 0 1 209.05855468441786 86.37541242000259 M 256 160 A 96 96 0 0 0 256 352 A 96 96 0 0 0 256 160" data-reactid=".1c0hi1r0074.1.4.1.0.0.0"></path></svg></div><div class="md-flex mb2 mxn2" data-reactid=".1c0hi1r0074.1.4.1.1"><div class="md-col-3 px2" data-reactid=".1c0hi1r0074.1.4.1.1.0"><div data-reactid=".1c0hi1r0074.1.4.1.1.0.0"><label for="teeth" class="h6 bold block" data-reactid=".1c0hi1r0074.1.4.1.1.0.0.0"><span data-reactid=".1c0hi1r0074.1.4.1.1.0.0.0.0">Teeth</span><span data-reactid=".1c0hi1r0074.1.4.1.1.0.0.0.1"> (</span><span data-reactid=".1c0hi1r0074.1.4.1.1.0.0.0.2">8</span><span data-reactid=".1c0hi1r0074.1.4.1.1.0.0.0.3">)</span></label><input type="range" class="col-12 range-light" id="teeth" name="teeth" min="3" max="24" value="8" data-reactid=".1c0hi1r0074.1.4.1.1.0.0.1"></div></div><div class="md-col-3 px2" data-reactid=".1c0hi1r0074.1.4.1.1.1"><div data-reactid=".1c0hi1r0074.1.4.1.1.1.0"><label for="d2" class="h6 bold block" data-reactid=".1c0hi1r0074.1.4.1.1.1.0.0"><span data-reactid=".1c0hi1r0074.1.4.1.1.1.0.0.0">Diameter 2</span><span data-reactid=".1c0hi1r0074.1.4.1.1.1.0.0.1"> (</span><span data-reactid=".1c0hi1r0074.1.4.1.1.1.0.0.2">0.6875</span><span data-reactid=".1c0hi1r0074.1.4.1.1.1.0.0.3">)</span></label><input type="range" class="col-12 range-light" id="d2" name="d2" min="0.25" max="1" step="0.03125" value="0.6875" data-reactid=".1c0hi1r0074.1.4.1.1.1.0.1"></div></div><div class="md-col-3 px2" data-reactid=".1c0hi1r0074.1.4.1.1.2"><div data-reactid=".1c0hi1r0074.1.4.1.1.2.0"><label for="d3" class="h6 bold block" data-reactid=".1c0hi1r0074.1.4.1.1.2.0.0"><span data-reactid=".1c0hi1r0074.1.4.1.1.2.0.0.0">Diameter 3</span><span data-reactid=".1c0hi1r0074.1.4.1.1.2.0.0.1"> (</span><span data-reactid=".1c0hi1r0074.1.4.1.1.2.0.0.2">0.375</span><span data-reactid=".1c0hi1r0074.1.4.1.1.2.0.0.3">)</span></label><input type="range" class="col-12 range-light" id="d3" name="d3" min="0" max="0.75" step="0.03125" value="0.375" data-reactid=".1c0hi1r0074.1.4.1.1.2.0.1"></div></div><div class="md-col-3 px2" data-reactid=".1c0hi1r0074.1.4.1.1.3"><div data-reactid=".1c0hi1r0074.1.4.1.1.3.0"><label for="splay" class="h6 bold block" data-reactid=".1c0hi1r0074.1.4.1.1.3.0.0"><span data-reactid=".1c0hi1r0074.1.4.1.1.3.0.0.0">Splay</span><span data-reactid=".1c0hi1r0074.1.4.1.1.3.0.0.1"> (</span><span data-reactid=".1c0hi1r0074.1.4.1.1.3.0.0.2">0.375</span><span data-reactid=".1c0hi1r0074.1.4.1.1.3.0.0.3">)</span></label><input type="range" class="col-12 range-light" id="splay" name="splay" min="0" max="1" step="0.03125" value="0.375" data-reactid=".1c0hi1r0074.1.4.1.1.3.0.1"></div></div></div><div data-reactid=".1c0hi1r0074.1.4.1.2"><button class="btn btn-outline blue" data-reactid=".1c0hi1r0074.1.4.1.2.0">Show Guidelines</button></div><div data-reactid=".1c0hi1r0074.1.4.1.3"><h3 class="h5" data-reactid=".1c0hi1r0074.1.4.1.3.0">SVG Code</h3><pre data-reactid=".1c0hi1r0074.1.4.1.3.1">
<span class="hljs-tag"><<span class="hljs-title">svg</span> <span class="hljs-attribute">viewBox</span>=<span class="hljs-value">"0 0 64 64"</span> <span class="hljs-attribute">width</span>=<span class="hljs-value">"64"</span> <span class="hljs-attribute">height</span>=<span class="hljs-value">"64"</span> <span class="hljs-attribute">fill</span>=<span class="hljs-value">"currentcolor"</span>></span>
<span class="hljs-tag"><<span class="hljs-title">path</span> <span class="hljs-attribute">d</span>=<span class="hljs-value">"M 28.053176443624363 0 L 35.94682355637564 0 L 37.86768066444777 10.796926552500324 A 22 22 0 0 1 42.84376022905525 12.858086195608351 L 51.8365912971095 6.5817573011704615 L 57.41824269882954 12.1634087028905 L 51.14191380439165 21.156239770944754 A 22 22 0 0 1 53.203073447499676 26.132319335552236 L 64 28.053176443624363 L 64 35.94682355637564 L 53.203073447499676 37.86768066444777 A 22 22 0 0 1 51.14191380439165 42.84376022905525 L 57.41824269882954 51.8365912971095 L 51.8365912971095 57.41824269882954 L 42.84376022905525 51.14191380439165 A 22 22 0 0 1 37.86768066444777 53.203073447499676 L 35.94682355637564 64 L 28.053176443624363 64 L 26.13231933555224 53.203073447499676 A 22 22 0 0 1 21.15623977094475 51.14191380439165 L 12.1634087028905 57.41824269882954 L 6.5817573011704615 51.8365912971095 L 12.858086195608351 42.84376022905525 A 22 22 0 0 1 10.796926552500327 37.867680664447775 L 0 35.94682355637565 L 0 28.05317644362437 L 10.79692655250032 26.132319335552246 A 22 22 0 0 1 12.858086195608351 21.156239770944744 L 6.581757301170455 12.163408702890502 L 12.163408702890493 6.581757301170461 L 21.156239770944747 12.858086195608351 A 22 22 0 0 1 26.132319335552232 10.796926552500324 M 32 20 A 12 12 0 0 0 32 44 A 12 12 0 0 0 32 20"</span>></span><span class="hljs-tag"></<span class="hljs-title">path</span>></span>
<span class="hljs-tag"></<span class="hljs-title">svg</span>></span></pre></div></div></div><div class="center py3" data-reactid=".1c0hi1r0074.1.5"><div class="inline-block" data-reactid=".1c0hi1r0074.1.5.0"><a href="https://twitter.com/share" class="twitter-share-button" data-text="Building SVG icons with React" data-via="jxnblk" data-size="large" data-reactid=".1c0hi1r0074.1.5.0.0">Tweet</a><script data-reactid=".1c0hi1r0074.1.5.0.1">!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?"http":"https";if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document, "script", "twitter-wjs");</script></div></div><div class="center py3" data-reactid=".1c0hi1r0074.1.6"><div class="px2 py3 border rounded" data-reactid=".1c0hi1r0074.1.6.0"><h4 class="mt1" data-reactid=".1c0hi1r0074.1.6.0.0">Questions, Comments, Suggestions?</h4><a href="//github.com/jxnblk/react-icons/issues" class="btn btn-outline blue" data-reactid=".1c0hi1r0074.1.6.0.1">Open an Issue</a></div></div><footer class="mt3 py3 border-top" data-reactid=".1c0hi1r0074.1.7"><div class="sm-flex flex-baseline flex-wrap mxn1" data-reactid=".1c0hi1r0074.1.7.0"><a class="h3 btn btn-narrow btn-link" data-reactid=".1c0hi1r0074.1.7.0.0">Building SVG Icons with React</a><div class="sm-flex flex-baseline" data-reactid=".1c0hi1r0074.1.7.0.1"></div><div class="flex-auto" data-reactid=".1c0hi1r0074.1.7.0.2"></div><a href="//jxnblk.com" class="btn btn-narrow btn-link" data-reactid=".1c0hi1r0074.1.7.0.3">Made by Jxnblk</a></div></footer><script id="initial-props" type="application/json" data-reactid=".1c0hi1r0074.1.8">{"path":"/","assets":{"main":"bundle.js"},"name":"react-icons","title":"Building SVG Icons with React","description":"How to Create Mathematically-Generated Graphics Using JavaScript and React","keywords":["react","svg","icon","icons","tutorial"],"created":"05/31/2015","modified":"6/24/2015","code":{"svgComponent1":"var React = require('react')\n\nvar Cog = React.createClass({\n\n getDefaultProps: function() {\n return {\n size: 64,\n fill: 'currentcolor'\n }\n },\n\n render: function() {\n\n var size = this.props.size\n var fill = this.props.fill\n\n var viewBox = [0, 0, size, size].join(' ')\n\n var pathData = [\n ''\n ].join(' ')\n\n return (\n <svg xmlns=\"http://www.w3.org/svg/2000\"\n viewBox={viewBox}\n width={size}\n height={size}\n fill={fill}>\n <path d={pathData} />\n </svg>\n )\n\n }\n\n});\n\nmodule.exports = Cog\n","defaultProps":"getDefaultProps: function() {\n return {\n size: 64,\n d1: 1,\n d2: .6875,\n d3: .375,\n teeth: 8,\n splay: 0.375,\n fill: 'currentcolor'\n }\n},\n","renderVariables":"render: function() {\n\n var size = this.props.size\n var fill = this.props.fill\n\n // Center\n var c = size / 2\n\n // Radii\n var r1 = this.props.d1 * size / 2\n var r2 = this.props.d2 * size / 2\n var r3 = this.props.d3 * size / 2\n\n // Angle\n var angle = 360 / this.props.teeth\n var offset = 90\n\n var viewBox = [0, 0, size, size].join(' ')\n\n // ...\n\n}\n","pathSquare":"var pathData = [\n 'M', 2, 2, // Move to 2,2\n 'L', 62, 2, // Draw a line to 62,2\n 'L', 62, 62, // Draw a line to 62,62\n 'L', 2, 62, // Draw a line to 2,62\n 'L', 2, 2, // Draw a line to 2,2\n].join(' ')\n","rxRy":"var rad = function(a) {\n return Math.PI * a / 180\n}\n\nvar rx = function(r, a) {\n return c + r * Math.cos(rad(a))\n}\n\nvar ry = function(r, a) {\n return c + r * Math.sin(rad(a))\n}\n","drawPolygon":"var num = function(n) {\n return (n < 0.0000001) ? 0 : n \n}\n\nvar drawTeeth = function(n) {\n var d = []\n for (var i = 0; i < n; i++) {\n var a = angle * i - offset\n var line = [\n (i === 0) ? 'M' : 'L',\n num(rx(r1, a)),\n num(ry(r1, a)),\n ].join(' ')\n d.push(line)\n }\n return d.join(' ')\n}\n\nvar pathData = [\n drawTeeth(this.props.teeth)\n].join(' ')\n","sunBurst":"var drawTeeth = function(n) {\n var d = []\n for (var i = 0; i < n; i++) {\n var a = angle * i - offset\n var a1 = a + 6\n var a2 = a + angle - 6\n var line = [\n (i === 0) ? 'M' : 'L',\n num(rx(r1, a)),\n num(ry(r1, a)),\n 'L',\n num(rx(r2, a1)),\n num(ry(r2, a1)),\n 'A', r2, r2,\n '0 0 1',\n num(rx(r2, a2)),\n num(ry(r2, a2)),\n ].join(' ')\n d.push(line)\n }\n return d.join(' ')\n}\n","flatTeeth":"var ta = angle / 4\nvar tw = Math.tan(rad(ta)) * r1\n\nvar tx = function(a, w) {\n return Math.sin(rad(a)) * w\n}\n\nvar ty = function(a, w) {\n return Math.cos(rad(a)) * w\n}\n\nvar drawTeeth = function(n) {\n var d = []\n for (var i = 0; i < n; i++) {\n var a = angle * i - offset\n var a1 = a + ta\n var a2 = a + angle - ta\n var line = [\n (i === 0) ? 'M' : 'L',\n num(rx(r1, a) + tx(a, tw)),\n num(ry(r1, a) - ty(a, tw)),\n 'L',\n num(rx(r1, a) - tx(a, tw)),\n num(ry(r1, a) + ty(a, tw)),\n 'L',\n num(rx(r2, a1)),\n num(ry(r2, a1)),\n 'A', r2, r2,\n '0 0 1',\n num(rx(r2, a2)),\n num(ry(r2, a2)),\n ].join(' ')\n d.push(line)\n }\n return d.join(' ')\n}\n","splay":"var ta = angle / 4\nvar splay = this.props.splay * ta\nvar tw = Math.tan(rad(ta - splay)) * r1\n","splayDraw":"var drawTeeth = function(n) {\n var d = []\n for (var i = 0; i < n; i++) {\n var a = angle * i - offset\n var a1 = a + ta + splay\n var a2 = a + angle - ta - splay\n var line = [\n (i === 0) ? 'M' : 'L',\n num(rx(r1, a) + tx(a, tw)),\n num(ry(r1, a) - ty(a, tw)),\n 'L',\n num(rx(r1, a) - tx(a, tw)),\n num(ry(r1, a) + ty(a, tw)),\n 'L',\n num(rx(r2, a1)),\n num(ry(r2, a1)),\n 'A', r2, r2,\n '0 0 1',\n num(rx(r2, a2)),\n num(ry(r2, a2)),\n ].join(' ')\n d.push(line)\n }\n return d.join(' ')\n}\n","hole":"var hole = function() {\n return [\n 'M', c, c - r3,\n 'A', r3, r3,\n '0 0 0',\n c, c + r3,\n 'A', r3, r3,\n '0 0 0',\n c, c - r3,\n ].join(' ')\n}\n\nvar pathData = [\n drawTeeth(this.props.teeth),\n hole()\n].join(' ')\n","build1":"var fs = require('fs')\nvar React = require('react')\nvar Cog = require('./Cog')\n\nvar build = function(name, props) {\n\n var svg = React.renderToStaticMarkup(React.createElement(Cog, props))\n \n fs.writeFileSync('icons/' + name + '.svg', svg)\n\n}\n\nbuild('cog-icon', {})\n","build2":"var build = function(name, props) {\n\n props.size = props.size || 64\n var size = props.size\n var viewBox = [0, 0, size, size].join(' ')\n var svg = [\n '<svg xmlns=\"http://www.w3.org/2000/svg\" ',\n 'viewBox=\"', viewBox, '\" ',\n 'width=\"', size, '\" ',\n 'height=\"', size, '\" ',\n '>',\n React.renderToStaticMarkup(React.createElement(Icon, props)),\n '</svg>'\n ].join('')\n \n fs.writeFileSync('icons/' + name + '.svg', svg)\n\n}\n","packageScripts":"\"scripts\": {\n \"build\": \"node build\",\n \"jsx\": \"jsx -x jsx src .\",\n \"watch:jsx\": \"jsx -w -x jsx src .\"\n}\n"}}</script><script src="bundle.js" data-reactid=".1c0hi1r0074.1.9"></script></body></html>