@napi-rs/canvas 0.1.82 → 0.1.84
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/index.d.ts +174 -20
- package/index.js +12 -0
- package/js-binding.js +2 -0
- package/package.json +14 -14
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# `skr canvas`
|
|
2
2
|
|
|
3
3
|
[](https://github.com/Brooooooklyn/canvas/actions/workflows/CI.yaml)
|
|
4
|
-

|
|
5
5
|
[](https://packagephobia.com/result?p=@napi-rs/canvas)
|
|
6
6
|
[](https://npmcharts.com/compare/@napi-rs/canvas?minimal=true)
|
|
7
7
|
|
package/index.d.ts
CHANGED
|
@@ -5,21 +5,21 @@ export function clearAllCache(): void
|
|
|
5
5
|
|
|
6
6
|
interface CanvasRenderingContext2D
|
|
7
7
|
extends CanvasCompositing,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
CanvasDrawPath,
|
|
9
|
+
CanvasFillStrokeStyles,
|
|
10
|
+
CanvasFilters,
|
|
11
|
+
CanvasImageData,
|
|
12
|
+
CanvasImageSmoothing,
|
|
13
|
+
CanvasPath,
|
|
14
|
+
CanvasPathDrawingStyles,
|
|
15
|
+
CanvasRect,
|
|
16
|
+
CanvasSettings,
|
|
17
|
+
CanvasShadowStyles,
|
|
18
|
+
CanvasState,
|
|
19
|
+
CanvasText,
|
|
20
|
+
CanvasTextDrawingStyles,
|
|
21
|
+
CanvasTransform,
|
|
22
|
+
CanvasPDFAnnotations { }
|
|
23
23
|
|
|
24
24
|
interface CanvasState {
|
|
25
25
|
isContextLost(): boolean
|
|
@@ -211,6 +211,7 @@ interface CanvasTextDrawingStyles {
|
|
|
211
211
|
textBaseline: CanvasTextBaseline
|
|
212
212
|
textRendering: CanvasTextRendering
|
|
213
213
|
wordSpacing: string
|
|
214
|
+
fontVariationSettings: string
|
|
214
215
|
}
|
|
215
216
|
|
|
216
217
|
interface CanvasFilters {
|
|
@@ -421,7 +422,7 @@ type OmitNeverOfMatrix = OmitMatrixMethod[keyof OmitMatrixMethod]
|
|
|
421
422
|
|
|
422
423
|
export const DOMMatrix: {
|
|
423
424
|
prototype: DOMMatrix
|
|
424
|
-
new
|
|
425
|
+
new(init?: string | number[]): DOMMatrix
|
|
425
426
|
fromFloat32Array(array32: Float32Array): DOMMatrix
|
|
426
427
|
fromFloat64Array(array64: Float64Array): DOMMatrix
|
|
427
428
|
fromMatrix(other?: DOMMatrixInit): DOMMatrix
|
|
@@ -448,7 +449,7 @@ export interface DOMRect extends DOMRectReadOnly {
|
|
|
448
449
|
|
|
449
450
|
export const DOMRect: {
|
|
450
451
|
prototype: DOMRect
|
|
451
|
-
new
|
|
452
|
+
new(x?: number, y?: number, width?: number, height?: number): DOMRect
|
|
452
453
|
fromRect(other?: DOMRectInit): DOMRect
|
|
453
454
|
}
|
|
454
455
|
|
|
@@ -470,7 +471,7 @@ export interface DOMPoint extends DOMPointReadOnly {
|
|
|
470
471
|
|
|
471
472
|
export const DOMPoint: {
|
|
472
473
|
prototype: DOMPoint
|
|
473
|
-
new
|
|
474
|
+
new(x?: number, y?: number, z?: number, w?: number): DOMPoint
|
|
474
475
|
fromPoint(other?: DOMPointInit): DOMPoint
|
|
475
476
|
}
|
|
476
477
|
|
|
@@ -618,6 +619,121 @@ export interface AvifConfig {
|
|
|
618
619
|
/** set to '4:2:0' to use chroma subsampling, default '4:4:4' */
|
|
619
620
|
chromaSubsampling?: ChromaSubsampling
|
|
620
621
|
}
|
|
622
|
+
|
|
623
|
+
/** GIF encoding configuration for single-frame encoding */
|
|
624
|
+
export interface GifConfig {
|
|
625
|
+
/**
|
|
626
|
+
* Quality for NeuQuant color quantization (1-30, lower = slower but better quality)
|
|
627
|
+
* @default 10
|
|
628
|
+
*/
|
|
629
|
+
quality?: number
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
/** Configuration for the GIF encoder (animated GIFs) */
|
|
633
|
+
export interface GifEncoderConfig {
|
|
634
|
+
/**
|
|
635
|
+
* Loop count: 0 = infinite loop, positive number = finite loops
|
|
636
|
+
* @default 0 (infinite)
|
|
637
|
+
*/
|
|
638
|
+
repeat?: number
|
|
639
|
+
/**
|
|
640
|
+
* Quality for NeuQuant color quantization (1-30, lower = slower but better quality)
|
|
641
|
+
* @default 10
|
|
642
|
+
*/
|
|
643
|
+
quality?: number
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/** Configuration for individual GIF frames */
|
|
647
|
+
export interface GifFrameConfig {
|
|
648
|
+
/**
|
|
649
|
+
* Frame delay in milliseconds
|
|
650
|
+
* @default 100
|
|
651
|
+
*/
|
|
652
|
+
delay?: number
|
|
653
|
+
/** Disposal method for this frame */
|
|
654
|
+
disposal?: GifDisposal
|
|
655
|
+
/** Transparent color index (0-255), if the frame has transparency */
|
|
656
|
+
transparent?: number
|
|
657
|
+
/** X offset of this frame within the canvas */
|
|
658
|
+
left?: number
|
|
659
|
+
/** Y offset of this frame within the canvas */
|
|
660
|
+
top?: number
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/** GIF frame disposal method */
|
|
664
|
+
export enum GifDisposal {
|
|
665
|
+
/** Keep the frame visible (default) */
|
|
666
|
+
Keep = 0,
|
|
667
|
+
/** Clear the frame area to the background color */
|
|
668
|
+
Background = 1,
|
|
669
|
+
/** Restore to the previous frame */
|
|
670
|
+
Previous = 2,
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* GIF Encoder for creating animated GIFs.
|
|
675
|
+
* Implements `Disposable` interface for use with the `using` keyword (ES2024).
|
|
676
|
+
*
|
|
677
|
+
* @example
|
|
678
|
+
* ```typescript
|
|
679
|
+
* // Basic usage
|
|
680
|
+
* const encoder = new GifEncoder(100, 100, { repeat: 0, quality: 10 });
|
|
681
|
+
* encoder.addFrame(rgbaData, 100, 100, { delay: 100 });
|
|
682
|
+
* encoder.addFrame(rgbaData2, 100, 100, { delay: 100 });
|
|
683
|
+
* const buffer = encoder.finish();
|
|
684
|
+
*
|
|
685
|
+
* // With `using` keyword (automatic cleanup)
|
|
686
|
+
* {
|
|
687
|
+
* using encoder = new GifEncoder(100, 100);
|
|
688
|
+
* encoder.addFrame(frame1, 100, 100, { delay: 100 });
|
|
689
|
+
* const buffer = encoder.finish();
|
|
690
|
+
* } // encoder automatically disposed
|
|
691
|
+
* ```
|
|
692
|
+
*/
|
|
693
|
+
export class GifEncoder implements Disposable {
|
|
694
|
+
/**
|
|
695
|
+
* Create a new GIF encoder with the specified dimensions
|
|
696
|
+
* @param width - Width of the GIF canvas in pixels
|
|
697
|
+
* @param height - Height of the GIF canvas in pixels
|
|
698
|
+
* @param config - Optional encoder configuration
|
|
699
|
+
*/
|
|
700
|
+
constructor(width: number, height: number, config?: GifEncoderConfig)
|
|
701
|
+
|
|
702
|
+
/** Width of the GIF canvas */
|
|
703
|
+
readonly width: number
|
|
704
|
+
/** Height of the GIF canvas */
|
|
705
|
+
readonly height: number
|
|
706
|
+
/** Number of frames added so far */
|
|
707
|
+
readonly frameCount: number
|
|
708
|
+
|
|
709
|
+
/**
|
|
710
|
+
* Add a frame from RGBA pixel data
|
|
711
|
+
* @param data - RGBA pixel data (must be width * height * 4 bytes)
|
|
712
|
+
* @param width - Width of the frame in pixels
|
|
713
|
+
* @param height - Height of the frame in pixels
|
|
714
|
+
* @param config - Optional frame configuration
|
|
715
|
+
*/
|
|
716
|
+
addFrame(data: Uint8Array, width: number, height: number, config?: GifFrameConfig): void
|
|
717
|
+
|
|
718
|
+
/**
|
|
719
|
+
* Finish encoding and return the GIF data.
|
|
720
|
+
* Clears all accumulated frames after encoding.
|
|
721
|
+
* @throws Error if no frames have been added
|
|
722
|
+
*/
|
|
723
|
+
finish(): Buffer
|
|
724
|
+
|
|
725
|
+
/**
|
|
726
|
+
* Dispose of the encoder, clearing all accumulated frames without encoding.
|
|
727
|
+
* Called automatically when using the `using` keyword.
|
|
728
|
+
*/
|
|
729
|
+
dispose(): void
|
|
730
|
+
|
|
731
|
+
/**
|
|
732
|
+
* Symbol.dispose implementation for ES2024 Explicit Resource Management.
|
|
733
|
+
* Allows using `using encoder = new GifEncoder(...)` syntax.
|
|
734
|
+
*/
|
|
735
|
+
[Symbol.dispose](): void
|
|
736
|
+
}
|
|
621
737
|
/**
|
|
622
738
|
* https://en.wikipedia.org/wiki/Chroma_subsampling#Types_of_sampling_and_subsampling
|
|
623
739
|
* https://developer.mozilla.org/en-US/docs/Web/Media/Formats/Video_concepts
|
|
@@ -675,24 +791,29 @@ export class Canvas {
|
|
|
675
791
|
encodeSync(format: 'webp' | 'jpeg', quality?: number): Buffer
|
|
676
792
|
encodeSync(format: 'png'): Buffer
|
|
677
793
|
encodeSync(format: 'avif', cfg?: AvifConfig): Buffer
|
|
794
|
+
encodeSync(format: 'gif', quality?: number): Buffer
|
|
678
795
|
encode(format: 'webp' | 'jpeg', quality?: number): Promise<Buffer>
|
|
679
796
|
encode(format: 'png'): Promise<Buffer>
|
|
680
797
|
encode(format: 'avif', cfg?: AvifConfig): Promise<Buffer>
|
|
798
|
+
encode(format: 'gif', quality?: number): Promise<Buffer>
|
|
681
799
|
encodeStream(format: 'webp' | 'jpeg', quality?: number): ReadableStream<Buffer>
|
|
682
800
|
encodeStream(format: 'png'): ReadableStream<Buffer>
|
|
683
801
|
toBuffer(mime: 'image/png'): Buffer
|
|
684
802
|
toBuffer(mime: 'image/jpeg' | 'image/webp', quality?: number): Buffer
|
|
685
803
|
toBuffer(mime: 'image/avif', cfg?: AvifConfig): Buffer
|
|
804
|
+
toBuffer(mime: 'image/gif', quality?: number): Buffer
|
|
686
805
|
// raw pixels
|
|
687
806
|
data(): Buffer
|
|
688
807
|
toDataURL(mime?: 'image/png'): string
|
|
689
808
|
toDataURL(mime: 'image/jpeg' | 'image/webp', quality?: number): string
|
|
690
|
-
toDataURL(mime
|
|
809
|
+
toDataURL(mime: 'image/gif', quality?: number): string
|
|
810
|
+
toDataURL(mime?: 'image/jpeg' | 'image/webp' | 'image/png' | 'image/gif', quality?: number): string
|
|
691
811
|
toDataURL(mime?: 'image/avif', cfg?: AvifConfig): string
|
|
692
812
|
|
|
693
813
|
toDataURLAsync(mime?: 'image/png'): Promise<string>
|
|
694
814
|
toDataURLAsync(mime: 'image/jpeg' | 'image/webp', quality?: number): Promise<string>
|
|
695
|
-
toDataURLAsync(mime
|
|
815
|
+
toDataURLAsync(mime: 'image/gif', quality?: number): Promise<string>
|
|
816
|
+
toDataURLAsync(mime?: 'image/jpeg' | 'image/webp' | 'image/png' | 'image/gif', quality?: number): Promise<string>
|
|
696
817
|
toDataURLAsync(mime?: 'image/avif', cfg?: AvifConfig): Promise<string>
|
|
697
818
|
|
|
698
819
|
toBlob(callback: (blob: Blob | null) => void, mime?: string, quality?: number): void
|
|
@@ -708,6 +829,21 @@ export declare class FontKey {
|
|
|
708
829
|
private readonly key: symbol
|
|
709
830
|
}
|
|
710
831
|
|
|
832
|
+
export interface FontVariationAxis {
|
|
833
|
+
/** OpenType tag as a 32-bit integer (e.g., 0x77676874 for 'wght') */
|
|
834
|
+
tag: number
|
|
835
|
+
/** Current value for this axis */
|
|
836
|
+
value: number
|
|
837
|
+
/** Minimum value for this axis */
|
|
838
|
+
min: number
|
|
839
|
+
/** Maximum value for this axis */
|
|
840
|
+
max: number
|
|
841
|
+
/** Default value for this axis */
|
|
842
|
+
def: number
|
|
843
|
+
/** Whether this axis should be hidden from UI */
|
|
844
|
+
hidden: boolean
|
|
845
|
+
}
|
|
846
|
+
|
|
711
847
|
interface IGlobalFonts {
|
|
712
848
|
readonly families: { family: string; styles: { weight: number; width: string; style: string }[] }[]
|
|
713
849
|
// return true if succeeded
|
|
@@ -717,6 +853,24 @@ interface IGlobalFonts {
|
|
|
717
853
|
has(name: string): boolean
|
|
718
854
|
loadFontsFromDir(path: string): number
|
|
719
855
|
remove(key: FontKey): void
|
|
856
|
+
/**
|
|
857
|
+
* Get variation axes for a specific font instance
|
|
858
|
+
* @param familyName The font family name
|
|
859
|
+
* @param weight Font weight (100-900)
|
|
860
|
+
* @param width Font width/stretch value
|
|
861
|
+
* @param slant Font slant (0 = upright, 1 = italic, 2 = oblique)
|
|
862
|
+
* @returns Array of variation axes or empty array if not a variable font
|
|
863
|
+
*/
|
|
864
|
+
getVariationAxes(familyName: string, weight: number, width: number, slant: number): FontVariationAxis[]
|
|
865
|
+
/**
|
|
866
|
+
* Check if a font has variable font capabilities
|
|
867
|
+
* @param familyName The font family name
|
|
868
|
+
* @param weight Font weight (100-900)
|
|
869
|
+
* @param width Font width/stretch value
|
|
870
|
+
* @param slant Font slant (0 = upright, 1 = italic, 2 = oblique)
|
|
871
|
+
* @returns true if the font is a variable font
|
|
872
|
+
*/
|
|
873
|
+
hasVariations(familyName: string, weight: number, width: number, slant: number): boolean
|
|
720
874
|
}
|
|
721
875
|
|
|
722
876
|
export const GlobalFonts: IGlobalFonts
|
package/index.js
CHANGED
|
@@ -17,12 +17,21 @@ const {
|
|
|
17
17
|
StrokeCap,
|
|
18
18
|
convertSVGTextToPath,
|
|
19
19
|
PdfDocument,
|
|
20
|
+
GifEncoder,
|
|
21
|
+
GifDisposal,
|
|
20
22
|
} = require('./js-binding')
|
|
21
23
|
|
|
22
24
|
const { DOMPoint, DOMMatrix, DOMRect } = require('./geometry')
|
|
23
25
|
|
|
24
26
|
const loadImage = require('./load-image')
|
|
25
27
|
|
|
28
|
+
// Add Symbol.dispose support for GifEncoder (ECMAScript 2024 Explicit Resource Management)
|
|
29
|
+
if (GifEncoder && typeof Symbol.dispose !== 'undefined') {
|
|
30
|
+
GifEncoder.prototype[Symbol.dispose] = function () {
|
|
31
|
+
this.dispose()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
26
35
|
const SvgExportFlag = {
|
|
27
36
|
ConvertTextToPaths: 0x01,
|
|
28
37
|
NoPrettyXML: 0x02,
|
|
@@ -178,4 +187,7 @@ module.exports = {
|
|
|
178
187
|
CanvasElement,
|
|
179
188
|
SVGCanvas,
|
|
180
189
|
PDFDocument: PdfDocument,
|
|
190
|
+
// GIF encoding
|
|
191
|
+
GifEncoder,
|
|
192
|
+
GifDisposal,
|
|
181
193
|
}
|
package/js-binding.js
CHANGED
|
@@ -460,3 +460,5 @@ module.exports.PathOp = nativeBinding.PathOp
|
|
|
460
460
|
module.exports.StrokeCap = nativeBinding.StrokeCap
|
|
461
461
|
module.exports.StrokeJoin = nativeBinding.StrokeJoin
|
|
462
462
|
module.exports.SvgExportFlag = nativeBinding.SvgExportFlag
|
|
463
|
+
module.exports.GifEncoder = nativeBinding.GifEncoder
|
|
464
|
+
module.exports.GifDisposal = nativeBinding.GifDisposal
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@napi-rs/canvas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.84",
|
|
4
4
|
"description": "Canvas for Node.js with skia backend",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"repository": {
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"@jimp/png": "^0.22.12",
|
|
78
78
|
"@napi-rs/cli": "^3.1.1",
|
|
79
79
|
"@octokit/rest": "^22.0.0",
|
|
80
|
-
"@oxc-node/core": "^0.0.
|
|
80
|
+
"@oxc-node/core": "^0.0.35",
|
|
81
81
|
"@taplo/cli": "^0.7.0",
|
|
82
82
|
"@types/lodash": "^4.17.17",
|
|
83
83
|
"@types/node": "^24.0.0",
|
|
@@ -102,7 +102,7 @@
|
|
|
102
102
|
"semver": "^7.7.2",
|
|
103
103
|
"skia-canvas": "^3.0.0",
|
|
104
104
|
"table": "^6.9.0",
|
|
105
|
-
"tinybench": "^
|
|
105
|
+
"tinybench": "^6.0.0",
|
|
106
106
|
"typescript": "^5.8.3"
|
|
107
107
|
},
|
|
108
108
|
"lint-staged": {
|
|
@@ -140,17 +140,17 @@
|
|
|
140
140
|
"singleQuote": true,
|
|
141
141
|
"arrowParens": "always"
|
|
142
142
|
},
|
|
143
|
-
"packageManager": "yarn@4.
|
|
143
|
+
"packageManager": "yarn@4.12.0",
|
|
144
144
|
"optionalDependencies": {
|
|
145
|
-
"@napi-rs/canvas-linux-x64-gnu": "0.1.
|
|
146
|
-
"@napi-rs/canvas-darwin-x64": "0.1.
|
|
147
|
-
"@napi-rs/canvas-win32-x64-msvc": "0.1.
|
|
148
|
-
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.
|
|
149
|
-
"@napi-rs/canvas-linux-x64-musl": "0.1.
|
|
150
|
-
"@napi-rs/canvas-linux-arm64-gnu": "0.1.
|
|
151
|
-
"@napi-rs/canvas-linux-arm64-musl": "0.1.
|
|
152
|
-
"@napi-rs/canvas-darwin-arm64": "0.1.
|
|
153
|
-
"@napi-rs/canvas-android-arm64": "0.1.
|
|
154
|
-
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.
|
|
145
|
+
"@napi-rs/canvas-linux-x64-gnu": "0.1.84",
|
|
146
|
+
"@napi-rs/canvas-darwin-x64": "0.1.84",
|
|
147
|
+
"@napi-rs/canvas-win32-x64-msvc": "0.1.84",
|
|
148
|
+
"@napi-rs/canvas-linux-arm-gnueabihf": "0.1.84",
|
|
149
|
+
"@napi-rs/canvas-linux-x64-musl": "0.1.84",
|
|
150
|
+
"@napi-rs/canvas-linux-arm64-gnu": "0.1.84",
|
|
151
|
+
"@napi-rs/canvas-linux-arm64-musl": "0.1.84",
|
|
152
|
+
"@napi-rs/canvas-darwin-arm64": "0.1.84",
|
|
153
|
+
"@napi-rs/canvas-android-arm64": "0.1.84",
|
|
154
|
+
"@napi-rs/canvas-linux-riscv64-gnu": "0.1.84"
|
|
155
155
|
}
|
|
156
156
|
}
|