+
+
-
+
-
Saahild.com
-
WIP.
+
👋🏾 Hi im Saahil
+
Welcome to my site.
+
diff --git a/src/components/main/type.tsx b/src/components/main/type.tsx
new file mode 100644
index 00000000..acf3a550
--- /dev/null
+++ b/src/components/main/type.tsx
@@ -0,0 +1,14 @@
+import Typewriter from 'typewriter-effect'
+export default function typewriter() {
+ return
+}
\ No newline at end of file
diff --git a/src/components/navbar/index.tsx b/src/components/navbar/index.tsx
new file mode 100644
index 00000000..7cce91cc
--- /dev/null
+++ b/src/components/navbar/index.tsx
@@ -0,0 +1,32 @@
+import "./nav.css"
+function NavLinks() {
+return <>
+
About
+
Projects
+
Contact
+>
+}
+export default function Navbar() {
+ return
+}
\ No newline at end of file
diff --git a/src/components/navbar/nav.css b/src/components/navbar/nav.css
new file mode 100644
index 00000000..9259e101
--- /dev/null
+++ b/src/components/navbar/nav.css
@@ -0,0 +1,4 @@
+.nav-links {
+ font-size:medium;
+ @apply font-bold;
+}
\ No newline at end of file
diff --git a/src/components/static/Icons.tsx b/src/components/static/Icons.tsx
new file mode 100644
index 00000000..1ca2fa39
--- /dev/null
+++ b/src/components/static/Icons.tsx
@@ -0,0 +1,17 @@
+import cssIcon from "../../assets/icons/css.svg"
+import htmlIcon from "../../assets/icons/html.svg"
+import reactjs from "../../assets/icons/reactjs.svg"
+import nodejs from "../../assets/icons/nodejs.svg"
+import typescript from "../../assets/icons/typescript.svg"
+import javascript from "../../assets/icons/javascript.svg"
+const icons:any = {
+ "css": cssIcon,
+ "html": htmlIcon,
+ "reactjs": reactjs,
+ "nodejs": nodejs,
+ "typescript": typescript,
+ javascript
+}
+export default function Icon({ icon, className }: { icon: string, className?: string }) {
+ return
+}
\ No newline at end of file
diff --git a/src/index.css b/src/index.css
index a90392ac..40adc57b 100644
--- a/src/index.css
+++ b/src/index.css
@@ -29,7 +29,20 @@
--base: #1e1e2e;
--mantle: #181825;
--crust: #11111b;
- }
+ }
+ .text-highlight {
+ color: var(--mauve);
+ /* color: linear-gradient(var(--mauve), var(--mantle); */
+ /* -webkit-background-clip: text; */
+ /* -webkit-text-fill-color: transparent; */
+ @apply ease-in duration-500;
+
+ }
+ .text-highlight:hover {
+ background: linear-gradient(var(--mauve), var(--yellow));
+ -webkit-background-clip: text;
+ -webkit-text-fill-color: transparent;
+ }
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
diff --git a/src/index.tsx b/src/index.tsx
index 5ade2327..a505c9b1 100644
--- a/src/index.tsx
+++ b/src/index.tsx
@@ -6,15 +6,22 @@ import App from './App';
import reportWebVitals from './reportWebVitals';
import Background from './bg/main';
import { injectOneko } from './scripts/oneko';
+import Navbar from './components/navbar';
+import { runTitle } from './scripts/title';
const root = ReactDOM.createRoot(
document.getElementById('root') as HTMLElement
);
+document.title = "Saahild.com"
injectOneko();
+runTitle()
document.title = 'React App';
root.render(
+
+
+
);
diff --git a/src/scripts/log.ts b/src/scripts/log.ts
new file mode 100644
index 00000000..84959cbb
--- /dev/null
+++ b/src/scripts/log.ts
@@ -0,0 +1,20 @@
+export default function startingLog():void {
+ const isDev = process.env.NODE_ENV !== 'production'
+ console.log(
+ `%c What's up?`,
+ `font-size: 120px;
+ font-family: "Poppins", sans-serif;
+ background-size: 1000% 1000%;
+ animation: gradient 1s ease infinite;
+ `
+ )
+ console.log(
+ `%c Thanks for visting this site you can dontate me at https://ko-fi.com/saahil\n Try to find the easter egg in this site🥚\n HINT: to use it you must use the console it is a very VERY hard one`,
+ `font-size: 15px;`
+ )
+ if (isDev) {
+ console.debug(
+ 'This message will show during production build. & development build'
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/scripts/oneko.ts b/src/scripts/oneko.ts
index 45b37030..d6e77d34 100644
--- a/src/scripts/oneko.ts
+++ b/src/scripts/oneko.ts
@@ -1,240 +1,287 @@
-// oneko.js: https://github.com/adryd325/oneko.js
+// oneko.js: https://github.com/tylxr59/oneko.js/blob/main/oneko.js
// modified by @NeonGamerBot-QK
-export const nekoEl = document.createElement("div");
-export function deleteOneko(): void {
- return nekoEl.remove();
+// oneko.js: https://github.com/adryd325/oneko.js
+
+export function injectOneko() {
+ const isReducedMotion = window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
+
+ if (isReducedMotion) return;
+
+ const nekoEl = document.createElement("div");
+
+ let nekoPosX = 32;
+ let nekoPosY = 32;
+
+ let mousePosX = 0;
+ let mousePosY = 0;
+
+ let frameCount = 0;
+ let idleTime = 0;
+ let idleAnimation:any = 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 = "auto";
+ nekoEl.style.imageRendering = "pixelated";
+ nekoEl.style.left = `${nekoPosX - 16}px`;
+ nekoEl.style.top = `${nekoPosY - 16}px`;
+ nekoEl.style.zIndex = "99999999";
+
+ 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: any ;
+
+ function onAnimationFrame(timestamp: any) {
+ // 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: any, frame: any) {
+ //@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 explodeHearts() {
+ const parent = nekoEl.parentElement;
+ const rect = nekoEl.getBoundingClientRect();
+ const scrollLeft = window.scrollX || document.documentElement.scrollLeft;
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
+ const centerX = rect.left + rect.width / 2 + scrollLeft;
+ const centerY = rect.top + rect.height / 2 + scrollTop;
+
+ for (let i = 0; i < 10; i++) {
+ const heart = document.createElement('div');
+ heart.className = 'heart';
+ heart.textContent = '❤';
+ const offsetX = (Math.random() - 0.5) * 50;
+ const offsetY = (Math.random() - 0.5) * 50;
+ heart.style.left = `${centerX + offsetX - 16}px`;
+ heart.style.top = `${centerY + offsetY - 16}px`;
+ heart.style.transform = `translate(-50%, -50%) rotate(${Math.random() * 360}deg)`;
+ parent?.appendChild(heart);
+
+ setTimeout(() => {
+ parent?.removeChild(heart);
+ }, 1000);
+ }
+ }
+
+ const style = document.createElement('style');
+ style.innerHTML = `
+ @keyframes heartBurst {
+ 0% { transform: scale(0); opacity: 1; }
+ 100% { transform: scale(1); opacity: 0; }
+ }
+ .heart {
+ position: absolute;
+ font-size: 2em;
+ animation: heartBurst 1s ease-out;
+ animation-fill-mode: forwards;
+ color: var(--mauve);
+ }
+ `;
+
+ document.head.appendChild(style);
+ nekoEl.addEventListener('click', explodeHearts);
+
+ 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();
}
-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();
- }
\ No newline at end of file
+
+export function stopOneko() {
+ return document.getElementById('oneko')?.remove()
+}
\ No newline at end of file
diff --git a/src/scripts/title.ts b/src/scripts/title.ts
new file mode 100644
index 00000000..11b92c14
--- /dev/null
+++ b/src/scripts/title.ts
@@ -0,0 +1,20 @@
+let title0: null | string = null
+let interId: any = null
+export function runTitle() {
+ if(interId) clearInterval(interId)
+ interId = setInterval(() => {
+ if(document.title !== 'Come Back :(') {
+ title0 = document.title
+ }
+ if (document.hasFocus()) {
+ document.title = title0 || "Saahild.com"
+ } else {
+ document.title = 'Come Back :('
+ }
+ }, 200)
+
+}
+export function stopTitle() {
+ if(!interId) return false;
+ return clearInterval(interId)
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index f2a7d53a..d7aa6b9d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1614,6 +1614,18 @@
resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz"
integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==
+"@mdi/js@^7.4.47":
+ version "7.4.47"
+ resolved "https://registry.yarnpkg.com/@mdi/js/-/js-7.4.47.tgz#7d8a4edc9631bffeed80d1ec784f9beae559a76a"
+ integrity sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==
+
+"@mdi/react@^1.6.1":
+ version "1.6.1"
+ resolved "https://registry.yarnpkg.com/@mdi/react/-/react-1.6.1.tgz#624313593ae8065d2a09878ca81beb3e4b676b03"
+ integrity sha512-4qZeDcluDFGFTWkHs86VOlHkm6gnKaMql13/gpIcUQ8kzxHgpj31NuCkD8abECVfbULJ3shc7Yt4HJ6Wu6SN4w==
+ dependencies:
+ prop-types "^15.7.2"
+
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
version "5.1.1-v1"
resolved "https://registry.npmjs.org/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz"
@@ -7724,7 +7736,7 @@ prompts@^2.0.1, prompts@^2.4.2:
kleur "^3.0.3"
sisteransi "^1.0.5"
-prop-types@^15.5.9, prop-types@^15.8.1:
+prop-types@^15.5.9, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -9168,6 +9180,14 @@ typescript@^4.9.5:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
+typewriter-effect@^2.21.0:
+ version "2.21.0"
+ resolved "https://registry.yarnpkg.com/typewriter-effect/-/typewriter-effect-2.21.0.tgz#7150f12fd2c188248ab2b2b031f77c0663d24c54"
+ integrity sha512-Y3VL1fuJpUBj0gS4OTXBLzy1gnYTYaBuVuuO99tGNyTkkub5CXi+b/hsV7Og9fp6HlhogOwWJwgq7iXI5sQlEg==
+ dependencies:
+ prop-types "^15.8.1"
+ raf "^3.4.1"
+
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz"