Created
November 15, 2023 23:09
-
-
Save ikalnytskyi/024ba9702cacb7db8cfae995a06a4254 to your computer and use it in GitHub Desktop.
Sketchify an inline SVG node
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import rough from "https://unpkg.com/[email protected]/bundled/rough.esm.js"; | |
// Sketchify a given SVG node using https://roughjs.com. | |
// | |
// The code is adopted from https://sketchviz.com. | |
export const sketchify = (function () { | |
function getAttributes(element) { | |
return Array.prototype.slice.call(element.attributes); | |
} | |
function getNum(element, attributes) { | |
return attributes.map(function (attr) { | |
return parseFloat(element.getAttribute(attr), 10); | |
}); | |
} | |
function getDiam(element, attributes) { | |
return attributes.map(function (attr) { | |
return 2 * parseFloat(element.getAttribute(attr), 10); | |
}); | |
} | |
function getCoords(element, attribute) { | |
return element | |
.getAttribute(attribute) | |
.trim() | |
.split(" ") | |
.filter(function (item) { | |
return item.length > 0; | |
}) | |
.map(function (item) { | |
return item | |
.trim() | |
.split(",") | |
.map(function (num) { | |
return parseFloat(num, 10); | |
}); | |
}); | |
} | |
function getSettings(element) { | |
var settings = {}; | |
if (element.hasAttribute("stroke")) { | |
settings.stroke = element.getAttribute("stroke"); | |
} | |
if (element.hasAttribute("fill")) { | |
settings.fill = element.getAttribute("fill"); | |
} | |
if ( | |
element.hasAttribute("stroke-width") && | |
!element.getAttribute("stroke-width").includes("%") | |
) { | |
settings.strokeWidth = parseFloat(element.getAttribute("stroke-width", 10)); | |
} | |
return settings; | |
} | |
return function sketchify(svg, options) { | |
var blacklist = [ | |
"cx", | |
"cy", | |
"d", | |
"fill", | |
"height", | |
"points", | |
"r", | |
"rx", | |
"ry", | |
"stroke-width", | |
"stroke", | |
"width", | |
"x", | |
"x1", | |
"x2", | |
"y", | |
"y1", | |
"y2", | |
]; | |
function flatten() { | |
var rv = []; | |
for (var i = 0; i < arguments.length; i++) { | |
var arr = arguments[i]; | |
for (var j = 0; j < arr.length; j++) { | |
rv.push(arr[j]); | |
} | |
} | |
return rv; | |
} | |
var options = options || {}; | |
var rc = rough.svg(svg, options); | |
var children = svg.querySelectorAll("circle, rect, ellipse, line, polygon, polyline, path"); | |
for (const original of children) { | |
var params = []; | |
var shapeType; | |
switch (original.tagName) { | |
case "circle": | |
params = flatten(getNum(original, ["cx", "cy"]), getDiam(original, ["r"])); | |
shapeType = "circle"; | |
break; | |
case "rect": | |
params = flatten(getNum(original, ["x", "y", "width", "height"])); | |
shapeType = "rectangle"; | |
break; | |
case "ellipse": | |
params = flatten(getNum(original, ["cx", "cy"]), getDiam(original, ["rx", "ry"])); | |
shapeType = "ellipse"; | |
break; | |
case "line": | |
params = flatten(getNum(original, ["x1", "y1", "x2", "y2"])); | |
shapeType = "line"; | |
break; | |
case "polygon": | |
params = [getCoords(original, "points")]; | |
shapeType = "polygon"; | |
break; | |
case "polyline": | |
params = [getCoords(original, "points")]; | |
shapeType = "linearPath"; | |
break; | |
case "path": | |
params = [original.getAttribute("d")]; | |
shapeType = "path"; | |
break; | |
} | |
var replacement = rc[shapeType](...params, getSettings(original)); | |
var attributes = getAttributes(original).filter(function (attribute) { | |
return !blacklist.includes(attribute.name); | |
}); | |
for (var j = 0; j < attributes.length; j++) { | |
replacement.setAttribute(attributes[j].name, attributes[j].value); | |
} | |
original.replaceWith(replacement); | |
} | |
for (const text of svg.querySelectorAll("text")) { | |
text.setAttribute("font-family", options.fontFamily || "Monaspace Radon"); | |
} | |
}; | |
})(); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script type="module"> | |
import { sketchify } from "/static/sketchysvg.js"; | |
window.document.querySelectorAll("svg").forEach(sketchify); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment