litecanvas 0.101.0 → 0.102.1

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
@@ -1,6 +1,7 @@
1
1
  <div align="center">
2
2
 
3
- ![logo](https://github.com/user-attachments/assets/cbff543a-17be-44e4-b4ce-f9ff0a0581bb)
3
+ <img width="128" height="128" alt="icon-128" src="https://github.com/user-attachments/assets/9dc09b77-6538-4fe9-8bc7-66204b57cf6e" />
4
+
4
5
 
5
6
  # Litecanvas
6
7
 
@@ -23,7 +24,6 @@ Litecanvas is a lightweight HTML5 canvas 2D engine suitable for small web games,
23
24
 
24
25
  - **Tiny**: Only `~4KB` (minified + gzipped).
25
26
  - **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
27
  - **ZzFX**: Play or create sound effects with [ZzFX](https://killedbyapixel.github.io/ZzFX/).
28
28
  - **Extensible**: Use or create [plugins](https://www.npmjs.com/search?q=keywords:litecanvas) to add functionalities or change the engine.
29
29
  - **Playground**: Access or install the [playground](https://litecanvas.js.org/) webapp to code and share games (even offline).
@@ -89,18 +89,9 @@ litecanvas({
89
89
 
90
90
  ### Colors
91
91
 
92
- Litecanvas has a default palette with 12 colors:
93
-
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 |
92
+ Litecanvas has a default palette with 4 colors:
102
93
 
103
- ![The litecanvas color palette](.github/_assets/palette.png)
94
+ <img src=".github/_assets/palette.png" src="The litecanvas color palette" style="2px solid #fff">
104
95
 
105
96
  Each time a Litecanvas' function ask for a color, you should use an of theses colors by its index.
106
97
 
@@ -110,6 +101,8 @@ let color = 3
110
101
  rectfill(0, 0, 32, 32, color)
111
102
  ```
112
103
 
104
+ > Note: You can customize the color palette using the `pal()` function. [Example](samples/custom-palette/custom-palette.js)
105
+
113
106
  ### Printing messages
114
107
 
115
108
  ```js
@@ -119,15 +112,17 @@ function draw() {
119
112
  // clear and fill the game screen with color #0 (black)
120
113
  cls(0)
121
114
 
122
- // print a red text at x=0, y=0
123
- text(0, 0, 'Hello!!!', 4)
115
+ // print a gray (color #1) text at x=0, y=0
116
+ text(0, 0, 'Hello!!!', 1)
124
117
 
125
118
  // use \n to break text lines
126
119
  text(0, 30, 'multi\nline\ntext')
127
120
  }
128
121
  ```
129
122
 
130
- [Live Demo](https://litecanvas.js.org?c=eJxVzEsKwkAMBuB9T%2FEXF52CYEG37j1EN3EadTBmZCb1gXh3pyqIIYs8PwnGnvRC2bVVtRvVW4iKIdHVtXhUKLFYwAtTAumAXRCBHRh7OjGyT8yKa7ADfJSYMOvgtkL%2B2L5%2FvWTXFfnrnFNQAyHxAONbKQ23dTfHfd29b6ahK33JZsMisa7rZo7Vjxgzo1dYxDYxHT%2BMBOX8Bywn4TSKhV6nba%2FTpmmr5wtwJEcj)
123
+ > By default, the texts are white (color #3).
124
+
125
+ [Live Demo](https://litecanvas.js.org?c=eJxVjM2OwjAMhO99iqn20ERCoogz932IXkxwIcI4q8TlRyvenbSLtGLky8x4PonGgfRKxfmmGScNFpPikOnmPH4bVK3XCMKUQXrAGEVgJ8aRLowSMrPiFu2EkCRlfPVwe6Fw9ss2SHF9Jb85PzmqgXDM9IB7LzYexvcaG%2B67foXHrl%2F%2B59BVX6%2F7ZpHUtm23wuYfNxXGoLCEfWY6%2F2EkKpcPwHYmXCaxOOjcDjo3nW%2BeL%2BleSpw%3D)
131
126
 
132
127
  ### Drawing shapes
133
128
 
@@ -153,12 +148,12 @@ function draw() {
153
148
 
154
149
  // draw a circle outline at x=64 and y=96
155
150
  // with radius=50
156
- // and color=5 (yellow)
157
- circ(64, 96, 50, 5)
151
+ // and color=1 (gray)
152
+ circ(64, 96, 50, 1)
158
153
  }
159
154
  ```
160
155
 
161
- [Live Demo](https://litecanvas.js.org?c=eJxljk0KwyAQhfc5xSwNBGJ%2BFLrwMKImCoOCMU1D6d2rabIoGZhBfeN7H7pklPRPuZC6qqbVq%2BSCBx3lRmp4V5BL4UJoVsu5bQ8NJKiAIcLkEI2GaFSSfkYDMsFLdBSk17CLnl6%2FNpdsHjpZMfSHao2bbcq3a6U8Hq5iALLZTFYfUjEvOaSjDfS5h%2F7sO5SLKkOENaHzJwwfT5gH%2F4OJUrt1EYze8xmQ3SCG7QdQXAkfG3jwBlgGYHX1%2BQLFaFeI)
156
+ [Live Demo](https://litecanvas.js.org?c=eJxljk0KwyAQhfc5xSwNBKL5gy48zKAmCqJgTNNQeveqTRYlwogzb3zvsyYqge6JK6mrat6ciMY7kAF3UsO7gnSEXQlNan63bdEAQXjrA8zGWiUhKBHRLVYBRnhxRgGdhIN39Pq1m6jTJaPmfVdUrcyiY%2BqulTwsrrwHsutEVhcpm%2BccwmgDXaq%2BO%2BsOZYJIEH6L1rgTZhpOmMf0BxNQmm3lI73nMyBLwOMXnz3JNDTwmBoYUzyrq88XCIBWlw%3D%3D)
162
157
 
163
158
  ### Drawing sprites
164
159
 
@@ -171,41 +166,50 @@ litecanvas({
171
166
  // each visible char is a pixel
172
167
  // numbers are colors
173
168
  // dots are transparent pixels
174
- let smile8x8 = `
175
- .555555.
176
- 55555555
177
- 55055055
178
- 55055055
179
- 55555555
180
- 50555505
181
- 55000055
182
- .555555.`
169
+ let smile = `
170
+ .333333.
171
+ 33333333
172
+ 33033033
173
+ 33033033
174
+ 33333333
175
+ 30333303
176
+ 33000033
177
+ .333333.`
183
178
 
184
179
  function draw() {
185
180
  cls(0)
186
181
 
187
182
  spr(
188
183
  0,
189
- 0, // the sprite Position X Y
190
- smile8x8 // the sprite Pixels
184
+ 0, // position X Y
185
+ smile // the pixels
191
186
  )
192
187
  }
193
188
  ```
194
189
 
195
- [Live Demo](https://litecanvas.js.org?c=eJxtUMtqwzAQvOsr5mhDSNxCIBR67x%2B0vUWR1UigSEa7zoOQf%2B9KdkwPHfawuzOzSBM8W6PjWVNzV8DF9%2Bze8PK6U49Wqc0GtzRCBDDZaragIYuDRMgOxNnHIxWZ1cbh7MkfgoVxOsMTNAZ%2FtaHwcTwdbJZVFjqFlKurTzytOOtIg3SRJw%2BpYBl08nLuHXt5GrDeVqzrsJ0xD12t%2F4a%2Fsq603SITzMzz9F6pnzEa9imiz%2FrStLhXgQnUdJJI6SWDpjYF3aqU%2FGVI5KvvC98Lu1uVEnbKDZ8lX%2BjY48P6o%2BNFOP1UhOzsM4Gyb9XjF0Vyb7o%3D)
190
+ [Live Demo](https://litecanvas.js.org?c=eJxtUDFuwzAM3PWKG22gSNRmKQr0H80WRVZrAopkiHTSIsjfS8lO0KEHDkfeHSEqkgTv0tlxdzXAhQYZ3%2FD88mpuvTHbLX7yDDXAl%2BAkgKeiCVajjGAplL642oLzI87EdIwBfnQFxHCY6DvEqqf5dAxFR0XlHHNpqSHLMpLiEk%2FKkiwZNjEI%2BES67h0HfRqw2TVsWrNbsTa21X%2FNX5ut1D5silW5rz4Y8zknL5QThuIuXY9rM%2FjIndUfqVz%2FoGukwj7V0lumzNRyH9g%2F1OUAVWUM98PqvDe3Xw5%2FZEM%3D)
196
191
 
197
192
  ### Creating and drawing images
198
193
 
199
194
  ```js
200
195
  litecanvas()
201
196
 
202
- // lets create flag of Japan
197
+ // lets create a flag of Japan
203
198
  let japanFlag = paint(
204
199
  48,
205
200
  32, // the image width and height
201
+
202
+ // we call theses operations once to create a image
206
203
  function () {
207
- cls(3) // white background
208
- circfill(24, 16, 8, 4) // red circle
204
+ // lets modify the litecanvas palette to white and red
205
+ pal(['#fff', '#bd0029'])
206
+
207
+ // lets draw the flag
208
+ cls(0) // the white
209
+ circfill(24, 16, 8, 1) // the sun
210
+
211
+ // reset the palette
212
+ pal()
209
213
  },
210
214
  {
211
215
  // you can scale your image
@@ -217,7 +221,7 @@ let japanFlag = paint(
217
221
  function draw() {
218
222
  cls(0)
219
223
 
220
- // draw the japanFlag image
224
+ // draw the our generated japanFlag image
221
225
  image(
222
226
  W / 2 - japanFlag.width / 2, // game screen center X
223
227
  H / 2 - japanFlag.height / 2, // game screen center Y
@@ -226,7 +230,7 @@ function draw() {
226
230
  }
227
231
  ```
228
232
 
229
- [Live Demo](https://litecanvas.js.org?c=eJxtUctOwzAQvPsr5phIgdA0QgipV4T4AeC4dTaJi%2BtUjkNUof47toOcqmJPXs%2FMPma1cizJfNOY5UKUJTS7EdIyOUarqcPQ4o1OZIRHcAivl%2FC9w4mUcZmAj%2FqpwLYq4PWuZ6gjdYxZNa4HmQY9q653kdlORjo1GGQ5fuJPCKnHbJsH%2Bdz7gbAn%2BdXZYTLNSlFWtkrrrKoLbB4L%2BJZ1lFhuIqo5ki%2FFVWEPn4cJfkOMkjSHzC7zXXP2ZzTc0qRdsfB2mwTH%2FBn1Ulx4l9IOjaU57RF2ePDoX8mARTNWy9a28ZWlFu9lhbuVeB%2BdK72foVBHR%2FZDWGYDycaxxUdSvt4oF6fL5RT%2FKD%2BTch3rNq6PGOm5uPwCs6aXUg%3D%3D)
233
+ [Live Demo](https://litecanvas.js.org?c=eJx9Uk1rwzAMvftXCHpIAtnaZmV0g17H2B%2FYxtjBdeTEw3WK4yyU0f8%2BRemclsJ88Yeenp6eZU1AJd23bNNMiPkcLIYWlEcZECRoKytoNLzIvXSCYvA1nJ6G5w3spXEhFUBrtc55vytyIJZQI5idrBB6U4YapCuhRlPVQTCMID2CktYO0BZbaPboZTCNo6NTCKGZVDAT5%2BnOqQEEaQY%2F%2FHJiY9m7pjT6wMVt7ItUUjAwY1%2BbgZDEeCxjOgHSj2SmtU5ySGbbcrEoHpLPTFwVKL3smX7wJUaVbdNF9tc215hixittrE2LVQ7L%2BxzWtEVs27mLIp6sCBw5ib7QmPHtOBp90f2h6chMBy05isPNn3l2wmwPUKKWnQ35iNssY5jvj7AaqY%2BCWo9ODz1Ht8dW4x9GP6apmOryKY01XmEOBdxM0NtxNOiVR6aSOzKE%2FhwdKHQBPbzF5Oer5HGa%2Fst%2Bj9mTuvPR5HAmjr8pYdU3)
230
234
 
231
235
  > 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.
232
236
 
@@ -302,8 +306,8 @@ function draw() {
302
306
  cls(0)
303
307
 
304
308
  if (x != null) {
305
- // Draw a red circle wherever you tap
306
- circfill(x, y, 32, 4)
309
+ // Draw a white circle wherever you tap
310
+ circfill(x, y, 32, 3)
307
311
  }
308
312
  }
309
313
  ```
@@ -318,8 +322,8 @@ litecanvas()
318
322
  function draw() {
319
323
  cls(0)
320
324
 
321
- // draw a red circle in the mouse cursor's position
322
- circfill(MX, MY, 32, 4)
325
+ // draw a white circle in the mouse cursor's position
326
+ circfill(MX, MY, 32, 3)
323
327
  }
324
328
  ```
325
329
 
@@ -343,9 +347,9 @@ You can find a complete list of everything litecanvas has to offer on our [cheat
343
347
  Try some demos in the playground:
344
348
 
345
349
  - [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)
346
- - [Scroller](https://litecanvas.js.org?c=eJxVUM1SgzAQvvMU68FpAhFDLVpH%2BxbOcOj0ECGUzATSIYsyOn13NwXRHpJNvv1%2BkrUGdam6D%2BUZj6J66Eo0rgPTGQTG4TsCaLX36qhhB6tC29K1GtCBXYQ3KyKN1C6onpSl034jcvEonsRWPItMiiw7ROd%2F9sOpUqiBVThFePMV%2FIv7OSu1ujtiQ52G4FxeAu528CAlxFDhHNiqkY0C1pJfuVe9%2Bvx9fGk9ozZA7XpgViMYEsoXKq9wnUZYkkwqgMBEYr4lTKZZbPiC0kLdh%2FRZ7Yd3jz0zArI%2FVumsCySax762zvUM4%2FyWbnMYP1yoqEcMn2dh4wvExsTEAYpluhXQJGuZeNORx4bHjZjfIKaUIDvTAH4AEIGEgw%3D%3D)
350
+ - [Scroller](https://litecanvas.js.org?c=eJxVUM1uhCAQvvsU00OzgNSi202atPsWTTxs9kAVVxKUjYytabPv3mG1tnuAgW%2B%2BHxhn0VS6%2F9CB8SRpxr5C63uwvUVgHL4TgM6EoE8G9rApjat8ZwA9uFV4tyHSRO2S6lk7Oh1yWcjtMbn8sxzPtUYDrMbZNtiv6Fk%2BLv6ZM%2F0JW%2Bq0BO%2FU1fRhD1ulQECNS0inJzZJKBS%2Fca8H%2Ffn74MoFRm2Axg%2FAnEGwJFQvVF7hNo2wNJ1VAJGJxHxLmcpyYfmK0kIzxPRFHcb3gAOzEvI%2FVuWdjySawaFx3g8Mxe6ebksYP16paCaMn2dx4yvEptSKCAmVPUto00Klwfbk8cRFK5c3yDklyi40gB98w4Iz)
347
351
  - [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)
348
- - [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)
352
+ - [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)
349
353
 
350
354
  > _See other demos in [samples](/samples) folder_
351
355
 
package/dist/dist.dev.js CHANGED
@@ -19,7 +19,7 @@
19
19
  };
20
20
 
21
21
  // src/version.js
22
- var version = "0.101.0";
22
+ var version = "0.102.1";
23
23
 
24
24
  // src/index.js
25
25
  function litecanvas(settings = {}) {
@@ -468,6 +468,31 @@
468
468
  _ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
469
469
  instance.fill(color);
470
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 += 2) {
488
+ if (0 === i) {
489
+ _ctx.moveTo(~~points[i], ~~points[i + 1]);
490
+ } else {
491
+ _ctx.lineTo(~~points[i], ~~points[i + 1]);
492
+ }
493
+ }
494
+ _ctx.lineTo(~~points[0], ~~points[1]);
495
+ },
471
496
  /**
472
497
  * Draw a line
473
498
  *
package/dist/dist.js CHANGED
@@ -309,6 +309,23 @@
309
309
  _ctx.ellipse(~~x, ~~y, ~~radiusX, ~~radiusY, 0, 0, TWO_PI);
310
310
  instance.fill(color);
311
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 += 2) {
321
+ if (0 === i) {
322
+ _ctx.moveTo(~~points[i], ~~points[i + 1]);
323
+ } else {
324
+ _ctx.lineTo(~~points[i], ~~points[i + 1]);
325
+ }
326
+ }
327
+ _ctx.lineTo(~~points[0], ~~points[1]);
328
+ },
312
329
  /**
313
330
  * Draw a line
314
331
  *
package/dist/dist.min.js CHANGED
@@ -1 +1 @@
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,C=0,I=0,T=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;T<N;t[T++]=M*e)++A%(100*v|0)||(M=s?1<s?2<s?3<s?H(C*C):z.max(z.min(z.tan(C),1),-1):1-(2*C/D%2+2)%2:1-4*z.abs(z.round(C/D)-C/D):H(C),M=(h?1-b+b*H(D*T/h):1)*(M<0?-1:1)*z.abs(M)**f*(T<i?T/i:T<i+y?1-(T-i)/y*(1-x):T<i+y+o?x:T<N-w?(N-T-w)/r*x:0),M=w?M/2+(w>T?0:(T<N-w?1:(N-T)/w)*t[T-w|0]/2/e):M,k&&(M=j=F*X+G*(X=Y)+F*(Y=M)-R*$-W*($=j))),C+=(q=(n+=d+=c)*z.cos(m*I++))+q*g*H(T**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,C=[],I=[.5,0,1750,,,.3,1,,,,600,.1],T={},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)},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||I,(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)=>(T[e=e.toLowerCase()]=T[e]||new Set,T[e].add(t),()=>T&&T[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,C=[],b=a},palc(e,t){null==e?C=[]:C[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,T,P,I,m,l.zzfxV,E,z,k,C,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,T={},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(T[e])for(let i of T[e])i(t,a,l,n)}function q(e){return P[~~(C[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}})();
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+=2)0===t?h.moveTo(~~e[t],~~e[t+1]):h.lineTo(~~e[t],~~e[t+1]);h.lineTo(~~e[0],~~e[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.101.0",
3
+ "version": "0.102.1",
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>",
package/src/index.js CHANGED
@@ -570,6 +570,32 @@ export default function litecanvas(settings = {}) {
570
570
  instance.fill(color)
571
571
  },
572
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 += 2) {
590
+ if (0 === i) {
591
+ _ctx.moveTo(~~points[i], ~~points[i + 1])
592
+ } else {
593
+ _ctx.lineTo(~~points[i], ~~points[i + 1])
594
+ }
595
+ }
596
+ _ctx.lineTo(~~points[0], ~~points[1])
597
+ },
598
+
573
599
  /**
574
600
  * Draw a line
575
601
  *
package/src/version.js CHANGED
@@ -1,2 +1,2 @@
1
1
  // Generated by genversion.
2
- export const version = '0.101.0'
2
+ export const version = '0.102.1'
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
  *
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
  *