1 | const { svg2cagX, svg2cagY, cagLengthX, cagLengthY, cagLengthP, reflect } = require('./helpers')
|
2 |
|
3 |
|
4 | const shapesMap = function (obj, codify, params) {
|
5 | const { level, indent, on, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, svgGroups, target, segments } = params
|
6 |
|
7 | const types = {
|
8 | group: (obj) => {
|
9 | let code = codify({ target, segments }, obj)
|
10 | code += `${indent}${on} = levels.l${level + 1}\n`
|
11 | return code
|
12 | },
|
13 |
|
14 | rect: (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, params, svgGroups, segments) => {
|
15 | let x = cagLengthX(obj.x, svgUnitsPmm, svgUnitsX)
|
16 | let y = (0 - cagLengthY(obj.y, svgUnitsPmm, svgUnitsY))
|
17 | const w = cagLengthX(obj.width, svgUnitsPmm, svgUnitsX)
|
18 | const h = cagLengthY(obj.height, svgUnitsPmm, svgUnitsY)
|
19 | const rx = cagLengthX(obj.rx, svgUnitsPmm, svgUnitsX)
|
20 |
|
21 | let code
|
22 | if (w > 0 && h > 0) {
|
23 | x = (x + (w / 2)).toFixed(4)
|
24 | y = (y - (h / 2)).toFixed(4)
|
25 | if (rx === 0) {
|
26 | code = `${indent}${on} = transforms.center({ center: [${x}, ${y}, 0] }, primitives.rectangle({size: [${w}, ${h}]})) // line ${obj.position}\n`
|
27 | } else {
|
28 | code = `${indent}${on} = transforms.center({ center: [${x}, ${y}, 0] }, primitives.roundedRectangle({segments: ${segments}, size: [${w}, ${h}], roundRadius: ${rx}})) // line ${obj.position}\n`
|
29 | }
|
30 | if (target === 'path') {
|
31 | code += `${indent}${on} = geometries.path2.fromPoints({closed: true}, geometries.geom2.toPoints(${on}))\n`
|
32 | }
|
33 | }
|
34 | return code
|
35 | },
|
36 |
|
37 | circle: (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, params, svgGroups, segments) => {
|
38 | const x = cagLengthX(obj.x, svgUnitsPmm, svgUnitsX)
|
39 | const y = (0 - cagLengthY(obj.y, svgUnitsPmm, svgUnitsY))
|
40 | const r = cagLengthP(obj.radius, svgUnitsPmm, svgUnitsV)
|
41 | let code
|
42 | if (r > 0) {
|
43 | code = `${indent}${on} = transforms.center({ center: [${x}, ${y}, 0] }, primitives.circle({segments: ${segments}, radius: ${r}})) // line ${obj.position}\n`
|
44 | if (target === 'path') {
|
45 | code += `${indent}${on} = geometries.path2.fromPoints({closed: true}, geometries.geom2.toPoints(${on}))\n`
|
46 | }
|
47 | }
|
48 | return code
|
49 | },
|
50 |
|
51 | ellipse: (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, params, svgGroups, segments) => {
|
52 | const rx = cagLengthX(obj.rx, svgUnitsPmm, svgUnitsX)
|
53 | const ry = cagLengthY(obj.ry, svgUnitsPmm, svgUnitsY)
|
54 | const cx = cagLengthX(obj.cx, svgUnitsPmm, svgUnitsX)
|
55 | const cy = (0 - cagLengthY(obj.cy, svgUnitsPmm, svgUnitsY))
|
56 | let code
|
57 | if (rx > 0 && ry > 0) {
|
58 | code = `${indent}${on} = transforms.center({ center: [${cx}, ${cy}, 0] }, primitives.ellipse({segments: ${segments}, radius: [${rx}, ${ry}]})) // line ${obj.position}\n`
|
59 | if (target === 'path') {
|
60 | code += `${indent}${on} = geometries.path2.fromPoints({closed: true}, geometries.geom2.toPoints(${on}))\n`
|
61 | }
|
62 | }
|
63 | return code
|
64 | },
|
65 |
|
66 | line: (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV) => {
|
67 | const x1 = cagLengthX(obj.x1, svgUnitsPmm, svgUnitsX)
|
68 | const y1 = (0 - cagLengthY(obj.y1, svgUnitsPmm, svgUnitsY))
|
69 | const x2 = cagLengthX(obj.x2, svgUnitsPmm, svgUnitsX)
|
70 | const y2 = (0 - cagLengthY(obj.y2, svgUnitsPmm, svgUnitsY))
|
71 | const code = `${indent}${on} = primitives.line([[${x1}, ${y1}], [${x2}, ${y2}]]) // line ${obj.position}\n`
|
72 | if (target === 'geom2') {
|
73 |
|
74 |
|
75 | }
|
76 | return code
|
77 | },
|
78 |
|
79 | polygon: (obj, svgUnitsPmm, svgUnitsX, svgUnitsY) => {
|
80 | let code = `${indent}${on} = primitives.polygon({points: [\n`
|
81 | for (let j = 0; j < obj.points.length; j++) {
|
82 | const p = obj.points[j]
|
83 | if ('x' in p && 'y' in p) {
|
84 | const x = cagLengthX(p.x, svgUnitsPmm, svgUnitsX)
|
85 | const y = (0 - cagLengthY(p.y, svgUnitsPmm, svgUnitsY))
|
86 | code += `${indent} [${x}, ${y}],\n`
|
87 | }
|
88 | }
|
89 | code += `${indent}]}) // line ${obj.position}\n`
|
90 | if (target === 'path') {
|
91 | code += `${indent}${on} = geometries.path2.fromPoints({closed: true}, geometries.geom2.toPoints(${on}))\n`
|
92 | }
|
93 | return code
|
94 | },
|
95 |
|
96 | polyline: (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV) => {
|
97 | let code = `${indent}${on} = geometries.path2.fromPoints({}, [\n`
|
98 | for (let j = 0; j < obj.points.length; j++) {
|
99 | const p = obj.points[j]
|
100 | if ('x' in p && 'y' in p) {
|
101 | const x = cagLengthX(p.x, svgUnitsPmm, svgUnitsX)
|
102 | const y = (0 - cagLengthY(p.y, svgUnitsPmm, svgUnitsY))
|
103 | code += `${indent} [${x}, ${y}],\n`
|
104 | }
|
105 | }
|
106 | code += `${indent}]) // line ${obj.position}\n`
|
107 | if (target === 'geom2') {
|
108 |
|
109 |
|
110 | }
|
111 | return code
|
112 | },
|
113 |
|
114 | path
|
115 | }
|
116 |
|
117 | return types[obj.type](obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, params, svgGroups, segments)
|
118 | }
|
119 |
|
120 | module.exports = shapesMap
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 | const path = (obj, svgUnitsPmm, svgUnitsX, svgUnitsY, svgUnitsV, params, svgGroups, segments) => {
|
136 | const { indent, on, target } = params
|
137 | let tmpCode = `${indent}parts = [] // line ${obj.position}\n`
|
138 |
|
139 |
|
140 | let sx = 0
|
141 | let sy = 0
|
142 | let cx = 0
|
143 | let cy = 0
|
144 | let pi = 0
|
145 | let pathName = on + pi
|
146 | let pc = false
|
147 | let bx = 0
|
148 | let by = 0
|
149 | let qx = 0
|
150 | let qy = 0
|
151 |
|
152 | for (let j = 0; j < obj.commands.length; j++) {
|
153 | const co = obj.commands[j]
|
154 | const pts = co.p
|
155 |
|
156 | switch (co.c) {
|
157 | case 'm':
|
158 |
|
159 | if (j === 0) {
|
160 | cx = 0; cy = 0
|
161 | }
|
162 |
|
163 | if (pi > 0 && pc === false) {
|
164 | tmpCode += `${indent}parts.push(${pathName})\n`
|
165 | }
|
166 |
|
167 | if (pts.length >= 2) {
|
168 | cx = cx + parseFloat(pts.shift())
|
169 | cy = cy + parseFloat(pts.shift())
|
170 | pi++
|
171 | pc = false
|
172 | pathName = on + pi
|
173 | tmpCode += `${indent}${pathName} = geometries.path2.fromPoints({}, [[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]])\n`
|
174 | sx = cx; sy = cy
|
175 | }
|
176 |
|
177 | while (pts.length >= 2) {
|
178 | cx = cx + parseFloat(pts.shift())
|
179 | cy = cy + parseFloat(pts.shift())
|
180 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}], ${pathName})\n`
|
181 | }
|
182 | break
|
183 | case 'M':
|
184 |
|
185 | if (pi > 0 && pc === false) {
|
186 | tmpCode += `${indent}parts.push(${pathName})\n`
|
187 | }
|
188 |
|
189 | if (pts.length >= 2) {
|
190 | cx = parseFloat(pts.shift())
|
191 | cy = parseFloat(pts.shift())
|
192 | pi++
|
193 | pc = false
|
194 | pathName = on + pi
|
195 | tmpCode += `${indent}${pathName} = geometries.path2.fromPoints({}, [[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]])\n`
|
196 | sx = cx; sy = cy
|
197 | }
|
198 |
|
199 | while (pts.length >= 2) {
|
200 | cx = parseFloat(pts.shift())
|
201 | cy = parseFloat(pts.shift())
|
202 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}], ${pathName})\n`
|
203 | }
|
204 | break
|
205 | case 'a':
|
206 | while (pts.length >= 7) {
|
207 | const rx = parseFloat(pts.shift())
|
208 | const ry = parseFloat(pts.shift())
|
209 | const ro = 0 - parseFloat(pts.shift()) * 0.017453292519943295
|
210 | const lf = (pts.shift() === '1')
|
211 | const sf = (pts.shift() === '1')
|
212 | cx = cx + parseFloat(pts.shift())
|
213 | cy = cy + parseFloat(pts.shift())
|
214 | tmpCode += `${indent}${pathName} = geometries.path2.appendArc({segments: ${segments}, endpoint: [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}], radius: [${svg2cagX(rx, svgUnitsPmm)}, ${svg2cagY(ry, svgUnitsPmm)}], xaxisrotation: ${ro}, clockwise: ${sf}, large: ${lf}}, ${pathName})\n`
|
215 | }
|
216 | break
|
217 | case 'A':
|
218 | while (pts.length >= 7) {
|
219 | const rx = parseFloat(pts.shift())
|
220 | const ry = parseFloat(pts.shift())
|
221 | const ro = 0 - parseFloat(pts.shift()) * 0.017453292519943295
|
222 | const lf = (pts.shift() === '1')
|
223 | const sf = (pts.shift() === '1')
|
224 | cx = parseFloat(pts.shift())
|
225 | cy = parseFloat(pts.shift())
|
226 | tmpCode += `${indent}${pathName} = geometries.path2.appendArc({segments: ${segments}, endpoint: [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}], radius: [${svg2cagX(rx, svgUnitsPmm)}, ${svg2cagY(ry, svgUnitsPmm)}], xaxisrotation: ${ro}, clockwise: ${sf}, large: ${lf}}, ${pathName})\n`
|
227 | }
|
228 | break
|
229 | case 'c':
|
230 | while (pts.length >= 6) {
|
231 | const x1 = cx + parseFloat(pts.shift())
|
232 | const y1 = cy + parseFloat(pts.shift())
|
233 | bx = cx + parseFloat(pts.shift())
|
234 | by = cy + parseFloat(pts.shift())
|
235 | cx = cx + parseFloat(pts.shift())
|
236 | cy = cy + parseFloat(pts.shift())
|
237 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(x1, svgUnitsPmm)}, ${svg2cagY(y1, svgUnitsPmm)}], [${svg2cagX(bx, svgUnitsPmm)}, ${svg2cagY(by, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
238 | const rf = reflect(bx, by, cx, cy)
|
239 | bx = rf[0]
|
240 | by = rf[1]
|
241 | }
|
242 | break
|
243 | case 'C':
|
244 | while (pts.length >= 6) {
|
245 | const x1 = parseFloat(pts.shift())
|
246 | const y1 = parseFloat(pts.shift())
|
247 | bx = parseFloat(pts.shift())
|
248 | by = parseFloat(pts.shift())
|
249 | cx = parseFloat(pts.shift())
|
250 | cy = parseFloat(pts.shift())
|
251 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(x1, svgUnitsPmm)}, ${svg2cagY(y1, svgUnitsPmm)}], [${svg2cagX(bx, svgUnitsPmm)}, ${svg2cagY(by, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
252 | const rf = reflect(bx, by, cx, cy)
|
253 | bx = rf[0]
|
254 | by = rf[1]
|
255 | }
|
256 | break
|
257 | case 'q':
|
258 | while (pts.length >= 4) {
|
259 | qx = cx + parseFloat(pts.shift())
|
260 | qy = cy + parseFloat(pts.shift())
|
261 | cx = cx + parseFloat(pts.shift())
|
262 | cy = cy + parseFloat(pts.shift())
|
263 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(qx, svgUnitsPmm)}, ${svg2cagY(qy, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
264 | const rf = reflect(qx, qy, cx, cy)
|
265 | qx = rf[0]
|
266 | qy = rf[1]
|
267 | }
|
268 | break
|
269 | case 'Q':
|
270 | while (pts.length >= 4) {
|
271 | qx = parseFloat(pts.shift())
|
272 | qy = parseFloat(pts.shift())
|
273 | cx = parseFloat(pts.shift())
|
274 | cy = parseFloat(pts.shift())
|
275 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(qx, svgUnitsPmm)}, ${svg2cagY(qy, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
276 | const rf = reflect(qx, qy, cx, cy)
|
277 | qx = rf[0]
|
278 | qy = rf[1]
|
279 | }
|
280 | break
|
281 | case 't':
|
282 | while (pts.length >= 2) {
|
283 | cx = cx + parseFloat(pts.shift())
|
284 | cy = cy + parseFloat(pts.shift())
|
285 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(qx, svgUnitsPmm)}, ${svg2cagY(qy, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
286 | const rf = reflect(qx, qy, cx, cy)
|
287 | qx = rf[0]
|
288 | qy = rf[1]
|
289 | }
|
290 | break
|
291 | case 'T':
|
292 | while (pts.length >= 2) {
|
293 | cx = parseFloat(pts.shift())
|
294 | cy = parseFloat(pts.shift())
|
295 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(qx, svgUnitsPmm)}, ${svg2cagY(qy, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
296 | const rf = reflect(qx, qy, cx, cy)
|
297 | qx = rf[0]
|
298 | qy = rf[1]
|
299 | }
|
300 | break
|
301 | case 's':
|
302 | while (pts.length >= 4) {
|
303 | const x1 = bx
|
304 | const y1 = by
|
305 | bx = cx + parseFloat(pts.shift())
|
306 | by = cy + parseFloat(pts.shift())
|
307 | cx = cx + parseFloat(pts.shift())
|
308 | cy = cy + parseFloat(pts.shift())
|
309 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(x1, svgUnitsPmm)}, ${svg2cagY(y1, svgUnitsPmm)}], [${svg2cagX(bx, svgUnitsPmm)}, ${svg2cagY(by, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
310 | const rf = reflect(bx, by, cx, cy)
|
311 | bx = rf[0]
|
312 | by = rf[1]
|
313 | }
|
314 | break
|
315 | case 'S':
|
316 | while (pts.length >= 4) {
|
317 | const x1 = bx
|
318 | const y1 = by
|
319 | bx = parseFloat(pts.shift())
|
320 | by = parseFloat(pts.shift())
|
321 | cx = parseFloat(pts.shift())
|
322 | cy = parseFloat(pts.shift())
|
323 | tmpCode += `${indent}${pathName} = geometries.path2.appendBezier({segments: ${segments}, controlPoints: [[${svg2cagX(x1, svgUnitsPmm)}, ${svg2cagY(y1, svgUnitsPmm)}], [${svg2cagX(bx, svgUnitsPmm)}, ${svg2cagY(by, svgUnitsPmm)}], [${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]]}, ${pathName})\n`
|
324 | const rf = reflect(bx, by, cx, cy)
|
325 | bx = rf[0]
|
326 | by = rf[1]
|
327 | }
|
328 | break
|
329 | case 'h':
|
330 | while (pts.length >= 1) {
|
331 | cx = cx + parseFloat(pts.shift())
|
332 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]], ${pathName})\n`
|
333 | }
|
334 | break
|
335 | case 'H':
|
336 | while (pts.length >= 1) {
|
337 | cx = parseFloat(pts.shift())
|
338 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]], ${pathName})\n`
|
339 | }
|
340 | break
|
341 | case 'l':
|
342 | while (pts.length >= 2) {
|
343 | cx = cx + parseFloat(pts.shift())
|
344 | cy = cy + parseFloat(pts.shift())
|
345 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]], ${pathName})\n`
|
346 | }
|
347 | break
|
348 | case 'L':
|
349 | while (pts.length >= 2) {
|
350 | cx = parseFloat(pts.shift())
|
351 | cy = parseFloat(pts.shift())
|
352 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]], ${pathName})\n`
|
353 | }
|
354 | break
|
355 | case 'v':
|
356 | while (pts.length >= 1) {
|
357 | cy = cy + parseFloat(pts.shift())
|
358 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]], ${pathName})\n`
|
359 | }
|
360 | break
|
361 | case 'V':
|
362 | while (pts.length >= 1) {
|
363 | cy = parseFloat(pts.shift())
|
364 | tmpCode += `${indent}${pathName} = geometries.path2.appendPoints([[${svg2cagX(cx, svgUnitsPmm)}, ${svg2cagY(cy, svgUnitsPmm)}]], ${pathName})\n`
|
365 | }
|
366 | break
|
367 | case 'z':
|
368 | case 'Z':
|
369 | tmpCode += `${indent}${pathName} = geometries.path2.close(${pathName})\n`
|
370 | if (target === 'geom2') {
|
371 | tmpCode += `${indent}${pathName} = geometries.geom2.fromPoints(geometries.path2.toPoints(${pathName}))\n`
|
372 | }
|
373 | tmpCode += `${indent}parts.push(${pathName})\n`
|
374 |
|
375 | cx = sx
|
376 | cy = sy
|
377 | pc = true
|
378 | break
|
379 | default:
|
380 | console.log('Warning: Unknow PATH command [' + co.c + ']')
|
381 | break
|
382 | }
|
383 |
|
384 | }
|
385 | if (pi > 0 && pc === false) {
|
386 | tmpCode += `${indent}parts.push(${pathName})\n`
|
387 | }
|
388 | tmpCode += `${indent}${on} = parts\n`
|
389 | return tmpCode
|
390 | }
|