Automattic / Automattic/node-canvas
[FEAT]: OffscreenCanvas API compatibility
- Dominant language
- JavaScript
- Stars
- 10.7k
- Forks
- 1.2k
- Avg merge
- 4d 8h
- Merged PRs (30d)
- 1
Description
## Motivation
Related #876 #2127
Creating platform agnostic canvas apps/products is very powerful.
Whether web, offscreen or node a product will probably use all in various scenarios.
This makes compatibility and standardization important.
Node canvas is an amazing repo and is nearly fully compatible with the OffscreenCanvas API.
Meaning that in most cases you can drop your app into node and it works.
I would like node canvas to be fully (or more) compatible so there is even less friction and am willing to contribute.
## ImageBitmap
In order to align `Image` to `ImageBitmap` it seems this is enough:
```typescript
class CompatibleImage extends Image implements ImageBitmap {
/**
* Free resources
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ImageBitmap#instance_methods spec}
*/
close(): void {
this.src = "";
this.width = 0;
this.height = 0;
}
}
```
## OffscreenCanvas
In order to align `Canvas` to `OffscreenCanvas` it seems this is enough:
```typescript
export class CompatibleCanvas extends Canvas implements OffscreenCanvas {
/**
* Can be sync but spec returns a promise
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas/convertToBlob#return_value spec}
*
*/
async convertToBlob() {
return new Blob([this.toBuffer()]);
}
transferToImageBitmap(): ImageBitmap {
const img = new CompatibleImage();
img.src = this.toBuffer();
return img;
}
oncontextlost() {}
oncontextrestored() {}
addEventListener() {}
removeEventListener() {}
/**
*
* @returns `false` as if event was cancelled
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/dispatchEvent#return_value spec}
*/
dispatchEvent(): boolean {
return false;
}
}
```
## OffscreenCanvasRenderingContext2D
This has a bit more difference, mainly in text props.
Focusing on methods is more important for compatibility IMO and that is not far off.
```typescript
class CompatibleCanvasRenderingContext2D
extends CanvasRenderingContext2D
implements OffscreenCanvasRenderingContext2D
{
fontKerning: CanvasFontKerning;
fontStretch: CanvasFontStretch;
fontVariantCaps: CanvasFontVariantCaps;
letterSpacing: string;
textRendering: CanvasTextRendering;
wordSpacing: string;
filter: string;
imageSmoothingQuality: ImageSmoothingQuality;
canvas: CompatibleCanvas;
isPointInStroke(path: unknown, x: unknown, y?: unknown): boolean {
// enhance isPointInPath?
throw new Error("Method not implemented.");
}
createConicGradient(
startAngle: number,
x: number,
y: number
): CanvasGradient {
throw new Error("Method not implemented.");
}
/**
* @see {@link https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/reset spec}
*/
reset(): void {
this.resetTransform();
// reset all saved values, clip path, path etc.
}
/**
* noop
*/
isContextLost() {
return false;
}
}
```
### Discussion
Before PRing I wanted to drop this here and see what maintainers think.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.