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 +46 -42
- package/dist/dist.dev.js +26 -1
- package/dist/dist.js +17 -0
- package/dist/dist.min.js +1 -1
- package/package.json +1 -1
- package/src/index.js +26 -0
- package/src/version.js +1 -1
- package/types/global.d.ts +13 -0
- package/types/types.d.ts +7 -0
package/README.md
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
123
|
-
text(0, 0, 'Hello!!!',
|
|
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
|
-
|
|
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=
|
|
157
|
-
circ(64, 96, 50,
|
|
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=
|
|
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
|
|
175
|
-
.
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
.
|
|
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, //
|
|
190
|
-
|
|
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=
|
|
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
|
-
|
|
208
|
-
|
|
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=
|
|
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
|
|
306
|
-
circfill(x, y, 32,
|
|
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
|
|
322
|
-
circfill(MX, MY, 32,
|
|
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=
|
|
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=
|
|
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.
|
|
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,
|
|
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.
|
|
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.
|
|
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
|
*
|