litecanvas 0.98.1 → 0.98.3
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 +183 -34
- package/dist/dist.dev.js +3 -3
- package/dist/dist.js +2 -2
- package/dist/dist.min.js +1 -1
- package/package.json +1 -1
- package/src/index.js +2 -2
- package/src/version.js +1 -1
package/README.md
CHANGED
|
@@ -28,74 +28,210 @@ Litecanvas is a lightweight HTML5 canvas 2D engine suitable for small web games,
|
|
|
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).
|
|
30
30
|
|
|
31
|
-
[Learn more in the cheatsheet...](https://litecanvas.js.org/about.html)
|
|
32
|
-
|
|
33
31
|
## Getting Started
|
|
34
32
|
|
|
35
|
-
|
|
33
|
+
### Installation
|
|
34
|
+
|
|
35
|
+
You can get started using our [online playground](https://litecanvas.github.io).
|
|
36
|
+
|
|
37
|
+
Or installing our package via NPM:
|
|
36
38
|
|
|
37
39
|
```sh
|
|
38
40
|
npm i litecanvas
|
|
39
41
|
```
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
Or just create a HTML file and add a `<script>` tag with our CDN link:
|
|
42
44
|
|
|
43
45
|
```html
|
|
44
46
|
<script src="https://unpkg.com/litecanvas"></script>
|
|
45
47
|
```
|
|
46
48
|
|
|
47
|
-
###
|
|
49
|
+
### Basic game structure
|
|
48
50
|
|
|
49
51
|
```js
|
|
50
|
-
// import the package if you installed via NPM
|
|
51
|
-
import litecanvas from 'litecanvas'
|
|
52
|
-
|
|
53
|
-
// Start and setup the engine
|
|
54
|
-
// learn more: https://litecanvas.js.org/about.html#settings
|
|
55
52
|
litecanvas({
|
|
56
|
-
|
|
53
|
+
// This is required only in ESM format.
|
|
54
|
+
// Note: the next examples will assume that you are
|
|
55
|
+
// testing through the playground or the CDN
|
|
56
|
+
loop: { init, update, draw },
|
|
57
57
|
})
|
|
58
58
|
|
|
59
|
-
// this function runs once at the beginning
|
|
60
59
|
function init() {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
// this functions is called one time only
|
|
61
|
+
// before the game starts
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function update(dt) {
|
|
65
|
+
// this functions is called 60 times per second
|
|
66
|
+
// your game logic goes here
|
|
66
67
|
}
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
//
|
|
71
|
-
// based on the position of the tap
|
|
72
|
-
posx = x
|
|
73
|
-
posy = y
|
|
69
|
+
function draw() {
|
|
70
|
+
// this functions is called 60 times per second
|
|
71
|
+
// your game rendering goes here
|
|
74
72
|
}
|
|
73
|
+
```
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
> **Note**: if you installed via NPM you need to import the package first: <br/>
|
|
76
|
+
> `import litecanvas from "litecanvas"`
|
|
77
|
+
|
|
78
|
+
### Set the width and height of the game screen
|
|
79
|
+
|
|
80
|
+
```js
|
|
81
|
+
// example: a game screen size equal to 480x360
|
|
82
|
+
litecanvas({
|
|
83
|
+
width: 480,
|
|
84
|
+
height: 360,
|
|
85
|
+
})
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Colors
|
|
89
|
+
|
|
90
|
+
Litecanvas has a default palette with 12 colors:
|
|
91
|
+
|
|
92
|
+
| # | Color | # | Color |
|
|
93
|
+
| --- | ---------- | --- | ----------- |
|
|
94
|
+
| 0 | Black | 6 | Dark blue |
|
|
95
|
+
| 1 | Dark grey | 7 | Light blue |
|
|
96
|
+
| 2 | Light grey | 8 | Dark green |
|
|
97
|
+
| 3 | White | 9 | Light green |
|
|
98
|
+
| 4 | Red | 10 | Brown |
|
|
99
|
+
| 5 | Yellow | 11 | Beige |
|
|
100
|
+
|
|
101
|
+

|
|
102
|
+
|
|
103
|
+
Each time a Litecanvas' function ask for a color, you should use an of theses colors by its index.
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
// example: draw a white rectangle
|
|
107
|
+
color = 3
|
|
108
|
+
rectfill(0, 0, 32, 32, color)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Printing messages
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
litecanvas()
|
|
115
|
+
|
|
116
|
+
function draw() {
|
|
117
|
+
// clear and fill the game screen with color #0 (black)
|
|
118
|
+
cls(0)
|
|
119
|
+
|
|
120
|
+
// print a red "Hello" text at x=0, y=0
|
|
121
|
+
text(0, 0, 'Hello', 4)
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Drawing shapes
|
|
126
|
+
|
|
127
|
+
You can use the following functions to draw shapes:
|
|
128
|
+
|
|
129
|
+
- `rect(x, y, width, height, color)` draw a rectangle outline
|
|
130
|
+
- `rectfill(x, y, width, height, color)` draw a color-filled rectangle
|
|
131
|
+
- `circ(x, y, radius, color)` draw a circle outline
|
|
132
|
+
- `circfill(x, y, radius, color)` draw a color-filled circle
|
|
133
|
+
- `oval(x, y, rx, ry, color)` draw a ellipse outline
|
|
134
|
+
- `ovalfill(x, y, rx, ry, color)` draw a color-filled ellipse
|
|
135
|
+
|
|
136
|
+
```js
|
|
137
|
+
litecanvas()
|
|
138
|
+
|
|
139
|
+
function draw() {
|
|
140
|
+
cls(0)
|
|
141
|
+
|
|
142
|
+
// draw a color filled rectangle at x=0 and y=0
|
|
143
|
+
// with width=32 and height=32
|
|
144
|
+
// and color=3 (white)
|
|
145
|
+
rectfill(0, 0, 32, 32, 3)
|
|
146
|
+
|
|
147
|
+
// draw a circle outline at x=64 and y=32
|
|
148
|
+
// with radius=40
|
|
149
|
+
// and color=5 (yellow)
|
|
150
|
+
circ(64, 32, 40, 5)
|
|
80
151
|
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Keyboard
|
|
155
|
+
|
|
156
|
+
```js
|
|
157
|
+
litecanvas()
|
|
158
|
+
|
|
159
|
+
function update() {
|
|
160
|
+
if (iskeydown('space')) {
|
|
161
|
+
// checks if the spacebar key is down
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (iskeypressed('a')) {
|
|
165
|
+
// checks if the "a" key was pressed
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Returns the last key pressed in your keyboard.
|
|
169
|
+
const key = lastkey()
|
|
170
|
+
|
|
171
|
+
console.log(key)
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
> Note: you can call `iskeydown()` or `iskeypressed()` (without arguments) to check for any key.
|
|
176
|
+
|
|
177
|
+
### Clicks and Touches
|
|
178
|
+
|
|
179
|
+
```js
|
|
180
|
+
litecanvas()
|
|
181
|
+
|
|
182
|
+
let x, y
|
|
183
|
+
|
|
184
|
+
function tapped(tapX, tapY) {
|
|
185
|
+
// this function is called when a click or a touch happens
|
|
186
|
+
// tapX and tapY is where the tap happened
|
|
187
|
+
x = tapX
|
|
188
|
+
y = tapY
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function draw() {
|
|
192
|
+
cls(0)
|
|
193
|
+
|
|
194
|
+
if (x != null) {
|
|
195
|
+
// Draw a red circle wherever you tap
|
|
196
|
+
circfill(x, y, 32, 4)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
### Mouse cursor
|
|
202
|
+
|
|
203
|
+
Use `MX` and `MY` variables (automatically declared by Litecanvas) to track the position of the mouse cursor.
|
|
204
|
+
|
|
205
|
+
```js
|
|
206
|
+
litecanvas()
|
|
81
207
|
|
|
82
|
-
// put the game rendering in this function
|
|
83
208
|
function draw() {
|
|
84
|
-
cls(
|
|
85
|
-
|
|
86
|
-
|
|
209
|
+
cls(0)
|
|
210
|
+
|
|
211
|
+
// draw a red circle in the mouse cursor's position
|
|
212
|
+
circfill(MX, MY, 32, 4)
|
|
87
213
|
}
|
|
88
214
|
```
|
|
89
215
|
|
|
90
|
-
|
|
216
|
+
### Litecanvas' variables
|
|
217
|
+
|
|
218
|
+
Like `MX` and `MY`, Litecanvas also declares these other variables:
|
|
219
|
+
|
|
220
|
+
- `W`: the width of the game canvas
|
|
221
|
+
- `H`: the height of the game canvas
|
|
222
|
+
- `T`: the amount of seconds since the game started
|
|
223
|
+
- `PI`: approximately 3.14 radians (or 180 degrees)
|
|
224
|
+
- `TWO_PI`: approximately 6.28 radians (or 360 degrees)
|
|
225
|
+
- `HALF_PI`: approximately 1.57 radians (or 90 degrees)
|
|
91
226
|
|
|
92
|
-
|
|
227
|
+
### And much more!
|
|
228
|
+
|
|
229
|
+
You can find a complete list of everything litecanvas has to offer on our [cheatsheet](https://litecanvas.js.org/about.html).
|
|
93
230
|
|
|
94
231
|
## Demos
|
|
95
232
|
|
|
96
233
|
Try some demos in the playground:
|
|
97
234
|
|
|
98
|
-
- [Pong](https://litecanvas.js.org?c=eJy1VV1y00gQftcpmidJWJYl2U5IIKFMyiEPgKk4YMLW1paQxvYUiqSSxiT8hCtwgn3bQ3AeLsAV6J7RzyjEKV42rozdPT39%2B803CROQh%2FECDsAPPMcA%2FEP5hORxI74h0Wu3z1EeDSs5ZqUgA7JTmndhkmg%2Fz9ufc%2F6Jaa5JNUlXCelqb7yQ0RrpvJXKnLEYxaBOpYyyQjub8CUrURwqUbArQQErWxEWQh5fhknJDCPhgkVh%2BiEsrc%2FS4pLHYr0Pw7oPa8ZXa7EPoweouLYNYzCAo00psgt4%2B%2Bn4DZTZJo1LWGYFiDUvYRVeMLLJCyYEZ0Wfr1LMz4iytBTwZPbqxdEUw%2F%2FlgAM%2BG9KX6w1pCVDhQEAaB%2FZGXrVRf1zccXeU%2Fc7fD7fHmJ9NTs8ohOeOHewKjLFT8tgIl6EeZbzrVZHlUgXyRne5fzJ59uyf2fHx%2FOh0On1BcXx36MtyxhjAcz2KSnFw2ZXRpNTfc%2Fdw3aGVPp7r%2B%2FWvQJ6T60iuPlVoLDdpJHiWAk%2B5sGz43AIL4y4GQYsulE8GAfThBAYw6kyeTFHpB8a15lKEec5i68qBj7VjvgTrXoWQWtcFjSg2rFUvryzZa7tRYcM2RSrF6861%2BPrVusLk5CUbQGB3UtnkcSiYFYvbE1FOAQciuMBbUkYFY%2BnjxrIC%2FAHeAN2YgAjZB1Y8NqQpqi5QRJQyyiNOmH6xE1bklry8Kmc1SLs5GmepKdBKaOdRDCuHKqcmJen0EeVTuffkFsMr1%2B73VDsOYdGYLaoeGY0nNdxeyxuHcKLPpgaDv%2BN1dASI3VZVk4L67oPfmWIX0nY1v7p0NR7pFfKs5DQzDYi9A0VX9ytmug%2Bx0HCpts%2B724qosJnvkD0inY%2BqmEqvYiJCbrS3Cqw3ZQFfvlQJPWr0eqNUjgfQb0tvgze4vm5npNLf6kwy8p2ummKiNYveq1qiLEl4SaC%2F5GKt45BC4m7BIqHqc6pno0lA%2F6WQSo%2BQXBdIM%2FYtCWrFqleiR0%2FYH2QtG6B2bQURSdzdexsX4WXDSlFSWp59J48QIYUJkqllRiwVrDAdMC84tcC0O1YlFmnV%2FNXdspD2HOI6PHs2eQlnM0X46Gto35yhgvshXcQ2DWrxkieJ9XsT6dFv%2FMiqeBFJ220jqSliS%2Ba31S47Q6Wvw3TF09WN2i0f3yT6N3%2F8%2B9%2FP79%2FAdAuWs1CoamwHRrf7ZWl8h1eiltqzZZp4eyQibBdrnlNGFr6tnn2zi%2F%2FX9DCbAN9J8%2Bnk%2BRRmr6enZqfvv7lB3vDcB%2BNt3nqqY%2FOj2el0n4r7oxIRzb8ATsCfrQ%3D%3D)
|
|
99
235
|
- [Bouncing Ball](https://litecanvas.js.org?c=eJxtkkFugzAQRfecYpaGOMFJW6lVQhddcQPWlm0iSy4gY0hRkrt3ADc4SRdI9nzm%2FzcMRjlo6lY7XVeQQa8E2TJG8YlpBHg3tdBuGM9Hy3t%2FtFzqrsX3X9%2BjyGinBK963pI4isquEpOZrrQjMZwDFx9QJDuap7t4v5h6hdEcq9fApWskd4pINzv9oW5%2BYJXdfPGWgHShPtzpw6wHKLOBT1%2F6g45AXtrTFL5qZFNQlyUoeVQtVnUJZCFb%2Ba%2FzCQVcLgHy2gsHYPM0dzhJBuvt%2Fp8q23y8TeVg%2BAyE4d9NkEr9UigUPifGpusjHc4FN778CWOYMJ4TxwXl3neyDXckLT%2F5TQvTEjYtVmgrSm1MiLjYUQ%2F78rDu8SfAUYbZzSrX2QrOYwUjfwF7%2FdPj)
|
|
100
236
|
- [Scroller](https://litecanvas.js.org?c=eJxVUM1SgzAQvvMU68FpAhFDLVpH%2BxbOcOj0ECGUzATSIYsyOn13NwXRHpJNvv1%2BkrUGdam6D%2BUZj6J66Eo0rgPTGQTG4TsCaLX36qhhB6tC29K1GtCBXYQ3KyKN1C6onpSl034jcvEonsRWPItMiiw7ROd%2F9sOpUqiBVThFePMV%2FIv7OSu1ujtiQ52G4FxeAu528CAlxFDhHNiqkY0C1pJfuVe9%2Bvx9fGk9ozZA7XpgViMYEsoXKq9wnUZYkkwqgMBEYr4lTKZZbPiC0kLdh%2FRZ7Yd3jz0zArI%2FVumsCySax762zvUM4%2FyWbnMYP1yoqEcMn2dh4wvExsTEAYpluhXQJGuZeNORx4bHjZjfIKaUIDvTAH4AEIGEgw%3D%3D)
|
|
101
237
|
- [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)
|
|
@@ -103,6 +239,19 @@ Try some demos in the playground:
|
|
|
103
239
|
|
|
104
240
|
> _See other demos in [samples](/samples) folder_
|
|
105
241
|
|
|
242
|
+
## Contributing
|
|
243
|
+
|
|
244
|
+
1. Fork this repository and clone it.
|
|
245
|
+
1. Install the dependencies: `npm i`
|
|
246
|
+
1. Create a new branch and make your changes.
|
|
247
|
+
1. Format the code: `npm run format`
|
|
248
|
+
1. Create new tests in `tests` directory, if necessary.
|
|
249
|
+
1. Test with `npm run test`
|
|
250
|
+
1. Create your pull request.
|
|
251
|
+
1. Done!
|
|
252
|
+
|
|
253
|
+
> Note: You'll need Node.JS installed in your machine.
|
|
254
|
+
|
|
106
255
|
## Inspirations
|
|
107
256
|
|
|
108
257
|
- [floppy](https://github.com/lpagg/floppy): a micro game engine for beginners.
|
package/dist/dist.dev.js
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
};
|
|
33
33
|
|
|
34
34
|
// src/version.js
|
|
35
|
-
var version = "0.98.
|
|
35
|
+
var version = "0.98.3";
|
|
36
36
|
|
|
37
37
|
// src/index.js
|
|
38
38
|
function litecanvas(settings = {}) {
|
|
@@ -642,9 +642,9 @@
|
|
|
642
642
|
const chars = pixels.replace(/\s/g, "");
|
|
643
643
|
for (let gridx = 0; gridx < width; gridx++) {
|
|
644
644
|
for (let gridy = 0; gridy < height; gridy++) {
|
|
645
|
-
const char = chars[
|
|
645
|
+
const char = chars[width * gridy + gridx] || ".";
|
|
646
646
|
if (char !== ".") {
|
|
647
|
-
instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char,
|
|
647
|
+
instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 36) || 0);
|
|
648
648
|
}
|
|
649
649
|
}
|
|
650
650
|
}
|
package/dist/dist.js
CHANGED
|
@@ -428,9 +428,9 @@
|
|
|
428
428
|
const chars = pixels.replace(/\s/g, "");
|
|
429
429
|
for (let gridx = 0; gridx < width; gridx++) {
|
|
430
430
|
for (let gridy = 0; gridy < height; gridy++) {
|
|
431
|
-
const char = chars[
|
|
431
|
+
const char = chars[width * gridy + gridx] || ".";
|
|
432
432
|
if (char !== ".") {
|
|
433
|
-
instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char,
|
|
433
|
+
instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 36) || 0);
|
|
434
434
|
}
|
|
435
435
|
}
|
|
436
436
|
}
|
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,l=Math,n=2*l.PI,i=requestAnimationFrame,o=[],r=(e,t,a)=>{e.addEventListener(t,a,!1),o.push(()=>e.removeEventListener(t,a,!1))},s=e=>e.toLowerCase(),c=e=>e.preventDefault(),f=e=>e.beginPath(),d=(e=>{let t=new AudioContext;return e.zzfxV=1,(a=1,l=.05,n=220,i=0,o=0,r=.1,s=0,c=1,f=0,d=0,u=0,p=0,h=0,m=0,g=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let E=Math,z=2*E.PI,T=f*=500*z/44100/44100,I=n*=(1-l+2*l*E.random(l=[]))*z/44100,D=0,S=0,A=0,M=1,C=0,L=0,N=0,P=k<0?-1:1,F=z*P*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+P*q)/2/O,G=-(P+q)/O,X=0,Y=0,$=0,j=0;for(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,d*=500*z/85766121e6,g*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,a*=.3*e.zzfxV,P=i+y+o+r+w|0;A<P;l[A++]=N*a)++L%(100*v|0)||(N=s?1<s?2<s?3<s?B(D*D):E.max(E.min(E.tan(D),1),-1):1-(2*D/z%2+2)%2:1-4*E.abs(E.round(D/z)-D/z):B(D),N=(h?1-b+b*B(z*A/h):1)*(N<0?-1:1)*E.abs(N)**c*(A<i?A/i:A<i+y?1-(A-i)/y*(1-x):A<i+y+o?x:A<P-w?(P-A-w)/r*x:0),N=w?N/2+(w>A?0:(A<P-w?1:(P-A)/w)*l[A-w|0]/2/a):N,k&&(N=j=R*X+G*(X=Y)+R*(Y=N)-W*$-V*($=j))),D+=(F=(n+=f+=d)*E.cos(g*S++))+F*m*B(A**5),M&&++M>p&&(n+=u,I+=u,M=0),!h||++C%h||(n=I,f=T,M=M||1);(a=t.createBuffer(1,P,44100)).getChannelData(0).set(l),(n=t.createBufferSource()).buffer=a,n.connect(t.destination),n.start()}})(a);t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let u=!1,p,h=1,m,g=.5,v=1,w,x=1e3/60,y,b,k="sans-serif",E=20,z=Date.now(),T=e,I=[],D=[.5,0,1750,,,.3,1,,,,600,.1],S={},A={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:n,HALF_PI:n/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>l.PI/180*e,rad2deg:e=>180/l.PI*e,round:(e,t=0)=>{if(!t)return l.round(e);let a=10**t;return l.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*l.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?A.clamp(o,l,n):o},norm:(e,t,a)=>A.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)=>l.floor(A.rand(e,t+1)),rseed(e){z=~~e},cls(e){null==e?m.clearRect(0,0,m.canvas.width,m.canvas.height):A.rectfill(0,0,m.canvas.width,m.canvas.height,e)},rect(e,t,a,l,n,i){f(m),m[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),A.stroke(n)},rectfill(e,t,a,l,n,i){f(m),m[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),A.fill(n)},circ(e,t,a,l){f(m),m.arc(~~e,~~t,~~a,0,n),A.stroke(l)},circfill(e,t,a,l){f(m),m.arc(~~e,~~t,~~a,0,n),A.fill(l)},oval(e,t,a,l,i){f(m),m.ellipse(~~e,~~t,~~a,~~l,0,0,n),A.stroke(i)},ovalfill(e,t,a,l,i){f(m),m.ellipse(~~e,~~t,~~a,~~l,0,0,n),A.fill(i)},line(e,t,a,l,n){f(m);let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);m.moveTo(~~e+i,~~t+o),m.lineTo(~~a+i,~~l+o),A.stroke(n)},linewidth(e){m.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){m.setLineDash(e),m.lineDashOffset=t},text(e,t,a,l=3,n="normal"){m.font=`${n} ${E}px ${k}`,m.fillStyle=P(l),m.fillText(a,~~e,~~t)},textfont(e){k=e},textsize(e){E=e},textalign(e,t){e&&(m.textAlign=e),t&&(m.textBaseline=t)},image(e,t,a){m.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
|
|
1
|
+
(()=>{var e=["#111","#6a7799","#aec2c2","#FFF1E8","#e83b3b","#fabc20","#155fd9","#3cbcfc","#327345","#63c64d","#6c2c1f","#ac7c00"];globalThis.litecanvas=function(t={}){let a=window,l=Math,n=2*l.PI,i=requestAnimationFrame,o=[],r=(e,t,a)=>{e.addEventListener(t,a,!1),o.push(()=>e.removeEventListener(t,a,!1))},s=e=>e.toLowerCase(),c=e=>e.preventDefault(),f=e=>e.beginPath(),d=(e=>{let t=new AudioContext;return e.zzfxV=1,(a=1,l=.05,n=220,i=0,o=0,r=.1,s=0,c=1,f=0,d=0,u=0,p=0,h=0,m=0,g=0,v=0,w=0,x=1,y=0,b=0,k=0)=>{let E=Math,z=2*E.PI,T=f*=500*z/44100/44100,I=n*=(1-l+2*l*E.random(l=[]))*z/44100,D=0,S=0,A=0,M=1,C=0,L=0,N=0,P=k<0?-1:1,F=z*P*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+P*q)/2/O,G=-(P+q)/O,X=0,Y=0,$=0,j=0;for(i=44100*i+9,y*=44100,o*=44100,r*=44100,w*=44100,d*=500*z/85766121e6,g*=z/44100,u*=z/44100,p*=44100,h=44100*h|0,a*=.3*e.zzfxV,P=i+y+o+r+w|0;A<P;l[A++]=N*a)++L%(100*v|0)||(N=s?1<s?2<s?3<s?B(D*D):E.max(E.min(E.tan(D),1),-1):1-(2*D/z%2+2)%2:1-4*E.abs(E.round(D/z)-D/z):B(D),N=(h?1-b+b*B(z*A/h):1)*(N<0?-1:1)*E.abs(N)**c*(A<i?A/i:A<i+y?1-(A-i)/y*(1-x):A<i+y+o?x:A<P-w?(P-A-w)/r*x:0),N=w?N/2+(w>A?0:(A<P-w?1:(P-A)/w)*l[A-w|0]/2/a):N,k&&(N=j=R*X+G*(X=Y)+R*(Y=N)-W*$-V*($=j))),D+=(F=(n+=f+=d)*E.cos(g*S++))+F*m*B(A**5),M&&++M>p&&(n+=u,I+=u,M=0),!h||++C%h||(n=I,f=T,M=M||1);(a=t.createBuffer(1,P,44100)).getChannelData(0).set(l),(n=t.createBufferSource()).buffer=a,n.connect(t.destination),n.start()}})(a);t=Object.assign({width:null,height:null,autoscale:!0,canvas:null,global:!0,loop:null,tapEvents:!0,keyboardEvents:!0},t);let u=!1,p,h=1,m,g=.5,v=1,w,x=1e3/60,y,b,k="sans-serif",E=20,z=Date.now(),T=e,I=[],D=[.5,0,1750,,,.3,1,,,,600,.1],S={},A={W:0,H:0,T:0,MX:-1,MY:-1,TWO_PI:n,HALF_PI:n/4,lerp:(e,t,a)=>a*(t-e)+e,deg2rad:e=>l.PI/180*e,rad2deg:e=>180/l.PI*e,round:(e,t=0)=>{if(!t)return l.round(e);let a=10**t;return l.round(e*a)/a},clamp:(e,t,a)=>e<t?t:e>a?a:e,wrap:(e,t,a)=>e-(a-t)*l.floor((e-t)/(a-t)),map(e,t,a,l,n,i){let o=(e-t)/(a-t)*(n-l)+l;return i?A.clamp(o,l,n):o},norm:(e,t,a)=>A.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)=>l.floor(A.rand(e,t+1)),rseed(e){z=~~e},cls(e){null==e?m.clearRect(0,0,m.canvas.width,m.canvas.height):A.rectfill(0,0,m.canvas.width,m.canvas.height,e)},rect(e,t,a,l,n,i){f(m),m[i?"roundRect":"rect"](~~e-g,~~t-g,~~a+2*g,~~l+2*g,i),A.stroke(n)},rectfill(e,t,a,l,n,i){f(m),m[i?"roundRect":"rect"](~~e,~~t,~~a,~~l,i),A.fill(n)},circ(e,t,a,l){f(m),m.arc(~~e,~~t,~~a,0,n),A.stroke(l)},circfill(e,t,a,l){f(m),m.arc(~~e,~~t,~~a,0,n),A.fill(l)},oval(e,t,a,l,i){f(m),m.ellipse(~~e,~~t,~~a,~~l,0,0,n),A.stroke(i)},ovalfill(e,t,a,l,i){f(m),m.ellipse(~~e,~~t,~~a,~~l,0,0,n),A.fill(i)},line(e,t,a,l,n){f(m);let i=.5*(0!==g&&~~e==~~a),o=.5*(0!==g&&~~t==~~l);m.moveTo(~~e+i,~~t+o),m.lineTo(~~a+i,~~l+o),A.stroke(n)},linewidth(e){m.lineWidth=~~e,g=.5*(0!=~~e%2)},linedash(e,t=0){m.setLineDash(e),m.lineDashOffset=t},text(e,t,a,l=3,n="normal"){m.font=`${n} ${E}px ${k}`,m.fillStyle=P(l),m.fillText(a,~~e,~~t)},textfont(e){k=e},textsize(e){E=e},textalign(e,t){e&&(m.textAlign=e),t&&(m.textBaseline=t)},image(e,t,a){m.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&&A.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=m;return n.width=e*i,n.height=t*i,(m=n.getContext("2d")).scale(i,i),a(m),m=o,n.transferToImageBitmap()},ctx:e=>(e&&(m=e),m),push(){m.save()},pop(){m.restore()},translate(e,t){m.translate(~~e,~~t)},scale(e,t){m.scale(e,t||e)},rotate(e){m.rotate(e)},alpha(e){m.globalAlpha=A.clamp(e,0,1)},fill(e){m.fillStyle=P(e),m.fill()},stroke(e){m.strokeStyle=P(e),m.stroke()},clip(e){f(m),e(m),m.clip()},sfx:(e,t=0,l=1)=>!!a.zzfxV&&(!navigator.userActivation||!!navigator.userActivation.hasBeenActive)&&(e=e||D,(0!==t||1!==l)&&((e=e.slice())[0]=l*(e[0]||1),e[10]=~~e[10]+t),d.apply(0,e),e),volume(e){a.zzfxV=e},canvas:()=>p,use(e,t={}){var a=e,l=t;let n=a(A,l);for(let e in n)A.def(e,n[e])},listen:(e,t)=>(S[e=s(e)]=S[e]||new Set,S[e].add(t),()=>S&&S[e].delete(t)),emit(e,t,a,l,n){u&&(N("before:"+(e=s(e)),t,a,l,n),N(e,t,a,l,n),N("after:"+e,t,a,l,n))},pal(t=e){T=t,I=[]},palc(e,t){null==e?I=[]:I[e]=t},def(e,l){A[e]=l,t.global&&(a[e]=l)},timescale(e){v=e},framerate(e){x=1e3/~~e},stat(e){let l={index:e,value:[t,u,x/1e3,h,S,T,D,v,a.zzfxV,z,E,k][e]};return A.emit("stat",l),l.value},quit(){for(let e of(A.pause(),A.emit("quit"),S={},o))e();if(t.global){for(let e in A)delete a[e];delete a.ENGINE}u=!1},pause(){cancelAnimationFrame(b),b=0},resume(){u&&!b&&(y=x,w=Date.now(),b=i(C))},paused:()=>!b};for(let e of"PI,sin,cos,atan2,hypot,tan,abs,ceil,floor,trunc,min,max,pow,sqrt,sign,exp".split(","))A[e]=l[e];function M(){let e=t.loop?t.loop:a;for(let t of"init,update,draw,tap,untap,tapping,tapped,resized".split(","))e[t]&&A.listen(t,e[t]);if(t.autoscale&&r(a,"resize",L),t.tapEvents){let e=e=>[(e.pageX-p.offsetLeft)/h,(e.pageY-p.offsetTop)/h],t=new Map,l=(e,a,l)=>{let n={x:a,y:l,xi:a,yi:l,t:Date.now()};return t.set(e,n),n},n=(e,a,n)=>{let i=t.get(e)||l(e);i.x=a,i.y=n},i=e=>e&&Date.now()-e.t<=300,o=!1;r(p,"mousedown",t=>{if(0===t.button){c(t);let[a,n]=e(t);A.emit("tap",a,n,0),l(0,a,n),o=!0}}),r(p,"mouseup",a=>{if(0===a.button){c(a);let l=t.get(0),[n,r]=e(a);i(l)&&A.emit("tapped",l.xi,l.yi,0),A.emit("untap",n,r,0),t.delete(0),o=!1}}),r(a,"mousemove",t=>{c(t);let[a,l]=e(t);A.def("MX",a),A.def("MY",l),o&&(A.emit("tapping",a,l,0),n(0,a,l))}),r(p,"touchstart",t=>{for(let a of(c(t),t.changedTouches)){let[t,n]=e(a);A.emit("tap",t,n,a.identifier+1),l(a.identifier+1,t,n)}}),r(p,"touchmove",t=>{for(let a of(c(t),t.changedTouches)){let[t,l]=e(a);A.emit("tapping",t,l,a.identifier+1),n(a.identifier+1,t,l)}});let s=e=>{c(e);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)&&A.emit("tapped",l.xi,l.yi,e),A.emit("untap",l.x,l.y,e),t.delete(e))};r(p,"touchend",s),r(p,"touchcancel",s),r(a,"blur",()=>{for(let[e,a]of(o=!1,t))A.emit("untap",a.x,a.y,e),t.delete(e)})}if(t.keyboardEvents){let e=new Set,t=new Set,l=(e,t="")=>(t=s(t))?e.has("space"===t?" ":t):e.size>0,n="";r(a,"keydown",a=>{let l=s(a.key);e.has(l)||(e.add(l),t.add(l),n=" "===l?"space":l)}),r(a,"keyup",t=>{e.delete(s(t.key))}),r(a,"blur",()=>e.clear()),A.listen("after:update",()=>t.clear()),A.def("iskeydown",t=>l(e,t)),A.def("iskeypressed",e=>l(t,e)),A.def("lastkey",()=>n)}u=!0,A.emit("init",A),A.resume()}function C(){b=i(C);let e=Date.now(),t=0,a=e-w;for(w=e,y+=a<100?a:x;y>=x;){t++,y-=x;let e=x/1e3*v;A.emit("update",e,t),A.def("T",A.T+e)}t&&(A.emit("draw",m),t>1&&(y=0))}function L(){let e=t.width>0?t.width:innerWidth,a=t.width>0?t.height||t.width:innerHeight;if(A.def("W",e),A.def("H",a),p.width=e,p.height=a,t.autoscale){let n=+t.autoscale;p.style.display||(p.style.display="block",p.style.margin="auto"),h=l.min(innerWidth/e,innerHeight/a),h=n>1&&h>n?n:h,p.style.width=e*h+"px",p.style.height=a*h+"px"}m.imageSmoothingEnabled=!1,A.textalign("start","top"),A.emit("resized",h)}function N(e,t,a,l,n){if(S[e])for(let i of S[e])i(t,a,l,n)}function P(e){return T[~~(I[e]??e)%T.length]}if(t.global){if(a.ENGINE)throw Error("only one global litecanvas is allowed");Object.assign(a,A),a.ENGINE=A}return m=(p=(p="string"==typeof t.canvas?document.querySelector(t.canvas):t.canvas)||document.createElement("canvas")).getContext("2d"),r(p,"click",()=>focus()),L(),p.parentNode||document.body.appendChild(p),p.style.imageRendering="pixelated",p.oncontextmenu=()=>!1,"loading"===document.readyState?r(a,"DOMContentLoaded",()=>i(M)):i(M),A}})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "litecanvas",
|
|
3
|
-
"version": "0.98.
|
|
3
|
+
"version": "0.98.3",
|
|
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
|
@@ -747,9 +747,9 @@ export default function litecanvas(settings = {}) {
|
|
|
747
747
|
const chars = pixels.replace(/\s/g, '')
|
|
748
748
|
for (let gridx = 0; gridx < width; gridx++) {
|
|
749
749
|
for (let gridy = 0; gridy < height; gridy++) {
|
|
750
|
-
const char = chars[
|
|
750
|
+
const char = chars[width * gridy + gridx] || '.'
|
|
751
751
|
if (char !== '.') {
|
|
752
|
-
instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char,
|
|
752
|
+
instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 36) || 0)
|
|
753
753
|
}
|
|
754
754
|
}
|
|
755
755
|
}
|
package/src/version.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Generated by genversion.
|
|
2
|
-
export const version = '0.98.
|
|
2
|
+
export const version = '0.98.3'
|