Skip to content

Instantly share code, notes, and snippets.

@ChadJPetersen
Last active June 23, 2023 19:42
Show Gist options
  • Save ChadJPetersen/7b1bac66c301f076877c3d917844c7d4 to your computer and use it in GitHub Desktop.
Save ChadJPetersen/7b1bac66c301f076877c3d917844c7d4 to your computer and use it in GitHub Desktop.
Conver the topaz SigString format into a SVG string using typescript.
function topazSigString2svg(SigString: string): SVGSVGElement {
let raw = Buffer.from(SigString, "hex").toString(); // Convert Hex
raw = raw.replace(/\r|\\r/g, ""); // Fix: remove '\r' occurrences because Windows
const arr = raw.split(/\r?\n/); // Split into array
if (parseInt(arr[1]) > 0) {
// Check if signature is empty
const coords = arr.slice(2, parseInt(arr[0]) + 2), // Separate coordinate pairs
lines = arr.slice(parseInt(arr[0]) + 2, parseInt(arr[1]) + parseInt(arr[0]) + 2), // Separate number of coordinate pairs per stroke
strokes: string[][] = [];
lines.push(arr[0]); // Add last coordinate as a fix
let done = 0;
for (let i = 0; i < lines.length; i++) {
const lineValue = parseInt(lines[i]);
if (lineValue > done) {
const lineLength = lineValue - done,
stroke = coords.slice(done, done + lineLength);
strokes.push(stroke);
}
done = lineValue;
}
// Calculate maximum and minimum coordinates on both axes
let xMax = 0,
xMin = Infinity,
yMax = 0,
yMin = Infinity;
const xy: { [key: string]: { x: number[]; y: number[] } } = {};
for (let i = 0; i < strokes.length; i++) {
xy[i] = { x: [], y: [] };
const xyCoords = strokes[i];
for (let j = 0; j < xyCoords.length; j++) {
const [x, y] = xyCoords[j].split(" ").map(parseFloat);
xy[i].x.push(x);
xy[i].y.push(y);
if (x > xMax) xMax = x;
if (x < xMin) xMin = x;
if (y > yMax) yMax = y;
if (y < yMin) yMin = y;
}
}
// Add 10-pixel border for strokes
xMax += 10;
xMin -= 10;
yMax += 10;
yMin -= 10;
// Calculate canvas size and offset
xMax -= xMin;
yMax -= yMin;
let polyLines = "";
for (const key in xy) {
const axis = xy[key];
const points = axis.x.map((x, i) => `${x - xMin},${axis.y[i] - yMin}`).join(" ");
polyLines += `<polyline class="sig" points="${points}"/>`;
}
// Build SVG image string
const image = `
<svg id="sig" data-name="sig" xmlns="http://www.w3.org/2000/svg" width="${xMax}" height="${yMax}" viewBox="0 0 ${xMax} ${yMax}">
<style>
.sig {
fill: none;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 4px;
}
</style>
<title>Signature</title>
<g>
${polyLines}
</g>
</svg>`;
return image;
}
throw new Error("Signature is empty");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment