p5.plotsvg
Version:
A Plotter-Oriented SVG Exporter for p5.js
249 lines (229 loc) • 11.7 kB
JavaScript
// Display an inlined Hershey font in p5.js from
// https://github.com/techninja/hersheytextjs
// Adapted from "hershey font json example" by Allison Parrish,
// https://editor.p5js.org/allison.parrish/sketches/SJv2DCYpQ
p5.disableFriendlyErrors = true; // hush, p5
let bDoExportSvg = false;
function setup() {
createCanvas(640, 280);
let saveButton = createButton("Save SVG");
saveButton.position(10, 10);
saveButton.mousePressed((event) => {
event.stopPropagation();
bDoExportSvg = true;
});
}
function draw(){
background(245);
stroke(0);
if (bDoExportSvg){
beginRecordSVG(this, "hershey_text.svg");
}
drawString("ABCDEFGHIJKLMNOPQRSTUVWXYZ", 50,70, 1.0);
drawString("abcdefghijklmnopqrstuvwxyz", 50,110, 1.0);
drawString("1234567890", 50,150, 1.0);
drawString("!@#$%^&*()?{}[]()<>,.;:'\"", 50,190, 1.0);
drawString("Hello World", 50,230, 1.0);
if (bDoExportSvg){
endRecordSVG();
bDoExportSvg = false;
}
}
function keyPressed() {
if ((key === 's') || (key === 'S')) {
bDoExportSvg = true;
}
}
//===================================================================
// convert a hersheytextjs SVG path to a list of opentype-esque commands
// By Allison Parrish
function drawString(str, x, y, sca){
drawPath(getPathCommandsForText(str), x,y, sca);
}
function drawChar(c, bCentered=false){
// Draws a character at the origin.
// It's up to you to scale, translate, rotate it, etc.
let cidx = c.charCodeAt(0) - 33;
if (cidx >= 0) {
let dx = bCentered ? 0-hersheyFutural.futural.chars[cidx].o : 0;
let dy = 0;
drawPath(getPathCommandsForText(c), dx,dy, 1.0);
}
}
//--------------------------------------------
// produce an array of commands for the given string
function getPathCommandsForText(s) {
const font = hersheyFutural.futural;
let commands = [];
let offset = 0;
for (let i = 0; i < s.length; i++) {
let cidx = s.charCodeAt(i) - 33;
if (cidx >= 0) {
Array.prototype.push.apply(
commands, getPathCommandsForChar(font.chars[cidx].d, offset));
offset += int(font.chars[cidx].o) * 2;
}
else {
offset += 10;
}
}
return commands;
}
//--------------------------------------------
function getPathCommandsForChar(s, offset) {
let instr = [];
let mode = '';
instr.push({type: 'B', 'x': 0, 'y': 0}); // beginSvgGroup
for (let t of s.split(' ')) {
if (t.charAt(0) == 'M' || t.charAt(0) == 'L') {
mode = t.charAt(0);
t = t.substr(1);
}
let coords = t.split(',');
if (mode == 'M') {
instr.push({type: 'M', 'x': int(coords[0])+offset, 'y': int(coords[1])});
}
else if (mode == 'L') {
instr.push({type: 'L', 'x': int(coords[0])+offset, 'y': int(coords[1])});
}
}
instr.push({type: 'E', 'x': 0, 'y': 0}); // endSvgGroup
return instr;
}
//--------------------------------------------
// draw commands.
// Note, this has been modified to use p5.plotSvg's SVG group commands.
function drawPath(cmds, x,y, sca) {
// current pen position
let cx = 0;
let cy = 0;
// start position of current contour
let startX = 0;
let startY = 0;
const dy = 22;
for (let cmd of cmds) {
switch (cmd.type) {
case 'B':
beginSvgGroup();
break;
case 'E':
endSvgGroup();
break;
case 'M':
startX = cmd.x;
startY = cmd.y;
cx = cmd.x;
cy = cmd.y;
break;
case 'L':
let x0 = x + cx*sca;
let y0 = y + (cy - dy)*sca;
let x1 = x + cmd.x*sca;
let y1 = y + (cmd.y - dy)*sca;
line(x0,y0, x1,y1);
cx = cmd.x;
cy = cmd.y;
break;
}
}
}
const hersheyFutural = {"futural":{
"name":"Sans 1-stroke",
"chars":[
{"d":"M5,1 L5,15 M5,20 L4,21 5,22 6,21 5,20","o":5},
{"d":"M4,1 L4,8 M12,1 L12,8","o":8},
{"d":"M11,-3 L4,29 M17,-3 L10,29 M4,10 L18,10 M3,16 L17,16","o":11},
{"d":"M8,-3 L8,26 M12,-3 L12,26 M17,4 L15,2 12,1 8,1 5,2 3,4 3,6 4,8 5,9 7,10 13,12 15,13 16,14 17,16 17,19 15,21 12,22 8,22 5,21 3,19","o":10},
{"d":"M21,1 L3,22 M8,1 L10,3 10,5 9,7 7,8 5,8 3,6 3,4 4,2 6,1 8,1 10,2 13,3 16,3 19,2 21,1 M17,15 L15,16 14,18 14,20 16,22 18,22 20,21 21,19 21,17 19,15 17,15","o":12},
{"d":"M23,10 L23,9 22,8 21,8 20,9 19,11 17,16 15,19 13,21 11,22 7,22 5,21 4,20 3,18 3,16 4,14 5,13 12,9 13,8 14,6 14,4 13,2 11,1 9,2 8,4 8,6 9,9 11,12 16,19 18,21 20,22 22,22 23,21 23,20","o":13},
{"d":"M5,3 L4,2 5,1 6,2 6,4 5,6 4,7","o":5},
{"d":"M11,-3 L9,-1 7,2 5,6 4,11 4,15 5,20 7,24 9,27 11,29","o":7},
{"d":"M3,-3 L5,-1 7,2 9,6 10,11 10,15 9,20 7,24 5,27 3,29","o":7},
{"d":"M8,7 L8,19 M3,10 L13,16 M13,10 L3,16","o":8},
{"d":"M13,4 L13,22 M4,13 L22,13","o":13},
{"d":"M5,18 L4,19 3,18 4,17 5,18 5,20 3,22","o":4},
{"d":"M4,13 L22,13","o":13},
{"d":"M4,17 L3,18 4,19 5,18 4,17","o":4},
{"d":"M20,-3 L2,29","o":11},
{"d":"M9,1 L6,2 4,5 3,10 3,13 4,18 6,21 9,22 11,22 14,21 16,18 17,13 17,10 16,5 14,2 11,1 9,1","o":10},
{"d":"M6,5 L8,4 11,1 11,22","o":10},
{"d":"M4,6 L4,5 5,3 6,2 8,1 12,1 14,2 15,3 16,5 16,7 15,9 13,12 3,22 17,22","o":10},
{"d":"M5,1 L16,1 10,9 13,9 15,10 16,11 17,14 17,16 16,19 14,21 11,22 8,22 5,21 4,20 3,18","o":10},
{"d":"M13,1 L3,15 18,15 M13,1 L13,22","o":10},
{"d":"M15,1 L5,1 4,10 5,9 8,8 11,8 14,9 16,11 17,14 17,16 16,19 14,21 11,22 8,22 5,21 4,20 3,18","o":10},
{"d":"M16,4 L15,2 12,1 10,1 7,2 5,5 4,10 4,15 5,19 7,21 10,22 11,22 14,21 16,19 17,16 17,15 16,12 14,10 11,9 10,9 7,10 5,12 4,15","o":10},
{"d":"M17,1 L7,22 M3,1 L17,1","o":10},
{"d":"M8,1 L5,2 4,4 4,6 5,8 7,9 11,10 14,11 16,13 17,15 17,18 16,20 15,21 12,22 8,22 5,21 4,20 3,18 3,15 4,13 6,11 9,10 13,9 15,8 16,6 16,4 15,2 12,1 8,1","o":10},
{"d":"M16,8 L15,11 13,13 10,14 9,14 6,13 4,11 3,8 3,7 4,4 6,2 9,1 10,1 13,2 15,4 16,8 16,13 15,18 13,21 10,22 8,22 5,21 4,19","o":10},
{"d":"M4,10 L3,11 4,12 5,11 4,10 M4,17 L3,18 4,19 5,18 4,17","o":4},
{"d":"M4,10 L3,11 4,12 5,11 4,10 M5,18 L4,19 3,18 4,17 5,18 5,20 3,22","o":4},
{"d":"M20,4 L4,13 20,22","o":12},
{"d":"M4,10 L22,10 M4,16 L22,16","o":13},
{"d":"M4,4 L20,13 4,22","o":12},
{"d":"M3,6 L3,5 4,3 5,2 7,1 11,1 13,2 14,3 15,5 15,7 14,9 13,10 9,12 9,15 M9,20 L8,21 9,22 10,21 9,20","o":9},
{"d":"M18,9 L17,7 15,6 12,6 10,7 9,8 8,11 8,14 9,16 11,17 14,17 16,16 17,14 M12,6 L10,8 9,11 9,14 10,16 11,17 M18,6 L17,14 17,16 19,17 21,17 23,15 24,12 24,10 23,7 22,5 20,3 18,2 15,1 12,1 9,2 7,3 5,5 4,7 3,10 3,13 4,16 5,18 7,20 9,21 12,22 15,22 18,21 20,20 21,19 M19,6 L18,14 18,16 19,17","o":14},
{"d":"M9,1 L1,22 M9,1 L17,22 M4,15 L14,15","o":9},
{"d":"M4,1 L4,22 M4,1 L13,1 16,2 17,3 18,5 18,7 17,9 16,10 13,11 M4,11 L13,11 16,12 17,13 18,15 18,18 17,20 16,21 13,22 4,22","o":10},
{"d":"M18,6 L17,4 15,2 13,1 9,1 7,2 5,4 4,6 3,9 3,14 4,17 5,19 7,21 9,22 13,22 15,21 17,19 18,17","o":11},
{"d":"M4,1 L4,22 M4,1 L11,1 14,2 16,4 17,6 18,9 18,14 17,17 16,19 14,21 11,22 4,22","o":10},
{"d":"M4,1 L4,22 M4,1 L17,1 M4,11 L12,11 M4,22 L17,22","o":9},
{"d":"M4,1 L4,22 M4,1 L17,1 M4,11 L12,11","o":8},
{"d":"M18,6 L17,4 15,2 13,1 9,1 7,2 5,4 4,6 3,9 3,14 4,17 5,19 7,21 9,22 13,22 15,21 17,19 18,17 18,14 M13,14 L18,14","o":11},
{"d":"M4,1 L4,22 M18,1 L18,22 M4,11 L18,11","o":11},
{"d":"M4,1 L4,22","o":4},
{"d":"M12,1 L12,17 11,20 10,21 8,22 6,22 4,21 3,20 2,17 2,15","o":8},
{"d":"M4,1 L4,22 M18,1 L4,15 M9,10 L18,22","o":10},
{"d":"M4,1 L4,22 M4,22 L16,22","o":7},
{"d":"M4,1 L4,22 M4,1 L12,22 M20,1 L12,22 M20,1 L20,22","o":12},
{"d":"M4,1 L4,22 M4,1 L18,22 M18,1 L18,22","o":11},
{"d":"M9,1 L7,2 5,4 4,6 3,9 3,14 4,17 5,19 7,21 9,22 13,22 15,21 17,19 18,17 19,14 19,9 18,6 17,4 15,2 13,1 9,1","o":11},
{"d":"M4,1 L4,22 M4,1 L13,1 16,2 17,3 18,5 18,8 17,10 16,11 13,12 4,12","o":10},
{"d":"M9,1 L7,2 5,4 4,6 3,9 3,14 4,17 5,19 7,21 9,22 13,22 15,21 17,19 18,17 19,14 19,9 18,6 17,4 15,2 13,1 9,1 M12,18 L18,24","o":11},
{"d":"M4,1 L4,22 M4,1 L13,1 16,2 17,3 18,5 18,7 17,9 16,10 13,11 4,11 M11,11 L18,22","o":10},
{"d":"M17,4 L15,2 12,1 8,1 5,2 3,4 3,6 4,8 5,9 7,10 13,12 15,13 16,14 17,16 17,19 15,21 12,22 8,22 5,21 3,19","o":10},
{"d":"M8,1 L8,22 M1,1 L15,1","o":8},
{"d":"M4,1 L4,16 5,19 7,21 10,22 12,22 15,21 17,19 18,16 18,1","o":11},
{"d":"M1,1 L9,22 M17,1 L9,22","o":9},
{"d":"M2,1 L7,22 M12,1 L7,22 M12,1 L17,22 M22,1 L17,22","o":12},
{"d":"M3,1 L17,22 M17,1 L3,22","o":10},
{"d":"M1,1 L9,11 9,22 M17,1 L9,11","o":9},
{"d":"M17,1 L3,22 M3,1 L17,1 M3,22 L17,22","o":10},
{"d":"M4,-3 L4,29 M5,-3 L5,29 M4,-3 L11,-3 M4,29 L11,29","o":7},
{"d":"M0,1 L14,25","o":7},
{"d":"M9,-3 L9,29 M10,-3 L10,29 M3,-3 L10,-3 M3,29 L10,29","o":7},
{"d":"M8,-1 L0,13 M8,-1 L16,13","o":8},
{"d":"M0,29 L18,29","o":9},
{"d":"M5,6 L3,8 3,10 4,11 5,10 4,9 3,10","o":4},
{"d":"M15,8 L15,22 M15,11 L13,9 11,8 8,8 6,9 4,11 3,14 3,16 4,19 6,21 8,22 11,22 13,21 15,19","o":10},
{"d":"M4,1 L4,22 M4,11 L6,9 8,8 11,8 13,9 15,11 16,14 16,16 15,19 13,21 11,22 8,22 6,21 4,19","o":9},
{"d":"M15,11 L13,9 11,8 8,8 6,9 4,11 3,14 3,16 4,19 6,21 8,22 11,22 13,21 15,19","o":9},
{"d":"M15,1 L15,22 M15,11 L13,9 11,8 8,8 6,9 4,11 3,14 3,16 4,19 6,21 8,22 11,22 13,21 15,19","o":10},
{"d":"M3,14 L15,14 15,12 14,10 13,9 11,8 8,8 6,9 4,11 3,14 3,16 4,19 6,21 8,22 11,22 13,21 15,19","o":9},
{"d":"M10,1 L8,1 6,2 5,5 5,22 M2,8 L9,8","o":7},
{"d":"M15,8 L15,24 14,27 13,28 11,29 8,29 6,28 M15,11 L13,9 11,8 8,8 6,9 4,11 3,14 3,16 4,19 6,21 8,22 11,22 13,21 15,19","o":10},
{"d":"M4,1 L4,22 M4,12 L7,9 9,8 12,8 14,9 15,12 15,22","o":10},
{"d":"M3,1 L4,2 5,1 4,0 3,1 M4,8 L4,22","o":4},
{"d":"M5,1 L6,2 7,1 6,0 5,1 M6,8 L6,25 5,28 3,29 1,29","o":5},
{"d":"M4,1 L4,22 M14,8 L4,18 M8,14 L15,22","o":8},
{"d":"M4,1 L4,22","o":4},
{"d":"M4,8 L4,22 M4,12 L7,9 9,8 12,8 14,9 15,12 15,22 M15,12 L18,9 20,8 23,8 25,9 26,12 26,22","o":15},
{"d":"M4,8 L4,22 M4,12 L7,9 9,8 12,8 14,9 15,12 15,22","o":10},
{"d":"M8,8 L6,9 4,11 3,14 3,16 4,19 6,21 8,22 11,22 13,21 15,19 16,16 16,14 15,11 13,9 11,8 8,8","o":10},
{"d":"M4,8 L4,29 M4,11 L6,9 8,8 11,8 13,9 15,11 16,14 16,16 15,19 13,21 11,22 8,22 6,21 4,19","o":9},
{"d":"M15,8 L15,29 M15,11 L13,9 11,8 8,8 6,9 4,11 3,14 3,16 4,19 6,21 8,22 11,22 13,21 15,19","o":10},
{"d":"M4,8 L4,22 M4,14 L5,11 7,9 9,8 12,8","o":6},
{"d":"M14,11 L13,9 10,8 7,8 4,9 3,11 4,13 6,14 11,15 13,16 14,18 14,19 13,21 10,22 7,22 4,21 3,19","o":9},
{"d":"M5,1 L5,18 6,21 8,22 10,22 M2,8 L9,8","o":7},
{"d":"M4,8 L4,18 5,21 7,22 10,22 12,21 15,18 M15,8 L15,22","o":10},
{"d":"M2,8 L8,22 M14,8 L8,22","o":8},
{"d":"M3,8 L7,22 M11,8 L7,22 M11,8 L15,22 M19,8 L15,22","o":11},
{"d":"M3,8 L14,22 M14,8 L3,22","o":9},
{"d":"M2,8 L8,22 M14,8 L8,22 6,26 4,28 2,29 1,29","o":8},
{"d":"M14,8 L3,22 M3,8 L14,8 M3,22 L14,22","o":9},
{"d":"M9,-3 L7,-2 6,-1 5,1 5,3 6,5 7,6 8,8 8,10 6,12 M7,-2 L6,0 6,2 7,4 8,5 9,7 9,9 8,11 4,13 8,15 9,17 9,19 8,21 7,22 6,24 6,26 7,28 M6,14 L8,16 8,18 7,20 6,21 5,23 5,25 6,27 7,28 9,29","o":7},
{"d":"M4,-3 L4,29","o":4},
{"d":"M5,-3 L7,-2 8,-1 9,1 9,3 8,5 7,6 6,8 6,10 8,12 M7,-2 L8,0 8,2 7,4 6,5 5,7 5,9 6,11 10,13 6,15 5,17 5,19 6,21 7,22 8,24 8,26 7,28 M8,14 L6,16 6,18 7,20 8,21 9,23 9,25 8,27 7,28 5,29","o":7},
{"d":"M3,16 L3,14 4,11 6,10 8,10 10,11 14,14 16,15 18,15 20,14 21,12 M3,14 L4,12 6,11 8,11 10,12 14,15 16,16 18,16 20,15 21,12 21,10","o":12},
{"d":"M0,1 L0,22 1,22 1,1 2,1 2,22 3,22 3,1 4,1 4,22 5,22 5,1 6,1 6,22 7,22 7,1 8,1 8,22 9,22 9,1 10,1 10,22 11,22 11,1 12,1 12,22 13,22 13,1 14,1 14,22 15,22 15,1 16,1 16,22","o":8}
]
}};