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 +53 -49
- package/dist/dist.dev.js +51 -36
- package/dist/dist.js +36 -31
- package/dist/dist.min.js +1 -1
- package/package.json +2 -2
- package/src/index.js +54 -20
- package/src/palette.js +2 -16
- package/src/version.js +1 -1
- package/src/web.js +1 -1
- package/types/global.d.ts +19 -7
- package/types/types.d.ts +13 -7
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
|
|
91
|
+
Litecanvas has a default palette with 4 colors:
|
|
93
92
|
|
|
94
|
-
|
|
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
|
-

|
|
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
|
|
123
|
-
text(0, 0, 'Hello!!!',
|
|
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
|
-
|
|
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=
|
|
158
|
-
circ(64, 96, 50,
|
|
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=
|
|
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
|
-
|
|
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
|
|
176
|
-
.
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
.
|
|
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,
|
|
190
|
-
|
|
191
|
-
|
|
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=
|
|
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,
|
|
198
|
+
48,
|
|
199
|
+
32, // the image width and height
|
|
200
|
+
|
|
201
|
+
// we call theses operations once to create a image
|
|
206
202
|
function () {
|
|
207
|
-
|
|
208
|
-
|
|
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,
|
|
222
|
-
H/2 - japanFlag.height/2, // game screen center Y
|
|
223
|
-
japanFlag
|
|
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=
|
|
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
|
|
305
|
-
circfill(x, y, 32,
|
|
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
|
|
321
|
-
circfill(MX, MY, 32,
|
|
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=
|
|
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=
|
|
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.
|
|
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
|
|
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 =
|
|
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
|
|
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,
|
|
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(
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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,
|
|
441
|
-
const
|
|
442
|
-
for (let
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
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 =
|
|
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
|
-
|
|
1108
|
+
window.litecanvas = litecanvas;
|
|
1104
1109
|
})();
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=["#
|
|
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.
|
|
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.
|
|
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
|
|
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 =
|
|
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
|
|
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,
|
|
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(
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
for (let
|
|
768
|
-
const char = chars[
|
|
769
|
-
if (char !== '.') {
|
|
770
|
-
instance.rectfill(x +
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
2
|
-
|
|
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.
|
|
2
|
+
export const version = '0.102.0'
|
package/src/web.js
CHANGED
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
*
|