Last active
June 28, 2019 08:30
-
-
Save mcshaz/394876e099d7efc1d1d509bb62fd5b66 to your computer and use it in GitHub Desktop.
cut and paste a section of svg markup, enter x & y translated, and all vectors will be offset (not bulletproof, but works for my markup)
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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>svg markup offset</title> | |
</head> | |
<body> | |
<form> | |
<label> | |
add to x | |
<input id="moveX" value="0" type="number" step="any"> | |
</label> | |
<label> | |
add to y | |
<input id="moveY" value="0" type="number" step="any"> | |
</label> | |
<textarea id="in"></textarea> | |
<input type="submit" value="transform"> | |
<pre><code id="out"></code></pre> | |
</form> | |
<script> | |
document.getElementsByTagName('form')[0].addEventListener('submit', submit); | |
function submit(evt) { | |
evt.preventDefault(); | |
const input = document.getElementById('in'); | |
const moveX = Number(document.getElementById('moveX').value); | |
const moveY = Number(document.getElementById('moveY').value); | |
let moved = parse(input.value, moveX, moveY); | |
document.getElementById('out').innerHTML = moved.replace(/&/g,'&').replace(/</g,'<'); | |
} | |
function parse(domStr, moveX, moveY) { | |
const colonPlace = '_colon_'; | |
if (typeof domStr !== 'string') { | |
throw new TypeError('domStr must be a string'); | |
} | |
const oParser = new DOMParser(); | |
const isWrappedSvg = /^[\s\r\n]*<\s*svg/.test(domStr) | |
if (!isWrappedSvg) { | |
domStr = '<svg>' + domStr.replace(/:/g,colonPlace) + '</svg>'; | |
} | |
const oDOM = oParser.parseFromString(domStr, "application/xml"); | |
const modifyAllAtt = (a, delegate) => { | |
const xpath = `//*[@${a}]`; | |
const nodesSnapshot = oDOM.evaluate(xpath, oDOM, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); | |
for (let i=0; i < nodesSnapshot.snapshotLength; i++ ) { | |
const thisNode = nodesSnapshot.snapshotItem(i); | |
const val = thisNode.getAttribute(a); | |
thisNode.setAttribute(a, delegate(val)); | |
} | |
} | |
const addValToAtt = (a, addVal) => { | |
modifyAllAtt(a, (v) => parseFloat(v) + addVal); | |
} | |
const xs = ['x', 'cx', 'x1', 'x2']; | |
for (const a of xs) { | |
addValToAtt(a, moveX); | |
addValToAtt(a.replace('x', 'y'), moveY); | |
} | |
modifyAllAtt('d', (a) => { | |
if (a[0] === 'm') { | |
return a.replace(/^m *([\d\-][\d.]*)([, ]+)([\d\-][\d.]*)/, (m, x, sep, y) => 'm ' + (parseFloat(x) + moveX) + sep + (parseFloat(y) + moveY)); | |
} | |
if (a[0] === 'M') { | |
return a.replace(/([vVhH]|[\d\-][\d.]*)([, ]*)([\d\-][\d.]*)/g, (m, x, sep, y) => { | |
const xVal = parseFloat(x); | |
if (isNaN(xVal)) { | |
if (x === 'V') { | |
return 'V' + sep + (parseFloat(y) + moveY); | |
} | |
if (x === 'H') { | |
return 'H' + sep + (parseFloat(y) + moveX); | |
} | |
} else { | |
return (xVal + moveX) + sep + (parseFloat(y) + moveY); | |
} | |
return m; | |
}); | |
} | |
console.log(`unknown d attribute='${a}'`); | |
}); | |
return (isWrappedSvg | |
? oDOM.documentElement.outerHTML | |
: oDOM.documentElement.innerHTML).replace(new RegExp(colonPlace, 'g'), ':'); | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment