Created
March 5, 2023 22:29
-
-
Save afternoon2/8f27430e6c59cfe817d2f7aa989cbb39 to your computer and use it in GitHub Desktop.
This file contains 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
// polygon transform with using svgpathdata.js matrix utility class | |
// results in the same polygon as in case of using svgpathdata directly | |
// but without the need of stringifying path data before processing. | |
// useful when working on polygons data instead of svg paths. | |
// Input format utilizes JS Clipper Lib polygon format: | |
// type PolygonRing = { X: number, Y: number }[]; | |
// type Polygon = PolygonRing[]; | |
// | |
// usage: | |
// const polygon = new Polygon(data) | |
// .translate(30, 40) | |
// .rotate(20) | |
// .scale(304) | |
// .skewX(20) | |
// .calc() | |
// .round(2); | |
import Matrix from 'svgpath/lib/matrix'; | |
class Polygon { | |
#queue = []; | |
constructor(data) { | |
this.data = data; | |
} | |
translate(tx, ty) { | |
this.#queue.push(['translate', [tx, ty]]); | |
return this; | |
} | |
scale(sx, sy) { | |
this.#queue.push(['scale', [sx, sy]]); | |
return this; | |
} | |
rotate(angle, rx = 0, ry = 0) { | |
this.#queue.push(['rotate', [angle, rx, ry]]); | |
return this; | |
} | |
skewX(angle) { | |
if (angle !== 0) { | |
this.#queue.push(['skewX', [angle]]); | |
} | |
return this; | |
} | |
skewY(angle) { | |
if (angle !== 0) { | |
this.#queue.push(['skewY', [angle]]); | |
} | |
return this; | |
} | |
round(precision) { | |
this.data = this.data.map((ring) => | |
ring.map((pt) => ({ | |
X: parseFloat(pt.X.toFixed(precision)), | |
Y: parseFloat(pt.Y.toFixed(precision)), | |
})) | |
); | |
return this; | |
} | |
calc() { | |
this.data = this.data.map((ring) => | |
ring.map((pt) => { | |
const mt = this.#queue.reduce((m, [cmd, args]) => { | |
m[cmd](...args); | |
return m; | |
}, new Matrix()); | |
const res = mt.calc(pt.X, pt.Y); | |
return { | |
X: res[0], | |
Y: res[1], | |
}; | |
}) | |
); | |
return this; | |
} | |
} | |
export default Polygon; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment