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

trusktr has just created a new issue for https://github.com/w3c/fxtf-drafts:

== [geometry-1] only `DOMMatrix` `toFloat32Array` and `toFloat64Array` methods, but no `toArray` method for regular arrays ==
`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:

```js
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:

```ts
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):

```ts
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:

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

This would make it easy to construct clones too:

```js
const matrix2 = new DOMMatrix(matrix.elements)
```

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

```js
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.

[Three.js](https://threejs.org/) 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](https://github.com/mrdoob/three.js/blob/284c5fee2bc069cd1575c08dd1a8f0ea415dc83c/src/math/Matrix4.js)

- `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()`

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, whil three allows XYZ, ZXY, YZX, etc.



Please view or discuss this issue at https://github.com/w3c/fxtf-drafts/issues/578 using your GitHub account


-- 
Sent via github-notify-ml as configured in https://github.com/w3c/github-notify-ml-config

Received on Sunday, 22 December 2024 01:07:00 UTC