Init v2
BIN
bun.lockb
93
package-lock.json
generated
|
@ -16,10 +16,17 @@
|
|||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"react": "^18.3.1",
|
||||
"react-animate-on-scroll": "^2.1.9",
|
||||
"react-dom": "^18.3.1",
|
||||
"react-parallax-tilt": "^1.7.228",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.9.5",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-animate-on-scroll": "^2.1.8",
|
||||
"daisyui": "^4.12.2",
|
||||
"tailwindcss": "^3.4.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@adobe/css-tools": {
|
||||
|
@ -4177,6 +4184,15 @@
|
|||
"csstype": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-animate-on-scroll": {
|
||||
"version": "2.1.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-animate-on-scroll/-/react-animate-on-scroll-2.1.8.tgz",
|
||||
"integrity": "sha512-Lyd1hb1aY9T0bOUL3VE7bKuOlAv2nBziJg5piDLqW+jxzy5jCa/nIftsOpYxZ0+Sdo0wFXuI6tpLo6B0Q288IQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/react-dom": {
|
||||
"version": "18.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.3.0.tgz",
|
||||
|
@ -5842,6 +5858,12 @@
|
|||
"resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz",
|
||||
"integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q=="
|
||||
},
|
||||
"node_modules/classnames": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||
"integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
|
||||
"peer": true
|
||||
},
|
||||
"node_modules/clean-css": {
|
||||
"version": "5.3.3",
|
||||
"resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz",
|
||||
|
@ -6285,6 +6307,16 @@
|
|||
"resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
|
||||
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
|
||||
},
|
||||
"node_modules/css-selector-tokenizer": {
|
||||
"version": "0.8.0",
|
||||
"resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.8.0.tgz",
|
||||
"integrity": "sha512-Jd6Ig3/pe62/qe5SBPTN8h8LeUg/pT4lLgtavPf7updwwHpvFzxvOQBHYj2LZDMjUnBzgvIUSjRcf6oT5HzHFg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"cssesc": "^3.0.0",
|
||||
"fastparse": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"node_modules/css-tree": {
|
||||
"version": "1.0.0-alpha.37",
|
||||
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
|
||||
|
@ -6482,6 +6514,34 @@
|
|||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
|
||||
},
|
||||
"node_modules/culori": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/culori/-/culori-3.3.0.tgz",
|
||||
"integrity": "sha512-pHJg+jbuFsCjz9iclQBqyL3B2HLCBF71BwVNujUYEvCeQMvV97R59MNK3R2+jgJ3a1fcZgI9B3vYgz8lzr/BFQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/daisyui": {
|
||||
"version": "4.12.2",
|
||||
"resolved": "https://registry.npmjs.org/daisyui/-/daisyui-4.12.2.tgz",
|
||||
"integrity": "sha512-ed3EFwPRLN+9+/MYPRB1pYjk6plRCBMobfBdSeB3voAS81KdL2pCKtbwJfUUpDdOnJ0F8T6oRdVX02P6UCD0Hg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"css-selector-tokenizer": "^0.8",
|
||||
"culori": "^3",
|
||||
"picocolors": "^1",
|
||||
"postcss-js": "^4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.9.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/daisyui"
|
||||
}
|
||||
},
|
||||
"node_modules/damerau-levenshtein": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
|
||||
|
@ -8061,6 +8121,12 @@
|
|||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
|
||||
},
|
||||
"node_modules/fastparse": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz",
|
||||
"integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/fastq": {
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
|
||||
|
@ -12167,6 +12233,11 @@
|
|||
"resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
|
||||
"integrity": "sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA=="
|
||||
},
|
||||
"node_modules/lodash.throttle": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz",
|
||||
"integrity": "sha512-wIkUCfVKpVsWo3JSZlc+8MB5it+2AN5W8J7YVMST30UrvcQNZ1Okbj+rbVniijTWE6FGYy4XJq/rHkas8qJMLQ=="
|
||||
},
|
||||
"node_modules/lodash.uniq": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
|
||||
|
@ -14517,6 +14588,19 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-animate-on-scroll": {
|
||||
"version": "2.1.9",
|
||||
"resolved": "https://registry.npmjs.org/react-animate-on-scroll/-/react-animate-on-scroll-2.1.9.tgz",
|
||||
"integrity": "sha512-E4PZLX6RDLLn+/iIMhnQrC1xU74ixGcCQ5/TBX8fBsaO+SnaU9VFoZLvIfUqVf3mH5HUNzO8wAqA11niot5Obw==",
|
||||
"dependencies": {
|
||||
"lodash.throttle": "^4.1.1",
|
||||
"prop-types": "^15.5.9"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"classnames": "^2.2.5",
|
||||
"react": ">= 15.4.1 < 19.0.0-0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-app-polyfill": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/react-app-polyfill/-/react-app-polyfill-3.0.0.tgz",
|
||||
|
@ -14734,6 +14818,15 @@
|
|||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
|
||||
},
|
||||
"node_modules/react-parallax-tilt": {
|
||||
"version": "1.7.228",
|
||||
"resolved": "https://registry.npmjs.org/react-parallax-tilt/-/react-parallax-tilt-1.7.228.tgz",
|
||||
"integrity": "sha512-dACuwQ+yOk47rjWYCYk1PGqIEA7lQM3x7kVeWrhxXleclyYPEJwdD8/EmjpileaH443dgLmNKHYf8366SjnR8g==",
|
||||
"peerDependencies": {
|
||||
"react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0",
|
||||
"react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.11.0",
|
||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz",
|
||||
|
|
11
package.json
|
@ -10,15 +10,19 @@
|
|||
"@types/node": "^16.18.98",
|
||||
"@types/react": "^18.3.3",
|
||||
"@types/react-dom": "^18.3.0",
|
||||
"react": "^18.3.1",
|
||||
"react-dom": "^18.3.1",
|
||||
"animate.css": "^4.1.1",
|
||||
"react": "^18.2.0",
|
||||
"react-animate-on-scroll": "^2.1.9",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-parallax-tilt": "^1.7.224",
|
||||
"react-scripts": "5.0.1",
|
||||
"typescript": "^4.9.5",
|
||||
"web-vitals": "^2.1.4"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"build:react": "react-scripts build",
|
||||
"build": "bun run scripts/build.ts",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
|
@ -41,6 +45,7 @@
|
|||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/react-animate-on-scroll": "^2.1.8",
|
||||
"daisyui": "^4.12.2",
|
||||
"tailwindcss": "^3.4.4"
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
public/favicon.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
|
@ -2,42 +2,215 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||
<link rel="icon" href="%PUBLIC_URL%/favicon.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<meta name="theme-color" content="#fff" class="theme-color" />
|
||||
<meta
|
||||
name="description"
|
||||
content="Web site created using create-react-app"
|
||||
/>
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<!--
|
||||
manifest.json provides metadata used when your web app is installed on a
|
||||
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
||||
-->
|
||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||
<!--
|
||||
Notice the use of %PUBLIC_URL% in the tags above.
|
||||
It will be replaced with the URL of the `public` folder during the build.
|
||||
Only files inside the `public` folder can be referenced from the HTML.
|
||||
<meta name="theme-color" content="#fff" class="theme-color" />
|
||||
<title>Loading...</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Self Developed personal website build with React.js"
|
||||
/>
|
||||
|
||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||
work correctly both with client-side routing and a non-root public URL.
|
||||
Learn how to configure a non-root public URL by running `npm run build`.
|
||||
-->
|
||||
<title>React App</title>
|
||||
<!-- Google / Search Engine Tags -->
|
||||
<meta itemprop="name" content="Saahil" />
|
||||
<meta
|
||||
itemprop="description"
|
||||
content="Self Developed personal website build with React.js"
|
||||
/>
|
||||
<meta
|
||||
itemprop="image"
|
||||
content="https://raw.githubusercontent.com/soumyajit4419/Portfolio/master/Images/readme-img.png?token=AK7VCIF5RYEUZZAURELPTAC76U6AK"
|
||||
/>
|
||||
|
||||
<!-- Facebook Meta Tags -->
|
||||
<meta property="og:url" content="https://saahild.com" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="Saahil" />
|
||||
<meta
|
||||
property="og:description"
|
||||
content="Self Developed personal website build with React.js"
|
||||
/>
|
||||
<meta
|
||||
property="og:image"
|
||||
content="https://raw.githubusercontent.com/soumyajit4419/Portfolio/master/Images/readme-img.png?token=AK7VCIF5RYEUZZAURELPTAC76U6AK"
|
||||
/>
|
||||
|
||||
<!-- Twitter Meta Tags -->
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:title" content="Saahil" />
|
||||
<meta
|
||||
name="twitter:description"
|
||||
content="Self Developed personal website build with React.js"
|
||||
/>
|
||||
<meta
|
||||
name="twitter:image"
|
||||
content="https://raw.githubusercontent.com/soumyajit4419/Portfolio/master/Images/readme-img.png?token=AK7VCIF5RYEUZZAURELPTAC76U6AK"
|
||||
/>
|
||||
<!-- <script async src="https://ackee.saahild.com/tracker.js" data-ackee-server="https://ackee.saahild.com" data-ackee-domain-id="c082bd15-f9d8-414f-aa10-926e1d66a5d6" data-ackee-opts='{ "ignoreOwnVisits": false, "detailed": true }'></script> -->
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css">
|
||||
</head>
|
||||
<!-- <script type="text/javascript">
|
||||
atOptions = {
|
||||
'key' : '71dc240529bf37dbe2cda5bd015d6e4d',
|
||||
'format' : 'iframe',
|
||||
'height' : window.innerHeight,
|
||||
'width' : window.innerWidth,
|
||||
'params' : {}
|
||||
};
|
||||
</script> -->
|
||||
<!-- <script src="ad.js"></script> -->
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
|
||||
<noscript>
|
||||
<META HTTP-EQUIV="refresh" CONTENT="15">
|
||||
<style>
|
||||
/* body {font-family: Arial, Helvetica, sans-serif;} */
|
||||
/* The Modal (background) */
|
||||
.my-modal {
|
||||
display: none;
|
||||
position: fixed; /* Stay in place */
|
||||
z-index: 1;
|
||||
left: 0;
|
||||
top: 0;
|
||||
width: 100%; /* Full width */
|
||||
height: 100%; /* Full height */
|
||||
overflow: auto; /* Enable scroll if needed */
|
||||
background-color: #1e1e2e; /* Fallback color */
|
||||
background-color: rgba(0, 0, 0, 0.4); /* Black w/ opacity */
|
||||
-webkit-animation-name: fadeIn; /* Fade in the background */
|
||||
-webkit-animation-duration: 0.4s;
|
||||
animation-name: fadeIn;
|
||||
animation-duration: 0.4s;
|
||||
}
|
||||
|
||||
/* Modal Content */
|
||||
.my-modal-content {
|
||||
position: fixed;
|
||||
color: #cdd6f4;
|
||||
bottom: 0;
|
||||
background-color: #313244;
|
||||
width: 100%;
|
||||
-webkit-animation-name: slideIn;
|
||||
-webkit-animation-duration: 0.4s;
|
||||
animation-name: slideIn;
|
||||
animation-duration: 0.4s;
|
||||
}
|
||||
|
||||
/* The Close Button */
|
||||
.my-close {
|
||||
color: #cba6f7;
|
||||
float: right;
|
||||
font-size: 28px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.my-close:hover,
|
||||
.my-close:focus {
|
||||
color: #f5c2e7;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.my-modal-header {
|
||||
padding: 2px 16px;
|
||||
background-image: linear-gradient(
|
||||
to left,
|
||||
#1e1e2e,
|
||||
#11111b
|
||||
);
|
||||
/*#5cb85c */;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.my-modal-body {
|
||||
padding: 2px 16px;
|
||||
}
|
||||
|
||||
.my-modal-footer {
|
||||
padding: 2px 16px;
|
||||
/* bottom: 0; */
|
||||
/* position: absolute; */
|
||||
/* right: 50%; */
|
||||
/* background-color: #5cb85c; */
|
||||
background-repeat: repeat-x;
|
||||
background-image: linear-gradient(
|
||||
to left,
|
||||
#1e1e2e,
|
||||
#11111b
|
||||
);
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
/* Add Animation */
|
||||
@-webkit-keyframes slideIn {
|
||||
from {
|
||||
bottom: -300px;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
bottom: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes slideIn {
|
||||
from {
|
||||
bottom: -300px;
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
bottom: 0;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
a {
|
||||
color: #89b4fa;
|
||||
}
|
||||
a:hover {
|
||||
color: #b4befe;
|
||||
}
|
||||
a:visited {
|
||||
color: #cba6f7;
|
||||
}
|
||||
</style>
|
||||
<div class="my-modal-content" style="height: 100vh;">
|
||||
<div class="my-modal-header">
|
||||
<span class="my-close"><a href="/">×</a> </span>
|
||||
<h2>Please enable javascript</h2>
|
||||
</div>
|
||||
<div class="my-modal-body" style="height: 85vh;">
|
||||
<p>You need to enable JavaScript to run this app.</p>
|
||||
</div>
|
||||
<div class="my-modal-footer">
|
||||
<h3>Reload page once you have enabled javascript or click <a href="/">here</a></h3>
|
||||
</div>
|
||||
</div>
|
||||
</noscript>
|
||||
<div id="root"></div>
|
||||
<!--
|
||||
This HTML file is a template.
|
||||
If you open it directly in the browser, you will see an empty page.
|
||||
|
||||
You can add webfonts, meta tags, or analytics to this file.
|
||||
The build step will place the bundled scripts into the <body> tag.
|
||||
|
||||
To begin the development, run `npm start` or `yarn start`.
|
||||
To create a production bundle, use `npm run build` or `yarn build`.
|
||||
-->
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
Before Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 9.4 KiB |
|
@ -6,20 +6,10 @@
|
|||
"src": "favicon.ico",
|
||||
"sizes": "64x64 32x32 24x24 16x16",
|
||||
"type": "image/x-icon"
|
||||
},
|
||||
{
|
||||
"src": "logo192.png",
|
||||
"type": "image/png",
|
||||
"sizes": "192x192"
|
||||
},
|
||||
{
|
||||
"src": "logo512.png",
|
||||
"type": "image/png",
|
||||
"sizes": "512x512"
|
||||
}
|
||||
],
|
||||
"start_url": ".",
|
||||
"display": "standalone",
|
||||
"theme_color": "#000000",
|
||||
"theme_color": "#FFF",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
|
|
4
public/php/index.php
Normal file
|
@ -0,0 +1,4 @@
|
|||
<?php
|
||||
header('Content-Type: application/json');
|
||||
echo json_encode(['status' => 200]);
|
||||
?>
|
BIN
public/projects/blog.png
Normal file
After Width: | Height: | Size: 128 KiB |
BIN
public/projects/cth.png
Normal file
After Width: | Height: | Size: 143 KiB |
BIN
public/projects/envelope.png
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
public/projects/globalwarming.jpeg
Normal file
After Width: | Height: | Size: 262 KiB |
BIN
public/projects/hobbit.png
Normal file
After Width: | Height: | Size: 640 KiB |
BIN
public/projects/passion.png
Normal file
After Width: | Height: | Size: 798 KiB |
BIN
public/projects/password.png
Normal file
After Width: | Height: | Size: 457 KiB |
BIN
public/projects/wallpaper.png
Normal file
After Width: | Height: | Size: 13 KiB |
8
scripts/build.ts
Normal file
|
@ -0,0 +1,8 @@
|
|||
import fs from 'fs'
|
||||
import path from 'path'
|
||||
const reactOutput = Bun.spawnSync({
|
||||
cmd: ['bun', 'build:react']
|
||||
})
|
||||
console.log(reactOutput.stdout.toString())
|
||||
console.log(`Built react app`)
|
||||
// fs.cpSync(path.join(__dirname, '../build'), path.join(__dirname, '../dist/php'), {recursive: true})
|
27
scripts/tsconfig.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": ["ESNext", "DOM"],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
}
|
||||
}
|
|
@ -1,11 +1,12 @@
|
|||
import React from 'react';
|
||||
import Main from './components/main';
|
||||
// import logo from './logo.svg';
|
||||
// import './App.css';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="App">
|
||||
|
||||
<div style={{ zIndex: 9999 }}>
|
||||
<Main />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
12
src/bg/main.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import "./style.css";
|
||||
export default function Background() {
|
||||
return (
|
||||
<div style={{ filter: 'blur(10px)'}}>
|
||||
<ul className="background">
|
||||
{new Array(49).join('.').split('.').map((_,i) => {
|
||||
return <li key={i} className={i % 2 === 0 ? "bg-effect" : ""}></li>
|
||||
})}
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
407
src/bg/style.css
Normal file
|
@ -0,0 +1,407 @@
|
|||
@keyframes animate {
|
||||
0%{
|
||||
transform: translateY(0) rotate(0deg);
|
||||
opacity: 1;
|
||||
border-radius: 0;
|
||||
}
|
||||
100%{
|
||||
transform: translateY(-1000px) rotate(720deg);
|
||||
opacity: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
@keyframes animate-inverse {
|
||||
0%{
|
||||
transform: translateY(0) rotate(720deg);
|
||||
opacity: 1;
|
||||
border-radius: 0;
|
||||
}
|
||||
100%{
|
||||
transform: translateY(-1000px) rotate(0deg);
|
||||
opacity: 0;
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
.bg-effect {
|
||||
/* transform: scale3d(100.1, 1, 100.1); */
|
||||
animation: animate 20s linear infinite;
|
||||
}
|
||||
.background {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
overflow: hidden;
|
||||
/* @apply bg-base-300; */
|
||||
/* @apply bg-gradient-to-b from-ctp-mantle to-ctp-crust; */
|
||||
background: linear-gradient( var(--mantle), var(--crust));
|
||||
/* backdrop-filter: blur(10px); */
|
||||
}
|
||||
.background li {
|
||||
position: absolute;
|
||||
display: block;
|
||||
list-style: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
/* background: rgba(255, 255, 255, 0.1); */
|
||||
background: rgba(203, 166, 247, 0.15);
|
||||
animation: animate 24s linear infinite;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.background li:nth-child(0) {
|
||||
left: 12%;
|
||||
width: 85px;
|
||||
height: 85px;
|
||||
bottom: -85px;
|
||||
animation-delay: 1s;
|
||||
background: var(--zeon-bonus-color-lighter) !important;
|
||||
}
|
||||
.background li:nth-child(1) {
|
||||
left: 49%;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
bottom: -34px;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
.background li:nth-child(2) {
|
||||
left: 61%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
bottom: -30px;
|
||||
animation-delay: 9s;
|
||||
}
|
||||
.background li:nth-child(3) {
|
||||
left: 54%;
|
||||
width: 96px;
|
||||
height: 96px;
|
||||
bottom: -96px;
|
||||
animation-delay: 8s;
|
||||
}
|
||||
.background li:nth-child(4) {
|
||||
left: 3%;
|
||||
width: 57px;
|
||||
height: 57px;
|
||||
bottom: -57px;
|
||||
animation-delay: 12s;
|
||||
}
|
||||
.background li:nth-child(5) {
|
||||
left: 8%;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
bottom: -45px;
|
||||
animation-delay: 23s;
|
||||
}
|
||||
.background li:nth-child(6) {
|
||||
left: 3%;
|
||||
width: 82px;
|
||||
height: 82px;
|
||||
bottom: -82px;
|
||||
animation-delay: 5s;
|
||||
}
|
||||
.background li:nth-child(7) {
|
||||
left: 63%;
|
||||
width: 87px;
|
||||
height: 87px;
|
||||
bottom: -87px;
|
||||
animation-delay: 10s;
|
||||
}
|
||||
.background li:nth-child(8) {
|
||||
left: 86%;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
bottom: -30px;
|
||||
animation-delay: 14s;
|
||||
}
|
||||
.background li:nth-child(9) {
|
||||
left: 23%;
|
||||
width: 56px;
|
||||
height: 56px;
|
||||
bottom: -56px;
|
||||
animation-delay: 17s;
|
||||
}
|
||||
.background li:nth-child(10) {
|
||||
left: 16%;
|
||||
width: 97px;
|
||||
height: 97px;
|
||||
bottom: -97px;
|
||||
animation-delay: 31s;
|
||||
}
|
||||
.background li:nth-child(11) {
|
||||
left: 43%;
|
||||
width: 82px;
|
||||
height: 82px;
|
||||
bottom: -82px;
|
||||
animation-delay: 21s;
|
||||
}
|
||||
.background li:nth-child(12) {
|
||||
left: 74%;
|
||||
width: 31px;
|
||||
height: 31px;
|
||||
bottom: -31px;
|
||||
animation-delay: 35s;
|
||||
}
|
||||
.background li:nth-child(13) {
|
||||
left: 19%;
|
||||
width: 97px;
|
||||
height: 97px;
|
||||
bottom: -97px;
|
||||
animation-delay: 57s;
|
||||
}
|
||||
.background li:nth-child(14) {
|
||||
left: 48%;
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
bottom: -21px;
|
||||
animation-delay: 65s;
|
||||
}
|
||||
.background li:nth-child(15) {
|
||||
left: 34%;
|
||||
width: 69px;
|
||||
height: 69px;
|
||||
bottom: -69px;
|
||||
animation-delay: 18s;
|
||||
}
|
||||
.background li:nth-child(16) {
|
||||
left: 74%;
|
||||
width: 31px;
|
||||
height: 31px;
|
||||
bottom: -31px;
|
||||
animation-delay: 68s;
|
||||
}
|
||||
.background li:nth-child(17) {
|
||||
left: 13%;
|
||||
width: 41px;
|
||||
height: 41px;
|
||||
bottom: -41px;
|
||||
animation-delay: 81s;
|
||||
}
|
||||
.background li:nth-child(18) {
|
||||
left: 30%;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
bottom: -64px;
|
||||
animation-delay: 27s;
|
||||
}
|
||||
.background li:nth-child(19) {
|
||||
left: 56%;
|
||||
width: 59px;
|
||||
height: 59px;
|
||||
bottom: -59px;
|
||||
animation-delay: 79s;
|
||||
}
|
||||
.background li:nth-child(20) {
|
||||
left: 0%;
|
||||
width: 53px;
|
||||
height: 53px;
|
||||
bottom: -53px;
|
||||
animation-delay: 55s;
|
||||
}
|
||||
.background li:nth-child(21) {
|
||||
left: 30%;
|
||||
width: 82px;
|
||||
height: 82px;
|
||||
bottom: -82px;
|
||||
animation-delay: 1s;
|
||||
}
|
||||
.background li:nth-child(22) {
|
||||
left: 25%;
|
||||
width: 2px;
|
||||
height: 2px;
|
||||
bottom: -2px;
|
||||
animation-delay: 15s;
|
||||
}
|
||||
.background li:nth-child(23) {
|
||||
left: 11%;
|
||||
width: 34px;
|
||||
height: 34px;
|
||||
bottom: -34px;
|
||||
animation-delay: 88s;
|
||||
}
|
||||
.background li:nth-child(24) {
|
||||
left: 88%;
|
||||
width: 88px;
|
||||
height: 88px;
|
||||
bottom: -88px;
|
||||
animation-delay: 113s;
|
||||
}
|
||||
.background li:nth-child(25) {
|
||||
left: 42%;
|
||||
width: 61px;
|
||||
height: 61px;
|
||||
bottom: -61px;
|
||||
animation-delay: 24s;
|
||||
}
|
||||
.background li:nth-child(26) {
|
||||
left: 48%;
|
||||
width: 98px;
|
||||
height: 98px;
|
||||
bottom: -98px;
|
||||
animation-delay: 14s;
|
||||
}
|
||||
.background li:nth-child(27) {
|
||||
left: 81%;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
bottom: -20px;
|
||||
animation-delay: 4s;
|
||||
}
|
||||
.background li:nth-child(28) {
|
||||
left: 36%;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
bottom: -68px;
|
||||
animation-delay: 31s;
|
||||
}
|
||||
.background li:nth-child(29) {
|
||||
left: 80%;
|
||||
width: 81px;
|
||||
height: 81px;
|
||||
bottom: -81px;
|
||||
animation-delay: 72s;
|
||||
}
|
||||
.background li:nth-child(30) {
|
||||
left: 86%;
|
||||
width: 78px;
|
||||
height: 78px;
|
||||
bottom: -78px;
|
||||
animation-delay: 114s;
|
||||
}
|
||||
.background li:nth-child(31) {
|
||||
left: 31%;
|
||||
width: 68px;
|
||||
height: 68px;
|
||||
bottom: -68px;
|
||||
animation-delay: 141s;
|
||||
}
|
||||
.background li:nth-child(32) {
|
||||
left: 24%;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
bottom: -15px;
|
||||
animation-delay: 129s;
|
||||
}
|
||||
.background li:nth-child(33) {
|
||||
left: 60%;
|
||||
width: 98px;
|
||||
height: 98px;
|
||||
bottom: -98px;
|
||||
animation-delay: 101s;
|
||||
}
|
||||
.background li:nth-child(34) {
|
||||
left: 71%;
|
||||
width: 19px;
|
||||
height: 19px;
|
||||
bottom: -19px;
|
||||
animation-delay: 78s;
|
||||
}
|
||||
.background li:nth-child(35) {
|
||||
left: 31%;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
bottom: -32px;
|
||||
animation-delay: 23s;
|
||||
}
|
||||
.background li:nth-child(36) {
|
||||
left: 7%;
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
bottom: -70px;
|
||||
animation-delay: 169s;
|
||||
}
|
||||
.background li:nth-child(37) {
|
||||
left: 3%;
|
||||
width: 26px;
|
||||
height: 26px;
|
||||
bottom: -26px;
|
||||
animation-delay: 98s;
|
||||
}
|
||||
.background li:nth-child(38) {
|
||||
left: 4%;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
bottom: -50px;
|
||||
animation-delay: 124s;
|
||||
}
|
||||
.background li:nth-child(39) {
|
||||
left: 34%;
|
||||
width: 51px;
|
||||
height: 51px;
|
||||
bottom: -51px;
|
||||
animation-delay: 30s;
|
||||
}
|
||||
.background li:nth-child(40) {
|
||||
left: 61%;
|
||||
width: 59px;
|
||||
height: 59px;
|
||||
bottom: -59px;
|
||||
animation-delay: 49s;
|
||||
}
|
||||
.background li:nth-child(41) {
|
||||
left: 78%;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
bottom: -45px;
|
||||
animation-delay: 184s;
|
||||
}
|
||||
.background li:nth-child(42) {
|
||||
left: 25%;
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
bottom: -58px;
|
||||
animation-delay: 152s;
|
||||
}
|
||||
.background li:nth-child(43) {
|
||||
left: 20%;
|
||||
width: 76px;
|
||||
height: 76px;
|
||||
bottom: -76px;
|
||||
animation-delay: 157s;
|
||||
}
|
||||
.background li:nth-child(44) {
|
||||
left: 44%;
|
||||
width: 59px;
|
||||
height: 59px;
|
||||
bottom: -59px;
|
||||
animation-delay: 5s;
|
||||
}
|
||||
.background li:nth-child(45) {
|
||||
left: 36%;
|
||||
width: 88px;
|
||||
height: 88px;
|
||||
bottom: -88px;
|
||||
animation-delay: 217s;
|
||||
}
|
||||
.background li:nth-child(46) {
|
||||
left: 78%;
|
||||
width: 43px;
|
||||
height: 43px;
|
||||
bottom: -43px;
|
||||
animation-delay: 185s;
|
||||
}
|
||||
.background li:nth-child(47) {
|
||||
left: 59%;
|
||||
width: 58px;
|
||||
height: 58px;
|
||||
bottom: -58px;
|
||||
animation-delay: 91s;
|
||||
}
|
||||
.background li:nth-child(48) {
|
||||
left: 87%;
|
||||
width: 73px;
|
||||
height: 73px;
|
||||
bottom: -73px;
|
||||
animation-delay: 226s;
|
||||
}
|
||||
.background li:nth-child(49) {
|
||||
left: 43%;
|
||||
width: 79px;
|
||||
height: 79px;
|
||||
bottom: -79px;
|
||||
animation-delay: 84s;
|
||||
}
|
32
src/components/main/avatar.css
Normal file
|
@ -0,0 +1,32 @@
|
|||
@keyframes float {
|
||||
0% {
|
||||
/* box-shadow: 0 5px 15px 0px rgba(0, 0, 0, 0.6); */
|
||||
transform: translatey(0px);
|
||||
}
|
||||
50% {
|
||||
/* box-shadow: 0 25px 15px 0px rgba(0, 0, 0, 0.2); */
|
||||
transform: translatey(-20px);
|
||||
}
|
||||
100% {
|
||||
/* box-shadow: 0 5px 15px 0px rgba(0, 0, 0, 0.6); */
|
||||
transform: translatey(0px);
|
||||
}
|
||||
}
|
||||
.avatar {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
box-sizing: border-box; /* Not needed */
|
||||
/*
|
||||
border: 5px white solid;
|
||||
border-radius: 50%;
|
||||
*/
|
||||
background: transparent;
|
||||
overflow: hidden;
|
||||
/* box-shadow: 0 5px 15px 0px rgba(0, 0, 0, 0.6); */
|
||||
transform: translatey(0px);
|
||||
animation: float 6s ease-in-out infinite;
|
||||
}
|
||||
.avatar img {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
25
src/components/main/index.tsx
Normal file
|
@ -0,0 +1,25 @@
|
|||
import './avatar.css'
|
||||
import ScrollAnimation from 'react-animate-on-scroll'
|
||||
import Tilt from 'react-parallax-tilt'
|
||||
// import 'animate.css/animate.css'
|
||||
export default function Main() {
|
||||
return (
|
||||
<div className='hero min-h-screen ' >
|
||||
<div style={{ animation: "fadeInDown", animationDuration: "1.5s", zIndex: 9999 }} className='animate__animated animate__fadeIn' >
|
||||
<div className='hero-content flex-col lg:flex-row max-w-xl' style={{ zIndex: 9999 }}>
|
||||
<div className='avatar'>
|
||||
<Tilt glareEnable glareColor={'#f9e2af'}>
|
||||
<img src={'favicon.png'} />
|
||||
</Tilt>
|
||||
</div>
|
||||
|
||||
<div style={{ zIndex: 9999 }}>
|
||||
|
||||
<h1 className='text-5xl font-bold zeon-word' >Saahild.com</h1>
|
||||
<p>WIP.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -1,3 +1,35 @@
|
|||
/* tailwind root */
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
:root {
|
||||
--rosewater: #f5e0dc;
|
||||
--flamingo: #f2cdcd;
|
||||
--pink: #f5c2e7;
|
||||
--mauve: #cba6f7;
|
||||
--red: #f38ba8;
|
||||
--maroon: #eba0ac;
|
||||
--peach: #fab387;
|
||||
--yellow: #f9e2af;
|
||||
--green: #a6e3a1;
|
||||
--teal: #94e2d5;
|
||||
--sky: #89dceb;
|
||||
--sapphire: #74c7ec;
|
||||
--blue: #89b4fa;
|
||||
--lavender: #b4befe;
|
||||
--text: #cdd6f4;
|
||||
--subtext1: #bac2de;
|
||||
--subtext0: #a6adc8;
|
||||
--overlay2: #9399b2;
|
||||
--overlay1: #7f849c;
|
||||
--overlay0: #6c7086;
|
||||
--surface2: #585b70;
|
||||
--surface1: #45475a;
|
||||
--surface0: #313244;
|
||||
--base: #1e1e2e;
|
||||
--mantle: #181825;
|
||||
--crust: #11111b;
|
||||
}
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
|
|
|
@ -1,14 +1,19 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import "animate.css/animate.compat.css";
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import App from './App';
|
||||
import reportWebVitals from './reportWebVitals';
|
||||
|
||||
import Background from './bg/main';
|
||||
import { injectOneko } from './scripts/oneko';
|
||||
const root = ReactDOM.createRoot(
|
||||
document.getElementById('root') as HTMLElement
|
||||
);
|
||||
injectOneko();
|
||||
document.title = 'React App';
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<Background />
|
||||
<App />
|
||||
</React.StrictMode>
|
||||
);
|
||||
|
@ -16,4 +21,4 @@ root.render(
|
|||
// If you want to start measuring performance in your app, pass a function
|
||||
// to log results (for example: reportWebVitals(console.log))
|
||||
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
|
||||
reportWebVitals();
|
||||
reportWebVitals(console.log);
|
||||
|
|
240
src/scripts/oneko.ts
Normal file
|
@ -0,0 +1,240 @@
|
|||
// oneko.js: https://github.com/adryd325/oneko.js
|
||||
// modified by @NeonGamerBot-QK
|
||||
export const nekoEl = document.createElement("div");
|
||||
export function deleteOneko(): void {
|
||||
return nekoEl.remove();
|
||||
}
|
||||
export function injectOneko():void {
|
||||
const isReducedMotion = window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
|
||||
|
||||
if (isReducedMotion) return;
|
||||
|
||||
|
||||
let nekoPosX = 32;
|
||||
let nekoPosY = 32;
|
||||
|
||||
let mousePosX = 0;
|
||||
let mousePosY = 0;
|
||||
|
||||
let frameCount = 0;
|
||||
let idleTime = 0;
|
||||
let idleAnimation: null | number | string = null;
|
||||
let idleAnimationFrame = 0;
|
||||
|
||||
const nekoSpeed = 10;
|
||||
const spriteSets = {
|
||||
idle: [[-3, -3]],
|
||||
alert: [[-7, -3]],
|
||||
scratchSelf: [
|
||||
[-5, 0],
|
||||
[-6, 0],
|
||||
[-7, 0],
|
||||
],
|
||||
scratchWallN: [
|
||||
[0, 0],
|
||||
[0, -1],
|
||||
],
|
||||
scratchWallS: [
|
||||
[-7, -1],
|
||||
[-6, -2],
|
||||
],
|
||||
scratchWallE: [
|
||||
[-2, -2],
|
||||
[-2, -3],
|
||||
],
|
||||
scratchWallW: [
|
||||
[-4, 0],
|
||||
[-4, -1],
|
||||
],
|
||||
tired: [[-3, -2]],
|
||||
sleeping: [
|
||||
[-2, 0],
|
||||
[-2, -1],
|
||||
],
|
||||
N: [
|
||||
[-1, -2],
|
||||
[-1, -3],
|
||||
],
|
||||
NE: [
|
||||
[0, -2],
|
||||
[0, -3],
|
||||
],
|
||||
E: [
|
||||
[-3, 0],
|
||||
[-3, -1],
|
||||
],
|
||||
SE: [
|
||||
[-5, -1],
|
||||
[-5, -2],
|
||||
],
|
||||
S: [
|
||||
[-6, -3],
|
||||
[-7, -2],
|
||||
],
|
||||
SW: [
|
||||
[-5, -3],
|
||||
[-6, -1],
|
||||
],
|
||||
W: [
|
||||
[-4, -2],
|
||||
[-4, -3],
|
||||
],
|
||||
NW: [
|
||||
[-1, 0],
|
||||
[-1, -1],
|
||||
],
|
||||
};
|
||||
|
||||
function init() {
|
||||
nekoEl.id = "oneko";
|
||||
nekoEl.ariaHidden = "true";
|
||||
nekoEl.style.width = "32px";
|
||||
nekoEl.style.height = "32px";
|
||||
nekoEl.style.position = "fixed";
|
||||
nekoEl.style.pointerEvents = "none";
|
||||
nekoEl.style.imageRendering = "pixelated";
|
||||
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||
nekoEl.style.zIndex = Number.MAX_VALUE.toString();
|
||||
let nekoFile = "https://saahild.com/oneko.gif"
|
||||
const curScript = document.currentScript
|
||||
if (curScript && curScript.dataset.cat) {
|
||||
nekoFile = curScript.dataset.cat
|
||||
}
|
||||
nekoEl.style.backgroundImage = `url(${nekoFile})`;
|
||||
|
||||
document.body.appendChild(nekoEl);
|
||||
|
||||
document.addEventListener("mousemove", function (event) {
|
||||
mousePosX = event.clientX;
|
||||
mousePosY = event.clientY;
|
||||
});
|
||||
|
||||
window.requestAnimationFrame(onAnimationFrame);
|
||||
}
|
||||
|
||||
let lastFrameTimestamp: undefined | number = undefined;
|
||||
|
||||
function onAnimationFrame(timestamp: number) {
|
||||
// Stops execution if the neko element is removed from DOM
|
||||
if (!nekoEl.isConnected) {
|
||||
return;
|
||||
}
|
||||
if (!lastFrameTimestamp) {
|
||||
lastFrameTimestamp = timestamp;
|
||||
}
|
||||
if (timestamp - lastFrameTimestamp > 100) {
|
||||
lastFrameTimestamp = timestamp
|
||||
frame()
|
||||
}
|
||||
window.requestAnimationFrame(onAnimationFrame);
|
||||
}
|
||||
|
||||
function setSprite(name: string, frame: number) {
|
||||
//@ts-ignore
|
||||
const sprite = spriteSets[name][frame % spriteSets[name].length];
|
||||
nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${sprite[1] * 32}px`;
|
||||
}
|
||||
|
||||
function resetIdleAnimation() {
|
||||
idleAnimation = null;
|
||||
idleAnimationFrame = 0;
|
||||
}
|
||||
|
||||
function idle() {
|
||||
idleTime += 1;
|
||||
|
||||
// every ~ 20 seconds
|
||||
if (
|
||||
idleTime > 10 &&
|
||||
Math.floor(Math.random() * 200) == 0 &&
|
||||
idleAnimation == null
|
||||
) {
|
||||
let avalibleIdleAnimations = ["sleeping", "scratchSelf"];
|
||||
if (nekoPosX < 32) {
|
||||
avalibleIdleAnimations.push("scratchWallW");
|
||||
}
|
||||
if (nekoPosY < 32) {
|
||||
avalibleIdleAnimations.push("scratchWallN");
|
||||
}
|
||||
if (nekoPosX > window.innerWidth - 32) {
|
||||
avalibleIdleAnimations.push("scratchWallE");
|
||||
}
|
||||
if (nekoPosY > window.innerHeight - 32) {
|
||||
avalibleIdleAnimations.push("scratchWallS");
|
||||
}
|
||||
idleAnimation =
|
||||
avalibleIdleAnimations[
|
||||
Math.floor(Math.random() * avalibleIdleAnimations.length)
|
||||
];
|
||||
}
|
||||
|
||||
switch (idleAnimation) {
|
||||
case "sleeping":
|
||||
if (idleAnimationFrame < 8) {
|
||||
setSprite("tired", 0);
|
||||
break;
|
||||
}
|
||||
setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
|
||||
if (idleAnimationFrame > 192) {
|
||||
resetIdleAnimation();
|
||||
}
|
||||
break;
|
||||
case "scratchWallN":
|
||||
case "scratchWallS":
|
||||
case "scratchWallE":
|
||||
case "scratchWallW":
|
||||
case "scratchSelf":
|
||||
setSprite(idleAnimation, idleAnimationFrame);
|
||||
if (idleAnimationFrame > 9) {
|
||||
resetIdleAnimation();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
setSprite("idle", 0);
|
||||
return;
|
||||
}
|
||||
idleAnimationFrame += 1;
|
||||
}
|
||||
|
||||
function frame() {
|
||||
frameCount += 1;
|
||||
const diffX = nekoPosX - mousePosX;
|
||||
const diffY = nekoPosY - mousePosY;
|
||||
const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
|
||||
|
||||
if (distance < nekoSpeed || distance < 48) {
|
||||
idle();
|
||||
return;
|
||||
}
|
||||
|
||||
idleAnimation = null;
|
||||
idleAnimationFrame = 0;
|
||||
|
||||
if (idleTime > 1) {
|
||||
setSprite("alert", 0);
|
||||
// count down after being alerted before moving
|
||||
idleTime = Math.min(idleTime, 7);
|
||||
idleTime -= 1;
|
||||
return;
|
||||
}
|
||||
|
||||
let direction;
|
||||
direction = diffY / distance > 0.5 ? "N" : "";
|
||||
direction += diffY / distance < -0.5 ? "S" : "";
|
||||
direction += diffX / distance > 0.5 ? "W" : "";
|
||||
direction += diffX / distance < -0.5 ? "E" : "";
|
||||
setSprite(direction, frameCount);
|
||||
|
||||
nekoPosX -= (diffX / distance) * nekoSpeed;
|
||||
nekoPosY -= (diffY / distance) * nekoSpeed;
|
||||
|
||||
nekoPosX = Math.min(Math.max(16, nekoPosX), window.innerWidth - 16);
|
||||
nekoPosY = Math.min(Math.max(16, nekoPosY), window.innerHeight - 16);
|
||||
|
||||
nekoEl.style.left = `${nekoPosX - 16}px`;
|
||||
nekoEl.style.top = `${nekoPosY - 16}px`;
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
11
tailwind.config.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
content: [
|
||||
'./src/**/*.tsx'
|
||||
],
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [require('daisyui')],
|
||||
}
|
||||
|