litecanvas 0.95.1 → 0.97.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 CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Litecanvas
6
6
 
7
- [![NPM Version](https://badgen.net/npm/v/litecanvas?scale=1.1&label=NPM&color=2f9e44&cache=3600)](https://www.npmjs.com/package/litecanvas/)  
7
+ [![NPM Version](https://badgen.net/npm/v/litecanvas?cache=300&scale=1.1&label=NPM&color=2f9e44)](https://www.npmjs.com/package/litecanvas/)  
8
8
  [![License](https://badgen.net/npm/license/litecanvas?scale=1.1)](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.
@@ -32,14 +32,10 @@ Litecanvas is a lightweight HTML5 canvas 2D engine suitable for small web games,
32
32
 
33
33
  ## Getting Started
34
34
 
35
- You can try our [online playground](https://litecanvas.github.io) or install the [basic template](https://github.com/litecanvas/template):
35
+ You can try our [online playground](https://litecanvas.github.io) or install the NPM package:
36
36
 
37
37
  ```sh
38
- # requires Node.js & NPM
39
- npx tiged litecanvas/template my-game
40
- cd my-game
41
- npm install
42
- npm run dev
38
+ npm i litecanvas
43
39
  ```
44
40
 
45
41
  or just use add a `<script>` tag with our CDN link:
@@ -91,7 +87,7 @@ function draw() {
91
87
  }
92
88
  ```
93
89
 
94
- [Play with this code in the playground](https://litecanvas.js.org?c=eJx9k91u4yAQhe%2F9FCP1ovauFZL2LlKu9hFaadtLDBNDQwDBeOOoyrsv4KR2V9FasuSfjzNnDgNj8EI8EHArISINHkghoO21xYoxMMiDhaMLuAVF5OOWMaMJBbd%2FeFx9xJULPeOdG2il6Ggekghp28dqpurPCtJlnPNb%2BARtNbUweMkJW5CBn1og7j1KuLTVpalyXVI6wn6wgrSzEAYbwVmBwKkY7DAZtKlO9cVk2bqBqVbXww7WUIQQhDMuwMMa6s5wcWgKMn3cwfM%2F1DPUJ5W8T1TgUg8xYb%2BBwWZWLI3BSUtSbLMuqHdxTOCvtwwJtIQB3qBOmt%2Fop%2BZGnzP9vqDf79KXO4FITOESCKPFITJyg1AY5yymOOuxhfMtkVxFcdtjnBrQQRjMLnRecUM6HtM2ZAU1%2FwS3L%2B9JddnouOzjfLXph2mDen7EtOO9FmljvpufbU4zUEtamDzyAy4d7rkxMSW%2FBq9HTI8%2BBRVROCvn%2Bj938JSIHyDpno%2BAVmJI0%2FIfL3kOv8ZHmFh3fVNCyyegSEUREKeksre9NqbOUbTFQ3sdlXaao7I2awK%2FdlIWEo5Ub9Yt5Pvxlft08M4nhQEflysyVl3%2BAgslJEg%3D)
90
+ [Play with this code in the playground](https://litecanvas.js.org?c=eJx9U8tu2zAQvOsrBsghcitYtnMz4HvvLdD2SJFriTVNEuSqthH430tSduQEQQUI0GNmdnZ22bb4ziIwhFWIxKMHDwSyvbZUtS0MiWBxdIG2GJh93Lat0UxS2L8iLv%2FEpQt9Kzo38nLgo3lKIqxtH6sZVb9WSJdxzm%2FxCm01Nxi9EkwNVBCnBiy8J4VrU10XVa7Lg47Yj1aydhZhtBHOSoLgYrCjZNCmOtUbJsvWC0y1uh47rFCECNIZF%2FC0Qt0ZIQ%2BLApk%2B7vDyAfWC%2BjQk7xMqCKXHmGA%2F0WI9K5bGcNKKh3a9KlDv4vkG3GScJMsU8At1kn1H2CzuhEsifPtA%2BP0p4fpJLIpSxAxptDzElt0oB4pzIlOo9bnB5Z5LrjII21Oc2tBBGspGdGbcIZ2IaRhZYZh%2Fwu3Le1J9bPf82MrlZtOP05h6caQ0917LNJ735meb0ybUih9MHsWBHh3uhTEx5b%2BC12dKjz4FFUk6q%2Bb6X3fYJMQXKP7MRyCrKKSd%2BY%2BXvI1vSyRNrLt%2BUULL56BIRRmIpqSyt702ps5RNMVDc1uYZtqmws2aELdOCpHpzPV61SDfzz%2BET8fvchoo0PMjI8Oq6z8yIyTy)
95
91
 
96
92
  https://github.com/user-attachments/assets/854ac6bd-724f-4da8-bb3c-bc04dba5d8c8
97
93
 
@@ -99,13 +95,13 @@ https://github.com/user-attachments/assets/854ac6bd-724f-4da8-bb3c-bc04dba5d8c8
99
95
 
100
96
  Try some demos in the playground:
101
97
 
102
- - [Pong](https://litecanvas.js.org?c=eJy1Vlly20YQ%2FccpOl8ATBACuEiWYslFM5DlKkdMkUwkJpVKwcCQnAoEoIChpdiWr%2BAT%2BC%2BHyHlygVwh3TODTZYU%2F0QsDdELenm9DBMmIA%2FjCzgGf%2BA5BuAf0mdEj2vykkivEa%2BQHg01HbNSkALpKc6bMElaj6vmccHfsZZpYk3STUK8yhovpLeaWjVUmTMWIzmoQimjrGi9m%2FA1K5EcKlKwG0EOta4ICyFfX4dJyQwj4YJFYfo2LK33UuOax2J7BMMKhy3jm604gtFTZNzahrG3B9NdKbIr%2BPnd6SWU2S6NS1hnBYgtL2ETXjHSyQsmBGdFn29SjM%2BIsrQU8GL24%2Fk0QPe%2FOOCAz4b05XpDOgbIcGBAHAcOR54WVB8XJe6%2B0t%2F%2F9duHfSyWk%2FmSXHju2EFUYIxIyddGeAzbXsYHnvYsD%2B3IGz1m%2FsXk9evfZqeni%2Bk8CM7Jj%2B8OfZnOGB14rkdeyQ8eB9KbpPqH7iGe%2B3TSx3N9v3oayPfkOZKnTxka610aCZ6lwFMuLBveN42FfqfB%2BTKYXzYdVvNW0Iez4NXLsyXswajTBqhz8eq75RkK%2FIFx2%2FIhwjxnsXXjwB%2BVJ74G6xvdMhWv20Wi2LGGvb6xJPh2zUIEd0UqydvOnHz8aN1glHLq9mBgd0LZ5XEomBWL%2BwNRRgErJLjAsSmjgrH0ea2pJ%2BAYR6KtTJ0J2VtWPDekKrKukMS2ZRRHnLD2pCesyC05zSpmVVm7fjXOUlOglmi9j2SoDaqY6pCk0WcUjzbvSRHDGWzkPQXHiapQrarqpbAyaouq4r1moZzokrcLVbWKv%2B91eNQqBw2rWhnquw9%2Bp6Tdhrd1MSscVK2kVcizklMBW23aO1bL7IneW08gFq2OVeJVV6zWGCL7BndL1N5W2qfiK5%2FYLnew1o7byCgIP3zQQT2rZW2wVJzH0G%2FSbwKoG%2F22KZpK4UFjcmc%2FaqpOKNqy6HeVT5QlCS9pCq652LYbk1yitGCRUDk6%2BmKpA2g%2Fqdala0qeF7iI7HsCbCWr7pEeXXJfEbUEQElt1SZytXcHOS7C63pvRUlpefaji4W2VJjgurXMiKWCFaYD5hUnCEy7o1Vikla11LoiSy9Gp9qGaGM5%2BQGWM3U1oM2hfbeWqvVPaEKbcAjqNU8S60sw6edBbUdmx4tI6j5Ummp3PJDBfRhIhAiCbZhueLq5g4Hl4%2B1F%2F%2Bbfn%2F%2F8569PYLoFy1koVDa2A6P77bI0fsRqtW8q65Zp4jTJ7rBdzHtBUVl4E3v2XST%2F70piVAO8Xc2Xk%2B8DmP0UzM1ODb4wh%2FvEc5%2BO%2F8tqT6G4mM7mwREl%2B1UpY6f%2FC73Is6Q%3D)
103
- - [Bouncing Ball](https://litecanvas.js.org?c=eJxtUstugzAQvPMVewTiBCdtpVYpPVStSu6ReraMiSy5gIyhRUn%2BvQZvg0NzsGTveGdmH0oYqKtGGlmVkEIneLimlNgTkQDsW1Vcmn64HzTr8KpZLtvG%2Fr9%2FDAIljeCs7FgTRkFQtCUfyWQpTRjB0WNBgc%2Fd2z6LNyR7331k%2B2QTbSd2%2FEIRtNDZ42zrnBkR5sbx%2Fhlf%2FcAivajYVwy58fH%2BCu8d7hlzBGhhyvcyPHhKTxJ4raw3AVVRgMgPorFRWUA4OVtgr15gLBtOJ8%2F2EsFnoK6iK0txCsv19kaUrp4exrDXgBS4Yl%2B1p0xwTMQpo1ZkE89zl7Y%2BuPjEzs%2F99KOf%2F9LDyFwKKowC%2FtRyzb5xE7hqQjrOm0vNC6mUb3jiJGj9brYAw27YwnrHpoVpdQnHIWIlfwGU6d0i)
104
- - [Scroller](https://litecanvas.js.org?c=eJxVUMFOwzAMvfcrzAEtacNIxwZDsAPSJoG0AxJIO0w7hDZdI6XN1HhQgfbvOOs22CGJ7ff8nh1rUGeq%2FlSe8SgqtnWGxtVgaoPAOPxEAJX2Xq01TKC30DZzlQZ0YE%2BNFz0itQQvXqbvzxRvlKVsORQjcSvuxFjci1SKNF1Fu38W202uUAPLsbNB6pnNn17fZlPKvPnWR8nrwwR9q%2Bs1loSWBI3k3vZqAjdSQgw5nsnnjfo6bpBZzySnoHANMKsRDAnIB3oe4VycaknSdQEEJoa5MGGyn8aGn8p0UDcEHdv99sNjw4yA9I%2BVOesCiX5kWVjnGoYYjy4pPdjx1Z6LusWwMQsXP5VYpVrWChhInpg4YLHsjwWUyUAm3tRBbcjjUhzGEZ1hENjRZ%2FwCV%2F6J0w%3D%3D)
105
- - [3D projection](https://litecanvas.js.org?c=eJyNVUuP2jAQvudXTA%2FVOsU8y6kt7WVXhftK7W6Ug0PCYggOckxhqfjvHT9CYjYslRC2Z75vPJ5Xcq6yORN%2FWEnCIFjsxFzxQgAXXJEQ%2FgYAORfZnqdqSUYhHkt%2BzGACv2b3j1P4DtOH2c%2FpI%2FyoNn0YwxenxT0StrJYZdbqBCIUAERDCgP8xdQecT%2F0j1pijrG2UHChyprd1T5QaC4xhX4fogOFVwrH2OLaYE1Ni6J7S9MA%2BMauKt7Ku62KuI5VlurHagETL7kO9yA4NbKz26ZMZSRVNkMW1EFUbzAMULAoJJA8U8A19Ssu31wQe3kmXtQSRZ2OJQPMC1Eq1OsIG9Row5TkB9Lr9Swr4nFooNqmLBSzHiJss8uJEaBbv4lxJKTalsVfxT6dsQ5yA%2F%2FcjneuV1Eb3dfMuuwuOGc0vkq%2FuCaj%2BuTFOZVs77pgnpdkEOrgbnflkmhTSjJR5joRVbmPaN0GplnaEjG%2BDL7A6wmnQDh0YBjCRxjT2q3QhyEEtaSBDa3oGoECbwGcTFtt8R3N91YkRiGhrmLqIUBcMbA4GuhfhdCCoSdILhHJGfHZv9ElS1%2Fo4mwyyuZFrsuRIceVbK2Txd7oLhWJIyUtpMSRkkqBGr4AYi%2F6MJlYRAhqiSvgxIMHKQtJ7mY4G3Oegu2JrLwzRWCtyqysGrUt08ZTL9tIsFUX2RF1Zq0sa4Us8wzc1izbd%2BVuYwaBlZyZa8tc6%2Fssc91kguF1dCh5HK1j%2BITxWcfRKnaAk1utayhHe0gJKt1JP1dmaieFxnjZqztfspRjN9h7HfrqrJ8X5ZlgBqdoHJtAX%2BPTBm5otvnz9J4%2FF2b8W658kS599J15x5Pn%2F%2FfkWhxuB%2BHNJ7PpiTfR3ffRdyY6YF9Gr%2FrvGGvyP3c3Xb8%3D)
106
- - [Rendering Benchmark](https://litecanvas.js.org?c=eJylVVtv2jAUfs%2BvsNikJG0aEqAdZcBUdd1F6i7aRXtAaDWJAasmYY5pyVr%2B%2B47tNBia0m7zA9j%2BvnN87onSJBMoShPBU5ahHorTaDEjifAjTrAgZ4zIk2PH9Mp2rTuiT5OE8HffPpyDyIXVBbRvIVjdDPBk0j%2BZpYtEdLr14qxBjKacjHu1V1jBvTAIan346dbxA4xDyTjcxQBxqeTyYUZDMRo7GC3FaO1gtBWjvYMRHmlDjnZwmtqUZmFLt67iJqOHMpEz0qvN04wKmiYdxAnDgl6RWqErwskVzhCNe7Wo1u%2FW9flOyYVVJm6UxrmP53OSxM5dvlxrC1fP%2BVHKUg4ZtJ%2BFYWhXUkY4upxwsD4%2BLcnj8di2LEYEWnAGNwm5Rt%2B%2FnDssjbA03vWUyZmAAgL4Rp3kilRRoH0Q8zOCeTT9jDmeZf6EQInpINkuur1FkFWvFLumsZh24K7RWl9OCZ1MQVmrXTBXYBIVRMfF0Y8WksoSXx00905YA%2FqkES3eAS8j21pB3MaLJJJOIZpQ4biFN28%2Bf%2F354ezb2Rc%2Fptmc4dwRfEFcwNau%2B9mcUxWBOabQQ6XpYcOr3A%2FKnVy2D6sFS%2F7bXgWG8QNYEEgsCCqxhtTZqMBewGrCOoR1Dzs6etEMw%2BbhaPR32A6d0pZjWFW2SB%2BO2%2B3jah98X2IPxUXq3MKG6%2B3NhkAWYUY6qLnGV2rnmmmkv2USzZzqWrIUqV5HUMWCRowgNTShWHQpqdk6L7CsaJQTzqFatDLVD65BjqnssEHooYNwqO7H0HOObDUKQPAS%2FrrIEIaL%2FX13o8WkniWQOYYB4KI9s%2FrRgeHTlkx%2BX0Y3xi6hQbz0UJwPpdUbgVWawI%2Bm1AZuDeQFdQIPhe7Q%2BxfqsNyVIR1Q%2BfANAhtyMEOZUiRwZRkZNHNQ7i0j7owml%2BbH79eC8PwrYSQSKXcuBptj%2FPmNkYFVbXihU0jHkClQZKZDnotJOoZZ%2FEMHFIboKGWxXVi6MqZMzPF1OWWgtE4ZzEkkpqSYTNpoljmBa5Wvnn86ef3%2B41sXPhpiwZP7dYkTOttVmFth%2Bo%2FK42aIIT9WiXN%2FiQ6gxPx4adzlxV2%2BJkqPJLmLAnerXeU1GLN1Fy%2FRXg86Zt3DiLCMFIryakV5laJ8W9F9q%2FbNqdA3m6va2Ee772k%2BVD6r%2B7Pat8c7%2BAk%2Bz%2FCESK89qdTbGIFuWbx%2FAI20sBc%3D)
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
+ - [Bouncing Ball](https://litecanvas.js.org?c=eJxtkkFugzAQRfecYpaGOMFJW6lVQhddcQPWlm0iSy4gY0hRkrt3ADc4SRdI9nzm%2FzcMRjlo6lY7XVeQQa8E2TJG8YlpBHg3tdBuGM9Hy3t%2FtFzqrsX3X9%2BjyGinBK963pI4isquEpOZrrQjMZwDFx9QJDuap7t4v5h6hdEcq9fApWskd4pINzv9oW5%2BYJXdfPGWgHShPtzpw6wHKLOBT1%2F6g45AXtrTFL5qZFNQlyUoeVQtVnUJZCFb%2Ba%2FzCQVcLgHy2gsHYPM0dzhJBuvt%2Fp8q23y8TeVg%2BAyE4d9NkEr9UigUPifGpusjHc4FN778CWOYMJ4TxwXl3neyDXckLT%2F5TQvTEjYtVmgrSm1MiLjYUQ%2F78rDu8SfAUYbZzSrX2QrOYwUjfwF7%2FdPj)
100
+ - [Scroller](https://litecanvas.js.org?c=eJxVUM1SgzAQvvMU68FpAhFDLVpH%2BxbOcOj0ECGUzATSIYsyOn13NwXRHpJNvv1%2BkrUGdam6D%2BUZj6J66Eo0rgPTGQTG4TsCaLX36qhhB6tC29K1GtCBXYQ3KyKN1C6onpSl034jcvEonsRWPItMiiw7ROd%2F9sOpUqiBVThFePMV%2FIv7OSu1ujtiQ52G4FxeAu528CAlxFDhHNiqkY0C1pJfuVe9%2Bvx9fGk9ozZA7XpgViMYEsoXKq9wnUZYkkwqgMBEYr4lTKZZbPiC0kLdh%2FRZ7Yd3jz0zArI%2FVumsCySax762zvUM4%2FyWbnMYP1yoqEcMn2dh4wvExsTEAYpluhXQJGuZeNORx4bHjZjfIKaUIDvTAH4AEIGEgw%3D%3D)
101
+ - [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)
102
+ - [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)
107
103
 
108
- _See other demos in [samples](samples) folder_
104
+ > _See other demos in [samples](/samples) folder_
109
105
 
110
106
  ## Inspirations
111
107
 
package/dist/dist.dev.js CHANGED
@@ -32,27 +32,25 @@
32
32
  };
33
33
 
34
34
  // src/version.js
35
- var version = "0.95.1";
35
+ var version = "0.97.0";
36
36
 
37
37
  // src/index.js
38
38
  function litecanvas(settings = {}) {
39
39
  const root = window, math = Math, TWO_PI = math.PI * 2, raf = requestAnimationFrame, _browserEventListeners = [], on = (elem, evt, callback) => {
40
40
  elem.addEventListener(evt, callback, false);
41
41
  _browserEventListeners.push(() => elem.removeEventListener(evt, callback, false));
42
- }, preventDefault = (ev) => ev.preventDefault(), beginPath = (c) => c.beginPath(), isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
42
+ }, lowerCase = (str) => str.toLowerCase(), preventDefault = (ev) => ev.preventDefault(), beginPath = (c) => c.beginPath(), isNumber = Number.isFinite, zzfx = setupZzFX(root), defaults = {
43
43
  width: null,
44
44
  height: null,
45
45
  autoscale: true,
46
- pixelart: true,
47
46
  canvas: null,
48
47
  global: true,
49
48
  loop: null,
50
49
  tapEvents: true,
51
- keyboardEvents: true,
52
- animate: true
50
+ keyboardEvents: true
53
51
  };
54
52
  settings = Object.assign(defaults, settings);
55
- let _initialized = false, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rngSeed = Date.now(), _colors = defaultPalette, _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, _plugins = [], _canvas, _scale = 1, _ctx, _outline_fix = 0.5, _timeScale = 1, _lastFrameTime, _fpsInterval = 1e3 / 60, _accumulated, _rafid, _fontFamily = "sans-serif", _fontSize = 20, _rngSeed = Date.now(), _currentPalette, _colors, _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 = {};
56
54
  const instance = {
57
55
  /** @type {number} */
58
56
  W: 0,
@@ -129,7 +127,7 @@
129
127
  round: (n, precision = 0) => {
130
128
  DEV: assert(isNumber(n), "[litecanvas] round() 1st param must be a number");
131
129
  DEV: assert(
132
- null == precision || isNumber(precision) && precision >= 0,
130
+ isNumber(precision) && precision >= 0,
133
131
  "[litecanvas] round() 2nd param must be a positive number or zero"
134
132
  );
135
133
  if (!precision) {
@@ -515,15 +513,15 @@
515
513
  instance.stroke(color);
516
514
  },
517
515
  /**
518
- * Sets the thickness of lines
516
+ * Sets the thickness of the lines
519
517
  *
520
518
  * @param {number} value
521
519
  * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/lineWidth
522
520
  */
523
521
  linewidth(value) {
524
522
  DEV: assert(
525
- isNumber(value) && ~~value > 0,
526
- "[litecanvas] linewidth() 1st param must be a positive number"
523
+ isNumber(value) && value >= 0,
524
+ "[litecanvas] linewidth() 1st param must be a positive number or zero"
527
525
  );
528
526
  _ctx.lineWidth = ~~value;
529
527
  _outline_fix = 0 === ~~value % 2 ? 0 : 0.5;
@@ -626,19 +624,44 @@
626
624
  DEV: assert(isNumber(y), "[litecanvas] image() 2nd param must be a number");
627
625
  _ctx.drawImage(source, ~~x, ~~y);
628
626
  },
627
+ /**
628
+ * 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.
629
+ *
630
+ * @param {number} x
631
+ * @param {number} y
632
+ * @param {number} width
633
+ * @param {number} height
634
+ * @param {string} pixels
635
+ */
636
+ spr(x, y, width, height, pixels) {
637
+ DEV: assert(isNumber(x), "[litecanvas] spr() 1st param must be a number");
638
+ DEV: assert(isNumber(y), "[litecanvas] spr() 2nd param must be a number");
639
+ DEV: assert(isNumber(width), "[litecanvas] spr() 3rd param must be a number");
640
+ DEV: assert(isNumber(height), "[litecanvas] spr() 4th param must be a number");
641
+ DEV: assert("string" === typeof pixels, "[litecanvas] spr() 5th param must be a string");
642
+ const chars = pixels.replace(/\s/g, "");
643
+ for (let gridx = 0; gridx < width; gridx++) {
644
+ for (let gridy = 0; gridy < height; gridy++) {
645
+ const char = chars[height * gridy + gridx] || ".";
646
+ if (char !== ".") {
647
+ instance.rectfill(x + gridx, y + gridy, 1, 1, parseInt(char, 16) || 0);
648
+ }
649
+ }
650
+ }
651
+ },
629
652
  /**
630
653
  * Draw in an OffscreenCanvas and returns its image.
631
654
  *
632
655
  * @param {number} width
633
656
  * @param {number} height
634
- * @param {string[]|drawCallback} drawing
657
+ * @param {drawCallback} callback
635
658
  * @param {object} [options]
636
659
  * @param {number} [options.scale=1]
637
660
  * @param {OffscreenCanvas} [options.canvas]
638
661
  * @returns {ImageBitmap}
639
662
  * @see https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
640
663
  */
641
- paint(width, height, drawing, options = {}) {
664
+ paint(width, height, callback, options = {}) {
642
665
  DEV: assert(
643
666
  isNumber(width) && width >= 1,
644
667
  "[litecanvas] paint() 1st param must be a positive number"
@@ -648,7 +671,7 @@
648
671
  "[litecanvas] paint() 2nd param must be a positive number"
649
672
  );
650
673
  DEV: assert(
651
- "function" === typeof drawing || Array.isArray(drawing),
674
+ "function" === typeof callback,
652
675
  "[litecanvas] paint() 3rd param must be a function or array"
653
676
  );
654
677
  DEV: assert(
@@ -659,28 +682,13 @@
659
682
  options && null == options.canvas || options.canvas instanceof OffscreenCanvas,
660
683
  "[litecanvas] paint() 4th param (options.canvas) must be an OffscreenCanvas"
661
684
  );
662
- const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, contextOriginal = _ctx;
685
+ const canvas = options.canvas || new OffscreenCanvas(1, 1), scale = options.scale || 1, currentContext = _ctx;
663
686
  canvas.width = width * scale;
664
687
  canvas.height = height * scale;
665
688
  _ctx = canvas.getContext("2d");
666
689
  _ctx.scale(scale, scale);
667
- if (Array.isArray(drawing)) {
668
- let x = 0, y = 0;
669
- _ctx.imageSmoothingEnabled = false;
670
- for (const str of drawing) {
671
- for (const color of str) {
672
- if (" " !== color && "." !== color) {
673
- instance.rectfill(x, y, 1, 1, parseInt(color, 16));
674
- }
675
- x++;
676
- }
677
- y++;
678
- x = 0;
679
- }
680
- } else {
681
- drawing(_ctx);
682
- }
683
- _ctx = contextOriginal;
690
+ callback(_ctx);
691
+ _ctx = currentContext;
684
692
  return canvas.transferToImageBitmap();
685
693
  },
686
694
  /** ADVANCED GRAPHICS API */
@@ -702,23 +710,27 @@
702
710
  *
703
711
  * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/save
704
712
  */
705
- push: () => _ctx.save(),
713
+ push() {
714
+ _ctx.save();
715
+ },
706
716
  /**
707
717
  * restores the drawing style settings and transformations
708
718
  *
709
719
  * @see https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/restore
710
720
  */
711
- pop: () => _ctx.restore(),
721
+ pop() {
722
+ _ctx.restore();
723
+ },
712
724
  /**
713
725
  * Adds a translation to the transformation matrix.
714
726
  *
715
727
  * @param {number} x
716
728
  * @param {number} y
717
729
  */
718
- translate: (x, y) => {
730
+ translate(x, y) {
719
731
  DEV: assert(isNumber(x), "[litecanvas] translate() 1st param must be a number");
720
732
  DEV: assert(isNumber(y), "[litecanvas] translate() 2nd param must be a number");
721
- return _ctx.translate(~~x, ~~y);
733
+ _ctx.translate(~~x, ~~y);
722
734
  },
723
735
  /**
724
736
  * Adds a scaling transformation to the canvas units horizontally and/or vertically.
@@ -726,19 +738,19 @@
726
738
  * @param {number} x
727
739
  * @param {number} [y]
728
740
  */
729
- scale: (x, y) => {
741
+ scale(x, y) {
730
742
  DEV: assert(isNumber(x), "[litecanvas] scale() 1st param must be a number");
731
743
  DEV: assert(null == y || isNumber(y), "[litecanvas] scale() 2nd param must be a number");
732
- return _ctx.scale(x, y || x);
744
+ _ctx.scale(x, y || x);
733
745
  },
734
746
  /**
735
747
  * Adds a rotation to the transformation matrix.
736
748
  *
737
749
  * @param {number} radians
738
750
  */
739
- rotate: (radians) => {
751
+ rotate(radians) {
740
752
  DEV: assert(isNumber(radians), "[litecanvas] rotate() 1st param must be a number");
741
- return _ctx.rotate(radians);
753
+ _ctx.rotate(radians);
742
754
  },
743
755
  /**
744
756
  * Sets the alpha (opacity) value to apply when drawing new shapes and images
@@ -878,7 +890,7 @@
878
890
  "function" === typeof callback,
879
891
  "[litecanvas] listen() 2nd param must be a function"
880
892
  );
881
- eventName = eventName.toLowerCase();
893
+ eventName = lowerCase(eventName);
882
894
  _eventListeners[eventName] = _eventListeners[eventName] || /* @__PURE__ */ new Set();
883
895
  _eventListeners[eventName].add(callback);
884
896
  return () => _eventListeners && _eventListeners[eventName].delete(callback);
@@ -898,14 +910,14 @@
898
910
  "[litecanvas] emit() 1st param must be a string"
899
911
  );
900
912
  if (_initialized) {
901
- eventName = eventName.toLowerCase();
913
+ eventName = lowerCase(eventName);
902
914
  triggerEvent("before:" + eventName, arg1, arg2, arg3, arg4);
903
915
  triggerEvent(eventName, arg1, arg2, arg3, arg4);
904
916
  triggerEvent("after:" + eventName, arg1, arg2, arg3, arg4);
905
917
  }
906
918
  },
907
919
  /**
908
- * Set or reset the color palette
920
+ * Set or reset the color palette.
909
921
  *
910
922
  * @param {string[]} [colors]
911
923
  */
@@ -915,6 +927,31 @@
915
927
  "[litecanvas] pal() 1st param must be a array of strings"
916
928
  );
917
929
  _colors = colors;
930
+ _currentPalette = [...colors];
931
+ },
932
+ /**
933
+ * Swap two colors of the current palette.
934
+ *
935
+ * If called without arguments, reset the current palette.
936
+ *
937
+ * @param {number?} a
938
+ * @param {number?} b
939
+ */
940
+ palc(a, b) {
941
+ DEV: assert(
942
+ null == a || isNumber(a) && a >= 0,
943
+ "[litecanvas] palc() 1st param must be a positive number"
944
+ );
945
+ DEV: assert(
946
+ isNumber(a) ? isNumber(b) && b >= 0 : null == b,
947
+ "[litecanvas] palc() 2nd param must be a positive number"
948
+ );
949
+ if (a == null) {
950
+ _colors = [..._currentPalette];
951
+ } else {
952
+ ;
953
+ [_colors[a], _colors[b]] = [_colors[b], _colors[a]];
954
+ }
918
955
  },
919
956
  /**
920
957
  * Define or update a instance property.
@@ -963,12 +1000,15 @@
963
1000
  /**
964
1001
  * Returns information about that engine instance.
965
1002
  *
966
- * @param {number} n
1003
+ * @param {number|string} index
967
1004
  * @returns {any}
968
1005
  */
969
- stat(n) {
970
- DEV: assert(isNumber(n) && n >= 0, "[litecanvas] stat() 1st param must be a number");
971
- const list = [
1006
+ stat(index) {
1007
+ DEV: assert(
1008
+ isNumber(index) || "string" === typeof index,
1009
+ "[litecanvas] stat() 1st param must be a number or string"
1010
+ );
1011
+ const internals = [
972
1012
  // 0
973
1013
  settings,
974
1014
  // 1
@@ -994,7 +1034,7 @@
994
1034
  // 11
995
1035
  _fontFamily
996
1036
  ];
997
- const data = { index: n, value: list[n] };
1037
+ const data = { index, value: internals[index] };
998
1038
  instance.emit("stat", data);
999
1039
  return data.value;
1000
1040
  },
@@ -1223,12 +1263,12 @@
1223
1263
  const _keysDown = /* @__PURE__ */ new Set();
1224
1264
  const _keysPress = /* @__PURE__ */ new Set();
1225
1265
  const keyCheck = (keySet, key = "") => {
1226
- key = key.toLowerCase();
1266
+ key = lowerCase(key);
1227
1267
  return !key ? keySet.size > 0 : keySet.has("space" === key ? " " : key);
1228
1268
  };
1229
1269
  let _lastKey = "";
1230
1270
  on(root, "keydown", (event) => {
1231
- const key = event.key.toLowerCase();
1271
+ const key = lowerCase(event.key);
1232
1272
  if (!_keysDown.has(key)) {
1233
1273
  _keysDown.add(key);
1234
1274
  _keysPress.add(key);
@@ -1236,7 +1276,7 @@
1236
1276
  }
1237
1277
  });
1238
1278
  on(root, "keyup", (event) => {
1239
- _keysDown.delete(event.key.toLowerCase());
1279
+ _keysDown.delete(lowerCase(event.key));
1240
1280
  });
1241
1281
  on(root, "blur", () => _keysDown.clear());
1242
1282
  instance.listen("after:update", () => _keysPress.clear());
@@ -1281,9 +1321,7 @@
1281
1321
  instance.resume();
1282
1322
  }
1283
1323
  function drawFrame() {
1284
- if (!settings.animate) {
1285
- return instance.emit("draw", _ctx);
1286
- }
1324
+ _rafid = raf(drawFrame);
1287
1325
  let now = Date.now();
1288
1326
  let updated = 0;
1289
1327
  let frameTime = now - _lastFrameTime;
@@ -1305,7 +1343,6 @@
1305
1343
  );
1306
1344
  }
1307
1345
  }
1308
- _rafid = raf(drawFrame);
1309
1346
  }
1310
1347
  function setupCanvas() {
1311
1348
  if ("string" === typeof settings.canvas) {
@@ -1324,11 +1361,11 @@
1324
1361
  );
1325
1362
  _ctx = _canvas.getContext("2d");
1326
1363
  on(_canvas, "click", () => focus());
1327
- _canvas.style = "";
1328
1364
  resizeCanvas();
1329
1365
  if (!_canvas.parentNode) {
1330
1366
  document.body.appendChild(_canvas);
1331
1367
  }
1368
+ _canvas.style.imageRendering = "pixelated";
1332
1369
  _canvas.oncontextmenu = () => false;
1333
1370
  }
1334
1371
  function resizeCanvas() {
@@ -1360,15 +1397,9 @@
1360
1397
  _canvas.style.width = width * _scale + "px";
1361
1398
  _canvas.style.height = height * _scale + "px";
1362
1399
  }
1363
- if (settings.pixelart) {
1364
- _ctx.imageSmoothingEnabled = false;
1365
- _canvas.style.imageRendering = "pixelated";
1366
- }
1400
+ _ctx.imageSmoothingEnabled = false;
1367
1401
  instance.textalign("start", "top");
1368
1402
  instance.emit("resized", _scale);
1369
- if (!settings.animate) {
1370
- raf(drawFrame);
1371
- }
1372
1403
  }
1373
1404
  function triggerEvent(eventName, arg1, arg2, arg3, arg4) {
1374
1405
  if (!_eventListeners[eventName]) return;
@@ -1396,6 +1427,7 @@
1396
1427
  DEV: console.info(`[litecanvas] version ${version} started`);
1397
1428
  DEV: console.debug(`[litecanvas] litecanvas() options =`, settings);
1398
1429
  setupCanvas();
1430
+ instance.pal();
1399
1431
  if ("loading" === document.readyState) {
1400
1432
  on(root, "DOMContentLoaded", () => raf(init));
1401
1433
  } else {