Skip to content

Instantly share code, notes, and snippets.

@HyroVitalyProtago
Created January 3, 2023 10:30
Show Gist options
  • Save HyroVitalyProtago/f2221555481ad8e94f13adce41addb1d to your computer and use it in GitHub Desktop.
Save HyroVitalyProtago/f2221555481ad8e94f13adce41addb1d to your computer and use it in GitHub Desktop.
D3 transform helper to translate and scale more easily
// inspired by https://github.com/d3/d3-zoom/blob/main/src/transform.js
class Transform() {
static identity = new Transform(0,0,1)
// https://stackoverflow.com/questions/70890280/d3-js-how-to-get-value-of-transform-attr
static fromSelection(selection) {
const translation = selection.node().transform.baseVal.getItem(0).matrix
const scale = selection.node().transform.baseVal.getItem(1).matrix
return new Transform(translation.e, translation.f, scale.a, scale.d)
}
constructor(x, y, kx, ky) {
this.x = x
this.y = y
this.kx = kx
this.ky = ky ?? kx
}
translate(x,y) {
this.x = x
this.y = y
return this
}
scale(kx, ky) {
this.kx = kx
this.ky = ky ?? kx
return this
}
toString() {
let ret = ''
if (this.x != 0 || this.y != 0) {
ret += `translate(${this.x}, ${this.y})`
}
if (this.kx != 1 || this.ky != 1) {
ret += `scale(${this.kx}, ${this.ky})`
}
return ret
}
}
d3.selection.prototype.translate = function(x, y) {
this.attr('transform', Transform.fromSelection(this).translate(x,y).toString())
}
d3.selection.prototype.scale = function(kx, ky) {
this.attr('transform', Transform.fromSelection(this).scale(kx, ky ?? kx).toString())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment