Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[geometry-1] only DOMMatrix toFloat32Array and toFloat64Array methods, but no toArray method for regular arrays #578

Open
trusktr opened this issue Dec 22, 2024 · 0 comments

Comments

@trusktr
Copy link

trusktr commented Dec 22, 2024

DOMMatrix only has toFloat32Array and toFloat64Array methods, but does not have a method for creating a simple Array:

https://drafts.fxtf.org/geometry/#ref-for-dom-dommatrixreadonly-tofloat32array

It is cumbersome out of the box to get a simple Array from a DOMMatrix. For consistency, it seems like having toArray() would be useful.

The performance cost of toFloat*Array methods is also bad, because it does a new allocation every time. Ideally we would have an API besides allowing for regular arrays would also allow to write to given arrays:

const f32array = new Float32Array(16)
matrix.toFloat32Array(f32array) // write to the given array

const f64array = new Float64Array(16)
matrix.toFloat32Array(f64array)

// New method:
const array = []
matrix.toArray(array)

The new signatures would be as follows, taking optional targets:

toFloat32Array(target?: Float32Array): Float32Array
toFloat64Array(target?: Float64Array): Float64Array
toArray(target?: Array<number>): Array<number>

It would also be possible to expose the internal matrix array as a readonly array using a Proxy, although I'm not sure what the performance implication would be (if it turns out to be more expensive to pass through the proxy traps than it is to simply call toArray to then read whatever you want, it may not be worth it, needs measuring):

class DOMMatrix {
  readonly elements = new Proxy(internalMatrix(this), { /* ... implement traps to make it readonly ... */ })
}

Then anyone whould would want to get a regular array could do:

const matrix = new DOMMatrix()
matrix.rotateSelf(10)
const array = [...matrix.elements]

This would make it easy to construct clones too:

const matrix2 = new DOMMatrix(matrix.elements)

although in that case just being able to pass another matrix would be intuitive:

const matrix2 = new DOMMatrix(matrix)

(and it would be nice if the same patterns applied for all the interfaces).

I think it would be really great to put some work into the developer experience to make things easy to do, and also possible to do in ways that are not allocating memory unnecessarily.

Real-world examples

Three.js has a great example of this. Their various interfaces have common methods like .clone() and .copy(other), and typically all methods accept a target so that objects can be re-used without allocation (f.e. like the toArray(targe) idea from above). For example check out Matrix4

  • set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) {
    • f.e. mat.set(...array)
  • copy( m ) {
    • f.e. mat.copy(other)
  • clone()
    • f.e. const mat2 = mat.clone()
  • toArray( array = [], offset = 0 ) {
    • f.e. mat.toArray(existingArray) will write to the given array or mat.toArray() will create a new one.

Or check out Vector3

  • fromArray( array, offset = 0 ) { (similar to the one in Matrix4)
    • f.e. vec.fromArray(values)
  • *[ Symbol.iterator ]() {
    • f.e. const array = [...vec] or for (const value of vec)

Those classes have a variety of useful methods.

It would also be nice to have more math functions, and more control over the existing functions (for example, rotateSelf is currently limited to a certain order of rotation, while three allows XYZ, ZXY, YZX, etc.

Devs would benefit from quaternions too (f.e. DOMQuaternion). DOMPoint could be more like a Vector3 or Vector4 and could have a bunch of useful methods for transformation like Three.js Vector3.

It would be incredible too if we could configure a matrix's handed ness and XYZ axis directions (f.e. Y up vs Y down), which would make it suitable for use in different scenarios (f.e. WebGL libraries and frameworks tend to be right-handed Y up).

TLDR

Making the class easier to use, and more featureful, could encourage more people to use it for web scenarios instead of installing matrix libraries. What are your thoughts on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant