1+ const Canvas = require ( 'canvas' ) ;
2+
3+ class CanvasConstructor {
4+
5+ constructor ( width , height ) {
6+ this . canvas = new Canvas ( width , height ) ;
7+ this . context = this . canvas . getContext ( '2d' ) ;
8+ }
9+
10+ /**
11+ * Restore the context changes.
12+ * @returns {CanvasConstructor }
13+ * @chainable
14+ */
15+ restore ( ) {
16+ this . context . restore ( ) ;
17+ return this ;
18+ }
19+
20+ /**
21+ * Add a rectangle.
22+ * @param {number } x The position x to start drawing the element.
23+ * @param {number } y The position y to start drawing the element.
24+ * @param {number } width The width of the element.
25+ * @param {number } height The heigth of the element.
26+ * @returns {CanvasConstructor }
27+ * @chainable
28+ */
29+ fillRect ( x , y , width , height ) {
30+ this . context . fillRect ( x , y , width , height ) ;
31+ return this ;
32+ }
33+
34+ /**
35+ * Add a text.
36+ * @param {string } text The text to write.
37+ * @param {number } x The position x to start drawing the element.
38+ * @param {number } y The position y to start drawing the element.
39+ * @returns {CanvasConstructor }
40+ * @chainable
41+ */
42+ addText ( text , x , y ) {
43+ this . context . fillText ( text , x , y ) ;
44+ return this ;
45+ }
46+
47+ /**
48+ * Add stroked text.
49+ * @param {string } text The text to write.
50+ * @param {number } x The position x to start drawing the element.
51+ * @param {number } y The position y to start drawing the element.
52+ * @returns {CanvasConstructor }
53+ * @chainable
54+ */
55+ addStrokeText ( text , x , y ) {
56+ this . context . strokeText ( text , x , y ) ;
57+ return this ;
58+ }
59+
60+ /**
61+ * Set a colour for the canvas' context.
62+ * @param {string } color A canvas' colour resolvable.
63+ * @returns {CanvasConstructor }
64+ * @chainable
65+ */
66+ setStroke ( color ) {
67+ this . context . strokeStyle = color ;
68+ return this ;
69+ }
70+
71+ /**
72+ * Add an image.
73+ * @param {Buffer } buffer The image's buffer.
74+ * @param {number } x The position x to start drawing the element.
75+ * @param {number } y The position y to start drawing the element.
76+ * @param {number } width The width of the element.
77+ * @param {number } height The heigth of the element.
78+ * @param {Object } options Options.
79+ * @param {number } options.radius The radius for the new image.
80+ * @param {'round'|'bevel' } options.type The type for the new image.
81+ * @returns {CanvasConstructor }
82+ * @chainable
83+ */
84+ addImage ( buffer , x , y , width , height , options = { } ) {
85+ if ( options . type !== null ) {
86+ if ( options . type === 'round' ) return this . addRoundImage ( buffer , x , y , width , height , options . radius ) ;
87+ if ( options . type === 'bevel' ) return this . addBevelImage ( buffer , x , y , width , height , options . radius ) ;
88+ }
89+ const image = new Canvas . Image ( ) ;
90+ image . onload = ( ) => this . context . drawImage ( image , x , y , width , height ) ;
91+ image . src = buffer ;
92+ return this . restore ( ) ;
93+ }
94+
95+ /**
96+ * Add a round image.
97+ * @param {Buffer } buffer The image's buffer.
98+ * @param {number } x The position x to start drawing the element.
99+ * @param {number } y The position y to start drawing the element.
100+ * @param {number } width The width of the element.
101+ * @param {number } height The heigth of the element.
102+ * @param {number } radius The radius for the new image.
103+ * @returns {CanvasConstructor }
104+ * @chainable
105+ */
106+ addRoundImage ( buffer , x , y , width , height , radius ) {
107+ this . createRoundClip ( x + radius , y + radius , radius ) ;
108+ return this . addImage ( buffer , x , y , width , height , radius , { type : null } ) ;
109+ }
110+
111+ /**
112+ * Add a beveled image.
113+ * @param {Buffer } buffer The image's buffer.
114+ * @param {number } x The position x to start drawing the element.
115+ * @param {number } y The position y to start drawing the element.
116+ * @param {number } width The width of the element.
117+ * @param {number } height The heigth of the element.
118+ * @param {number } radius The radius for the new image.
119+ * @returns {CanvasConstructor }
120+ * @chainable
121+ */
122+ addBevelImage ( buffer , x , y , width , height , radius ) {
123+ this . createBeveledClip ( x , y , width , height , radius ) ;
124+ return this . addImage ( buffer , x , y , width , height , radius , { type : null } ) ;
125+ }
126+
127+ /**
128+ * Create a round clip.
129+ * @param {number } x The position x in the center of the clip's circle.
130+ * @param {number } y The position y in the center of the clip's circle.
131+ * @param {number } radius The radius for the clip.
132+ * @returns {CanvasConstructor }
133+ * @chainable
134+ */
135+ createRoundClip ( x , y , radius ) {
136+ this . context . save ( ) ;
137+ this . context . beginPath ( ) ;
138+ this . context . arc ( x , y , radius , 0 , Math . PI * 2 , false ) ;
139+ this . context . clip ( ) ;
140+ return this ;
141+ }
142+
143+ /**
144+ * Create a round clip.
145+ * @param {number } x The position x to start drawing clip.
146+ * @param {number } y The position y to start drawing clip.
147+ * @param {number } width The width of clip.
148+ * @param {number } height The heigth of clip.
149+ * @param {number } radius The radius for clip's rounded borders.
150+ * @returns {CanvasConstructor }
151+ * @chainable
152+ */
153+ createBeveledClip ( x , y , width , height , radius ) {
154+ if ( width > 0 && height > 0 ) {
155+ radius = Math . min ( radius , width / 2 , height / 2 ) ;
156+ this . context . beginPath ( ) ;
157+ this . context . moveTo ( x + radius , y ) ;
158+ this . context . lineTo ( x + width - radius , y ) ;
159+ this . context . quadraticCurveTo ( x + width , y , x + width , y + radius ) ;
160+ this . context . lineTo ( x + width , y + height - radius ) ;
161+ this . context . quadraticCurveTo ( x + width , y + height , x + width - radius , y + height ) ;
162+ this . context . lineTo ( x + radius , y + height ) ;
163+ this . context . quadraticCurveTo ( x , y + height , x , y + height - radius ) ;
164+ this . context . lineTo ( x , y + radius ) ;
165+ this . context . quadraticCurveTo ( x , y , x + radius , y ) ;
166+ this . context . closePath ( ) ;
167+ this . context . clip ( ) ;
168+ }
169+ return this ;
170+ }
171+
172+ /**
173+ * Register a new font.
174+ * @param {string } path The path for the font.
175+ * @param {string } family The font's family name.
176+ * @returns {CanvasConstructor }
177+ * @chainable
178+ */
179+ registerTextFont ( path , family ) {
180+ Canvas . registerFont ( path , { family } ) ;
181+ return this ;
182+ }
183+
184+ /**
185+ * Set a colour for the canvas' context.
186+ * @param {string } color A canvas' colour resolvable.
187+ * @returns {CanvasConstructor }
188+ * @chainable
189+ */
190+ setColor ( color ) {
191+ this . context . fillStyle = color ;
192+ return this ;
193+ }
194+
195+ /**
196+ * Change the font.
197+ * @param {string } font The font's name to set.
198+ * @returns {CanvasConstructor }
199+ * @chainable
200+ */
201+ setTextFont ( font ) {
202+ this . context . font = font ;
203+ return this ;
204+ }
205+
206+ /**
207+ * Change the font alignment.
208+ * @param {('left'|'center'|'right'|'justified') } align The font's alignment to set.
209+ * @returns {CanvasConstructor }
210+ * @chainable
211+ */
212+ setTextAlign ( align ) {
213+ this . context . textAlign = align ;
214+ return this ;
215+ }
216+
217+ /**
218+ * Set the shadow's blur.
219+ * @param {number } radius The shadow's blur radius to set.
220+ * @returns {CanvasConstructor }
221+ * @chainable
222+ */
223+ setShadowBlur ( radius ) {
224+ this . context . shadowBlur = radius ;
225+ return this ;
226+ }
227+
228+ /**
229+ * Set the shadow's colour.
230+ * @param {string } colour A canvas' colour resolvable to set as shadow's colour.
231+ * @returns {CanvasConstructor }
232+ * @chainable
233+ */
234+ setShadowColour ( colour ) {
235+ this . context . shadowColor = colour ;
236+ return this ;
237+ }
238+
239+ /**
240+ * Reset the canvas' shadows.
241+ * @returns {CanvasConstructor }
242+ * @chainable
243+ */
244+ resetShadows ( ) {
245+ return this . setShadowBlur ( 0 ) . setShadowColour ( '#000000' ) ;
246+ }
247+
248+ /**
249+ * Render the canvas into a buffer.
250+ * @param {Object } options The render's options.
251+ * @returns {Buffer }
252+ */
253+ toBuffer ( options ) {
254+ return this . canvas . toBuffer ( options ) ;
255+ }
256+
257+ }
258+
259+ module . exports = CanvasConstructor ;
0 commit comments