litecanvas 0.99.0 → 0.100.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 +58 -42
- package/dist/dist.dev.js +29 -14
- package/dist/dist.js +25 -10
- package/dist/dist.min.js +1 -1
- package/package.json +13 -9
- package/src/index.js +32 -11
- package/src/version.js +1 -1
- package/types/global.d.ts +10 -1
- package/types/types.d.ts +10 -1
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
# Litecanvas
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/litecanvas/)
|
|
8
8
|
[](LICENSE)
|
|
9
9
|
|
|
10
10
|
Litecanvas is a lightweight HTML5 canvas 2D engine suitable for small web games, prototypes, game jams, animations, creative coding, learning game programming and game design, etc.
|
|
@@ -30,22 +30,24 @@ Litecanvas is a lightweight HTML5 canvas 2D engine suitable for small web games,
|
|
|
30
30
|
|
|
31
31
|
## Getting Started
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
You can get started using our [online playground](https://litecanvas.github.io) without installing nothing.
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
If you want to test locally, just use one of the installation options.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
### HTML/CDN
|
|
38
38
|
|
|
39
|
-
|
|
40
|
-
npm i litecanvas
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
Or just create a HTML file and add a `<script>` tag with our CDN link:
|
|
39
|
+
Create a HTML file and add a `<script>` tag with our CDN link:
|
|
44
40
|
|
|
45
41
|
```html
|
|
46
42
|
<script src="https://unpkg.com/litecanvas"></script>
|
|
47
43
|
```
|
|
48
44
|
|
|
45
|
+
### Template
|
|
46
|
+
|
|
47
|
+
For those who are familiar with Node/NPM, we have a [basic template](https://github.com/litecanvas/template).
|
|
48
|
+
|
|
49
|
+
## API
|
|
50
|
+
|
|
49
51
|
### Basic game structure
|
|
50
52
|
|
|
51
53
|
```js
|
|
@@ -104,7 +106,7 @@ Each time a Litecanvas' function ask for a color, you should use an of theses co
|
|
|
104
106
|
|
|
105
107
|
```js
|
|
106
108
|
// example: draw a white rectangle
|
|
107
|
-
color = 3
|
|
109
|
+
let color = 3
|
|
108
110
|
rectfill(0, 0, 32, 32, color)
|
|
109
111
|
```
|
|
110
112
|
|
|
@@ -117,11 +119,17 @@ function draw() {
|
|
|
117
119
|
// clear and fill the game screen with color #0 (black)
|
|
118
120
|
cls(0)
|
|
119
121
|
|
|
120
|
-
// print a red
|
|
121
|
-
text(0, 0, 'Hello', 4)
|
|
122
|
+
// print a red text at x=0, y=0
|
|
123
|
+
text(0, 0, 'Hello!!!', 4)
|
|
124
|
+
|
|
125
|
+
// use \n to break text lines
|
|
126
|
+
text(0, 30, 'multi\nline\ntext')
|
|
122
127
|
}
|
|
123
128
|
```
|
|
124
129
|
|
|
130
|
+
[Live Demo](https://litecanvas.js.org?c=eJxVzEsKwkAMBuB9T%2FEXF52CYEG37j1EN3EadTBmZCb1gXh3pyqIIYs8PwnGnvRC2bVVtRvVW4iKIdHVtXhUKLFYwAtTAumAXRCBHRh7OjGyT8yKa7ADfJSYMOvgtkL%2B2L5%2FvWTXFfnrnFNQAyHxAONbKQ23dTfHfd29b6ahK33JZsMisa7rZo7Vjxgzo1dYxDYxHT%2BMBOX8Bywn4TSKhV6nba%2FTpmmr5wtwJEcj)
|
|
131
|
+
|
|
132
|
+
|
|
125
133
|
### Drawing shapes
|
|
126
134
|
|
|
127
135
|
You can use the following functions to draw shapes:
|
|
@@ -139,18 +147,20 @@ litecanvas()
|
|
|
139
147
|
function draw() {
|
|
140
148
|
cls(0)
|
|
141
149
|
|
|
142
|
-
// draw a color filled rectangle at x=
|
|
150
|
+
// draw a color filled rectangle at x=10 and y=20
|
|
143
151
|
// with width=32 and height=32
|
|
144
152
|
// and color=3 (white)
|
|
145
|
-
rectfill(
|
|
153
|
+
rectfill(10, 20, 32, 32, 3)
|
|
146
154
|
|
|
147
|
-
// draw a circle outline at x=64 and y=
|
|
148
|
-
// with radius=
|
|
155
|
+
// draw a circle outline at x=64 and y=96
|
|
156
|
+
// with radius=50
|
|
149
157
|
// and color=5 (yellow)
|
|
150
|
-
circ(64,
|
|
158
|
+
circ(64, 96, 50, 5)
|
|
151
159
|
}
|
|
152
160
|
```
|
|
153
161
|
|
|
162
|
+
[Live Demo](https://litecanvas.js.org?c=eJxljk0KwyAQhfc5xSwNBGJ%2BFLrwMKImCoOCMU1D6d2rabIoGZhBfeN7H7pklPRPuZC6qqbVq%2BSCBx3lRmp4V5BL4UJoVsu5bQ8NJKiAIcLkEI2GaFSSfkYDMsFLdBSk17CLnl6%2FNpdsHjpZMfSHao2bbcq3a6U8Hq5iALLZTFYfUjEvOaSjDfS5h%2F7sO5SLKkOENaHzJwwfT5gH%2F4OJUrt1EYze8xmQ3SCG7QdQXAkfG3jwBlgGYHX1%2BQLFaFeI)
|
|
163
|
+
|
|
154
164
|
### Drawing sprites
|
|
155
165
|
|
|
156
166
|
```js
|
|
@@ -162,7 +172,7 @@ litecanvas({
|
|
|
162
172
|
// each visible char is a pixel
|
|
163
173
|
// numbers are colors
|
|
164
174
|
// dots are transparent pixels
|
|
165
|
-
|
|
175
|
+
let smile8x8 = `
|
|
166
176
|
.555555.
|
|
167
177
|
55555555
|
|
168
178
|
55055055
|
|
@@ -176,26 +186,26 @@ function draw() {
|
|
|
176
186
|
cls(0)
|
|
177
187
|
|
|
178
188
|
spr(
|
|
179
|
-
0, 0,
|
|
180
|
-
8, 8,
|
|
181
|
-
|
|
189
|
+
0, 0, // position X Y
|
|
190
|
+
8, 8, // the sprite Width and Height
|
|
191
|
+
smile8x8 // the sprite Pixels
|
|
182
192
|
)
|
|
183
193
|
}
|
|
184
194
|
```
|
|
185
195
|
|
|
196
|
+
[Live Demo](https://litecanvas.js.org?c=eJxtUMtqwzAQvOsr5mhDSNxCIBR67x%2B0vUWR1UigSEa7zoOQf%2B9KdkwPHfawuzOzSBM8W6PjWVNzV8DF9%2Bze8PK6U49Wqc0GtzRCBDDZaragIYuDRMgOxNnHIxWZ1cbh7MkfgoVxOsMTNAZ%2FtaHwcTwdbJZVFjqFlKurTzytOOtIg3SRJw%2BpYBl08nLuHXt5GrDeVqzrsJ0xD12t%2F4a%2Fsq603SITzMzz9F6pnzEa9imiz%2FrStLhXgQnUdJJI6SWDpjYF3aqU%2FGVI5KvvC98Lu1uVEnbKDZ8lX%2BjY48P6o%2BNFOP1UhOzsM4Gyb9XjF0Vyb7o%3D)
|
|
197
|
+
|
|
186
198
|
### Creating and drawing images
|
|
187
199
|
|
|
188
200
|
```js
|
|
189
201
|
litecanvas()
|
|
190
202
|
|
|
191
|
-
// lets create
|
|
192
|
-
|
|
193
|
-
48, 32, // image width and height
|
|
203
|
+
// lets create flag of Japan
|
|
204
|
+
let japanFlag = paint(
|
|
205
|
+
48, 32, // the image width and height
|
|
194
206
|
function () {
|
|
195
|
-
//
|
|
196
|
-
|
|
197
|
-
rectfill(0, 0, 48, 32, 3)
|
|
198
|
-
circfill(24, 16, 8, 4)
|
|
207
|
+
cls(3) // white background
|
|
208
|
+
circfill(24, 16, 8, 4) // red circle
|
|
199
209
|
}, {
|
|
200
210
|
// you can scale your image
|
|
201
211
|
// by default, scale=1
|
|
@@ -206,25 +216,31 @@ const japan = paint(
|
|
|
206
216
|
function draw() {
|
|
207
217
|
cls(0)
|
|
208
218
|
|
|
209
|
-
//
|
|
210
|
-
image(
|
|
219
|
+
// draw the japanFlag image
|
|
220
|
+
image(
|
|
221
|
+
W/2 - japanFlag.width/2, // game screen center X
|
|
222
|
+
H/2 - japanFlag.height/2, // game screen center Y
|
|
223
|
+
japanFlag // the image
|
|
224
|
+
)
|
|
211
225
|
}
|
|
212
226
|
```
|
|
213
227
|
|
|
214
|
-
|
|
228
|
+
[Live Demo](https://litecanvas.js.org?c=eJxtUctOwzAQvPsr5phIgdA0QgipV4T4AeC4dTaJi%2BtUjkNUof47toOcqmJPXs%2FMPma1cizJfNOY5UKUJTS7EdIyOUarqcPQ4o1OZIRHcAivl%2FC9w4mUcZmAj%2FqpwLYq4PWuZ6gjdYxZNa4HmQY9q653kdlORjo1GGQ5fuJPCKnHbJsH%2Bdz7gbAn%2BdXZYTLNSlFWtkrrrKoLbB4L%2BJZ1lFhuIqo5ki%2FFVWEPn4cJfkOMkjSHzC7zXXP2ZzTc0qRdsfB2mwTH%2FBn1Ulx4l9IOjaU57RF2ePDoX8mARTNWy9a28ZWlFu9lhbuVeB%2BdK72foVBHR%2FZDWGYDycaxxUdSvt4oF6fL5RT%2FKD%2BTch3rNq6PGOm5uPwCs6aXUg%3D%3D)
|
|
215
229
|
|
|
216
|
-
|
|
230
|
+
> 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
|
+
|
|
232
|
+
You can also draw PNG/JPG image files, but you'll need to load them first:
|
|
217
233
|
|
|
218
234
|
```js
|
|
219
235
|
litecanvas()
|
|
220
236
|
|
|
221
|
-
let
|
|
237
|
+
let myImage
|
|
222
238
|
|
|
223
239
|
function init() {
|
|
224
240
|
// load a image from its URL
|
|
225
|
-
|
|
241
|
+
let img = new Image()
|
|
226
242
|
img.onload = () => {
|
|
227
|
-
|
|
243
|
+
myImage = img
|
|
228
244
|
}
|
|
229
245
|
img.src = 'https://litecanvas.js.org/icons/icon-128.png'
|
|
230
246
|
}
|
|
@@ -232,17 +248,19 @@ function init() {
|
|
|
232
248
|
function draw() {
|
|
233
249
|
cls(0)
|
|
234
250
|
|
|
235
|
-
if (!
|
|
251
|
+
if (!myImage) {
|
|
236
252
|
// if not loaded, show this message
|
|
237
253
|
text(10, 10, 'Loading image...')
|
|
238
254
|
} else {
|
|
239
255
|
// when loaded, draw the image file
|
|
240
|
-
image(0, 0,
|
|
256
|
+
image(0, 0, myImage)
|
|
241
257
|
}
|
|
242
258
|
}
|
|
243
259
|
```
|
|
244
260
|
|
|
245
|
-
|
|
261
|
+
[Live Demo](https://litecanvas.js.org?c=eJxVkMFOwzAMhu95CnNqKo1044SQyh1pJyQeIGrTNih1ptpQEOq742RtGVGSg%2F37s38Hz66x%2BGlJl0oFxzB%2Bv4y2d0p1H9iwjwgePesSfhTIqSoI0bZgwScZdFMcwTPB2%2Bs5CxLDjz3UgG6GzBJ0ykjURMzVNQiwfl6Z6axtJSOyHF32IpoaiRcD84WeqirsM5t3MnHqK99EpPzfnx4ezQX7Qi03DtrJzruDJpA%2BitlM70Dfra3Lm2nEpaQwcjbr2gPQEGfgwROMjigtaNOy%2B2J9Oh4gveIseo%2F9dTvGmOLqfQEXyP3vMA8Od34aUfhuW6sPfx1ySAtd7jbsuqLlFwWNf7A%3D)
|
|
262
|
+
|
|
263
|
+
If you need to load multiple assets (images, fonts, music, etc.), I recommend you the [Asset Loader Plugin](https://github.com/litecanvas/plugin-asset-loader).
|
|
246
264
|
|
|
247
265
|
### Keyboard
|
|
248
266
|
|
|
@@ -259,9 +277,7 @@ function update() {
|
|
|
259
277
|
}
|
|
260
278
|
|
|
261
279
|
// Returns the last key pressed in your keyboard.
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
console.log(key)
|
|
280
|
+
let key = lastkey()
|
|
265
281
|
}
|
|
266
282
|
```
|
|
267
283
|
|
|
@@ -325,7 +341,7 @@ You can find a complete list of everything litecanvas has to offer on our [cheat
|
|
|
325
341
|
|
|
326
342
|
Try some demos in the playground:
|
|
327
343
|
|
|
328
|
-
- [Bouncing Ball](https://litecanvas.js.org?c=
|
|
344
|
+
- [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)
|
|
329
345
|
- [Scroller](https://litecanvas.js.org?c=eJxVUM1SgzAQvvMU68FpAhFDLVpH%2BxbOcOj0ECGUzATSIYsyOn13NwXRHpJNvv1%2BkrUGdam6D%2BUZj6J66Eo0rgPTGQTG4TsCaLX36qhhB6tC29K1GtCBXYQ3KyKN1C6onpSl034jcvEonsRWPItMiiw7ROd%2F9sOpUqiBVThFePMV%2FIv7OSu1ujtiQ52G4FxeAu528CAlxFDhHNiqkY0C1pJfuVe9%2Bvx9fGk9ozZA7XpgViMYEsoXKq9wnUZYkkwqgMBEYr4lTKZZbPiC0kLdh%2FRZ7Yd3jz0zArI%2FVumsCySax762zvUM4%2FyWbnMYP1yoqEcMn2dh4wvExsTEAYpluhXQJGuZeNORx4bHjZjfIKaUIDvTAH4AEIGEgw%3D%3D)
|
|
330
346
|
- [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)
|
|
331
347
|
- [Rendering Benchmark](https://litecanvas.js.org?c=eJylVVtP2zAUfs%2BvsLpJSSCkSS9QurYTQkx7AAkB0x6qariJ21q4See40Az633dsp8G9UNDmB1Kf853j71yJ0iQTKEoTwVOWoS6K02g%2BJYnwI06wIBeMyJtjx%2FTRdq0V0KdJQvj3u6tLMLm3OqDtWQhOJwN9Mu6dTdN5ItqdanHXSowmnIy6la9YqbthEFR68KdTxW8gmhLR3IcAc%2Bnk4W1ETSFqexANhWjsQbQUorUHER5rIsd7MHVNpV5w6VRV3mT2UCZyRrqVWZpRQdOkjThhWNBHUil8RTh5xBmicbcSVXqdqr6vnNxbZeGGaZz7eDYjSeys6uVaG3r1nB%2BlLOVQQftTGIb2TsgQRw9jDuzj8xI8Go1sy2JEoDlnIEnIE%2Fpxc%2BmwNMKSvOspypmABgL1s7rJE6mmQIdg5mcE82hyjTmeZv6YQIvpJNkuenlBUFWvNHuisZi0QVZrvAonhI4n4KzRKpBLoEQF0Xlx9KOFpWLiq4vGroy1Qt%2B0Rpu3IcrItpaQNw3JZpyqYGaYwjgoaFjz1r79kpvtw2nAkV%2Fb25BjvEMeBFIeBFvymvRT25CfwKnDacJZkx8fn9TDsN4cDj8mf8OPfPcUzua7kudpq3W6zdP3pXxXvNKPIR%2Foz2tTZBFmpI3qqypCzkfzJJKNhGhCheMW4G%2FXt7%2BuLu4ubvyYZjOGc0fwOQF42Wx%2BRv%2FIIpk102XXoGoVQcMJGjGC1H6DN3TV1RqcFbqs6OkzzuER7Uy1rmuAYyqHoR966CgcKPkIxsORU0FBEXyBTwcZxiA4PHTXpkH6WQCYY5hVFx2YjYqOjJg2bPJtG93D%2B4z68cJDcT6QrEuVPMoTxFGX3iCsvhRQJ%2FBQ6A68f4EOyl9lSvtUPvyMgEMONBQVKLYuuVFBswblb8vIO6PJg%2Fl%2F6vec8PyWMBKJlDv3%2FfWN%2B%2FnZqMCyMrjXJaQjqBQ4Mssh78XSG8Ha%2FKkTCvtumLLYLpgujeaMOX4qmxNa65zBSkNiQoolokmzzAnc7fbDCZ3u67%2BNbPxHg3Ezk1AGq9Rzf4GOoJP8eGHI8kKWvwJluiS4gwLT%2F8oHkNmQxQt00IXBKMVLRFhGCkf5bkf5Lkf5pqNtVofm8PfMGdpN9t0h%2B1gMO5%2FVY7g7tvcH9QMxT%2FGYyKg96dRb23Ru2aN%2FASaYns8%3D)
|
package/dist/dist.dev.js
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
// src/version.js
|
|
35
|
-
var version = "0.
|
|
35
|
+
var version = "0.100.1";
|
|
36
36
|
|
|
37
37
|
// src/index.js
|
|
38
38
|
function litecanvas(settings = {}) {
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
keyboardEvents: true
|
|
51
51
|
};
|
|
52
52
|
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, _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 = {};
|
|
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 = {};
|
|
54
54
|
const instance = {
|
|
55
55
|
/** @type {number} */
|
|
56
56
|
W: 0,
|
|
@@ -545,7 +545,7 @@
|
|
|
545
545
|
},
|
|
546
546
|
/** TEXT RENDERING API */
|
|
547
547
|
/**
|
|
548
|
-
* Draw text
|
|
548
|
+
* Draw text. You can use `\n` to break lines.
|
|
549
549
|
*
|
|
550
550
|
* @param {number} x
|
|
551
551
|
* @param {number} y
|
|
@@ -566,7 +566,20 @@
|
|
|
566
566
|
);
|
|
567
567
|
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
|
|
568
568
|
_ctx.fillStyle = getColor(color);
|
|
569
|
-
|
|
569
|
+
const messages = ("" + message).split("\n");
|
|
570
|
+
for (let i = 0; i < messages.length; i++) {
|
|
571
|
+
_ctx.fillText(messages[i], ~~x, ~~y + _fontSize * _fontLineHeight * i);
|
|
572
|
+
}
|
|
573
|
+
},
|
|
574
|
+
/**
|
|
575
|
+
* Sets the height ratio of the text lines based on current text size.
|
|
576
|
+
*
|
|
577
|
+
* Default = `1.2`
|
|
578
|
+
*
|
|
579
|
+
* @param value
|
|
580
|
+
*/
|
|
581
|
+
textgap(value) {
|
|
582
|
+
_fontLineHeight = value;
|
|
570
583
|
},
|
|
571
584
|
/**
|
|
572
585
|
* Set the font family
|
|
@@ -619,10 +632,10 @@
|
|
|
619
632
|
* @param {number} y
|
|
620
633
|
* @param {CanvasImageSource} source
|
|
621
634
|
*/
|
|
622
|
-
image(x, y,
|
|
635
|
+
image(x, y, source2) {
|
|
623
636
|
DEV: assert(isNumber(x), "[litecanvas] image() 1st param must be a number");
|
|
624
637
|
DEV: assert(isNumber(y), "[litecanvas] image() 2nd param must be a number");
|
|
625
|
-
_ctx.drawImage(
|
|
638
|
+
_ctx.drawImage(source2, ~~x, ~~y);
|
|
626
639
|
},
|
|
627
640
|
/**
|
|
628
641
|
* Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
|
|
@@ -1031,7 +1044,9 @@
|
|
|
1031
1044
|
// 11
|
|
1032
1045
|
_fontFamily,
|
|
1033
1046
|
// 12
|
|
1034
|
-
_colorPaletteState
|
|
1047
|
+
_colorPaletteState,
|
|
1048
|
+
// 13
|
|
1049
|
+
_fontLineHeight
|
|
1035
1050
|
];
|
|
1036
1051
|
const data = { index, value: internals[index] };
|
|
1037
1052
|
instance.emit("stat", data);
|
|
@@ -1091,13 +1106,6 @@
|
|
|
1091
1106
|
instance[k] = math[k];
|
|
1092
1107
|
}
|
|
1093
1108
|
function init() {
|
|
1094
|
-
const source = settings.loop ? settings.loop : root;
|
|
1095
|
-
for (const event of _coreEvents.split(",")) {
|
|
1096
|
-
DEV: if (root === source && source[event]) {
|
|
1097
|
-
console.info(`[litecanvas] using window.${event}()`);
|
|
1098
|
-
}
|
|
1099
|
-
if (source[event]) instance.listen(event, source[event]);
|
|
1100
|
-
}
|
|
1101
1109
|
if (settings.autoscale) {
|
|
1102
1110
|
on(root, "resize", resizeCanvas);
|
|
1103
1111
|
}
|
|
@@ -1433,6 +1441,13 @@
|
|
|
1433
1441
|
DEV: console.info(`[litecanvas] version ${version} started`);
|
|
1434
1442
|
DEV: console.debug(`[litecanvas] litecanvas() options =`, settings);
|
|
1435
1443
|
setupCanvas();
|
|
1444
|
+
const source = settings.loop ? settings.loop : root;
|
|
1445
|
+
for (const event of _coreEvents.split(",")) {
|
|
1446
|
+
DEV: if (root === source && source[event]) {
|
|
1447
|
+
console.info(`[litecanvas] using window.${event}()`);
|
|
1448
|
+
}
|
|
1449
|
+
if (source[event]) instance.listen(event, source[event]);
|
|
1450
|
+
}
|
|
1436
1451
|
if ("loading" === document.readyState) {
|
|
1437
1452
|
on(root, "DOMContentLoaded", () => raf(init));
|
|
1438
1453
|
} else {
|
package/dist/dist.js
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
keyboardEvents: true
|
|
43
43
|
};
|
|
44
44
|
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, _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 = {};
|
|
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 = {};
|
|
46
46
|
const instance = {
|
|
47
47
|
/** @type {number} */
|
|
48
48
|
W: 0,
|
|
@@ -363,7 +363,7 @@
|
|
|
363
363
|
},
|
|
364
364
|
/** TEXT RENDERING API */
|
|
365
365
|
/**
|
|
366
|
-
* Draw text
|
|
366
|
+
* Draw text. You can use `\n` to break lines.
|
|
367
367
|
*
|
|
368
368
|
* @param {number} x
|
|
369
369
|
* @param {number} y
|
|
@@ -374,7 +374,20 @@
|
|
|
374
374
|
text(x, y, message, color = 3, fontStyle = "normal") {
|
|
375
375
|
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`;
|
|
376
376
|
_ctx.fillStyle = getColor(color);
|
|
377
|
-
|
|
377
|
+
const messages = ("" + message).split("\n");
|
|
378
|
+
for (let i = 0; i < messages.length; i++) {
|
|
379
|
+
_ctx.fillText(messages[i], ~~x, ~~y + _fontSize * _fontLineHeight * i);
|
|
380
|
+
}
|
|
381
|
+
},
|
|
382
|
+
/**
|
|
383
|
+
* Sets the height ratio of the text lines based on current text size.
|
|
384
|
+
*
|
|
385
|
+
* Default = `1.2`
|
|
386
|
+
*
|
|
387
|
+
* @param value
|
|
388
|
+
*/
|
|
389
|
+
textgap(value) {
|
|
390
|
+
_fontLineHeight = value;
|
|
378
391
|
},
|
|
379
392
|
/**
|
|
380
393
|
* Set the font family
|
|
@@ -412,8 +425,8 @@
|
|
|
412
425
|
* @param {number} y
|
|
413
426
|
* @param {CanvasImageSource} source
|
|
414
427
|
*/
|
|
415
|
-
image(x, y,
|
|
416
|
-
_ctx.drawImage(
|
|
428
|
+
image(x, y, source2) {
|
|
429
|
+
_ctx.drawImage(source2, ~~x, ~~y);
|
|
417
430
|
},
|
|
418
431
|
/**
|
|
419
432
|
* Draw a sprite pxiel by pixel represented by a string. Each pixel must be a base 36 number (0-9 or a-z) or a dot.
|
|
@@ -719,7 +732,9 @@
|
|
|
719
732
|
// 11
|
|
720
733
|
_fontFamily,
|
|
721
734
|
// 12
|
|
722
|
-
_colorPaletteState
|
|
735
|
+
_colorPaletteState,
|
|
736
|
+
// 13
|
|
737
|
+
_fontLineHeight
|
|
723
738
|
];
|
|
724
739
|
const data = { index, value: internals[index] };
|
|
725
740
|
instance.emit("stat", data);
|
|
@@ -774,10 +789,6 @@
|
|
|
774
789
|
instance[k] = math[k];
|
|
775
790
|
}
|
|
776
791
|
function init() {
|
|
777
|
-
const source = settings.loop ? settings.loop : root;
|
|
778
|
-
for (const event of _coreEvents.split(",")) {
|
|
779
|
-
if (source[event]) instance.listen(event, source[event]);
|
|
780
|
-
}
|
|
781
792
|
if (settings.autoscale) {
|
|
782
793
|
on(root, "resize", resizeCanvas);
|
|
783
794
|
}
|
|
@@ -1076,6 +1087,10 @@
|
|
|
1076
1087
|
root.ENGINE = instance;
|
|
1077
1088
|
}
|
|
1078
1089
|
setupCanvas();
|
|
1090
|
+
const source = settings.loop ? settings.loop : root;
|
|
1091
|
+
for (const event of _coreEvents.split(",")) {
|
|
1092
|
+
if (source[event]) instance.listen(event, source[event]);
|
|
1093
|
+
}
|
|
1079
1094
|
if ("loading" === document.readyState) {
|
|
1080
1095
|
on(root, "DOMContentLoaded", () => raf(init));
|
|
1081
1096
|
} else {
|
package/dist/dist.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,
|
|
1
|
+
(()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a,l=window,n=Math,i=2*n.PI,o=requestAnimationFrame,r=[],s=(e,t,a)=>{e.addEventListener(t,a,!1),r.push(()=>e.removeEventListener(t,a,!1))},f=(a=new AudioContext,l.zzfxV=1,(e=1,t=.05,n=220,i=0,o=0,r=.1,s=0,f=1,c=0,d=0,u=0,p=0,h=0,g=0,m=0,v=0,w=0,x=1,b=0,y=0,k=0)=>{let E=Math,z=2*E.PI,D=c*=500*z/44100/44100,P=n*=(1-t+2*t*E.random(t=[]))*z/44100,T=0,C=0,I=0,L=1,S=0,A=0,M=0,N=k<0?-1:1,F=z*N*k*2/44100,q=E.cos(F),B=E.sin,H=B(F)/4,O=1+H,V=-2*q/O,W=(1-H)/O,R=(1+N*q)/2/O,G=-(N+q)/O,X=0,Y=0,$=0,j=0;for(i=44100*i+9,b*=44100,o*=44100,r*=44100,w*=44100,d*=500*z/85766121e6,m*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,e*=.3*l.zzfxV,N=i+b+o+r+w|0;I<N;t[I++]=M*e)++A%(100*v|0)||(M=s?1<s?2<s?3<s?B(T*T):E.max(E.min(E.tan(T),1),-1):1-(2*T/z%2+2)%2:1-4*E.abs(E.round(T/z)-T/z):B(T),M=(h?1-y+y*B(z*I/h):1)*(M<0?-1:1)*E.abs(M)**f*(I<i?I/i:I<i+b?1-(I-i)/b*(1-x):I<i+b+o?x:I<N-w?(N-I-w)/r*x:0),M=w?M/2+(w>I?0:(I<N-w?1:(N-I)/w)*t[I-w|0]/2/e):M,k&&(M=j=R*X+G*(X=Y)+R*(Y=M)-W*$-V*($=j))),T+=(F=(n+=c+=d)*E.cos(m*C++))+F*g*B(I**5),L&&++L>p&&(n+=u,P+=u,L=0),!h||++S%h||(n=P,c=D,L=L||1);(e=a.createBuffer(1,N,44100)).getChannelData(0).set(t),(n=a.createBufferSource()).buffer=e,n.connect(a.destination),n.start()});t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let c=!1,d=!0,u,p=1,h,g=.5,m=1,v,w=1e3/60,x,b,y="sans-serif",k=20,E=1.2,z=Date.now(),D=e,P=[],T=[.5,0,1750,,,.3,1,,,,600,.1],C={},I={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:i,HALF_PI:i/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>n.PI/180*e,rad2deg:e=>180/n.PI*e,round:(e,t=0)=>{if(!t)return n.round(e);let a=10**t;return n.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*n.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?I.clamp(o,l,n):o},norm:(e,t,a)=>I.map(e,t,a,0,1),wave:(e,t,a,l=Math.sin)=>e+(l(a)+1)/2*(t-e),rand:(e=0,t=1)=>(z=(1664525*z+0x3c6ef35f)%0x100000000)/0x100000000*(t-e)+e,randi:(e=0,t=1)=>n.floor(I.rand(e,t+1)),rseed(e){z=~~e},cls(e){null==e?h.clearRect(0,0,h.canvas.width,h.canvas.height):I.rectfill(0,0,h.canvas.width,h.canvas.height,e)},rect(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),I.stroke(n)},rectfill(e,t,a,l,n,i){h.beginPath(),h[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),I.fill(n)},circ(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),I.stroke(l)},circfill(e,t,a,l){h.beginPath(),h.arc(~~e,~~t,~~a,0,i),I.fill(l)},oval(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),I.stroke(n)},ovalfill(e,t,a,l,n){h.beginPath(),h.ellipse(~~e,~~t,~~a,~~l,0,0,i),I.fill(n)},line(e,t,a,l,n){h.beginPath();let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);h.moveTo(~~e+i,~~t+o),h.lineTo(~~a+i,~~l+o),I.stroke(n)},linewidth(e){h.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){h.setLineDash(e),h.lineDashOffset=t},text(e,t,a,l=3,n="normal"){h.font=`${n} ${k}px ${y}`,h.fillStyle=N(l);let i=(""+a).split("\n");for(let a=0;a<i.length;a++)h.fillText(i[a],~~e,~~t+k*E*a)},textgap(e){E=e},textfont(e){y=e},textsize(e){k=e},textalign(e,t){e&&(h.textAlign=e),t&&(h.textBaseline=t)},image(e,t,a){h.drawImage(a,~~e,~~t)},spr(e,t,a,l,n){let i=n.replace(/\s/g,"");for(let n=0;n<a;n++)for(let o=0;o<l;o++){let l=i[a*o+n]||".";"."!==l&&I.rectfill(e+n,t+o,1,1,parseInt(l,36)||0)}},paint(e,t,a,l={}){let n=l.canvas||new OffscreenCanvas(1,1),i=l.scale||1,o=h;return n.width=e*i,n.height=t*i,(h=n.getContext("2d")).scale(i,i),a(h),h=o,n.transferToImageBitmap()},ctx:e=>(e&&(h=e),h),push(){h.save()},pop(){h.restore()},translate(e,t){h.translate(~~e,~~t)},scale(e,t){h.scale(e,t||e)},rotate(e){h.rotate(e)},alpha(e){h.globalAlpha=I.clamp(e,0,1)},fill(e){h.fillStyle=N(e),h.fill()},stroke(e){h.strokeStyle=N(e),h.stroke()},clip(e){h.beginPath(),e(h),h.clip()},sfx:(e,t=0,a=1)=>!!l.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||T,(0!==t||1!==a)&&((e=e.slice())[0]=a*(e[0]||1),e[10]=~~e[10]+t),f.apply(0,e),e),volume(e){l.zzfxV=e},canvas:()=>u,use(e,t={}){var a=e,l=t;let n=a(I,l);for(let e in n)I.def(e,n[e])},listen:(e,t)=>(C[e=e.toLowerCase()]=C[e]||new Set,C[e].add(t),()=>C&&C[e].delete(t)),emit(e,t,a,l,n){c&&(M("before:"+(e=e.toLowerCase()),t,a,l,n),M(e,t,a,l,n),M("after:"+e,t,a,l,n))},pal(t=e){D=t,P=[]},palc(e,t){null==e?P=[]:P[e]=t},def(e,a){I[e]=a,t.global&&(l[e]=a)},timescale(e){m=e},framerate(e){w=1e3/~~e},stat(e){let a={index:e,value:[t,c,w/1e3,p,C,D,T,m,l.zzfxV,z,k,y,P,E][e]};return I.emit("stat",a),a.value},pause(){d=!0,cancelAnimationFrame(b)},resume(){c&&d&&(d=!1,x=w,v=Date.now(),b=o(S))},paused:()=>d,quit(){for(let e of(I.emit("quit"),I.pause(),c=!1,C={},r))e();if(t.global){for(let e in I)delete l[e];delete l.ENGINE}}};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))I[e]=n[e];function L(){if(t.autoscale&&s(l,"resize",A),t.tapEvents){let e=e=>[(e.pageX-u.offsetLeft)/p,(e.pageY-u.offsetTop)/p],t=new Map,a=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:Date.now()};return t.set(e,n),n},n=(e,l,n)=>{let i=t.get(e)||a(e);i.x=l,i.y=n},i=e=>e&&Date.now()-e.t<=300,o=!1;s(u,"mousedown",t=>{if(0===t.button){t.preventDefault();let[l,n]=e(t);I.emit("tap",l,n,0),a(0,l,n),o=!0}}),s(u,"mouseup",a=>{if(0===a.button){a.preventDefault();let l=t.get(0),[n,r]=e(a);i(l)&&I.emit("tapped",l.xi,l.yi,0),I.emit("untap",n,r,0),t.delete(0),o=!1}}),s(l,"mousemove",t=>{t.preventDefault();let[a,l]=e(t);I.def("MX",a),I.def("MY",l),o&&(I.emit("tapping",a,l,0),n(0,a,l))}),s(u,"touchstart",t=>{for(let l of(t.preventDefault(),t.changedTouches)){let[t,n]=e(l);I.emit("tap",t,n,l.identifier+1),a(l.identifier+1,t,n)}}),s(u,"touchmove",t=>{for(let a of(t.preventDefault(),t.changedTouches)){let[t,l]=e(a);I.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let r=e=>{e.preventDefault();let a=[];if(e.targetTouches.length>0)for(let t of e.targetTouches)a.push(t.identifier+1);for(let[e,l]of t)a.includes(e)||(i(l)&&I.emit("tapped",l.xi,l.yi,e),I.emit("untap",l.x,l.y,e),t.delete(e))};s(u,"touchend",r),s(u,"touchcancel",r),s(l,"blur",()=>{for(let[e,a]of(o=!1,t))I.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,a=(e,t="")=>(t=t.toLowerCase())?e.has("space"===t?" ":t):e.size>0,n="";s(l,"keydown",a=>{let l=a.key.toLowerCase();e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),s(l,"keyup",t=>{e.delete(t.key.toLowerCase())}),s(l,"blur",()=>e.clear()),I.listen("after:update",()=>t.clear()),I.def("iskeydown",t=>a(e,t)),I.def("iskeypressed",e=>a(t,e)),I.def("lastkey",()=>n)}c=!0,I.emit("init",I),I.resume()}function S(){b=o(S);let e=Date.now(),t=0,a=e-v;for(v=e,x+=a<100?a:w;x>=w;){t++,x-=w;let e=w/1e3*m;I.emit("update",e,t),I.def("T",I.T+e)}t&&(I.emit("draw",h),t>1&&(x=0))}function A(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(I.def("W",e),I.def("H",a),u.width=e,u.height=a,t.autoscale){let l=+t.autoscale;u.style.display||(u.style.display="block",u.style.margin="auto"),p=n.min(innerWidth/e,innerHeight/a),p=l>1&&p>l?l:p,u.style.width=e*p+"px",u.style.height=a*p+"px"}h.imageSmoothingEnabled=!1,I.textalign("start","top"),I.emit("resized",p)}function M(e,t,a,l,n){if(C[e])for(let i of C[e])i(t,a,l,n)}function N(e){return D[~~(P[e]??e)%D.length]}if(t.global){if(l.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(l,I),l.ENGINE=I}h=(u=(u="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),s(u,"click",()=>focus()),A(),u.parentNode||document.body.appendChild(u),u.style.imageRendering="pixelated",u.oncontextmenu=()=>!1;let F=t.loop?t.loop:l;for(let e of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))F[e]&&I.listen(e,F[e]);return"loading"===document.readyState?s(l,"DOMContentLoaded",()=>o(L)):b=o(L),I}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.100.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>",
|
|
@@ -31,15 +31,13 @@
|
|
|
31
31
|
"creative coding"
|
|
32
32
|
],
|
|
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.
|
|
37
|
-
"@types/jsdom": "^21.1.7",
|
|
36
|
+
"@swc/core": "^1.15.0",
|
|
38
37
|
"ava": "^6.4.1",
|
|
39
|
-
"esbuild": "^0.25.
|
|
38
|
+
"esbuild": "^0.25.12",
|
|
40
39
|
"genversion": "^3.2.0",
|
|
41
40
|
"gzip-size": "^7.0.0",
|
|
42
|
-
"jsdom": "^26.1.0",
|
|
43
41
|
"prettier": "^3.6.2",
|
|
44
42
|
"sinon": "^21.0.0",
|
|
45
43
|
"size-limit": "^11.2.0",
|
|
@@ -51,7 +49,7 @@
|
|
|
51
49
|
"scripts": {
|
|
52
50
|
"prepare": "npm run build",
|
|
53
51
|
"prepublishOnly": "npm test",
|
|
54
|
-
"test": "ava --
|
|
52
|
+
"test": "ava --tap | tap-min",
|
|
55
53
|
"test:watch": "ava --watch",
|
|
56
54
|
"dev": "esbuild src/web.js --bundle --watch --outfile=samples/dist.js --servedir=samples",
|
|
57
55
|
"build": "npm run genversion && node script/build.js && size-limit",
|
|
@@ -66,8 +64,14 @@
|
|
|
66
64
|
],
|
|
67
65
|
"ava": {
|
|
68
66
|
"files": [
|
|
69
|
-
"tests/**/*.js"
|
|
70
|
-
|
|
67
|
+
"tests/**/*.js",
|
|
68
|
+
"!tests/_preload/**/*.js"
|
|
69
|
+
],
|
|
70
|
+
"require": [
|
|
71
|
+
"./tests/_preload/happy-dom.js"
|
|
72
|
+
],
|
|
73
|
+
"failFast": true,
|
|
74
|
+
"timeout": "10s"
|
|
71
75
|
},
|
|
72
76
|
"size-limit": [
|
|
73
77
|
{
|
package/src/index.js
CHANGED
|
@@ -73,6 +73,8 @@ export default function litecanvas(settings = {}) {
|
|
|
73
73
|
/** @type {number} */
|
|
74
74
|
_fontSize = 20,
|
|
75
75
|
/** @type {number} */
|
|
76
|
+
_fontLineHeight = 1.2,
|
|
77
|
+
/** @type {number} */
|
|
76
78
|
_rngSeed = Date.now(),
|
|
77
79
|
/** @type {string[]} */
|
|
78
80
|
_colorPalette = defaultPalette,
|
|
@@ -639,7 +641,7 @@ export default function litecanvas(settings = {}) {
|
|
|
639
641
|
|
|
640
642
|
/** TEXT RENDERING API */
|
|
641
643
|
/**
|
|
642
|
-
* Draw text
|
|
644
|
+
* Draw text. You can use `\n` to break lines.
|
|
643
645
|
*
|
|
644
646
|
* @param {number} x
|
|
645
647
|
* @param {number} y
|
|
@@ -661,7 +663,22 @@ export default function litecanvas(settings = {}) {
|
|
|
661
663
|
|
|
662
664
|
_ctx.font = `${fontStyle} ${_fontSize}px ${_fontFamily}`
|
|
663
665
|
_ctx.fillStyle = getColor(color)
|
|
664
|
-
|
|
666
|
+
|
|
667
|
+
const messages = ('' + message).split('\n')
|
|
668
|
+
for (let i = 0; i < messages.length; i++) {
|
|
669
|
+
_ctx.fillText(messages[i], ~~x, ~~y + _fontSize * _fontLineHeight * i)
|
|
670
|
+
}
|
|
671
|
+
},
|
|
672
|
+
|
|
673
|
+
/**
|
|
674
|
+
* Sets the height ratio of the text lines based on current text size.
|
|
675
|
+
*
|
|
676
|
+
* Default = `1.2`
|
|
677
|
+
*
|
|
678
|
+
* @param value
|
|
679
|
+
*/
|
|
680
|
+
textgap(value) {
|
|
681
|
+
_fontLineHeight = value
|
|
665
682
|
},
|
|
666
683
|
|
|
667
684
|
/**
|
|
@@ -1197,6 +1214,8 @@ export default function litecanvas(settings = {}) {
|
|
|
1197
1214
|
_fontFamily,
|
|
1198
1215
|
// 12
|
|
1199
1216
|
_colorPaletteState,
|
|
1217
|
+
// 13
|
|
1218
|
+
_fontLineHeight,
|
|
1200
1219
|
]
|
|
1201
1220
|
|
|
1202
1221
|
const data = { index, value: internals[index] }
|
|
@@ -1280,15 +1299,6 @@ export default function litecanvas(settings = {}) {
|
|
|
1280
1299
|
}
|
|
1281
1300
|
|
|
1282
1301
|
function init() {
|
|
1283
|
-
// setup default event listeners
|
|
1284
|
-
const source = settings.loop ? settings.loop : root
|
|
1285
|
-
for (const event of _coreEvents.split(',')) {
|
|
1286
|
-
DEV: if (root === source && source[event]) {
|
|
1287
|
-
console.info(`[litecanvas] using window.${event}()`)
|
|
1288
|
-
}
|
|
1289
|
-
if (source[event]) instance.listen(event, source[event])
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
1302
|
// listen window resize event when "autoscale" is enabled
|
|
1293
1303
|
if (settings.autoscale) {
|
|
1294
1304
|
on(root, 'resize', resizeCanvas)
|
|
@@ -1720,8 +1730,19 @@ export default function litecanvas(settings = {}) {
|
|
|
1720
1730
|
DEV: console.info(`[litecanvas] version ${version} started`)
|
|
1721
1731
|
DEV: console.debug(`[litecanvas] litecanvas() options =`, settings)
|
|
1722
1732
|
|
|
1733
|
+
// setup the canvas
|
|
1723
1734
|
setupCanvas()
|
|
1724
1735
|
|
|
1736
|
+
// setup default event listeners
|
|
1737
|
+
const source = settings.loop ? settings.loop : root
|
|
1738
|
+
for (const event of _coreEvents.split(',')) {
|
|
1739
|
+
DEV: if (root === source && source[event]) {
|
|
1740
|
+
console.info(`[litecanvas] using window.${event}()`)
|
|
1741
|
+
}
|
|
1742
|
+
if (source[event]) instance.listen(event, source[event])
|
|
1743
|
+
}
|
|
1744
|
+
|
|
1745
|
+
// init the engine (async)
|
|
1725
1746
|
if ('loading' === document.readyState) {
|
|
1726
1747
|
on(root, 'DOMContentLoaded', () => raf(init))
|
|
1727
1748
|
} else {
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.
|
|
2
|
+
export const version = '0.100.1'
|
package/types/global.d.ts
CHANGED
|
@@ -325,7 +325,7 @@ declare global {
|
|
|
325
325
|
|
|
326
326
|
/** TEXT RENDERING API */
|
|
327
327
|
/**
|
|
328
|
-
* Draw text
|
|
328
|
+
* Draw text. You can use `\n` to break lines.
|
|
329
329
|
*
|
|
330
330
|
* @param x
|
|
331
331
|
* @param y
|
|
@@ -355,6 +355,14 @@ declare global {
|
|
|
355
355
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
|
|
356
356
|
*/
|
|
357
357
|
function textalign(align: CanvasTextAlign, baseline: CanvasTextBaseline): void
|
|
358
|
+
/**
|
|
359
|
+
* Sets the height ratio of the text lines based on current text size.
|
|
360
|
+
*
|
|
361
|
+
* Default = `1.2`
|
|
362
|
+
*
|
|
363
|
+
* @param value
|
|
364
|
+
*/
|
|
365
|
+
function textgap(value: number): void
|
|
358
366
|
|
|
359
367
|
/** BASIC GRAPHICS API */
|
|
360
368
|
/**
|
|
@@ -598,6 +606,7 @@ declare global {
|
|
|
598
606
|
* - n = 10: the current font size
|
|
599
607
|
* - n = 11: the current font family
|
|
600
608
|
* - n = 12: the current state of the color palette
|
|
609
|
+
* - n = 13: the current font gap
|
|
601
610
|
* - n = *any other value*: probably returns undefined
|
|
602
611
|
*
|
|
603
612
|
* @param index
|
package/types/types.d.ts
CHANGED
|
@@ -319,7 +319,7 @@ type LitecanvasInstance = {
|
|
|
319
319
|
|
|
320
320
|
/** TEXT RENDERING API */
|
|
321
321
|
/**
|
|
322
|
-
* Draw text
|
|
322
|
+
* Draw text. You can use `\n` to break lines.
|
|
323
323
|
*
|
|
324
324
|
* @param x
|
|
325
325
|
* @param y
|
|
@@ -349,6 +349,14 @@ type LitecanvasInstance = {
|
|
|
349
349
|
* @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign
|
|
350
350
|
*/
|
|
351
351
|
textalign(align: CanvasTextAlign, baseline: CanvasTextBaseline): void
|
|
352
|
+
/**
|
|
353
|
+
* Sets the height ratio of the text lines based on current text size.
|
|
354
|
+
*
|
|
355
|
+
* Default = `1.2`
|
|
356
|
+
*
|
|
357
|
+
* @param value
|
|
358
|
+
*/
|
|
359
|
+
textgap(value: number): void
|
|
352
360
|
|
|
353
361
|
/** BASIC GRAPHICS API */
|
|
354
362
|
/**
|
|
@@ -588,6 +596,7 @@ type LitecanvasInstance = {
|
|
|
588
596
|
* - n = 10: the current font size
|
|
589
597
|
* - n = 11: the current font family
|
|
590
598
|
* - n = 12: the current state of the color palette
|
|
599
|
+
* - n = 13: the current font gap
|
|
591
600
|
* - n = *any other value*: probably returns undefined
|
|
592
601
|
*
|
|
593
602
|
* @param index
|