|
1 | 1 | /* eslint-disable @typescript-eslint/no-var-requires */
|
| 2 | +import type Path from 'path'; |
| 3 | + |
| 4 | +import type NapiRs from '@napi-rs/canvas'; |
| 5 | + |
| 6 | +/* |
| 7 | +import type { |
| 8 | + Canvas as NapiCanvas, |
| 9 | + Image as NapiImage, |
| 10 | + GlobalFonts as NapiGlobalFonts, |
| 11 | +} from '@napi-rs/canvas'; |
| 12 | +*/ |
| 13 | + |
| 14 | +export interface CanvasUtils { |
| 15 | + createCanvas(width: number, height: number): any; |
| 16 | + loadImage(src: string): Promise<any>; |
| 17 | + getPath(filename: string): string | URL; |
| 18 | + useFont(): void; |
| 19 | + saveToImage(canvas: HTMLCanvasElement | NapiRs.Canvas): Promise<Uint8Array>; |
| 20 | + noteBlockImage: Promise<any> | any; |
| 21 | + DrawingCanvas: any; |
| 22 | + RenderedImage: any; |
| 23 | +} |
2 | 24 |
|
3 |
| -let content = {} as any; |
| 25 | +let canvasUtils: CanvasUtils; |
4 | 26 |
|
5 | 27 | if (typeof document === 'undefined') {
|
6 |
| - // Assume Node.js environment |
7 |
| - const canvasModule = require('@napi-rs/canvas'); |
8 |
| - const { createCanvas, loadImage, registerFont, GlobalFonts } = canvasModule; |
9 |
| - |
10 |
| - const path = require('path'); |
| 28 | + // Node.js/Bun environment |
| 29 | + const canvasModule = require('@napi-rs/canvas') as typeof NapiRs; |
| 30 | + const path = require('path') as typeof Path; |
11 | 31 |
|
12 |
| - const Canvas = canvasModule.Canvas; |
13 |
| - const Image = canvasModule.Image; |
| 32 | + const { |
| 33 | + createCanvas: nodeCreateCanvas, |
| 34 | + loadImage: nodeLoadImage, |
| 35 | + GlobalFonts, |
| 36 | + } = canvasModule; |
14 | 37 |
|
15 | 38 | const getPath = (filename: string) => {
|
16 |
| - const dir = path.join( |
17 |
| - __dirname, |
18 |
| - '..', |
19 |
| - '..', |
20 |
| - '..', |
21 |
| - 'assets', |
22 |
| - filename.split('/').join(path.sep), |
| 39 | + return ( |
| 40 | + 'file://' + |
| 41 | + path.join( |
| 42 | + __dirname, |
| 43 | + '..', |
| 44 | + '..', |
| 45 | + '..', |
| 46 | + 'web', |
| 47 | + filename.split('/').join(path.sep), |
| 48 | + ) |
23 | 49 | );
|
24 |
| - |
25 |
| - console.log('dir', dir); |
26 |
| - return dir; |
27 | 50 | };
|
28 | 51 |
|
29 |
| - const saveToImage = (canvas: typeof Canvas) => { |
30 |
| - return canvas.encode('png'); |
| 52 | + const saveToImage = (canvas: NapiRs.Canvas) => canvas.encode('png'); |
| 53 | + |
| 54 | + const useFont = () => { |
| 55 | + GlobalFonts.registerFromPath( |
| 56 | + 'file:' + getPath('/fonts/Lato-Regular.ttf').toString(), |
| 57 | + 'Lato', |
| 58 | + ); |
31 | 59 | };
|
32 | 60 |
|
33 |
| - // Load note block image |
34 |
| - let noteBlockImage; |
| 61 | + let noteBlockImage: Promise<any>; |
35 | 62 |
|
36 | 63 | try {
|
37 |
| - noteBlockImage = loadImage(getPath('/img/note-block-grayscale.png')); |
| 64 | + noteBlockImage = nodeLoadImage( |
| 65 | + new URL(getPath('public/img/note-block-grayscale.png')), |
| 66 | + ); |
38 | 67 | } catch (error) {
|
39 |
| - console.log('Error loading image: ', error); |
| 68 | + console.error('Error loading image: ', error); |
| 69 | + noteBlockImage = Promise.reject(error); |
40 | 70 | }
|
41 | 71 |
|
42 |
| - const useFont = () => { |
43 |
| - GlobalFonts.registerFromPath(getPath('/fonts/Lato-Regular.ttf'), 'Lato'); |
44 |
| - }; |
45 |
| - |
46 |
| - useFont(); |
47 |
| - |
48 |
| - content = { |
49 |
| - createCanvas, |
50 |
| - loadImage, |
51 |
| - registerFont, |
| 72 | + canvasUtils = { |
| 73 | + createCanvas: nodeCreateCanvas, |
| 74 | + loadImage: nodeLoadImage, |
52 | 75 | getPath,
|
53 | 76 | useFont,
|
54 | 77 | saveToImage,
|
55 | 78 | noteBlockImage,
|
56 |
| - Canvas, |
57 |
| - Image, |
| 79 | + DrawingCanvas: canvasModule.Canvas, |
| 80 | + RenderedImage: canvasModule.Image, |
58 | 81 | };
|
59 | 82 | } else {
|
60 |
| - // Assume browser environment |
| 83 | + // Browser environment |
61 | 84 | const createCanvas = (width: number, height: number) => {
|
62 |
| - const canvas = new OffscreenCanvas(width, height); |
63 |
| - return canvas; |
| 85 | + return new OffscreenCanvas(width, height); |
64 | 86 | };
|
65 | 87 |
|
66 |
| - const loadImage = function (src: string): Promise<HTMLImageElement> { |
| 88 | + const loadImage = (src: string): Promise<HTMLImageElement> => { |
67 | 89 | return new Promise((resolve, reject) => {
|
68 |
| - const img = document.createElement('img'); |
| 90 | + const img = new Image(); |
69 | 91 | img.onload = () => resolve(img);
|
70 | 92 | img.onerror = reject;
|
71 | 93 | img.src = src;
|
72 | 94 | });
|
73 | 95 | };
|
74 | 96 |
|
75 |
| - const getPath = (filename: string) => { |
76 |
| - return filename; |
77 |
| - }; |
| 97 | + const getPath = (filename: string) => filename; |
78 | 98 |
|
79 |
| - const saveToImage = (canvas: HTMLCanvasElement) => { |
80 |
| - console.log('Not implemented'); |
| 99 | + const saveToImage = (_canvas: any) => { |
| 100 | + console.warn('saveToImage not implemented in browser'); |
| 101 | + throw new Error('saveToImage not implemented in browser'); |
81 | 102 | };
|
82 | 103 |
|
83 |
| - // TODO: refactor into resources attribute of some sort |
84 |
| - |
85 |
| - // Load note block image |
86 |
| - const noteBlockImage = loadImage(getPath('/img/note-block-grayscale.png')); |
87 |
| - |
88 |
| - // Register font |
89 | 104 | const useFont = () => {
|
90 |
| - const f = new FontFace('Lato', 'url(/fonts/Lato-Regular.ttf)'); |
| 105 | + const font = new FontFace('Lato', 'url(/fonts/Lato-Regular.ttf)'); |
91 | 106 |
|
92 |
| - f.load().then((font) => { |
93 |
| - document.fonts.add(font); |
| 107 | + font.load().then((loadedFont) => { |
| 108 | + document.fonts.add(loadedFont); |
94 | 109 | });
|
95 | 110 | };
|
96 | 111 |
|
97 |
| - useFont(); |
98 |
| - |
99 |
| - const Canvas = HTMLCanvasElement; |
100 |
| - const Image = HTMLImageElement; |
| 112 | + const noteBlockImage = loadImage(getPath('/img/note-block-grayscale.png')); |
101 | 113 |
|
102 |
| - content = { |
| 114 | + canvasUtils = { |
103 | 115 | createCanvas,
|
104 | 116 | loadImage,
|
105 | 117 | getPath,
|
| 118 | + useFont, |
106 | 119 | saveToImage,
|
107 | 120 | noteBlockImage,
|
108 |
| - Canvas, |
109 |
| - Image, |
| 121 | + DrawingCanvas: HTMLCanvasElement, |
| 122 | + RenderedImage: HTMLImageElement, |
110 | 123 | };
|
111 | 124 | }
|
112 | 125 |
|
113 |
| -const { |
114 |
| - createCanvas, |
115 |
| - loadImage, |
116 |
| - getPath, |
117 |
| - useFont, |
118 |
| - saveToImage, |
119 |
| - noteBlockImage, |
120 |
| - Canvas, |
121 |
| - Image, |
122 |
| -} = content; |
123 |
| - |
124 |
| -export { |
| 126 | +export const { |
125 | 127 | createCanvas,
|
126 | 128 | loadImage,
|
127 | 129 | getPath,
|
128 | 130 | useFont,
|
129 | 131 | saveToImage,
|
130 | 132 | noteBlockImage,
|
131 |
| - Canvas, |
132 |
| - Image, |
133 |
| -}; |
| 133 | + DrawingCanvas, |
| 134 | + RenderedImage, |
| 135 | +} = canvasUtils; |
0 commit comments