svgdom
Version:
Straightforward DOM implementation for SVG, HTML and XML
104 lines (86 loc) • 2.15 kB
JavaScript
const radians = function (d) {
return d % 360 * Math.PI / 180
}
export function matrixFactory (a, b, c, d, e, f) {
var r = new SVGMatrix()
r.a = a
r.b = b
r.c = c
r.d = d
r.e = e
r.f = f
return r
}
export class SVGMatrix {
constructor () {
this.a = this.d = 1
this.b = this.c = this.e = this.f = 0
}
inverse () {
// Get the current parameters out of the matrix
var a = this.a
var b = this.b
var c = this.c
var d = this.d
var e = this.e
var f = this.f
// Invert the 2x2 matrix in the top left
var det = a * d - b * c
if (!det) throw new Error('Cannot invert ' + this)
// Calculate the top 2x2 matrix
var na = d / det
var nb = -b / det
var nc = -c / det
var nd = a / det
// Apply the inverted matrix to the top right
var ne = -(na * e + nc * f)
var nf = -(nb * e + nd * f)
// Construct the inverted matrix
this.a = na
this.b = nb
this.c = nc
this.d = nd
this.e = ne
this.f = nf
return this
}
multiply (m) {
var r = new SVGMatrix()
r.a = this.a * m.a + this.c * m.b + this.e * 0
r.b = this.b * m.a + this.d * m.b + this.f * 0
r.c = this.a * m.c + this.c * m.d + this.e * 0
r.d = this.b * m.c + this.d * m.d + this.f * 0
r.e = this.a * m.e + this.c * m.f + this.e * 1
r.f = this.b * m.e + this.d * m.f + this.f * 1
return r
}
rotate (r, x, y) {
r = r % 360 * Math.PI / 180
return this.multiply(matrixFactory(
Math.cos(r),
Math.sin(r),
-Math.sin(r),
Math.cos(r),
x ? -Math.cos(r) * x + Math.sin(r) * y + x : 0,
y ? -Math.sin(r) * x - Math.cos(r) * y + y : 0
))
}
scale (scaleX, scaleY = scaleX) {
return this.multiply(matrixFactory(scaleX, 0, 0, scaleY, 0, 0))
}
skew (x, y) {
return this.multiply(matrixFactory(1, Math.tan(radians(y)), Math.tan(radians(x)), 1, 0, 0))
}
skewX (x) {
return this.skew(x, 0)
}
skewY (y) {
return this.skew(0, y)
}
toString () {
return 'SVGMatrix'
}
translate (x = 0, y = 0) {
return this.multiply(matrixFactory(1, 0, 0, 1, x, y))
}
}