svgdom
Version:
Straightforward DOM implementation for SVG, HTML and XML
117 lines (91 loc) • 2.29 kB
JavaScript
import { SVGPoint } from '../dom/svg/SVGPoint.js'
export class Point {
// Initialize
constructor (x, y) {
const base = { x: 0, y: 0 }
// ensure source as object
const source = Array.isArray(x)
? { x: x[0], y: x[1] }
: typeof x === 'object'
? { x: x.x, y: x.y }
: x != null
? { x: x, y: (y != null ? y : x) }
: base // If y has no value, then x is used has its value
// merge source
this.x = source.x
this.y = source.y
}
abs () {
return Math.sqrt(this.absQuad())
}
absQuad () {
return this.x * this.x + this.y * this.y
}
add (x, y) {
const p = new Point(x, y)
return new Point(this.x + p.x, this.y + p.y)
}
angleTo (p) {
let sign = Math.sign(this.x * p.y - this.y * p.x)
sign = sign || 1
return sign * Math.acos(Math.round((this.dot(p) / (this.abs() * p.abs())) * 1000000) / 1000000)
}
// Clone point
clone () {
return new Point(this)
}
closeTo (p, eta = 0.00001) {
return this.equals(p) || (Math.abs(this.x - p.x) < eta && Math.abs(this.y - p.y) < eta)
}
div (factor) {
return new Point(this.x / factor, this.y / factor)
}
dot (p) {
return this.x * p.x + this.y * p.y
}
equals (p) {
return this.x === p.x && this.y === p.y
}
mul (factor) {
return new Point(this.x * factor, this.y * factor)
}
// Convert to native SVGPoint
native () {
// create new point
const point = new SVGPoint()
// update with current values
point.x = this.x
point.y = this.y
return point
}
normal () {
return new Point(this.y, -this.x)
}
normalize () {
const abs = this.abs()
if (!abs) throw new Error('Can\'t normalize vector of zero length')
return this.div(abs)
}
reflectAt (p) {
return p.add(p.sub(this))
}
sub (x, y) {
const p = new Point(x, y)
return new Point(this.x - p.x, this.y - p.y)
}
toArray () {
return [ this.x, this.y ]
}
toPath () {
return [ 'M', this.x, this.y ].join(' ')
}
// transform point with matrix
transform (matrix) {
return new Point(this.native().matrixTransform(matrix))
}
transformO (matrix) {
const { x, y } = this.native().matrixTransform(matrix)
this.x = x
this.y = y
}
}