feat(www): Add logic to the homepage and Steam integration (#258)

## Description
<!-- Briefly describe the purpose and scope of your changes -->


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Upgraded API and authentication services with dynamic scaling,
enhanced load balancing, and real-time interaction endpoints.
- Introduced new commands to streamline local development and container
builds.
- Added new endpoints for retrieving Steam account information and
managing connections.
- Implemented a QR code authentication interface for Steam, enhancing
user login experiences.

- **Database Updates**
- Rolled out comprehensive schema migrations that improve data integrity
and indexing.
- Introduced new tables for managing Steam user credentials and machine
information.

- **UI Enhancements**
- Added refreshed animated assets and an improved QR code login flow for
a more engaging experience.
	- Introduced new styled components for displaying friends and games.

- **Maintenance**
- Completed extensive refactoring and configuration updates to optimize
performance and development workflows.
- Updated logging configurations and improved error handling mechanisms.
	- Streamlined resource definitions in the configuration files.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
This commit is contained in:
Wanjohi
2025-04-13 14:30:45 +03:00
committed by GitHub
parent 8394bb4259
commit f408ec56cb
103 changed files with 12755 additions and 2053 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,588 @@
{"frames": [
{
"filename": "intro_00000.png",
"frame": {"x":1,"y":1,"w":3,"h":3},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":3,"h":3},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00001.png",
"frame": {"x":911,"y":364,"w":150,"h":150},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00002.png",
"frame": {"x":1063,"y":367,"w":150,"h":150},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00003.png",
"frame": {"x":1215,"y":372,"w":150,"h":150},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00004.png",
"frame": {"x":1367,"y":374,"w":150,"h":150},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00005.png",
"frame": {"x":1519,"y":375,"w":150,"h":150},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00006.png",
"frame": {"x":1671,"y":379,"w":150,"h":150},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00007.png",
"frame": {"x":1823,"y":381,"w":150,"h":150},
"rotated": false,
"trimmed": false,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00008.png",
"frame": {"x":759,"y":362,"w":150,"h":149},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":0,"y":0,"w":150,"h":149},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00009.png",
"frame": {"x":456,"y":355,"w":148,"h":149},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":148,"h":149},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00010.png",
"frame": {"x":607,"y":360,"w":148,"h":150},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":0,"w":148,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00011.png",
"frame": {"x":1,"y":349,"w":147,"h":150},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":147,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00012.png",
"frame": {"x":153,"y":351,"w":147,"h":150},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":3,"y":0,"w":147,"h":150},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00013.png",
"frame": {"x":305,"y":353,"w":147,"h":149},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":2,"y":1,"w":147,"h":149},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00014.png",
"frame": {"x":1867,"y":235,"w":144,"h":148},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":4,"y":2,"w":144,"h":148},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00015.png",
"frame": {"x":1719,"y":235,"w":142,"h":146},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":5,"y":3,"w":142,"h":146},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00016.png",
"frame": {"x":1574,"y":233,"w":140,"h":143},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":4,"w":140,"h":143},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00017.png",
"frame": {"x":1432,"y":233,"w":139,"h":140},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":6,"w":139,"h":140},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00018.png",
"frame": {"x":1292,"y":233,"w":138,"h":137},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":6,"y":7,"w":138,"h":137},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00019.png",
"frame": {"x":1154,"y":231,"w":136,"h":134},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":7,"y":9,"w":136,"h":134},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00020.png",
"frame": {"x":1018,"y":229,"w":134,"h":133},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":8,"y":9,"w":134,"h":133},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00021.png",
"frame": {"x":885,"y":229,"w":131,"h":131},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":9,"y":10,"w":131,"h":131},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00022.png",
"frame": {"x":754,"y":229,"w":129,"h":129},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":10,"y":11,"w":129,"h":129},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00023.png",
"frame": {"x":624,"y":229,"w":128,"h":127},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":11,"y":12,"w":128,"h":127},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00024.png",
"frame": {"x":496,"y":227,"w":126,"h":126},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":12,"y":12,"w":126,"h":126},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00025.png",
"frame": {"x":370,"y":227,"w":124,"h":124},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":13,"y":13,"w":124,"h":124},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00026.png",
"frame": {"x":246,"y":227,"w":122,"h":122},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":14,"w":122,"h":122},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00027.png",
"frame": {"x":1,"y":227,"w":121,"h":120},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":14,"y":15,"w":121,"h":120},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00028.png",
"frame": {"x":124,"y":227,"w":120,"h":120},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":15,"y":15,"w":120,"h":120},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00029.png",
"frame": {"x":1855,"y":115,"w":118,"h":118},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":16,"y":16,"w":118,"h":118},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00030.png",
"frame": {"x":1735,"y":115,"w":117,"h":118},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":16,"y":16,"w":117,"h":118},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00031.png",
"frame": {"x":1381,"y":115,"w":116,"h":116},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":17,"y":17,"w":116,"h":116},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00032.png",
"frame": {"x":1499,"y":115,"w":116,"h":116},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":17,"y":17,"w":116,"h":116},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00033.png",
"frame": {"x":1617,"y":115,"w":116,"h":116},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":17,"y":17,"w":116,"h":116},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00034.png",
"frame": {"x":685,"y":113,"w":114,"h":114},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":18,"w":114,"h":114},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00035.png",
"frame": {"x":801,"y":113,"w":114,"h":114},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":18,"w":114,"h":114},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00036.png",
"frame": {"x":917,"y":113,"w":114,"h":114},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":18,"w":114,"h":114},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00037.png",
"frame": {"x":1033,"y":113,"w":114,"h":114},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":18,"w":114,"h":114},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00038.png",
"frame": {"x":1149,"y":113,"w":114,"h":114},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":18,"w":114,"h":114},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00039.png",
"frame": {"x":1265,"y":115,"w":114,"h":114},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":18,"w":114,"h":114},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00040.png",
"frame": {"x":1350,"y":1,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00041.png",
"frame": {"x":1464,"y":1,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00042.png",
"frame": {"x":1578,"y":1,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00043.png",
"frame": {"x":1692,"y":1,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00044.png",
"frame": {"x":1806,"y":1,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00045.png",
"frame": {"x":1920,"y":1,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00046.png",
"frame": {"x":1,"y":113,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00047.png",
"frame": {"x":115,"y":113,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00048.png",
"frame": {"x":229,"y":113,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00049.png",
"frame": {"x":343,"y":113,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00050.png",
"frame": {"x":457,"y":113,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00051.png",
"frame": {"x":571,"y":113,"w":112,"h":112},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":19,"w":112,"h":112},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00052.png",
"frame": {"x":6,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00053.png",
"frame": {"x":118,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00054.png",
"frame": {"x":230,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00055.png",
"frame": {"x":342,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00056.png",
"frame": {"x":454,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00057.png",
"frame": {"x":566,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00058.png",
"frame": {"x":678,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00059.png",
"frame": {"x":790,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00060.png",
"frame": {"x":902,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00061.png",
"frame": {"x":1014,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00062.png",
"frame": {"x":1126,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "intro_00063.png",
"frame": {"x":1238,"y":1,"w":110,"h":110},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":20,"w":110,"h":110},
"sourceSize": {"w":150,"h":150},
"pivot": {"x":0.5,"y":0.5}
}],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "1.0",
"image": "play_button_intro.png",
"format": "RGBA8888",
"size": {"w":2033,"h":532},
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:c182f7ef1f119bbfd7cc0a11dba8aad6:0f1ccfe8fb1cdc864d87b7e8f6fb3197:356e3de40db0da0fa679697918a56687$"
}
}

View File

@@ -0,0 +1,237 @@
{"frames": [
{
"filename": "processing_outro_190822_00000.png",
"frame": {"x":82,"y":37,"w":25,"h":13},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":36,"y":16,"w":25,"h":13},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00001.png",
"frame": {"x":173,"y":1,"w":27,"h":11},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":16,"w":27,"h":11},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00002.png",
"frame": {"x":186,"y":1,"w":30,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":50,"y":16,"w":30,"h":15},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00003.png",
"frame": {"x":122,"y":35,"w":32,"h":27},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":58,"y":16,"w":32,"h":27},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00004.png",
"frame": {"x":1,"y":1,"w":22,"h":37},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":72,"y":23,"w":22,"h":37},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00005.png",
"frame": {"x":25,"y":1,"w":17,"h":37},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":77,"y":40,"w":17,"h":37},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00006.png",
"frame": {"x":1,"y":40,"w":31,"h":21},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":59,"y":63,"w":31,"h":21},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00007.png",
"frame": {"x":34,"y":40,"w":29,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":44,"y":65,"w":29,"h":19},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00008.png",
"frame": {"x":65,"y":37,"w":15,"h":25},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":41,"y":52,"w":15,"h":25},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00009.png",
"frame": {"x":186,"y":18,"w":19,"h":18},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":43,"y":47,"w":19,"h":18},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00010.png",
"frame": {"x":186,"y":38,"w":18,"h":18},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":47,"y":46,"w":18,"h":18},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00011.png",
"frame": {"x":97,"y":37,"w":23,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":45,"y":43,"w":23,"h":24},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00012.png",
"frame": {"x":156,"y":35,"w":27,"h":28},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":43,"y":41,"w":27,"h":28},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00013.png",
"frame": {"x":142,"y":1,"w":29,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":39,"w":29,"h":32},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00014.png",
"frame": {"x":110,"y":1,"w":30,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":39,"w":30,"h":32},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00015.png",
"frame": {"x":44,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00016.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00017.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00018.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00019.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00020.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00021.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00022.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00023.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing_outro_190822_00024.png",
"frame": {"x":77,"y":1,"w":31,"h":34},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":42,"y":38,"w":31,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
}],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "1.0",
"image": "play_icon_exit.png",
"format": "RGBA8888",
"size": {"w":217,"h":63},
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:c3c530fe6905479b4ca8719a9d079c2e:313834a760df7f23cb3a698e4cd74589:0d545ddd0574d55083449defb59d19dc$"
}
}

View File

@@ -0,0 +1,237 @@
{"frames": [
{
"filename": "processing-intro_190822_00000.png",
"frame": {"x":1,"y":1,"w":35,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":40,"y":36,"w":35,"h":38},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00001.png",
"frame": {"x":38,"y":1,"w":34,"h":38},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":40,"y":36,"w":34,"h":38},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00002.png",
"frame": {"x":74,"y":1,"w":29,"h":32},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":43,"y":39,"w":29,"h":32},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00003.png",
"frame": {"x":1,"y":41,"w":22,"h":24},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":46,"y":43,"w":22,"h":24},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00004.png",
"frame": {"x":142,"y":43,"w":17,"h":18},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":48,"y":46,"w":17,"h":18},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00005.png",
"frame": {"x":161,"y":40,"w":14,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":49,"y":45,"w":14,"h":14},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00006.png",
"frame": {"x":183,"y":1,"w":10,"h":10},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":54,"y":42,"w":10,"h":10},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00007.png",
"frame": {"x":183,"y":37,"w":9,"h":9},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":62,"y":38,"w":9,"h":9},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00008.png",
"frame": {"x":183,"y":25,"w":10,"h":10},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":73,"y":38,"w":10,"h":10},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00009.png",
"frame": {"x":180,"y":13,"w":10,"h":12},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":82,"y":46,"w":10,"h":12},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00010.png",
"frame": {"x":168,"y":1,"w":10,"h":13},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":84,"y":59,"w":10,"h":13},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00011.png",
"frame": {"x":177,"y":48,"w":13,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":76,"y":72,"w":13,"h":13},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00012.png",
"frame": {"x":139,"y":13,"w":17,"h":12},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":63,"y":80,"w":17,"h":12},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00013.png",
"frame": {"x":158,"y":13,"w":20,"h":10},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":49,"y":84,"w":20,"h":10},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00014.png",
"frame": {"x":160,"y":25,"w":21,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":36,"y":81,"w":21,"h":13},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00015.png",
"frame": {"x":114,"y":27,"w":21,"h":18},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":26,"y":73,"w":21,"h":18},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00016.png",
"frame": {"x":94,"y":35,"w":18,"h":22},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":20,"y":63,"w":18,"h":22},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00017.png",
"frame": {"x":123,"y":1,"w":14,"h":24},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":53,"w":14,"h":24},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00018.png",
"frame": {"x":139,"y":1,"w":10,"h":27},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":42,"w":10,"h":27},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00019.png",
"frame": {"x":114,"y":50,"w":13,"h":26},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":34,"w":13,"h":26},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00020.png",
"frame": {"x":75,"y":35,"w":17,"h":25},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":19,"y":27,"w":17,"h":25},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00021.png",
"frame": {"x":27,"y":41,"w":21,"h":22},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":21,"y":22,"w":21,"h":22},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00022.png",
"frame": {"x":50,"y":41,"w":23,"h":19},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":25,"y":19,"w":23,"h":19},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00023.png",
"frame": {"x":105,"y":1,"w":24,"h":16},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":30,"y":17,"w":24,"h":16},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-intro_190822_00024.png",
"frame": {"x":134,"y":27,"w":24,"h":14},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":35,"y":16,"w":24,"h":14},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
}],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "1.0",
"image": "play_icon_intro.png",
"format": "RGBA8888",
"size": {"w":194,"h":64},
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:a423de98fed1e06cc62611996868a2db:909cd8dbde93c0d2fca4402e7546ffd8:5ea08d4d7caaa5043281f5095baffab1$"
}
}

View File

@@ -0,0 +1,237 @@
{"frames": [
{
"filename": "processing-loop_190822_00000.png",
"frame": {"x":37,"y":97,"w":23,"h":11},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":40,"y":16,"w":23,"h":11},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00001.png",
"frame": {"x":37,"y":110,"w":23,"h":10},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":46,"y":16,"w":23,"h":10},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00002.png",
"frame": {"x":30,"y":257,"w":24,"h":12},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":51,"y":16,"w":24,"h":12},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00003.png",
"frame": {"x":34,"y":225,"w":25,"h":15},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":56,"y":16,"w":25,"h":15},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00004.png",
"frame": {"x":1,"y":252,"w":27,"h":20},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":61,"y":17,"w":27,"h":20},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00005.png",
"frame": {"x":35,"y":180,"w":24,"h":25},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":68,"y":19,"w":24,"h":25},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00006.png",
"frame": {"x":39,"y":39,"w":21,"h":30},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":74,"y":24,"w":21,"h":30},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00007.png",
"frame": {"x":1,"y":120,"w":16,"h":34},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":80,"y":30,"w":16,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00008.png",
"frame": {"x":1,"y":58,"w":13,"h":36},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":83,"y":38,"w":13,"h":36},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00009.png",
"frame": {"x":41,"y":1,"w":19,"h":36},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":77,"y":47,"w":19,"h":36},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00010.png",
"frame": {"x":1,"y":151,"w":27,"h":33},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":68,"y":57,"w":27,"h":33},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00011.png",
"frame": {"x":1,"y":73,"w":34,"h":26},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":57,"y":68,"w":34,"h":26},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00012.png",
"frame": {"x":1,"y":1,"w":38,"h":18},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":46,"y":76,"w":38,"h":18},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00013.png",
"frame": {"x":1,"y":21,"w":38,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":36,"y":81,"w":38,"h":13},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00014.png",
"frame": {"x":1,"y":36,"w":36,"h":20},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":27,"y":74,"w":36,"h":20},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00015.png",
"frame": {"x":1,"y":197,"w":31,"h":27},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":21,"y":66,"w":31,"h":27},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00016.png",
"frame": {"x":1,"y":226,"w":24,"h":31},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":57,"w":24,"h":31},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00017.png",
"frame": {"x":1,"y":101,"w":17,"h":34},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":47,"w":17,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00018.png",
"frame": {"x":1,"y":138,"w":11,"h":34},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":39,"w":11,"h":34},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00019.png",
"frame": {"x":1,"y":180,"w":15,"h":32},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":31,"w":15,"h":32},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00020.png",
"frame": {"x":37,"y":149,"w":20,"h":29},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":18,"y":25,"w":20,"h":29},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00021.png",
"frame": {"x":37,"y":122,"w":22,"h":25},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":21,"y":21,"w":22,"h":25},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00022.png",
"frame": {"x":39,"y":71,"w":24,"h":21},
"rotated": true,
"trimmed": true,
"spriteSourceSize": {"x":25,"y":18,"w":24,"h":21},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00023.png",
"frame": {"x":34,"y":206,"w":25,"h":17},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":30,"y":16,"w":25,"h":17},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
},
{
"filename": "processing-loop_190822_00024.png",
"frame": {"x":34,"y":242,"w":25,"h":13},
"rotated": false,
"trimmed": true,
"spriteSourceSize": {"x":36,"y":16,"w":25,"h":13},
"sourceSize": {"w":110,"h":110},
"pivot": {"x":0.5,"y":0.5}
}],
"meta": {
"app": "https://www.codeandweb.com/texturepacker",
"version": "1.0",
"image": "play_icon_loop.png",
"format": "RGBA8888",
"size": {"w":61,"h":273},
"scale": "1",
"smartupdate": "$TexturePacker:SmartUpdate:4d92719faa27cbc50926429a66fc808c:25af8a045fca3b76dba8d8d26ed4ccf7:9b86d3b10829102d2ccf1bd5942144f2$"
}
}

View File

@@ -0,0 +1,309 @@
import PlayIconLoop from "./assets/play_icon_loop.json"
import PlayIconExit from "./assets/play_icon_exit.json"
import PlayIconIntro from "./assets/play_icon_intro.json"
import PlayButtonIdle from "./assets/play_button_idle.json"
import PlayButtonIntro from "./assets/play_button_intro.json"
const button_assets = {
intro: {
image: "/src/assets/portal/play_button_intro.png",
json: PlayButtonIntro
},
idle: {
image: "/src/assets/portal/play_button_idle.png",
json: PlayButtonIdle
}
}
const icon_assets = {
intro: {
image: "/src/assets/portal/play_icon_intro.png",
json: PlayIconIntro
},
loop: {
image: "/src/assets/portal/play_icon_loop.png",
json: PlayIconLoop
},
exit: {
image: "/src/assets/portal/play_icon_exit.png",
json: PlayIconExit
}
}
export class PortalButton {
private canvas: HTMLCanvasElement;
private currentFrame: number;
private index: number;
private buttonQueue: (() => void)[];
private isButtonRunning: boolean;
private animationSpeed: number;
constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas;
this.currentFrame = 0;
this.index = 0;
this.buttonQueue = [];
this.isButtonRunning = false;
this.animationSpeed = 50;
}
render(type: "intro" | "idle", loop: boolean, image: HTMLImageElement, index?: number) {
if (index) this.index = index
return new Promise<void>((resolve) => {
const buttonTask = () => {
// Get the canvas element
const ctx = this.canvas.getContext('2d');
// Load the JSON data
const animationData = button_assets[type].json;
// Play the animation
const frames = animationData.frames;
const totalFrames = frames.length;
if (this.index) this.currentFrame = this.index;
const targetDim = 100 //target dimensions of the output image (height, width)
// Start the animation
const updateFrame = () => {
// Check if we have reached the last frame
if (!loop && this.currentFrame === totalFrames - 1) {
// Animation has reached the last frame, stop playing
this.isButtonRunning = false;
// Resolve the Promise to indicate completion
resolve();
return null;
}
// Clear the canvas
ctx?.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Get the current frame details
const singleFrame = frames[this.currentFrame];
const { frame, sourceSize: ss, rotated, spriteSourceSize: sss, trimmed } = singleFrame;
this.canvas.width = targetDim;
this.canvas.height = targetDim;
this.canvas.style.borderRadius = `${ss.h / 2}px`
const newSize = {
w: frame.w,
h: frame.h
};
const newPosition = {
x: 0,
y: 0
};
if (rotated) {
ctx?.save()
ctx?.translate(this.canvas.width / 2, this.canvas.height / 2)
ctx?.rotate(-Math.PI / 2);
ctx?.translate(-this.canvas.height / 2, -this.canvas.width / 2);
newSize.w = frame.h;
newSize.h = frame.w;
}
if (trimmed) {
newPosition.x = sss.x;
newPosition.y = sss.y;
if (rotated) {
newPosition.x = this.canvas.height - sss.h - sss.y;
newPosition.y = sss.x;
}
}
const scaleFactor = Math.min(targetDim / newSize.w, targetDim / newSize.h);
const scaledWidth = newSize.w * scaleFactor;
const scaledHeight = newSize.h * scaleFactor;
// Calculate the center position to draw the resized image
const x = (targetDim - scaledWidth) / 2;
const y = (targetDim - scaledHeight) / 2;
ctx?.drawImage(
image,
frame.x,
frame.y,
newSize.w,
newSize.h,
x,
y,
scaledWidth,
scaledHeight
)
if (rotated) {
ctx?.restore()
}
// Increment the frame index
this.currentFrame = (this.currentFrame + 1) % totalFrames
// Schedule the next frame update
setTimeout(updateFrame, this.animationSpeed);
};
return updateFrame()
}
// Check if the button function is already running
if (this.isButtonRunning) {
// If running, add the button task to the queue
this.buttonQueue.push(buttonTask);
} else {
// If not running, set the flag and execute the button task immediately
this.isButtonRunning = true;
buttonTask();
}
})
}
}
export class PortalIcon {
private canvas: HTMLCanvasElement;
private currentFrame: number;
private index: number;
private iconQueue: (() => void)[];
private isIconRunning: boolean;
private animationSpeed: number;
constructor(canvas: HTMLCanvasElement) {
this.canvas = canvas;
this.currentFrame = 0;
this.index = 0;
this.iconQueue = [];
this.isIconRunning = false;
this.animationSpeed = 50;
}
render(type: "loop" | "intro" | "exit", loop: boolean, image: HTMLImageElement, play: boolean) {
return new Promise<void>((resolve) => {
const iconTask = () => {
// Get the canvas element
const ctx = this.canvas.getContext('2d');
// Load the JSON data
const animationData = icon_assets[type].json;
// Load the image
// const image = new Image();
image.src = icon_assets[type].image; // Path to the sprite sheet image
// Play the animation
const frames = animationData.frames;
const totalFrames = frames.length;
if (!play) {
this.currentFrame = totalFrames - 3
} else { this.currentFrame = 0 }
// Start the animation
const updateFrame = () => {
// Check if we have reached the last frame
if (!loop && this.currentFrame === totalFrames - 1) {
// Animation has reached the last frame, stop playing
this.isIconRunning = false;
// Resolve the Promise to indicate completion
resolve();
return;
}
// Clear the canvas
ctx?.clearRect(0, 0, this.canvas.width, this.canvas.height);
// Get the current frame details
const singleFrame = frames[this.currentFrame];
const { frame, sourceSize: ss, rotated, spriteSourceSize: sss, trimmed } = singleFrame;
this.canvas.width = ss.w;
this.canvas.height = ss.h
this.canvas.style.borderRadius = `${ss.h / 2}px`
const newSize = {
w: frame.w,
h: frame.h
};
const newPosition = {
x: 0,
y: 0
};
if (rotated) {
ctx?.save()
ctx?.translate(this.canvas.width / 2, this.canvas.height / 2)
ctx?.rotate(-Math.PI / 2);
ctx?.translate(-this.canvas.height / 2, -this.canvas.width / 2);
newSize.w = frame.h;
newSize.h = frame.w;
}
if (trimmed) {
newPosition.x = sss.x;
newPosition.y = sss.y;
if (rotated) {
newPosition.x = this.canvas.height - sss.h - sss.y;
newPosition.y = sss.x;
}
}
ctx?.drawImage(
image,
frame.x,
frame.y,
newSize.w,
newSize.h,
newPosition.x,
newPosition.y,
newSize.w,
newSize.h
)
if (rotated) {
ctx?.restore()
}
// Increment the frame index
this.currentFrame = (this.currentFrame + 1) % totalFrames
// Schedule the next frame update
if (!play) {
this.isIconRunning = false;
resolve();
return;
}
setTimeout(updateFrame, this.animationSpeed)
};
return updateFrame();
}
// Check if the icon function is already running
if (this.isIconRunning) {
// If running, add the button icon to the queue
this.iconQueue.push(iconTask);
} else {
// If not running, set the flag and execute the button task immediately
this.isIconRunning = true;
iconTask();
}
})
}
}
const portal = { assets: { button_assets, icon_assets } }
export default portal;

View File

@@ -0,0 +1,123 @@
import { createEffect, createSignal, onCleanup } from "solid-js";
import portalbtn, { PortalButton, PortalIcon } from "./button";
import { styled } from "@macaron-css/solid";
import { theme } from "@nestri/www/ui";
const PlayBtn = styled("button", {
base: {
position: "relative",
backgroundColor: "transparent",
outline: "none",
border: "none",
padding: 0,
margin: 0,
height: 100,
borderRadius: 999,
":focus": {
outline: `3px solid ${theme.color.brand}`
}
}
})
const CanvasOne = styled("canvas", {
base: {
position: "absolute",
inset: 0,
height: "100%",
width: "100%",
borderRadius: 999,
}
})
const CanvasTwo = styled("canvas", {
base: {
position: "relative",
inset: 0,
zIndex: 1,
height: "100%",
width: "100%",
borderRadius: 999,
}
})
/**
* Renders a portal play button with animated canvas icons.
*
* This Solid.js component manages two canvas elements that display an animated portal button and its icon. It asynchronously loads a set of image assets and uses instances of PortalButton and PortalIcon to render various animation states—including intro, idle, exit, and loop—on the canvases. Image loading errors are logged to the console.
*
* @returns A JSX element containing a styled button with two canvases for rendering animations.
*/
export function Portal() {
const [iconRef, setIconRef] = createSignal<HTMLCanvasElement | undefined>();
const [buttonRef, setButtonRef] = createSignal<HTMLCanvasElement | undefined>();
const imageUrls = [
portalbtn.assets.button_assets["intro"].image,
portalbtn.assets.button_assets["idle"].image,
portalbtn.assets.icon_assets["exit"].image,
portalbtn.assets.icon_assets["intro"].image,
portalbtn.assets.icon_assets["loop"].image
];
const loadImages = () => {
return Promise.all(imageUrls.map(url => {
return new Promise((resolve, reject) => {
const img = new Image();
img.onload = () => resolve(img);
img.onerror = (e) => {
console.error(`Failed to load image from ${url}:`, e);
reject(new Error(`Failed to load image from ${url}`));
};
img.src = url;
});
}));
}
createEffect(() => {
(async () => {
const btnRef = buttonRef()
const icnRef = iconRef()
let isActive = true;
if (icnRef && btnRef) {
try {
// Destructure images for each animation type - skipping introIconImg at index 3
const [introImg, idleImg, exitImg, , loopImg] = await loadImages();
const button = new PortalButton(btnRef);
const icon = new PortalIcon(icnRef)
if (!isActive) return;
await button.render("intro", false, introImg as HTMLImageElement);
await icon.render("exit", false, exitImg as HTMLImageElement, false);
await button.render("idle", true, idleImg as HTMLImageElement, 3);
// Intro and loop animation
await Promise.all([
(async () => {
if (icnRef) {
await icon.render("loop", false, loopImg as HTMLImageElement, true);
await icon.render("loop", false, loopImg as HTMLImageElement, true);
await icon.render("exit", false, exitImg as HTMLImageElement, true);
}
})(),
button.render("idle", true, idleImg as HTMLImageElement, 2),
]);
} catch (err) {
console.error("Failed to load animation images:", err);
}
}
onCleanup(() => {
isActive = false;
});
})()
});
return (
<PlayBtn autofocus>
<CanvasOne height={100} width={100} ref={setButtonRef} />
<CanvasTwo height={100} width={100} ref={setIconRef} />
</PlayBtn>
)
}