litecanvas 0.100.1 → 0.102.0

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 CHANGED
@@ -23,7 +23,6 @@ Litecanvas is a lightweight HTML5 canvas 2D engine suitable for small web games,
23
23
 
24
24
  - **Tiny**: Only `~4KB` (minified + gzipped).
25
25
  - **Simple API**: Just few functions to draw shapes and some utilities.
26
- - **Predefined colors**: Just use a number (from 0 to 11) to choose a color in our 12-color palette.
27
26
  - **ZzFX**: Play or create sound effects with [ZzFX](https://killedbyapixel.github.io/ZzFX/).
28
27
  - **Extensible**: Use or create [plugins](https://www.npmjs.com/search?q=keywords:litecanvas) to add functionalities or change the engine.
29
28
  - **Playground**: Access or install the [playground](https://litecanvas.js.org/) webapp to code and share games (even offline).
@@ -89,18 +88,9 @@ litecanvas({
89
88
 
90
89
  ### Colors
91
90
 
92
- Litecanvas has a default palette with 12 colors:
91
+ Litecanvas has a default palette with 4 colors:
93
92
 
94
- | # | Color | # | Color |
95
- | --- | ---------- | --- | ----------- |
96
- | 0 | Black | 6 | Dark blue |
97
- | 1 | Dark grey | 7 | Light blue |
98
- | 2 | Light grey | 8 | Dark green |
99
- | 3 | White | 9 | Light green |
100
- | 4 | Red | 10 | Brown |
101
- | 5 | Yellow | 11 | Beige |
102
-
103
- ![The litecanvas color palette](.github/_assets/palette.png)
93
+ <img src=".github/_assets/palette.png" src="The litecanvas color palette" style="2px solid #fff">
104
94
 
105
95
  Each time a Litecanvas' function ask for a color, you should use an of theses colors by its index.
106
96
 
@@ -110,6 +100,8 @@ let color = 3
110
100
  rectfill(0, 0, 32, 32, color)
111
101
  ```
112
102
 
103
+ > Note: You can customize the color palette using the `pal()` function. [Example](samples/custom-palette/custom-palette.js)
104
+
113
105
  ### Printing messages
114
106
 
115
107
  ```js
@@ -119,16 +111,17 @@ function draw() {
119
111
  // clear and fill the game screen with color #0 (black)
120
112
  cls(0)
121
113
 
122
- // print a red text at x=0, y=0
123
- text(0, 0, 'Hello!!!', 4)
114
+ // print a gray (color #1) text at x=0, y=0
115
+ text(0, 0, 'Hello!!!', 1)
124
116
 
125
117
  // use \n to break text lines
126
118
  text(0, 30, 'multi\nline\ntext')
127
119
  }
128
120
  ```
129
121
 
130
- [Live Demo](https://litecanvas.js.org?c=eJxVzEsKwkAMBuB9T%2FEXF52CYEG37j1EN3EadTBmZCb1gXh3pyqIIYs8PwnGnvRC2bVVtRvVW4iKIdHVtXhUKLFYwAtTAumAXRCBHRh7OjGyT8yKa7ADfJSYMOvgtkL%2B2L5%2FvWTXFfnrnFNQAyHxAONbKQ23dTfHfd29b6ahK33JZsMisa7rZo7Vjxgzo1dYxDYxHT%2BMBOX8Bywn4TSKhV6nba%2FTpmmr5wtwJEcj)
122
+ > By default, the texts are white (color #3).
131
123
 
124
+ [Live Demo](https://litecanvas.js.org?c=eJxVjM2OwjAMhO99iqn20ERCoogz932IXkxwIcI4q8TlRyvenbSLtGLky8x4PonGgfRKxfmmGScNFpPikOnmPH4bVK3XCMKUQXrAGEVgJ8aRLowSMrPiFu2EkCRlfPVwe6Fw9ss2SHF9Jb85PzmqgXDM9IB7LzYexvcaG%2B67foXHrl%2F%2B59BVX6%2F7ZpHUtm23wuYfNxXGoLCEfWY6%2F2EkKpcPwHYmXCaxOOjcDjo3nW%2BeL%2BleSpw%3D)
132
125
 
133
126
  ### Drawing shapes
134
127
 
@@ -154,78 +147,89 @@ function draw() {
154
147
 
155
148
  // draw a circle outline at x=64 and y=96
156
149
  // with radius=50
157
- // and color=5 (yellow)
158
- circ(64, 96, 50, 5)
150
+ // and color=1 (gray)
151
+ circ(64, 96, 50, 1)
159
152
  }
160
153
  ```
161
154
 
162
- [Live Demo](https://litecanvas.js.org?c=eJxljk0KwyAQhfc5xSwNBGJ%2BFLrwMKImCoOCMU1D6d2rabIoGZhBfeN7H7pklPRPuZC6qqbVq%2BSCBx3lRmp4V5BL4UJoVsu5bQ8NJKiAIcLkEI2GaFSSfkYDMsFLdBSk17CLnl6%2FNpdsHjpZMfSHao2bbcq3a6U8Hq5iALLZTFYfUjEvOaSjDfS5h%2F7sO5SLKkOENaHzJwwfT5gH%2F4OJUrt1EYze8xmQ3SCG7QdQXAkfG3jwBlgGYHX1%2BQLFaFeI)
155
+ [Live Demo](https://litecanvas.js.org?c=eJxljk0KwyAQhfc5xSwNBKL5gy48zKAmCqJgTNNQeveqTRYlwogzb3zvsyYqge6JK6mrat6ciMY7kAF3UsO7gnSEXQlNan63bdEAQXjrA8zGWiUhKBHRLVYBRnhxRgGdhIN39Pq1m6jTJaPmfVdUrcyiY%2BqulTwsrrwHsutEVhcpm%2BccwmgDXaq%2BO%2BsOZYJIEH6L1rgTZhpOmMf0BxNQmm3lI73nMyBLwOMXnz3JNDTwmBoYUzyrq88XCIBWlw%3D%3D)
163
156
 
164
157
  ### Drawing sprites
165
158
 
166
159
  ```js
167
160
  litecanvas({
168
- width: 128
161
+ width: 128,
169
162
  })
170
163
 
171
164
  // you can create sprites with strings
172
165
  // each visible char is a pixel
173
166
  // numbers are colors
174
167
  // dots are transparent pixels
175
- let smile8x8 = `
176
- .555555.
177
- 55555555
178
- 55055055
179
- 55055055
180
- 55555555
181
- 50555505
182
- 55000055
183
- .555555.`
168
+ let smile = `
169
+ .333333.
170
+ 33333333
171
+ 33033033
172
+ 33033033
173
+ 33333333
174
+ 30333303
175
+ 33000033
176
+ .333333.`
184
177
 
185
178
  function draw() {
186
179
  cls(0)
187
180
 
188
181
  spr(
189
- 0, 0, // position X Y
190
- 8, 8, // the sprite Width and Height
191
- smile8x8 // the sprite Pixels
182
+ 0,
183
+ 0, // position X Y
184
+ smile // the pixels
192
185
  )
193
186
  }
194
187
  ```
195
188
 
196
- [Live Demo](https://litecanvas.js.org?c=eJxtUMtqwzAQvOsr5mhDSNxCIBR67x%2B0vUWR1UigSEa7zoOQf%2B9KdkwPHfawuzOzSBM8W6PjWVNzV8DF9%2Bze8PK6U49Wqc0GtzRCBDDZaragIYuDRMgOxNnHIxWZ1cbh7MkfgoVxOsMTNAZ%2FtaHwcTwdbJZVFjqFlKurTzytOOtIg3SRJw%2BpYBl08nLuHXt5GrDeVqzrsJ0xD12t%2F4a%2Fsq603SITzMzz9F6pnzEa9imiz%2FrStLhXgQnUdJJI6SWDpjYF3aqU%2FGVI5KvvC98Lu1uVEnbKDZ8lX%2BjY48P6o%2BNFOP1UhOzsM4Gyb9XjF0Vyb7o%3D)
189
+ [Live Demo](https://litecanvas.js.org?c=eJxtUDFuwzAM3PWKG22gSNRmKQr0H80WRVZrAopkiHTSIsjfS8lO0KEHDkfeHSEqkgTv0tlxdzXAhQYZ3%2FD88mpuvTHbLX7yDDXAl%2BAkgKeiCVajjGAplL642oLzI87EdIwBfnQFxHCY6DvEqqf5dAxFR0XlHHNpqSHLMpLiEk%2FKkiwZNjEI%2BES67h0HfRqw2TVsWrNbsTa21X%2FNX5ut1D5silW5rz4Y8zknL5QThuIuXY9rM%2FjIndUfqVz%2FoGukwj7V0lumzNRyH9g%2F1OUAVWUM98PqvDe3Xw5%2FZEM%3D)
197
190
 
198
191
  ### Creating and drawing images
199
192
 
200
193
  ```js
201
194
  litecanvas()
202
195
 
203
- // lets create flag of Japan
196
+ // lets create a flag of Japan
204
197
  let japanFlag = paint(
205
- 48, 32, // the image width and height
198
+ 48,
199
+ 32, // the image width and height
200
+
201
+ // we call theses operations once to create a image
206
202
  function () {
207
- cls(3) // white background
208
- circfill(24, 16, 8, 4) // red circle
209
- }, {
203
+ // lets modify the litecanvas palette to white and red
204
+ pal(['#fff', '#bd0029'])
205
+
206
+ // lets draw the flag
207
+ cls(0) // the white
208
+ circfill(24, 16, 8, 1) // the sun
209
+
210
+ // reset the palette
211
+ pal()
212
+ },
213
+ {
210
214
  // you can scale your image
211
215
  // by default, scale=1
212
- scale: 4
216
+ scale: 4,
213
217
  }
214
218
  )
215
219
 
216
220
  function draw() {
217
221
  cls(0)
218
222
 
219
- // draw the japanFlag image
223
+ // draw the our generated japanFlag image
220
224
  image(
221
- W/2 - japanFlag.width/2, // game screen center X
222
- H/2 - japanFlag.height/2, // game screen center Y
223
- japanFlag // the image
225
+ W / 2 - japanFlag.width / 2, // game screen center X
226
+ H / 2 - japanFlag.height / 2, // game screen center Y
227
+ japanFlag // the image
224
228
  )
225
229
  }
226
230
  ```
227
231
 
228
- [Live Demo](https://litecanvas.js.org?c=eJxtUctOwzAQvPsr5phIgdA0QgipV4T4AeC4dTaJi%2BtUjkNUof47toOcqmJPXs%2FMPma1cizJfNOY5UKUJTS7EdIyOUarqcPQ4o1OZIRHcAivl%2FC9w4mUcZmAj%2FqpwLYq4PWuZ6gjdYxZNa4HmQY9q653kdlORjo1GGQ5fuJPCKnHbJsH%2Bdz7gbAn%2BdXZYTLNSlFWtkrrrKoLbB4L%2BJZ1lFhuIqo5ki%2FFVWEPn4cJfkOMkjSHzC7zXXP2ZzTc0qRdsfB2mwTH%2FBn1Ulx4l9IOjaU57RF2ePDoX8mARTNWy9a28ZWlFu9lhbuVeB%2BdK72foVBHR%2FZDWGYDycaxxUdSvt4oF6fL5RT%2FKD%2BTch3rNq6PGOm5uPwCs6aXUg%3D%3D)
232
+ [Live Demo](https://litecanvas.js.org?c=eJx9Uk1rwzAMvftXCHpIAtnaZmV0g17H2B%2FYxtjBdeTEw3WK4yyU0f8%2BRemclsJ88Yeenp6eZU1AJd23bNNMiPkcLIYWlEcZECRoKytoNLzIvXSCYvA1nJ6G5w3spXEhFUBrtc55vytyIJZQI5idrBB6U4YapCuhRlPVQTCMID2CktYO0BZbaPboZTCNo6NTCKGZVDAT5%2BnOqQEEaQY%2F%2FHJiY9m7pjT6wMVt7ItUUjAwY1%2BbgZDEeCxjOgHSj2SmtU5ySGbbcrEoHpLPTFwVKL3smX7wJUaVbdNF9tc215hixittrE2LVQ7L%2BxzWtEVs27mLIp6sCBw5ib7QmPHtOBp90f2h6chMBy05isPNn3l2wmwPUKKWnQ35iNssY5jvj7AaqY%2BCWo9ODz1Ht8dW4x9GP6apmOryKY01XmEOBdxM0NtxNOiVR6aSOzKE%2FhwdKHQBPbzF5Oer5HGa%2Fst%2Bj9mTuvPR5HAmjr8pYdU3)
229
233
 
230
234
  > Note: It's very useful when you need to draw something the same way every time. This way, you create an image of that drawing, working as a kind of cache.
231
235
 
@@ -301,8 +305,8 @@ function draw() {
301
305
  cls(0)
302
306
 
303
307
  if (x != null) {
304
- // Draw a red circle wherever you tap
305
- circfill(x, y, 32, 4)
308
+ // Draw a white circle wherever you tap
309
+ circfill(x, y, 32, 3)
306
310
  }
307
311
  }
308
312
  ```
@@ -317,8 +321,8 @@ litecanvas()
317
321
  function draw() {
318
322
  cls(0)
319
323
 
320
- // draw a red circle in the mouse cursor's position
321
- circfill(MX, MY, 32, 4)
324
+ // draw a white circle in the mouse cursor's position
325
+ circfill(MX, MY, 32, 3)
322
326
  }
323
327
  ```
324
328
 
@@ -342,9 +346,9 @@ You can find a complete list of everything litecanvas has to offer on our [cheat
342
346
  Try some demos in the playground:
343
347
 
344
348
  - [Bouncing Ball](https://litecanvas.js.org?c=eJxtksFygyAQhu8%2BxR7VmGjSdqZNag89%2BQaeGcAMM1QdRBsm8d27Co3Y9MAM7M%2F%2B%2By2L5BraphNaNDXkMHAa7rMswRUlAeBZNlRoM%2B3PigxuqwgTfYf3n1%2BDQArNKakH0oVREFR9TWczUQsdRnD1XDDhejmW8SExxyI9jKfF1UrZJGB49Hz6lhHNQ6at1y%2Fs7gKb%2FO6MpxiY9nWz0o3VPRhr4Mov%2BV6GJy%2FpaQqfDbJxaKoKODvzDqOignAh27j3%2BYASbjcPeeuEd8hsNyucOIft%2FvRPNNu9vcxhr%2FkcqCRfrVc1cWNJoHR1Ikwa%2F9JhX3DnKx4wzIzxWHGaUOF8Z1t%2FRkyRbzdrKrswi6YuqFC0ElL6iItd4mCfovW4px%2BIrRjrprjuVY1fAyNY8gdFptV%2F)
345
- - [Scroller](https://litecanvas.js.org?c=eJxVUM1SgzAQvvMU68FpAhFDLVpH%2BxbOcOj0ECGUzATSIYsyOn13NwXRHpJNvv1%2BkrUGdam6D%2BUZj6J66Eo0rgPTGQTG4TsCaLX36qhhB6tC29K1GtCBXYQ3KyKN1C6onpSl034jcvEonsRWPItMiiw7ROd%2F9sOpUqiBVThFePMV%2FIv7OSu1ujtiQ52G4FxeAu528CAlxFDhHNiqkY0C1pJfuVe9%2Bvx9fGk9ozZA7XpgViMYEsoXKq9wnUZYkkwqgMBEYr4lTKZZbPiC0kLdh%2FRZ7Yd3jz0zArI%2FVumsCySax762zvUM4%2FyWbnMYP1yoqEcMn2dh4wvExsTEAYpluhXQJGuZeNORx4bHjZjfIKaUIDvTAH4AEIGEgw%3D%3D)
349
+ - [Scroller](https://litecanvas.js.org?c=eJxVUM1uhCAQvvsU00OzgNSi202atPsWTTxs9kAVVxKUjYytabPv3mG1tnuAgW%2B%2BHxhn0VS6%2F9CB8SRpxr5C63uwvUVgHL4TgM6EoE8G9rApjat8ZwA9uFV4tyHSRO2S6lk7Oh1yWcjtMbn8sxzPtUYDrMbZNtiv6Fk%2BLv6ZM%2F0JW%2Bq0BO%2FU1fRhD1ulQECNS0inJzZJKBS%2Fca8H%2Ffn74MoFRm2Axg%2FAnEGwJFQvVF7hNo2wNJ1VAJGJxHxLmcpyYfmK0kIzxPRFHcb3gAOzEvI%2FVuWdjySawaFx3g8Mxe6ebksYP16paCaMn2dx4yvEptSKCAmVPUto00Klwfbk8cRFK5c3yDklyi40gB98w4Iz)
346
350
  - [3D projection](https://litecanvas.js.org?c=eJyNVcuS2jAQvPsrJofUykE8wykJySlVyRckuy4fZGwWgZEpWQSWFP%2BeGUlgizVLqgyyprul1mgkl9IUc6H%2BiJrFUbTYqbmRlQKppGEx%2FI0AanksYAa%2F4Cv8gG%2F4G8IUPmEfW4S3uloVTjSDBAMAyZjDCJ%2BUuy6%2Bj8MuRWw3pREqqUzdqPs0I4d2k3IYDiE5cHjhcEwdr4vWRjqA%2Fj2kRQgHuwm8jvc7gbTJVZHTYikg1HNJyR1Fp1byd9tcmILlxm2AI%2FWQNRiNIwwsKg2sLAxIkn7G5otP4qAs1LNZYqjXc2KAeaVqgzhl2LImG2G0PLDBYOBUiUxjS6UxdWWEc4i0za5kNoC2fjNrJOY0luPf5D5euJ5yh%2F%2FUzb%2FkCx02oqbiAvopyGGuxd4X8Lys2SimxG139ZIRt5Sq2MvcLNmEukYLVZeUc6rqCbdFbpGuVE%2Bv06vQDZMcmIQejGN4D1PeeI9DGlIQZS1u7EK3BBxkB%2BFkD84WV9Ne9VkkOGTc14QzSitmfrtFmozoOTMoMA4C2TUjuzA%2BhjP6PaEJfbZtuYl5VVLBCdT4omwwXe0tdg1kXpR1iDIvys4AInIBzE30bjZzjBjMElvA7YXvWleaPfzEy62UObiqL%2BoHWwpuVF3U56PYtdPWabDbKHC1mLhL6KJaOdUKVXYZ%2BNqo3Mmqdxt71F3kolw75Zrmc8p1WwlW16NUyjRZp%2FAB87NOk1XqCSffOmsYx%2FFQEp2xEy1XF2anFXGC3WvOtha5xEPg5vXsm7f5vKovAns1qla3TQyRUDby12KXn8e3%2FFwNE85y45tz7TE084aTp%2F93cisP95Pw6qPYdhLc2f4LGJpJDngukxf6O6Yk%2FgdWEko3)
347
- - [Rendering Benchmark](https://litecanvas.js.org?c=eJylVVtP2zAUfs%2BvsLpJSSCkSS9QurYTQkx7AAkB0x6qariJ21q4See40Az633dsp8G9UNDmB1Kf853j71yJ0iQTKEoTwVOWoS6K02g%2BJYnwI06wIBeMyJtjx%2FTRdq0V0KdJQvj3u6tLMLm3OqDtWQhOJwN9Mu6dTdN5ItqdanHXSowmnIy6la9YqbthEFR68KdTxW8gmhLR3IcAc%2Bnk4W1ETSFqexANhWjsQbQUorUHER5rIsd7MHVNpV5w6VRV3mT2UCZyRrqVWZpRQdOkjThhWNBHUil8RTh5xBmicbcSVXqdqr6vnNxbZeGGaZz7eDYjSeys6uVaG3r1nB%2BlLOVQQftTGIb2TsgQRw9jDuzj8xI8Go1sy2JEoDlnIEnIE%2Fpxc%2BmwNMKSvOspypmABgL1s7rJE6mmQIdg5mcE82hyjTmeZv6YQIvpJNkuenlBUFWvNHuisZi0QVZrvAonhI4n4KzRKpBLoEQF0Xlx9KOFpWLiq4vGroy1Qt%2B0Rpu3IcrItpaQNw3JZpyqYGaYwjgoaFjz1r79kpvtw2nAkV%2Fb25BjvEMeBFIeBFvymvRT25CfwKnDacJZkx8fn9TDsN4cDj8mf8OPfPcUzua7kudpq3W6zdP3pXxXvNKPIR%2Foz2tTZBFmpI3qqypCzkfzJJKNhGhCheMW4G%2FXt7%2BuLu4ubvyYZjOGc0fwOQF42Wx%2BRv%2FIIpk102XXoGoVQcMJGjGC1H6DN3TV1RqcFbqs6OkzzuER7Uy1rmuAYyqHoR966CgcKPkIxsORU0FBEXyBTwcZxiA4PHTXpkH6WQCYY5hVFx2YjYqOjJg2bPJtG93D%2B4z68cJDcT6QrEuVPMoTxFGX3iCsvhRQJ%2FBQ6A68f4EOyl9lSvtUPvyMgEMONBQVKLYuuVFBswblb8vIO6PJg%2Fl%2F6vec8PyWMBKJlDv3%2FfWN%2B%2FnZqMCyMrjXJaQjqBQ4Mssh78XSG8Ha%2FKkTCvtumLLYLpgujeaMOX4qmxNa65zBSkNiQoolokmzzAnc7fbDCZ3u67%2BNbPxHg3Ezk1AGq9Rzf4GOoJP8eGHI8kKWvwJluiS4gwLT%2F8oHkNmQxQt00IXBKMVLRFhGCkf5bkf5Lkf5pqNtVofm8PfMGdpN9t0h%2B1gMO5%2FVY7g7tvcH9QMxT%2FGYyKg96dRb23Ru2aN%2FASaYns8%3D)
351
+ - [Rendering Benchmark](https://litecanvas.js.org?c=eJylVFFv2jAQfs%2Bv8NikJAUCtLSqGDBVVadNaqWq7bQHhFbXMWDV2MwxLVnLf9%2FZDqlLKa22PAR8993lu7vvTKTINCJSaCV5hnoolWQ%2BpUInRFGs6Qmn5hSFKbsL42AFTJgQVH27OjuFkOugC95%2BgODpZuAX4%2F7RVM6F7nQbxdk5MZooOupVvmDr7rWazUofXt0GfgWxbxD72xAQbpLcvo7YtYjdLYi2RbS3IA4t4nALonXgiBxswew5KnsFl27D9s10D2U657RXmcmMaSZFBynKsWZ3tFLkIljc4QyxtFchlX634c6rJNdBObgbmeYJns2oSKPVvOJgzW8%2FlxDJpYIJhh9brVa4EXKDye1YAfv0uASPRqMwCDjVaK44WAS9Rz8uTiMuCTbk45qlnGkQELgf7Mk8xIoCVSEsyShWZHKOFZ5myZiCxFyTwhg9PiKYaq0Mu2epnnTAttt%2BMk4oG08gWfvQQ2bsD%2B2gg7Y1LIEj09Q1KnIsilSWWmIPLniVzTncyXlceAfKJmGwhEaO5oKYKhETTEdxUR6xi8TlWBYN%2BT7FYxrF1mnMiRRc4hS8ENPrl11xX8xmitlmGWjBvozMFDF9bzDzEfuuH7STmRiHFmNfX88vf52dXJ1cJCnLZhznkVZzCnSNs9FA0GjNCKfI7jXQ91jPCl9WUD9SCuIdMTuy2AOnzIhg0Kqhemto7SOQRWTUwMDR%2FAw%2FXeQFg6FajZ%2BpwORZAFhh0GiMdvx5oPqqJTDLtZj8ZYwb1bagQbqooTQfGtalyzw2E9SxZ7JBWQNjYFGzhlrxsPYv0GH5r2zpgJkPPyDgkAMNS6WY7TJ4WpPEn0H5P%2FClxcStfz%2F%2FnlOVX1JOiZYquh48v2k%2BPXgTWFaG126EbASTgkT%2BOMy5WPYRXBc%2FXUNBbzeSp2HBdOnpPlX4vtQ9SOuYwyojPaHFrjjSPIv2CvmZr37wdR7D7abnSrxUJxZsuk2ea836D%2F0pv9EwpaD0q2SB6iC0JF14tryw5U9AU5cBd1HTz7%2FKAWTWbOkC7fRgb0rzElGe0SJRvjlRvilRvp7oJauqtxKo76%2FYZrJv7uD7atj4Wbelm2t7e4%2FfUbO9bKGOmklae3apxqWE%2FwKDkIFn)
348
352
 
349
353
  > _See other demos in [samples](/samples) folder_
350
354
 
package/dist/dist.dev.js CHANGED
@@ -11,20 +11,7 @@
11
11
  };
12
12
 
13
13
  // src/palette.js
14
- var defaultPalette = [
15
- "#111",
16
- "#6a7799",
17
- "#aec2c2",
18
- "#FFF1E8",
19
- "#e83b3b",
20
- "#fabc20",
21
- "#155fd9",
22
- "#3cbcfc",
23
- "#327345",
24
- "#63c64d",
25
- "#6c2c1f",
26
- "#ac7c00"
27
- ];
14
+ var defaultPalette = ["#211e20", "#555568", "#a0a08b", "#e9efec"];
28
15
 
29
16
  // src/dev.js
30
17
  var assert = (condition, message = "Assertion failed") => {
@@ -32,7 +19,7 @@
32
19
  };
33
20
 
34
21
  // src/version.js
35
- var version = "0.100.1";
22
+ var version = "0.102.0";
36
23
 
37
24
  // src/index.js
38
25
  function litecanvas(settings = {}) {
@@ -50,7 +37,7 @@
50
37
  keyboardEvents: true
51
38
  };
52
39
  settings = Object.assign(defaults, settings);
53
- let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
40
+ let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _defaultTextColor = 3, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
54
41
  const instance = {
55
42
  /** @type {number} */
56
43
  W: 0,
@@ -481,6 +468,31 @@
481
468
  _ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
482
469
  instance.fill(color);
483
470
  },
471
+ /**
472
+ * Make a custom shape in the canvas context.
473
+ * Then, just use `fill` or `stroke` to draw the shape.
474
+ *
475
+ * @param {number[]} points an array of Xs and Ys coordinates
476
+ */
477
+ shape(points) {
478
+ DEV: assert(
479
+ Array.isArray(points),
480
+ "[litecanvas] shape() 1st param must be an array of numbers"
481
+ );
482
+ DEV: assert(
483
+ points.length >= 6,
484
+ "[litecanvas] shape() 1st param must be an array with at least 6 numbers (3 points)"
485
+ );
486
+ beginPath(_ctx);
487
+ for (let i = 0; i < points.length; i++) {
488
+ if (0 === i) {
489
+ _ctx.moveTo(~~points[i][0], ~~points[i][1]);
490
+ } else {
491
+ _ctx.lineTo(~~points[i][0], ~~points[i][1]);
492
+ }
493
+ }
494
+ _ctx.lineTo(~~points[0][0], ~~points[0][1]);
495
+ },
484
496
  /**
485
497
  * Draw a line
486
498
  *
@@ -550,10 +562,10 @@
550
562
  * @param {number} x
551
563
  * @param {number} y
552
564
  * @param {string} message the text message
553
- * @param {number} [color=3] the color index
565
+ * @param {number} [color] the color index
554
566
  * @param {string} [fontStyle] can be "normal" (default), "italic" and/or "bold".
555
567
  */
556
- text(x, y, message, color = 3, fontStyle = "normal") {
568
+ text(x, y, message, color = _defaultTextColor, fontStyle = "normal") {
557
569
  DEV: assert(isNumber(x), "[litecanvas] text() 1st param must be a number");
558
570
  DEV: assert(isNumber(y), "[litecanvas] text() 2nd param must be a number");
559
571
  DEV: assert(
@@ -638,26 +650,23 @@
638
650
  _ctx.drawImage(source2, ~~x, ~~y);
639
651
  },
640
652
  /**
641
- * Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
653
+ * Draw a sprite pixel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
642
654
  *
643
655
  * @param {number} x
644
656
  * @param {number} y
645
- * @param {number} width
646
- * @param {number} height
647
657
  * @param {string} pixels
648
658
  */
649
- spr(x, y, width, height, pixels) {
659
+ spr(x, y, pixels) {
650
660
  DEV: assert(isNumber(x), "[litecanvas] spr() 1st param must be a number");
651
661
  DEV: assert(isNumber(y), "[litecanvas] spr() 2nd param must be a number");
652
- DEV: assert(isNumber(width), "[litecanvas] spr() 3rd param must be a number");
653
- DEV: assert(isNumber(height), "[litecanvas] spr() 4th param must be a number");
654
- DEV: assert("string" === typeof pixels, "[litecanvas] spr() 5th param must be a string");
655
- const chars = pixels.replace(/\s/g, "");
656
- for (let gridx = 0; gridx < width; gridx++) {
657
- for (let gridy = 0; gridy < height; gridy++) {
658
- const char = chars[width * gridy + gridx] || ".";
659
- if (char !== ".") {
660
- instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 36) || 0);
662
+ DEV: assert("string" === typeof pixels, "[litecanvas] spr() 3rd param must be a string");
663
+ const rows = pixels.trim().split("\n");
664
+ for (let row = 0; row < rows.length; row++) {
665
+ const chars = rows[row].trim();
666
+ for (let col = 0; col < chars.length; col++) {
667
+ const char = chars[col];
668
+ if (char !== "." && char !== " ") {
669
+ instance.rectfill(x + col, y + row, 1, 1, parseInt(char, 36) || 0);
661
670
  }
662
671
  }
663
672
  }
@@ -928,15 +937,21 @@
928
937
  /**
929
938
  * Set new palette colors or restore the default palette.
930
939
  *
931
- * @param {string[]} [colors]
940
+ * @param {string[]} [colors] an array of colors
941
+ * @param {number} [textColor] the default text color this palette
932
942
  */
933
- pal(colors = defaultPalette) {
943
+ pal(colors, textColor = 3) {
934
944
  DEV: assert(
935
945
  Array.isArray(colors) && colors.length > 0,
936
- "[litecanvas] pal() 1st param must be a array of strings"
946
+ "[litecanvas] pal() 1st param must be a array of color strings"
947
+ );
948
+ DEV: assert(
949
+ isNumber(textColor) && textColor >= 0,
950
+ "[litecanvas] pal() 2nd param must be a positive number or zero"
937
951
  );
938
- _colorPalette = colors;
952
+ _colorPalette = colors || defaultPalette;
939
953
  _colorPaletteState = [];
954
+ _defaultTextColor = textColor;
940
955
  },
941
956
  /**
942
957
  * Replace the color "a" with color "b".
@@ -1457,5 +1472,5 @@
1457
1472
  }
1458
1473
 
1459
1474
  // src/web.js
1460
- globalThis.litecanvas = litecanvas;
1475
+ window.litecanvas = litecanvas;
1461
1476
  })();
package/dist/dist.js CHANGED
@@ -11,20 +11,7 @@
11
11
  };
12
12
 
13
13
  // src/palette.js
14
- var defaultPalette = [
15
- "#111",
16
- "#6a7799",
17
- "#aec2c2",
18
- "#FFF1E8",
19
- "#e83b3b",
20
- "#fabc20",
21
- "#155fd9",
22
- "#3cbcfc",
23
- "#327345",
24
- "#63c64d",
25
- "#6c2c1f",
26
- "#ac7c00"
27
- ];
14
+ var defaultPalette = ["#211e20", "#555568", "#a0a08b", "#e9efec"];
28
15
 
29
16
  // src/index.js
30
17
  function litecanvas(settings = {}) {
@@ -42,7 +29,7 @@
42
29
  keyboardEvents: true
43
30
  };
44
31
  settings = Object.assign(defaults, settings);
45
- let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
32
+ let _initialized = false, _paused = true, _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _defaultTextColor = 3, _fontFamily = "sans-serif", _fontSize = 20, _fontLineHeight = 1.2, _rngSeed = Date.now(), _colorPalette = defaultPalette, _colorPaletteState = [], _defaultSound = [0.5, 0, 1750, , , 0.3, 1, , , , 600, 0.1], _coreEvents = "init,update,draw,tap,untap,tapping,tapped,resized", _mathFunctions = "PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp", _eventListeners = {};
46
33
  const instance = {
47
34
  /** @type {number} */
48
35
  W: 0,
@@ -322,6 +309,23 @@
322
309
  _ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
323
310
  instance.fill(color);
324
311
  },
312
+ /**
313
+ * Make a custom shape in the canvas context.
314
+ * Then, just use `fill` or `stroke` to draw the shape.
315
+ *
316
+ * @param {number[]} points an array of Xs and Ys coordinates
317
+ */
318
+ shape(points) {
319
+ beginPath(_ctx);
320
+ for (let i = 0; i < points.length; i++) {
321
+ if (0 === i) {
322
+ _ctx.moveTo(~~points[i][0], ~~points[i][1]);
323
+ } else {
324
+ _ctx.lineTo(~~points[i][0], ~~points[i][1]);
325
+ }
326
+ }
327
+ _ctx.lineTo(~~points[0][0], ~~points[0][1]);
328
+ },
325
329
  /**
326
330
  * Draw a line
327
331
  *
@@ -368,10 +372,10 @@
368
372
  * @param {number} x
369
373
  * @param {number} y
370
374
  * @param {string} message the text message
371
- * @param {number} [color=3] the color index
375
+ * @param {number} [color] the color index
372
376
  * @param {string} [fontStyle] can be "normal" (default), "italic" and/or "bold".
373
377
  */
374
- text(x, y, message, color = 3, fontStyle = "normal") {
378
+ text(x, y, message, color = _defaultTextColor, fontStyle = "normal") {
375
379
  _ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
376
380
  _ctx.fillStyle = getColor(color);
377
381
  const messages = ("" + message).split("\n");
@@ -429,21 +433,20 @@
429
433
  _ctx.drawImage(source2, ~~x, ~~y);
430
434
  },
431
435
  /**
432
- * Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
436
+ * Draw a sprite pixel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
433
437
  *
434
438
  * @param {number} x
435
439
  * @param {number} y
436
- * @param {number} width
437
- * @param {number} height
438
440
  * @param {string} pixels
439
441
  */
440
- spr(x, y, width, height, pixels) {
441
- const chars = pixels.replace(/\s/g, "");
442
- for (let gridx = 0; gridx < width; gridx++) {
443
- for (let gridy = 0; gridy < height; gridy++) {
444
- const char = chars[width * gridy + gridx] || ".";
445
- if (char !== ".") {
446
- instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 36) || 0);
442
+ spr(x, y, pixels) {
443
+ const rows = pixels.trim().split("\n");
444
+ for (let row = 0; row < rows.length; row++) {
445
+ const chars = rows[row].trim();
446
+ for (let col = 0; col < chars.length; col++) {
447
+ const char = chars[col];
448
+ if (char !== "." && char !== " ") {
449
+ instance.rectfill(x + col, y + row, 1, 1, parseInt(char, 36) || 0);
447
450
  }
448
451
  }
449
452
  }
@@ -646,11 +649,13 @@
646
649
  /**
647
650
  * Set new palette colors or restore the default palette.
648
651
  *
649
- * @param {string[]} [colors]
652
+ * @param {string[]} [colors] an array of colors
653
+ * @param {number} [textColor] the default text color this palette
650
654
  */
651
- pal(colors = defaultPalette) {
652
- _colorPalette = colors;
655
+ pal(colors, textColor = 3) {
656
+ _colorPalette = colors || defaultPalette;
653
657
  _colorPaletteState = [];
658
+ _defaultTextColor = textColor;
654
659
  },
655
660
  /**
656
661
  * Replace the color "a" with color "b".
@@ -1100,5 +1105,5 @@
1100
1105
  }
1101
1106
 
1102
1107
  // src/web.js
1103
- globalThis.litecanvas = litecanvas;
1108
+ window.litecanvas = litecanvas;
1104
1109
  })();
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
1
- (()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a,l=window,n=Math,i=2*n.PI,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))},f=(a=new AudioContext,l.zzfxV=1,(e=1,t=.05,n=220,i=0,o=0,r=.1,s=0,f=1,c=0,d=0,u=0,p=0,h=0,g=0,m=0,v=0,w=0,x=1,b=0,y=0,k=0)=>{let E=Math,z=2*E.PI,D=c*=500*z/44100/44100,P=n*=(1-t+2*t*E.random(t=[]))*z/44100,T=0,C=0,I=0,L=1,S=0,A=0,M=0,N=k<0?-1:1,F=z*N*k*2/44100,q=E.cos(F),B=E.sin,H=B(F)/4,O=1+H,V=-2*q/O,W=(1-H)/O,R=(1+N*q)/2/O,G=-(N+q)/O,X=0,Y=0,$=0,j=0;for(i=44100*i+9,b*=44100,o*=44100,r*=44100,w*=44100,d*=500*z/85766121e6,m*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,e*=.3*l.zzfxV,N=i+b+o+r+w|0;I<N;t[I++]=M*e)++A%(100*v|0)||(M=s?1<s?2<s?3<s?B(T*T):E.max(E.min(E.tan(T),1),-1):1-(2*T/z%2+2)%2:1-4*E.abs(E.round(T/z)-T/z):B(T),M=(h?1-y+y*B(z*I/h):1)*(M<0?-1:1)*E.abs(M)**f*(I<i?I/i:I<i+b?1-(I-i)/b*(1-x):I<i+b+o?x:I<N-w?(N-I-w)/r*x:0),M=w?M/2+(w>I?0:(I<N-w?1:(N-I)/w)*t[I-w|0]/2/e):M,k&&(M=j=R*X+G*(X=Y)+R*(Y=M)-W*$-V*($=j))),T+=(F=(n+=c+=d)*E.cos(m*C++))+F*g*B(I**5),L&&++L>p&&(n+=u,P+=u,L=0),!h||++S%h||(n=P,c=D,L=L||1);(e=a.createBuffer(1,N,44100)).getChannelData(0).set(t),(n=a.createBufferSource()).buffer=e,n.connect(a.destination),n.start()});t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let c=!1,d=!0,u,p=1,h,g=.5,m=1,v,w=1e3/60,x,b,y="sans-serif",k=20,E=1.2,z=Date.now(),D=e,P=[],T=[.5,0,1750,,,.3,1,,,,600,.1],C={},I={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:i/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?I.clamp(o,l,n):o},norm:(e,t,a)=>I.map(e,t,a,0,1),wave:(e,t,a,l=Math.sin)=>e+(l(a)+1)/2*(t-e),rand:(e=0,t=1)=>(z=(1664525*z+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(I.rand(e,t+1)),rseed(e){z=~~e},cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):I.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),I.stroke(n)},rectfill(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),I.fill(n)},circ(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),I.stroke(l)},circfill(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),I.fill(l)},oval(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),I.stroke(n)},ovalfill(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),I.fill(n)},line(e,t,a,l,n){h.beginPath();let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);h.moveTo(~~e+i,~~t+o),h.lineTo(~~a+i,~~l+o),I.stroke(n)},linewidth(e){h.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,l=3,n="normal"){h.font=`${n} ${k}px ${y}`,h.fillStyle=N(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)h.fillText(i[a],~~e,~~t+k*E*a)},textgap(e){E=e},textfont(e){y=e},textsize(e){k=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},spr(e,t,a,l,n){let i=n.replace(/\s/g,"");for(let n=0;n<a;n++)for(let o=0;o<l;o++){let l=i[a*o+n]||".";"."!==l&&I.rectfill(e+n,t+o,1,1,parseInt(l,36)||0)}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=h;return n.width=e*i,n.height=t*i,(h=n.getContext("2d")).scale(i,i),a(h),h=o,n.transferToImageBitmap()},ctx:e=>(e&&(h=e),h),push(){h.save()},pop(){h.restore()},translate(e,t){h.translate(~~e,~~t)},scale(e,t){h.scale(e,t||e)},rotate(e){h.rotate(e)},alpha(e){h.globalAlpha=I.clamp(e,0,1)},fill(e){h.fillStyle=N(e),h.fill()},stroke(e){h.strokeStyle=N(e),h.stroke()},clip(e){h.beginPath(),e(h),h.clip()},sfx:(e,t=0,a=1)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||T,(0!==t||1!==a)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),f.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>u,use(e,t={}){var a=e,l=t;let n=a(I,l);for(let e in n)I.def(e,n[e])},listen:(e,t)=>(C[e=e.toLowerCase()]=C[e]||new Set,C[e].add(t),()=>C&&C[e].delete(t)),emit(e,t,a,l,n){c&&(M("before:"+(e=e.toLowerCase()),t,a,l,n),M(e,t,a,l,n),M("after:"+e,t,a,l,n))},pal(t=e){D=t,P=[]},palc(e,t){null==e?P=[]:P[e]=t},def(e,a){I[e]=a,t.global&&(l[e]=a)},timescale(e){m=e},framerate(e){w=1e3/~~e},stat(e){let a={index:e,value:[t,c,w/1e3,p,C,D,T,m,l.zzfxV,z,k,y,P,E][e]};return I.emit("stat",a),a.value},pause(){d=!0,cancelAnimationFrame(b)},resume(){c&&d&&(d=!1,x=w,v=Date.now(),b=o(S))},paused:()=>d,quit(){for(let e of(I.emit("quit"),I.pause(),c=!1,C={},r))e();if(t.global){for(let e in I)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))I[e]=n[e];function L(){if(t.autoscale&&s(l,"resize",A),t.tapEvents){let e=e=>[(e.pageX-u.offsetLeft)/p,(e.pageY-u.offsetTop)/p],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:Date.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&Date.now()-e.t<=300,o=!1;s(u,"mousedown",t=>{if(0===t.button){t.preventDefault();let[l,n]=e(t);I.emit("tap",l,n,0),a(0,l,n),o=!0}}),s(u,"mouseup",a=>{if(0===a.button){a.preventDefault();let l=t.get(0),[n,r]=e(a);i(l)&&I.emit("tapped",l.xi,l.yi,0),I.emit("untap",n,r,0),t.delete(0),o=!1}}),s(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);I.def("MX",a),I.def("MY",l),o&&(I.emit("tapping",a,l,0),n(0,a,l))}),s(u,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);I.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(u,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a);I.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let r=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&I.emit("tapped",l.xi,l.yi,e),I.emit("untap",l.x,l.y,e),t.delete(e))};s(u,"touchend",r),s(u,"touchcancel",r),s(l,"blur",()=>{for(let[e,a]of(o=!1,t))I.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";s(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear()),I.listen("after:update",()=>t.clear()),I.def("iskeydown",t=>a(e,t)),I.def("iskeypressed",e=>a(t,e)),I.def("lastkey",()=>n)}c=!0,I.emit("init",I),I.resume()}function S(){b=o(S);let e=Date.now(),t=0,a=e-v;for(v=e,x+=a<100?a:w;x>=w;){t++,x-=w;let e=w/1e3*m;I.emit("update",e,t),I.def("T",I.T+e)}t&&(I.emit("draw",h),t>1&&(x=0))}function A(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(I.def("W",e),I.def("H",a),u.width=e,u.height=a,t.autoscale){let l=+t.autoscale;u.style.display||(u.style.display="block",u.style.margin="auto"),p=n.min(innerWidth/e,innerHeight/a),p=l>1&&p>l?l:p,u.style.width=e*p+"px",u.style.height=a*p+"px"}h.imageSmoothingEnabled=!1,I.textalign("start","top"),I.emit("resized",p)}function M(e,t,a,l,n){if(C[e])for(let i of C[e])i(t,a,l,n)}function N(e){return D[~~(P[e]??e)%D.length]}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,I),l.ENGINE=I}h=(u=(u="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),s(u,"click",()=>focus()),A(),u.parentNode||document.body.appendChild(u),u.style.imageRendering="pixelated",u.oncontextmenu=()=>!1;let F=t.loop?t.loop:l;for(let e of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))F[e]&&I.listen(e,F[e]);return"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(L)):b=o(L),I}})();
1
+ (()=>{var e=["#211e20","#555568","#a0a08b","#e9efec"];window.litecanvas=function(t={}){let a,l=window,n=Math,i=2*n.PI,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))},f=(a=new AudioContext,l.zzfxV=1,(e=1,t=.05,n=220,i=0,o=0,r=.1,s=0,f=1,d=0,c=0,u=0,p=0,h=0,g=0,m=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let z=Math,D=2*z.PI,E=d*=500*D/44100/44100,P=n*=(1-t+2*t*z.random(t=[]))*D/44100,T=0,C=0,I=0,L=1,S=0,A=0,M=0,N=k<0?-1:1,q=D*N*k*2/44100,B=z.cos(q),H=z.sin,O=H(q)/4,V=1+O,W=-2*B/V,R=(1-O)/V,F=(1+N*B)/2/V,G=-(N+B)/V,X=0,Y=0,$=0,j=0;for(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,c*=500*D/85766121e6,m*=D/44100,u*=D/44100,p*=44100,h=44100*h|0,e*=.3*l.zzfxV,N=i+y+o+r+w|0;I<N;t[I++]=M*e)++A%(100*v|0)||(M=s?1<s?2<s?3<s?H(T*T):z.max(z.min(z.tan(T),1),-1):1-(2*T/D%2+2)%2:1-4*z.abs(z.round(T/D)-T/D):H(T),M=(h?1-b+b*H(D*I/h):1)*(M<0?-1:1)*z.abs(M)**f*(I<i?I/i:I<i+y?1-(I-i)/y*(1-x):I<i+y+o?x:I<N-w?(N-I-w)/r*x:0),M=w?M/2+(w>I?0:(I<N-w?1:(N-I)/w)*t[I-w|0]/2/e):M,k&&(M=j=F*X+G*(X=Y)+F*(Y=M)-R*$-W*($=j))),T+=(q=(n+=d+=c)*z.cos(m*C++))+q*g*H(I**5),L&&++L>p&&(n+=u,P+=u,L=0),!h||++S%h||(n=P,d=E,L=L||1);(e=a.createBuffer(1,N,44100)).getChannelData(0).set(t),(n=a.createBufferSource()).buffer=e,n.connect(a.destination),n.start()});t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let d=!1,c=!0,u,p=1,h,g=.5,m=1,v,w=1e3/60,x,y,b=3,k="sans-serif",z=20,D=1.2,E=Date.now(),P=e,T=[],C=[.5,0,1750,,,.3,1,,,,600,.1],I={},L={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:i/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?L.clamp(o,l,n):o},norm:(e,t,a)=>L.map(e,t,a,0,1),wave:(e,t,a,l=Math.sin)=>e+(l(a)+1)/2*(t-e),rand:(e=0,t=1)=>(E=(1664525*E+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(L.rand(e,t+1)),rseed(e){E=~~e},cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):L.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),L.stroke(n)},rectfill(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),L.fill(n)},circ(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),L.stroke(l)},circfill(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),L.fill(l)},oval(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),L.stroke(n)},ovalfill(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),L.fill(n)},shape(e){h.beginPath();for(let t=0;t<e.length;t++)0===t?h.moveTo(~~e[t][0],~~e[t][1]):h.lineTo(~~e[t][0],~~e[t][1]);h.lineTo(~~e[0][0],~~e[0][1])},line(e,t,a,l,n){h.beginPath();let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);h.moveTo(~~e+i,~~t+o),h.lineTo(~~a+i,~~l+o),L.stroke(n)},linewidth(e){h.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,l=b,n="normal"){h.font=`${n} ${z}px ${k}`,h.fillStyle=q(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)h.fillText(i[a],~~e,~~t+z*D*a)},textgap(e){D=e},textfont(e){k=e},textsize(e){z=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},spr(e,t,a){let l=a.trim().split("\n");for(let a=0;a<l.length;a++){let n=l[a].trim();for(let l=0;l<n.length;l++){let i=n[l];"."!==i&&" "!==i&&L.rectfill(e+l,t+a,1,1,parseInt(i,36)||0)}}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=h;return n.width=e*i,n.height=t*i,(h=n.getContext("2d")).scale(i,i),a(h),h=o,n.transferToImageBitmap()},ctx:e=>(e&&(h=e),h),push(){h.save()},pop(){h.restore()},translate(e,t){h.translate(~~e,~~t)},scale(e,t){h.scale(e,t||e)},rotate(e){h.rotate(e)},alpha(e){h.globalAlpha=L.clamp(e,0,1)},fill(e){h.fillStyle=q(e),h.fill()},stroke(e){h.strokeStyle=q(e),h.stroke()},clip(e){h.beginPath(),e(h),h.clip()},sfx:(e,t=0,a=1)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||C,(0!==t||1!==a)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),f.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>u,use(e,t={}){var a=e,l=t;let n=a(L,l);for(let e in n)L.def(e,n[e])},listen:(e,t)=>(I[e=e.toLowerCase()]=I[e]||new Set,I[e].add(t),()=>I&&I[e].delete(t)),emit(e,t,a,l,n){d&&(N("before:"+(e=e.toLowerCase()),t,a,l,n),N(e,t,a,l,n),N("after:"+e,t,a,l,n))},pal(t,a=3){P=t||e,T=[],b=a},palc(e,t){null==e?T=[]:T[e]=t},def(e,a){L[e]=a,t.global&&(l[e]=a)},timescale(e){m=e},framerate(e){w=1e3/~~e},stat(e){let a={index:e,value:[t,d,w/1e3,p,I,P,C,m,l.zzfxV,E,z,k,T,D][e]};return L.emit("stat",a),a.value},pause(){c=!0,cancelAnimationFrame(y)},resume(){d&&c&&(c=!1,x=w,v=Date.now(),y=o(A))},paused:()=>c,quit(){for(let e of(L.emit("quit"),L.pause(),d=!1,I={},r))e();if(t.global){for(let e in L)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))L[e]=n[e];function S(){if(t.autoscale&&s(l,"resize",M),t.tapEvents){let e=e=>[(e.pageX-u.offsetLeft)/p,(e.pageY-u.offsetTop)/p],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:Date.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&Date.now()-e.t<=300,o=!1;s(u,"mousedown",t=>{if(0===t.button){t.preventDefault();let[l,n]=e(t);L.emit("tap",l,n,0),a(0,l,n),o=!0}}),s(u,"mouseup",a=>{if(0===a.button){a.preventDefault();let l=t.get(0),[n,r]=e(a);i(l)&&L.emit("tapped",l.xi,l.yi,0),L.emit("untap",n,r,0),t.delete(0),o=!1}}),s(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);L.def("MX",a),L.def("MY",l),o&&(L.emit("tapping",a,l,0),n(0,a,l))}),s(u,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);L.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(u,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a);L.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let r=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&L.emit("tapped",l.xi,l.yi,e),L.emit("untap",l.x,l.y,e),t.delete(e))};s(u,"touchend",r),s(u,"touchcancel",r),s(l,"blur",()=>{for(let[e,a]of(o=!1,t))L.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";s(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear()),L.listen("after:update",()=>t.clear()),L.def("iskeydown",t=>a(e,t)),L.def("iskeypressed",e=>a(t,e)),L.def("lastkey",()=>n)}d=!0,L.emit("init",L),L.resume()}function A(){y=o(A);let e=Date.now(),t=0,a=e-v;for(v=e,x+=a<100?a:w;x>=w;){t++,x-=w;let e=w/1e3*m;L.emit("update",e,t),L.def("T",L.T+e)}t&&(L.emit("draw",h),t>1&&(x=0))}function M(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(L.def("W",e),L.def("H",a),u.width=e,u.height=a,t.autoscale){let l=+t.autoscale;u.style.display||(u.style.display="block",u.style.margin="auto"),p=n.min(innerWidth/e,innerHeight/a),p=l>1&&p>l?l:p,u.style.width=e*p+"px",u.style.height=a*p+"px"}h.imageSmoothingEnabled=!1,L.textalign("start","top"),L.emit("resized",p)}function N(e,t,a,l,n){if(I[e])for(let i of I[e])i(t,a,l,n)}function q(e){return P[~~(T[e]??e)%P.length]}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,L),l.ENGINE=L}h=(u=(u="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),s(u,"click",()=>focus()),M(),u.parentNode||document.body.appendChild(u),u.style.imageRendering="pixelated",u.oncontextmenu=()=>!1;let B=t.loop?t.loop:l;for(let e of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))B[e]&&L.listen(e,B[e]);return"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(S)):y=o(S),L}})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "litecanvas",
3
- "version": "0.100.1",
3
+ "version": "0.102.0",
4
4
  "description": "Lightweight HTML5 canvas 2D game engine suitable for small projects and creative coding. Inspired by PICO-8 and p5.js/Processing.",
5
5
  "license": "MIT",
6
6
  "author": "Luiz Bills <luizbills@pm.me>",
@@ -33,7 +33,7 @@
33
33
  "devDependencies": {
34
34
  "@happy-dom/global-registrator": "^18.0.1",
35
35
  "@size-limit/preset-small-lib": "^11.2.0",
36
- "@swc/core": "^1.15.0",
36
+ "@swc/core": "^1.15.2",
37
37
  "ava": "^6.4.1",
38
38
  "esbuild": "^0.25.12",
39
39
  "genversion": "^3.2.0",
package/src/index.js CHANGED
@@ -68,6 +68,8 @@ export default function litecanvas(settings = {}) {
68
68
  _accumulated,
69
69
  /** @type {number?} */
70
70
  _rafid,
71
+ /** @type {number} */
72
+ _defaultTextColor = 3,
71
73
  /** @type {string} */
72
74
  _fontFamily = 'sans-serif',
73
75
  /** @type {number} */
@@ -568,6 +570,32 @@ export default function litecanvas(settings = {}) {
568
570
  instance.fill(color)
569
571
  },
570
572
 
573
+ /**
574
+ * Make a custom shape in the canvas context.
575
+ * Then, just use `fill` or `stroke` to draw the shape.
576
+ *
577
+ * @param {number[]} points an array of Xs and Ys coordinates
578
+ */
579
+ shape(points) {
580
+ DEV: assert(
581
+ Array.isArray(points),
582
+ '[litecanvas] shape() 1st param must be an array of numbers'
583
+ )
584
+ DEV: assert(
585
+ points.length >= 6,
586
+ '[litecanvas] shape() 1st param must be an array with at least 6 numbers (3 points)'
587
+ )
588
+ beginPath(_ctx)
589
+ for (let i = 0; i < points.length; i++) {
590
+ if (0 === i) {
591
+ _ctx.moveTo(~~points[i][0], ~~points[i][1])
592
+ } else {
593
+ _ctx.lineTo(~~points[i][0], ~~points[i][1])
594
+ }
595
+ }
596
+ _ctx.lineTo(~~points[0][0], ~~points[0][1])
597
+ },
598
+
571
599
  /**
572
600
  * Draw a line
573
601
  *
@@ -646,10 +674,10 @@ export default function litecanvas(settings = {}) {
646
674
  * @param {number} x
647
675
  * @param {number} y
648
676
  * @param {string} message the text message
649
- * @param {number} [color=3] the color index
677
+ * @param {number} [color] the color index
650
678
  * @param {string} [fontStyle] can be "normal" (default), "italic" and/or "bold".
651
679
  */
652
- text(x, y, message, color = 3, fontStyle = 'normal') {
680
+ text(x, y, message, color = _defaultTextColor, fontStyle = 'normal') {
653
681
  DEV: assert(isNumber(x), '[litecanvas] text() 1st param must be a number')
654
682
  DEV: assert(isNumber(y), '[litecanvas] text() 2nd param must be a number')
655
683
  DEV: assert(
@@ -747,27 +775,25 @@ export default function litecanvas(settings = {}) {
747
775
  },
748
776
 
749
777
  /**
750
- * Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
778
+ * Draw a sprite pixel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
751
779
  *
752
780
  * @param {number} x
753
781
  * @param {number} y
754
- * @param {number} width
755
- * @param {number} height
756
782
  * @param {string} pixels
757
783
  */
758
- spr(x, y, width, height, pixels) {
784
+ spr(x, y, pixels) {
759
785
  DEV: assert(isNumber(x), '[litecanvas] spr() 1st param must be a number')
760
786
  DEV: assert(isNumber(y), '[litecanvas] spr() 2nd param must be a number')
761
- DEV: assert(isNumber(width), '[litecanvas] spr() 3rd param must be a number')
762
- DEV: assert(isNumber(height), '[litecanvas] spr() 4th param must be a number')
763
- DEV: assert('string' === typeof pixels, '[litecanvas] spr() 5th param must be a string')
764
-
765
- const chars = pixels.replace(/\s/g, '')
766
- for (let gridx = 0; gridx < width; gridx++) {
767
- for (let gridy = 0; gridy < height; gridy++) {
768
- const char = chars[width * gridy + gridx] || '.'
769
- if (char !== '.') {
770
- instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 36) || 0)
787
+ DEV: assert('string' === typeof pixels, '[litecanvas] spr() 3rd param must be a string')
788
+
789
+ const rows = pixels.trim().split('\n')
790
+
791
+ for (let row = 0; row < rows.length; row++) {
792
+ const chars = rows[row].trim()
793
+ for (let col = 0; col < chars.length; col++) {
794
+ const char = chars[col]
795
+ if (char !== '.' && char !== ' ') {
796
+ instance.rectfill(x + col, y + row, 1, 1, parseInt(char, 36) || 0)
771
797
  }
772
798
  }
773
799
  }
@@ -1088,15 +1114,22 @@ export default function litecanvas(settings = {}) {
1088
1114
  /**
1089
1115
  * Set new palette colors or restore the default palette.
1090
1116
  *
1091
- * @param {string[]} [colors]
1117
+ * @param {string[]} [colors] an array of colors
1118
+ * @param {number} [textColor] the default text color this palette
1092
1119
  */
1093
- pal(colors = defaultPalette) {
1120
+ pal(colors, textColor = 3) {
1094
1121
  DEV: assert(
1095
1122
  Array.isArray(colors) && colors.length > 0,
1096
- '[litecanvas] pal() 1st param must be a array of strings'
1123
+ '[litecanvas] pal() 1st param must be a array of color strings'
1124
+ )
1125
+ DEV: assert(
1126
+ isNumber(textColor) && textColor >= 0,
1127
+ '[litecanvas] pal() 2nd param must be a positive number or zero'
1097
1128
  )
1098
- _colorPalette = colors
1129
+
1130
+ _colorPalette = colors || defaultPalette
1099
1131
  _colorPaletteState = []
1132
+ _defaultTextColor = textColor
1100
1133
  },
1101
1134
 
1102
1135
  /**
@@ -1118,6 +1151,7 @@ export default function litecanvas(settings = {}) {
1118
1151
  isNumber(a) ? isNumber(b) && b >= 0 : null == b,
1119
1152
  '[litecanvas] palc() 2nd param must be a positive number'
1120
1153
  )
1154
+
1121
1155
  if (a == null) {
1122
1156
  _colorPaletteState = []
1123
1157
  } else {
package/src/palette.js CHANGED
@@ -1,16 +1,2 @@
1
- export const defaultPalette = [
2
- '#111',
3
- '#6a7799',
4
- '#aec2c2',
5
- '#FFF1E8',
6
-
7
- '#e83b3b',
8
- '#fabc20',
9
- '#155fd9',
10
- '#3cbcfc',
11
-
12
- '#327345',
13
- '#63c64d',
14
- '#6c2c1f',
15
- '#ac7c00',
16
- ]
1
+ /** colors based on https://lospec.com/palette-list/2bit-demichrome */
2
+ export const defaultPalette = ['#211e20', '#555568', '#a0a08b', '#e9efec']
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.100.1'
2
+ export const version = '0.102.0'
package/src/web.js CHANGED
@@ -1,3 +1,3 @@
1
1
  import litecanvas from './index.js'
2
2
 
3
- globalThis.litecanvas = litecanvas
3
+ window.litecanvas = litecanvas
package/types/global.d.ts CHANGED
@@ -296,6 +296,19 @@ declare global {
296
296
  * @param [color=0] the color index
297
297
  */
298
298
  function ovalfill(x: number, y: number, radiusX: number, radiusY: number, color?: number): void
299
+ /**
300
+ * Make a custom shape in the canvas context.
301
+ * Then, just use `fill` or `stroke` to draw the shape.
302
+ *
303
+ * @param points an array of Xs and Ys coordinates
304
+ *
305
+ * @example ```
306
+ * // draw a 8x8 white triangle
307
+ * shape([4,0,8,8,0,8])
308
+ * fill(3)
309
+ * ```
310
+ */
311
+ function shape(points: number[]): void
299
312
  /**
300
313
  * Draw a line
301
314
  *
@@ -374,19 +387,17 @@ declare global {
374
387
  */
375
388
  function image(x: number, y: number, source: CanvasImageSource): void
376
389
  /**
377
- * Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number or a dot:
390
+ * Draw a sprite pixel by pixel represented by a string. Each pixel must be a base 36 number or a dot:
378
391
  *
379
392
  * - A base 36 number (`0-9` or `a-z`) represent a pixel color (supporting color palettes with max 36 colors).
380
393
  * - A dot (`.`) represent a transparent pixel.
381
- * - Spaces and lines breaks are ignored and can be used to improve the visualization.
394
+ * - Spaces are ignored and can be used to improve the visualization.
382
395
  *
383
396
  * @param x the position X of the first pixel
384
397
  * @param y the position Y of the first pixel
385
- * @param width the width of the sprite
386
- * @param height the height of the sprite
387
398
  * @param pixels
388
399
  */
389
- function spr(x: number, y: number, width: number, height: number, pixels: string): void
400
+ function spr(x: number, y: number, pixels: string): void
390
401
  /**
391
402
  * Draw in an OffscreenCanvas and returns its image.
392
403
  *
@@ -555,9 +566,10 @@ declare global {
555
566
  /**
556
567
  * Set new palette colors or restore the default palette.
557
568
  *
558
- * @param [colors]
569
+ * @param colors an array of colors
570
+ * @param textColor the new default text color (default: 3)
559
571
  */
560
- function pal(colors?: string[]): void
572
+ function pal(colors?: string[], textColor?: number): void
561
573
  /**
562
574
  * Replace the color "a" with color "b".
563
575
  *
package/types/types.d.ts CHANGED
@@ -290,6 +290,13 @@ type LitecanvasInstance = {
290
290
  * @param [color=0] the color index
291
291
  */
292
292
  ovalfill(x: number, y: number, radiusX: number, radiusY: number, color?: number): void
293
+ /**
294
+ * Make a custom shape in the canvas context.
295
+ * Then, just use `fill` or `stroke` to draw the shape.
296
+ *
297
+ * @param points an array of Xs and Ys coordinates
298
+ */
299
+ shape(points: number[]): void
293
300
  /**
294
301
  * Draw a line
295
302
  *
@@ -368,19 +375,17 @@ type LitecanvasInstance = {
368
375
  */
369
376
  image(x: number, y: number, source: CanvasImageSource): void
370
377
  /**
371
- * Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number or a dot:
378
+ * Draw a sprite pixel by pixel represented by a string. Each pixel must be a base 36 number or a dot:
372
379
  *
373
380
  * - A base 36 number (`0-9` or `a-z`) represent a pixel color (supporting color palettes with max 36 colors).
374
381
  * - A dot (`.`) represent a transparent pixel.
375
- * - Spaces and lines breaks are ignored and can be used to improve the visualization.
382
+ * - Spaces are ignored and can be used to improve the visualization.
376
383
  *
377
384
  * @param x the position X of the first pixel
378
385
  * @param y the position Y of the first pixel
379
- * @param width the width of the sprite
380
- * @param height the height of the sprite
381
386
  * @param pixels
382
387
  */
383
- spr(x: number, y: number, width: number, height: number, pixels: string): void
388
+ spr(x: number, y: number, pixels: string): void
384
389
  /**
385
390
  * Draw in an OffscreenCanvas and returns its image.
386
391
  *
@@ -552,9 +557,10 @@ type LitecanvasInstance = {
552
557
  /**
553
558
  * Set new palette colors or restore the default palette.
554
559
  *
555
- * @param [colors]
560
+ * @param colors an array of colors
561
+ * @param textColor the new default text color (default: 3)
556
562
  */
557
- pal(colors?: string[]): void
563
+ pal(colors?: string[], textColor?: number): void
558
564
  /**
559
565
  * Replace the color "a" with color "b".
560
566
  *