UNPKG

@dromney/gear-gen

Version:

A set of types and pattern generators for working with front-end gears

148 lines (147 loc) 6.72 kB
import { fix2, fix6, polarToLinear } from "./utils.js"; export function createSVGCircle(r) { return "M-" + r + ",0a" + r + "," + r + ",0 0,1 " + (2 * r) + ",0a " + r + "," + r + " 0 0,1 -" + (2 * r) + ",0z"; } export function createSVGgrid(sc, subd = 10, weight = 1) { const scdot = sc + 0.5; let out = '<svg version="1.2" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="' + sc + 'px" height="' + sc + 'px" viewBox="0 0 ' + sc + ' ' + sc + '" xml:space="preserve">'; out += '<g class="grid" stroke="#888" opacity="0.2">'; out += '<polyline class="grid-line grid-line-major" fill="none" stroke-width="' + weight + '" stroke-linecap="square" stroke-miterlimit="2" points="'; out += '0.5 ' + scdot + ' 0.5 0.5 ' + scdot + ' 0.5"></polyline>'; for (var i = 1; i < subd; i++) { var pos = (sc / subd) * i + 0.5; out += '<polyline class="grid-line grid-line-minor grid-line-minor-horizontal" fill="none" stroke-width="' + (weight / 2) + '" stroke-linecap="square" stroke-miterlimit="2" points="0.5 ' + pos + ' ' + scdot + ' ' + pos + '"></polyline>'; out += '<polyline class="grid-line grid-line-minor grid-line-minor-vertical" fill="none" stroke-width="' + (weight / 2) + '" stroke-linecap="square" stroke-miterlimit="2" points="' + pos + ' 0.5 ' + pos + ' ' + scdot + '"></polyline>'; } out += '</g></svg>'; return out; } const font = ["ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-/=*;:,.<>", "0204284442324335464738181215080307480525452224683316263634174130100106373120004014232713", "4ABCDE/BD 4AFGDHIJKLM/NH/OL 4GFMPQLKJ 4AFGJKO/LM 4EAOR/ST 4AOR/ST 4HUEMPQLR 4ER/US/OA 2VA/ML/CO 4RGFMP 4ENR/AO/NS 4EAO 4ERWOA 4REOA 4UGFMPQLKJU 4SHIJKOA 4DVMPQLKJD 4ENHIJKOA/NS 4JKLQGFMP 4RO/CV 4RGFMPO 6XFO 6XEHVO 4RA/EO 4RTO/TV 4EARO 4YVMPSZaHYE 4OBabUGFVBA 4EMPSZI 4EDVMPSZaDR 4FMPSZbUcB 4MdCKJ/HS 4EMPSZbUefgh 4BabUE/AO 0Ai/QO 3Kj/bklgh 4EWI/AO/WB 1MPO 4Ai/SZTbUE/WT 4Ai/BabUE 4GFMPSZbUG 4mi/SZbUGFA 4nI/EMPSZbU 4Ai/BabU 4IZSocGFA 4GFpC/Ii 4IE/DVMPi 4IVi 4IFaMi 4IA/Ei 4Igm/Vi 4EAIi 3YVMPQLCjY 2QLM/VA 4EABNHIJKLQ 4QLKJIHDGFMP/TH 4DBKF 4ROibUGFMP 4SHDGFMPiCK 4ORV 4NBPMFGDHNiQLKJIH 4UNiQLKJDVM 4pq/US 4US 4RA 4Ii/DB 4US/pq/JP/GQ 1ZN/oMh 1ZN/or 1rMh 0PA 3KSF 3OHA"]; function getASCIIndex(code) { let movedCode = code - 65; if (movedCode > 25) movedCode -= 6; return movedCode * 2; } function getchardata(chr) { var i = font[0].lastIndexOf(chr); if (i === -1) return { type: (chr === " " ? 3 : -1), data: [] }; var chdata = font[2].split(" ")[i]; const type = Number(chdata.substr(0, 1)); const data = []; let line = 0; for (var p = 0; p < chdata.length; p++) { if (!data[line]) data[line] = []; var pi = getASCIIndex(chdata.charCodeAt(p)); if (pi < 0) { if (data[0].length) line++; } else data[line].push(font[1].substr(pi, 2)); } return { type, data }; } export function makeText(txt, chs = 1) { let pos = 0; const lines = []; for (let i = 0; i < txt.length; i++) { const cdata = getchardata(txt.substr(i, 1)); if (cdata.type >= 0) { for (let l = 0; l < cdata.data.length; l++) { const line = []; for (var p = 0; p < cdata.data[l].length; p++) { const pt = cdata.data[l][p].split(""); line.push({ x: Number(pt[0]) + pos, y: Number(pt[1]) }); } lines.push(line); } pos += chs + cdata.type; } } if (pos > 0) pos = pos - 1; return { something: pos, lines: lines }; } function getPrecisionPolarTextLines(tdata, textB, pixH) { const plotAngle = pixH * 180 / (textB * Math.PI); const angularLength = tdata.something * plotAngle; const ba = angularLength / 2; const lines = []; tdata.lines.forEach(line => { const points = []; let lx = 0, ly = 0, a, r, dx; line.forEach((pt, index) => { if (index === 0) { lx = pt.x; ly = pt.y; a = -lx * plotAngle + ba; r = (ly - 5) * pixH + textB; points.push(polarToLinear({ r, a })); } else { dx = Math.abs(pt.x - lx); if (dx === 0) dx = 1; const ix = (pt.x - lx) / dx; const iy = (pt.y - ly) / dx; for (var s = 1; s <= dx; s++) { let Y = ly + iy * s; let X = lx + ix * s; a = -X * plotAngle + ba; r = (Y - 5) * pixH + textB; points.push(polarToLinear({ r, a })); } lx = pt.x; ly = pt.y; } }); lines.push(points); }); return lines; } export function getPrecisionPolarTextDXFLines(tdata, textB, pixH, sc) { const linesPolar = getPrecisionPolarTextLines(tdata, textB, pixH); const linesLinear = linesPolar.map(line => line.map(pt => [fix6(pt.x * sc), -fix6(pt.y * sc)])); return linesLinear; } export function getPrecisionPolarTextSVG(tdata, textB, pixH, sc) { const linesPolar = getPrecisionPolarTextLines(tdata, textB, pixH); const linesLinear = linesPolar.map(group => group.map(pt => [fix2(pt.x * sc), fix2(pt.y * sc)])); let out = '<g class="gear-text-container">'; linesLinear.forEach(line => { out += '<polyline class="gear-text" fill="none" stroke="#444" stroke-width="0.5" stroke-linecap="square" stroke-miterlimit="1" points="'; line.forEach(pt => { out += pt[0] + " " + pt[1] + " "; }); out += '"/>'; }); out += "</g>"; return out; } export function getPolarTextSVG(tdata, textB, pixH, sc) { const plotAngle = 180 / ((textB * Math.PI) / pixH); var angularLength = tdata.something * plotAngle; const ba = angularLength / 2; let out = '<g class="gear-text">'; for (var i = 0; i < tdata.lines.length; i++) { out += '<polyline class="gear-text" fill="none" stroke="#444" stroke-width="0.5" stroke-linecap="square" stroke-miterlimit="1" points="'; for (var p = 0, a, r, dot; p < tdata.lines[i].length; p++) { a = -tdata.lines[i][p].x * plotAngle + ba; r = (tdata.lines[i][p].y - 5) * pixH + textB; dot = polarToLinear({ r, a }); out += dot.x * sc + " " + dot.y * sc + " "; } out += '"/>'; } out += "</g>"; return out; }