Initial commit

This commit is contained in:
Rinuuri
2025-05-29 17:51:13 +03:00
parent 9c466b65fb
commit 7daa036e57
43 changed files with 996 additions and 0 deletions

34
.gitignore vendored Normal file
View File

@@ -0,0 +1,34 @@
# dependencies (bun install)
node_modules
# output
out
dist
*.tgz
# code coverage
coverage
*.lcov
# logs
logs
_.log
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local
# caches
.eslintcache
.cache
*.tsbuildinfo
# IntelliJ based IDEs
.idea
# Finder (MacOS) folder config
.DS_Store

View File

@@ -1,2 +1,26 @@
<<<<<<< HEAD
# rinuuri.dev
=======
# bun-react-template
To install dependencies:
```bash
bun install
```
To start a development server:
```bash
bun dev
```
To run for production:
```bash
bun start
```
This project was created using `bun init` in bun v1.2.13. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime.
>>>>>>> d46ce56 (Initial commit)

17
bun-env.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
// Generated by `bun init`
declare module "*.svg" {
/**
* A path to the SVG file
*/
const path: `${string}.svg`;
export = path;
}
declare module "*.module.css" {
/**
* A record of class names to their corresponding CSS module classes
*/
const classes: { readonly [key: string]: string };
export = classes;
}

41
bun.lock Normal file
View File

@@ -0,0 +1,41 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "bun-react-template",
"dependencies": {
"react": "^19",
"react-dom": "^19",
"three": "^0.176.0",
},
"devDependencies": {
"@types/bun": "latest",
"@types/react": "^19",
"@types/react-dom": "^19",
},
},
},
"packages": {
"@types/bun": ["@types/bun@1.2.15", "", { "dependencies": { "bun-types": "1.2.15" } }, "sha512-U1ljPdBEphF0nw1MIk0hI7kPg7dFdPyM7EenHsp6W5loNHl7zqy6JQf/RKCgnUn2KDzUpkBwHPnEJEjII594bA=="],
"@types/node": ["@types/node@22.15.24", "", { "dependencies": { "undici-types": "~6.21.0" } }, "sha512-w9CZGm9RDjzTh/D+hFwlBJ3ziUaVw7oufKA3vOFSOZlzmW9AkZnfjPb+DLnrV6qtgL/LNmP0/2zBNCFHL3F0ng=="],
"@types/react": ["@types/react@19.1.6", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q=="],
"@types/react-dom": ["@types/react-dom@19.1.5", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg=="],
"bun-types": ["bun-types@1.2.15", "", { "dependencies": { "@types/node": "*" } }, "sha512-NarRIaS+iOaQU1JPfyKhZm4AsUOrwUOqRNHY0XxI8GI8jYxiLXLcdjYMG9UKS+fwWasc1uw1htV9AX24dD+p4w=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"react": ["react@19.1.0", "", {}, "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg=="],
"react-dom": ["react-dom@19.1.0", "", { "dependencies": { "scheduler": "^0.26.0" }, "peerDependencies": { "react": "^19.1.0" } }, "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g=="],
"scheduler": ["scheduler@0.26.0", "", {}, "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA=="],
"three": ["three@0.176.0", "", {}, "sha512-PWRKYWQo23ojf9oZSlRGH8K09q7nRSWx6LY/HF/UUrMdYgN9i1e2OwJYHoQjwc6HF/4lvvYLC5YC1X8UJL2ZpA=="],
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
}
}

2
bunfig.toml Normal file
View File

@@ -0,0 +1,2 @@
[serve.static]
env = "BUN_PUBLIC_*"

23
package.json Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "bun-react-template",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "src/index.tsx",
"module": "src/index.tsx",
"scripts": {
"dev": "bun --hot src/index.tsx",
"build": "bun build ./src/index.html --outdir=dist --sourcemap --target=browser --minify --define:process.env.NODE_ENV='\"production\"' --env='BUN_PUBLIC_*'",
"start": "NODE_ENV=production bun src/index.tsx"
},
"dependencies": {
"react": "^19",
"react-dom": "^19",
"three": "^0.176.0"
},
"devDependencies": {
"@types/react": "^19",
"@types/react-dom": "^19",
"@types/bun": "latest"
}
}

10
src/App.tsx Normal file
View File

@@ -0,0 +1,10 @@
import Background from "./components/Background";
import "./main.css";
export function App() {
return (
<Background />
);
}
export default App;

View File

@@ -0,0 +1,17 @@
import { useEffect, useRef } from "react";
import { init } from "../scripts/background";
export default function Background() {
const canvasRef = useRef(null);
useEffect(() => {
init(canvasRef.current);
}, []);
return (
<>
<div className="gradient-overlay"></div>
<canvas ref={canvasRef} />
</>
);
}

BIN
src/fonts/Nunito-Bold.ttf Normal file

Binary file not shown.

26
src/frontend.tsx Normal file
View File

@@ -0,0 +1,26 @@
/**
* This file is the entry point for the React app, it sets up the root
* element and renders the App component to the DOM.
*
* It is included in `src/index.html`.
*/
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { App } from "./App";
const elem = document.getElementById("root")!;
const app = (
<StrictMode>
<App />
</StrictMode>
);
if (import.meta.hot) {
// With hot module reloading, `import.meta.hot.data` is persisted.
const root = (import.meta.hot.data.root ??= createRoot(elem));
root.render(app);
} else {
// The hot module reloading API is not available in production.
createRoot(elem).render(app);
}

1
src/images/android.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#30dc80" d="M24,14.088C11.427,14.088,1.108,23.716,0,36h48C46.892,23.716,36.573,14.088,24,14.088z M33.179,27.079c0-1.104,0.895-1.999,1.999-1.999c1.104,0,1.999,0.895,1.999,1.999c0,1.104-0.895,1.999-1.999,1.999 C34.074,29.078,33.179,28.183,33.179,27.079z M12.822,29.078c-1.104,0-1.999-0.895-1.999-1.999c0-1.104,0.895-1.999,1.999-1.999 s1.999,0.895,1.999,1.999C14.821,28.183,13.926,29.078,12.822,29.078z"/><path fill="#30dc80" d="M34.038,19.313c-0.14,0-0.281-0.035-0.41-0.11c-0.393-0.227-0.527-0.729-0.301-1.122l5.197-9.008 c0.227-0.394,0.729-0.529,1.122-0.301c0.393,0.227,0.527,0.729,0.301,1.122l-5.197,9.008C34.598,19.166,34.322,19.313,34.038,19.313 z"/><path fill="#30dc80" d="M13.962,19.313c-0.284,0-0.56-0.148-0.712-0.411L8.054,9.894C7.827,9.501,7.962,8.999,8.354,8.772 c0.392-0.228,0.895-0.093,1.122,0.301l5.197,9.008c0.227,0.394,0.092,0.896-0.301,1.122C14.243,19.278,14.102,19.313,13.962,19.313z"/></svg>

After

Width:  |  Height:  |  Size: 1007 B

BIN
src/images/debian.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

1
src/images/discord.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><svg viewBox="0 0 40 40" xmlns="http://www.w3.org/2000/svg"><defs><style>.cls-1{fill:none;}</style></defs><title/><g id="Discord"><path class="cls-1" d="M22.26,14.39l-.19.22a9.16,9.16,0,0,1,3.42,1.74A11.22,11.22,0,0,0,21.36,15a11.59,11.59,0,0,0-2.77,0l-.24,0a10.36,10.36,0,0,0-3.11.86c-.51.24-.81.4-.81.4A9.27,9.27,0,0,1,18,14.56l-.14-.17a6.77,6.77,0,0,0-3.85,1.44,18.34,18.34,0,0,0-2,8,5,5,0,0,0,4.19,2.08l.91-1.14a4.27,4.27,0,0,1-2.4-1.62s.14.1.39.24l.05,0,.13.07a7.31,7.31,0,0,0,1,.46,11.3,11.3,0,0,0,2,.59,9.61,9.61,0,0,0,3.56,0,8.85,8.85,0,0,0,2-.59,7.92,7.92,0,0,0,1.58-.81A4.32,4.32,0,0,1,23,24.8c.41.52.9,1.11.9,1.11a5,5,0,0,0,4.2-2.08,18.41,18.41,0,0,0-2-8A6.81,6.81,0,0,0,22.26,14.39Zm-4.74,8.16A1.53,1.53,0,1,1,18.92,21,1.47,1.47,0,0,1,17.52,22.55Zm5,0a1.53,1.53,0,0,1,0-3,1.53,1.53,0,0,1,0,3Z"/><path d="M29.19,8H10.81A2.82,2.82,0,0,0,8,10.83V29.17A2.82,2.82,0,0,0,10.81,32H26.36l-.72-2.54,1.75,1.83,1.66,1.53L32,35.43V10.83A2.82,2.82,0,0,0,29.19,8Zm-5.3,17.91s-.49-.59-.9-1.11a4.32,4.32,0,0,0,2.48-1.63,7.92,7.92,0,0,1-1.58.81,8.85,8.85,0,0,1-2,.59,9.61,9.61,0,0,1-3.56,0,11.3,11.3,0,0,1-2-.59,7.31,7.31,0,0,1-1-.46l-.13-.07-.05,0c-.25-.14-.39-.24-.39-.24a4.27,4.27,0,0,0,2.4,1.62l-.91,1.14a5,5,0,0,1-4.19-2.08,18.34,18.34,0,0,1,2-8,6.77,6.77,0,0,1,3.85-1.44l.14.17a9.27,9.27,0,0,0-3.61,1.79s.3-.16.81-.4a10.36,10.36,0,0,1,3.11-.86l.24,0a11.59,11.59,0,0,1,2.77,0,11.22,11.22,0,0,1,4.13,1.31,9.16,9.16,0,0,0-3.42-1.74l.19-.22a6.81,6.81,0,0,1,3.86,1.44,18.41,18.41,0,0,1,2,8A5,5,0,0,1,23.89,25.91Z"/><ellipse cx="22.52" cy="21.03" rx="1.4" ry="1.52"/><path d="M17.52,19.51A1.53,1.53,0,1,0,18.92,21,1.46,1.46,0,0,0,17.52,19.51Z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/images/dutch.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

1
src/images/email.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><svg viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg"><title/><g data-name="mail email e-mail letter" id="mail_email_e-mail_letter"><path d="M28,13a1,1,0,0,0-1,1v8a1,1,0,0,1-1,1H6a1,1,0,0,1-1-1V14a1,1,0,0,0-2,0v8a3,3,0,0,0,.88,2.12A3,3,0,0,0,6,25H26a3,3,0,0,0,2.12-.88A3,3,0,0,0,29,22V14A1,1,0,0,0,28,13Z"/><path d="M15.4,18.8a1,1,0,0,0,1.2,0L28.41,9.94a1,1,0,0,0,.3-1.23,3.06,3.06,0,0,0-.59-.83A3,3,0,0,0,26,7H6a3,3,0,0,0-2.12.88,3.06,3.06,0,0,0-.59.83,1,1,0,0,0,.3,1.23ZM6,9H26a.9.9,0,0,1,.28,0L16,16.75,5.72,9A.9.9,0,0,1,6,9Z"/></g></svg>

After

Width:  |  Height:  |  Size: 569 B

BIN
src/images/english.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 996 B

BIN
src/images/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

BIN
src/images/folia.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

1
src/images/github.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><svg fill="none" height="25" viewBox="0 0 25 25" width="25" xmlns="http://www.w3.org/2000/svg"><path clip-rule="evenodd" d="M15.7481 24.9471C24.0901 24.7061 24.9111 22.9501 24.9111 12.9811C24.9111 1.98108 23.9111 0.981079 12.9111 0.981079C1.91113 0.981079 0.911133 1.98108 0.911133 12.9811C0.911133 22.9761 1.73713 24.7151 10.1391 24.9491C10.2121 24.8581 10.2391 24.7441 10.2391 24.6281C10.2391 24.3781 10.2291 21.8121 10.2241 20.9291C7.18713 21.5681 6.54613 19.5101 6.54613 19.5101C6.04913 18.2881 5.33313 17.9621 5.33313 17.9621C4.34213 17.3061 5.40813 17.3191 5.40813 17.3191C6.50413 17.3941 7.08113 18.4101 7.08113 18.4101C8.05513 20.0271 9.63713 19.5601 10.2591 19.2891C10.3581 18.6061 10.6401 18.1391 10.9521 17.8751C8.52713 17.6081 5.97813 16.7001 5.97813 12.6451C5.97813 11.4901 6.40413 10.5461 7.10213 9.80608C6.98913 9.53808 6.61513 8.46208 7.20913 7.00608C7.20913 7.00608 8.12613 6.72108 10.2121 8.09008C11.0831 7.85508 12.0171 7.73808 12.9461 7.73408C13.8731 7.73808 14.8071 7.85508 15.6801 8.09008C17.7651 6.72108 18.6801 7.00608 18.6801 7.00608C19.2761 8.46208 18.9011 9.53808 18.7881 9.80608C19.4881 10.5461 19.9111 11.4901 19.9111 12.6451C19.9111 16.7101 17.3581 17.6051 14.9251 17.8661C15.3171 18.1931 15.6661 18.8391 15.6661 19.8261C15.6661 20.7721 15.6601 22.4451 15.6561 23.5541C15.6541 24.1031 15.6531 24.5131 15.6531 24.6281C15.6531 24.7371 15.6821 24.8521 15.7481 24.9471V24.9471Z" fill="black" fill-rule="evenodd"/></svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

1
src/images/golang.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#ffcc80" d="M35.547 42.431l-3.182-3.182-2.121 2.121 3.182 3.182c.586.586 1.536.586 2.121 0S36.133 43.017 35.547 42.431zM38.547 24.431l-3.182-3.182-2.121 2.121 3.182 3.182c.586.586 1.536.586 2.121 0S39.133 25.017 38.547 24.431zM12.683 42.431l3.182-3.182 2.121 2.121-3.182 3.182c-.586.586-1.536.586-2.121 0S12.097 43.017 12.683 42.431zM9.433 24.431l3.182-3.182 2.121 2.121-3.182 3.182c-.586.586-1.536.586-2.121 0S8.847 25.017 9.433 24.431z"/><path fill="#4dd0e1" d="M38 8c0-1.933-1.149-3-3.231-3S31 7.567 31 9.5c0 1 1.923 1.5 3 1.5C36.082 11 38 9.933 38 8zM10 8c0-1.933 1.149-3 3.231-3S17 7.567 17 9.5c0 1-1.923 1.5-3 1.5C11.918 11 10 9.933 10 8z"/><path fill="#424242" d="M35 7A1 1 0 1 0 35 9 1 1 0 1 0 35 7zM13 7A1 1 0 1 0 13 9 1 1 0 1 0 13 7z"/><path fill="#4dd0e1" d="M37,34c0,4.774-3.219,10-13.31,10C15.568,44,11,38.774,11,34c0-5,1-5.806,1-10c0-4.688,0-7,0-10 c0-4.774,3.076-11,11.69-11S36,6.991,36,13c0,3-0.237,5.453,0,10C36.186,26.562,37,31,37,34z"/><g><path fill="#f5f5f5" d="M29 6A4 4 0 1 0 29 14 4 4 0 1 0 29 6zM19 6A4 4 0 1 0 19 14 4 4 0 1 0 19 6z"/></g><g><path fill="#eee" d="M24 20c0 .552.448 1 1 1s1-.448 1-1v-3h-2V20zM22 20c0 .552.448 1 1 1s1-.448 1-1v-3h-2V20z"/></g><path fill="#ffcc80" d="M26.5,18c-0.412,0-0.653-0.085-1.011-0.205c-0.975-0.328-2.021-0.326-2.996,0.002 C22.138,17.916,21.91,18,21.5,18c-1.334,0-1.5-1-1.5-1.5c0-1.5,1.5-2.5,3-2.5c0.835,0,1.165,0,2,0c1.5,0,3,1,3,2.5 C28,17,27.834,18,26.5,18z"/><g><path fill="#424242" d="M27 9A1 1 0 1 0 27 11 1 1 0 1 0 27 9zM17 9A1 1 0 1 0 17 11 1 1 0 1 0 17 9zM24 13A2 1 0 1 0 24 15 2 1 0 1 0 24 13z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

1
src/images/java.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#F44336" d="M23.65,24.898c-0.998-1.609-1.722-2.943-2.725-5.455C19.229,15.2,31.24,11.366,26.37,3.999c2.111,5.089-7.577,8.235-8.477,12.473C17.07,20.37,23.645,24.898,23.65,24.898z"/><path fill="#F44336" d="M23.878,17.27c-0.192,2.516,2.229,3.857,2.299,5.695c0.056,1.496-1.447,2.743-1.447,2.743s2.728-0.536,3.579-2.818c0.945-2.534-1.834-4.269-1.548-6.298c0.267-1.938,6.031-5.543,6.031-5.543S24.311,11.611,23.878,17.27z"/><g><path fill="#1565C0" d="M32.084 25.055c1.754-.394 3.233.723 3.233 2.01 0 2.901-4.021 5.643-4.021 5.643s6.225-.742 6.225-5.505C37.521 24.053 34.464 23.266 32.084 25.055zM29.129 27.395c0 0 1.941-1.383 2.458-1.902-4.763 1.011-15.638 1.147-15.638.269 0-.809 3.507-1.638 3.507-1.638s-7.773-.112-7.773 2.181C11.683 28.695 21.858 28.866 29.129 27.395z"/><path fill="#1565C0" d="M27.935,29.571c-4.509,1.499-12.814,1.02-10.354-0.993c-1.198,0-2.974,0.963-2.974,1.889c0,1.857,8.982,3.291,15.63,0.572L27.935,29.571z"/><path fill="#1565C0" d="M18.686,32.739c-1.636,0-2.695,1.054-2.695,1.822c0,2.391,9.76,2.632,13.627,0.205l-2.458-1.632C24.271,34.404,17.014,34.579,18.686,32.739z"/><path fill="#1565C0" d="M36.281,36.632c0-0.936-1.055-1.377-1.433-1.588c2.228,5.373-22.317,4.956-22.317,1.784c0-0.721,1.807-1.427,3.477-1.093l-1.42-0.839C11.26,34.374,9,35.837,9,37.017C9,42.52,36.281,42.255,36.281,36.632z"/><path fill="#1565C0" d="M39,38.604c-4.146,4.095-14.659,5.587-25.231,3.057C24.341,46.164,38.95,43.628,39,38.604z"/></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#ffd600" d="M6,42V6h36v36H6z"/><path fill="#000001" d="M29.538 32.947c.692 1.124 1.444 2.201 3.037 2.201 1.338 0 2.04-.665 2.04-1.585 0-1.101-.726-1.492-2.198-2.133l-.807-.344c-2.329-.988-3.878-2.226-3.878-4.841 0-2.41 1.845-4.244 4.728-4.244 2.053 0 3.528.711 4.592 2.573l-2.514 1.607c-.553-.988-1.151-1.377-2.078-1.377-.946 0-1.545.597-1.545 1.377 0 .964.6 1.354 1.985 1.951l.807.344C36.452 29.645 38 30.839 38 33.523 38 36.415 35.716 38 32.65 38c-2.999 0-4.702-1.505-5.65-3.368L29.538 32.947zM17.952 33.029c.506.906 1.275 1.603 2.381 1.603 1.058 0 1.667-.418 1.667-2.043V22h3.333v11.101c0 3.367-1.953 4.899-4.805 4.899-2.577 0-4.437-1.746-5.195-3.368L17.952 33.029z"/></svg>

After

Width:  |  Height:  |  Size: 777 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

19
src/images/kotlin.svg Normal file
View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 24.1.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 500 500" style="enable-background:new 0 0 500 500;" xml:space="preserve">
<style type="text/css">
.st0{fill:url(#SVGID_1_);}
</style>
<g id="Logotypes">
<g>
<linearGradient id="SVGID_1_" gradientUnits="userSpaceOnUse" x1="500.0035" y1="579.1058" x2="-9.653803e-02" y2="1079.2058" gradientTransform="matrix(0.9998 0 0 0.9998 9.651873e-02 -578.99)">
<stop offset="3.435144e-03" style="stop-color:#E44857"/>
<stop offset="0.4689" style="stop-color:#C711E1"/>
<stop offset="1" style="stop-color:#7F52FF"/>
</linearGradient>
<polygon class="st0" points="500,500 0,500 0,0 500,0 250,250 "/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 904 B

1
src/images/linkedin.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="100%" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" version="1.1" viewBox="0 0 512 512" width="100%" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:serif="http://www.serif.com/" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M473.305,-1.353c20.88,0 37.885,16.533 37.885,36.926l0,438.251c0,20.393 -17.005,36.954 -37.885,36.954l-436.459,0c-20.839,0 -37.773,-16.561 -37.773,-36.954l0,-438.251c0,-20.393 16.934,-36.926 37.773,-36.926l436.459,0Zm-37.829,436.389l0,-134.034c0,-65.822 -14.212,-116.427 -91.12,-116.427c-36.955,0 -61.739,20.263 -71.867,39.476l-1.04,0l0,-33.411l-72.811,0l0,244.396l75.866,0l0,-120.878c0,-31.883 6.031,-62.773 45.554,-62.773c38.981,0 39.468,36.461 39.468,64.802l0,118.849l75.95,0Zm-284.489,-244.396l-76.034,0l0,244.396l76.034,0l0,-244.396Zm-37.997,-121.489c-24.395,0 -44.066,19.735 -44.066,44.047c0,24.318 19.671,44.052 44.066,44.052c24.299,0 44.026,-19.734 44.026,-44.052c0,-24.312 -19.727,-44.047 -44.026,-44.047Z" style="fill-rule:nonzero;"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/images/papermc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

1
src/images/python.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="48px" height="48px"><path fill="#0277BD" d="M24.047,5c-1.555,0.005-2.633,0.142-3.936,0.367c-3.848,0.67-4.549,2.077-4.549,4.67V14h9v2H15.22h-4.35c-2.636,0-4.943,1.242-5.674,4.219c-0.826,3.417-0.863,5.557,0,9.125C5.851,32.005,7.294,34,9.931,34h3.632v-5.104c0-2.966,2.686-5.896,5.764-5.896h7.236c2.523,0,5-1.862,5-4.377v-8.586c0-2.439-1.759-4.263-4.218-4.672C27.406,5.359,25.589,4.994,24.047,5z M19.063,9c0.821,0,1.5,0.677,1.5,1.502c0,0.833-0.679,1.498-1.5,1.498c-0.837,0-1.5-0.664-1.5-1.498C17.563,9.68,18.226,9,19.063,9z"/><path fill="#FFC107" d="M23.078,43c1.555-0.005,2.633-0.142,3.936-0.367c3.848-0.67,4.549-2.077,4.549-4.67V34h-9v-2h9.343h4.35c2.636,0,4.943-1.242,5.674-4.219c0.826-3.417,0.863-5.557,0-9.125C41.274,15.995,39.831,14,37.194,14h-3.632v5.104c0,2.966-2.686,5.896-5.764,5.896h-7.236c-2.523,0-5,1.862-5,4.377v8.586c0,2.439,1.759,4.263,4.218,4.672C19.719,42.641,21.536,43.006,23.078,43z M28.063,39c-0.821,0-1.5-0.677-1.5-1.502c0-0.833,0.679-1.498,1.5-1.498c0.837,0,1.5,0.664,1.5,1.498C29.563,38.32,28.899,39,28.063,39z"/></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

8
src/images/react.svg Normal file
View File

@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-11.5 -10.23174 23 20.46348">
<circle cx="0" cy="0" r="2.05" fill="#61dafb"/>
<g stroke="#61dafb" stroke-width="1" fill="none">
<ellipse rx="11" ry="4.2"/>
<ellipse rx="11" ry="4.2" transform="rotate(60)"/>
<ellipse rx="11" ry="4.2" transform="rotate(120)"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 338 B

BIN
src/images/russian.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

1
src/images/sqlite.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" width="50px" height="50px"><path d="M 43.640625 1.0019531 C 42.177246 0.96137695 40.611719 1.7683594 39.058594 3.1464844 C 38.689594 3.4744844 38.321078 3.8385625 37.955078 4.2265625 C 33.705078 8.7355625 29.759203 17.086844 28.533203 23.464844 C 29.010203 24.432844 29.384859 25.669281 29.630859 26.613281 C 29.693859 26.855281 29.749922 27.081391 29.794922 27.275391 C 29.902922 27.733391 29.960938 28.029297 29.960938 28.029297 C 29.960938 28.029297 29.923578 27.885641 29.767578 27.431641 C 29.737578 27.344641 29.703062 27.250672 29.664062 27.138672 C 29.647063 27.092672 29.625609 27.036562 29.599609 26.976562 C 29.322609 26.331563 28.554797 24.970906 28.216797 24.378906 C 27.927797 25.230906 27.673937 26.027047 27.460938 26.748047 C 28.434938 28.531047 29.027344 31.585937 29.027344 31.585938 C 29.027344 31.585938 28.977422 31.388266 28.732422 30.697266 C 28.515422 30.086266 27.432781 28.188141 27.175781 27.744141 C 26.736781 29.364141 26.56175 30.458609 26.71875 30.724609 C 27.02375 31.240609 27.315313 32.129281 27.570312 33.113281 C 27.659312 33.454281 27.742266 33.806203 27.822266 34.158203 C 27.557266 36.485203 27.495047 38.822719 27.623047 41.136719 C 27.756047 43.644719 28.106906 46.1205 28.503906 48.5625 C 28.545906 48.8195 28.781922 49.005469 29.044922 48.980469 C 29.319922 48.954469 29.522094 48.710547 29.496094 48.435547 C 29.371094 47.104547 29.265266 45.777125 29.197266 44.453125 L 29.257812 45.046875 C 29.162813 43.857875 29.1365 42.577844 29.1875 41.214844 C 29.3685 36.380844 30.482109 30.550609 32.537109 24.474609 C 36.010109 15.302609 40.827328 7.9417344 45.236328 4.4277344 C 41.217328 8.0577344 35.778391 19.807203 34.150391 24.158203 C 32.327391 29.030203 31.034859 33.601422 30.255859 37.982422 C 31.599859 33.875422 35.943359 32.111328 35.943359 32.111328 C 35.943359 32.111328 38.075453 29.482516 40.564453 25.728516 C 39.073453 26.068516 36.622734 26.651094 35.802734 26.996094 C 34.592734 27.504094 34.267578 27.677734 34.267578 27.677734 C 34.267578 27.677734 38.186828 25.289984 41.548828 24.208984 C 46.173828 16.924984 51.212672 6.5767813 46.138672 2.0507812 C 45.359047 1.3555312 44.518652 1.0262988 43.640625 1.0019531 z M 9 3 C 6.79 3 5 4.79 5 7 L 5 40 C 5 42.21 6.79 44 9 44 L 25.849609 44 C 25.749609 43.1 25.680859 42.170234 25.630859 41.240234 C 25.500859 38.920234 25.550781 36.569297 25.800781 34.279297 C 25.740781 34.049297 25.690859 33.829141 25.630859 33.619141 C 25.290859 32.299141 25.06 31.850234 25 31.740234 C 24.55 30.990234 24.470234 30.080703 25.240234 27.220703 C 25.901234 24.955703 28.786375 11.163 36.359375 3 L 9 3 z"/></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

6
src/images/telegram.svg Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" ?><svg style="enable-background:new 0 0 32 32;" version="1.1" viewBox="0 0 32 32" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><style type="text/css">
.st0{fill:#000000;}
.st1{fill:none;stroke:#222A30;stroke-width:1.8761;stroke-linejoin:round;stroke-miterlimit:10;}
.st2{fill:#000000;}
.st3{fill-rule:evenodd;clip-rule:evenodd;fill:#222A30;}
</style><g id="Layer_1"/><g id="icons"><g id="telegram"><path class="st0" d="M21,12.1L13.2,19c-0.1,0.1-0.1,0.2-0.1,0.3l-0.3,2.7c0,0.1-0.1,0.1-0.2,0l-1.2-4c-0.1-0.2,0-0.4,0.2-0.5 l9.1-5.7C21,11.7,21.2,12,21,12.1z"/><path class="st0" d="M16,2.2c-3.8,0-7.3,1.5-9.8,4c-2.5,2.5-4.1,6-4.1,9.8c0,3.8,1.5,7.3,4.1,9.8c2.5,2.5,6,4,9.8,4 c3.8,0,7.3-1.5,9.8-4c2.5-2.5,4.1-6,4.1-9.8C29.8,8.4,23.6,2.2,16,2.2z M24.2,10.1l-2.8,13.6c-0.1,0.6-0.9,0.9-1.4,0.5l-4.3-3.2 l-2.2,2.2c-0.4,0.4-1,0.2-1.2-0.3l-1.6-5l-4.2-1.3c-0.6-0.2-0.6-0.9,0-1.1l16.7-6.5C23.7,8.9,24.4,9.4,24.2,10.1z"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1006 B

1
src/images/youtube.svg Normal file
View File

@@ -0,0 +1 @@
<?xml version="1.0" ?><!DOCTYPE svg PUBLIC '-//W3C//DTD SVG 1.1//EN' 'http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd'><svg height="100%" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;" version="1.1" viewBox="0 0 512 512" width="100%" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:serif="http://www.serif.com/" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M501.303,132.765c-5.887,-22.03 -23.235,-39.377 -45.265,-45.265c-39.932,-10.7 -200.038,-10.7 -200.038,-10.7c0,0 -160.107,0 -200.039,10.7c-22.026,5.888 -39.377,23.235 -45.264,45.265c-10.697,39.928 -10.697,123.238 -10.697,123.238c0,0 0,83.308 10.697,123.232c5.887,22.03 23.238,39.382 45.264,45.269c39.932,10.696 200.039,10.696 200.039,10.696c0,0 160.106,0 200.038,-10.696c22.03,-5.887 39.378,-23.239 45.265,-45.269c10.696,-39.924 10.696,-123.232 10.696,-123.232c0,0 0,-83.31 -10.696,-123.238Zm-296.506,200.039l0,-153.603l133.019,76.802l-133.019,76.801Z" style="fill-rule:nonzero;"/></svg>

After

Width:  |  Height:  |  Size: 1006 B

12
src/index.html Normal file
View File

@@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>@Rinuuri - The dev</title>
<link rel="icon" type="image/x-icon" href="images/favicon.ico">
</head>
<body>
<div id="root"></div>
<script type="module" src="./frontend.tsx"></script>
</body>
</html>

41
src/index.tsx Normal file
View File

@@ -0,0 +1,41 @@
import { serve } from "bun";
import index from "./index.html";
const server = serve({
routes: {
// Serve index.html for all unmatched routes.
"/*": index,
"/api/hello": {
async GET(req) {
return Response.json({
message: "Hello, world!111",
method: "GET",
});
},
async PUT(req) {
return Response.json({
message: "Hello, world!",
method: "PUT",
});
},
},
"/api/hello/:name": async req => {
const name = req.params.name;
return Response.json({
message: `Hello, ${name}!`,
});
},
},
development: process.env.NODE_ENV !== "production" && {
// Enable browser hot reloading in development
hmr: true,
// Echo console logs from the browser to the server
console: true,
},
});
console.log(`🚀 Server running at ${server.url}`);

315
src/main.css Normal file
View File

@@ -0,0 +1,315 @@
@font-face {
font-family: 'Host Grotesk';
src:
url('fonts/Nunito-Bold.ttf') format('truetype') /* Safari, Android, iOS */
}
@keyframes background-pan {
from {
background-position: 0% center;
}
to {
background-position: -200% center;
}
}
@keyframes bar {
0% {
background-position: 0% center;
}
33% {
background-position: -200% center;
}
100% {
background-position: -200% center;
}
}
@keyframes float {
0% {
transform: translateY(1.1svh)
}
50% {
transform: translateY(0svh)
}
100% {
transform: translateY(1.1svh)
}
}
@keyframes float-rotate {
0% {
transform: rotate(5deg)
}
50% {
transform: rotate(-5deg)
}
100% {
transform: rotate(5deg)
}
}
*, html, body {
font-family: "Host Grotesk", serif;
font-optical-sizing: auto;
font-weight: 600;
font-style: normal;
padding: 0;
margin: 0;
}
html, body, #root{
width:100%;
height:100%;
}
body {
background: black;
}
#background-renderer {
position: fixed; z-index: -1000; width: 100%; height: 100%; margin: 0; padding: 0;
filter: blur(0.2svh);
}
.circular-mask {
border-radius: 50%;
overflow: hidden;
width: 90px;
height: 90px;
}
#profile-picture-div {
position: absolute; padding: 10px; padding-left: 20px; z-index: 3;
}
#profile-picture-img {
transform-origin: 0% 0%;
transform: scale(0.15) translateX(-50%) translateY(-50%);
transition-duration: 0.5s;
}
#profile-picture-img:hover {
rotate: 90deg;
}
#language-div {
position: absolute; padding: 10px; padding-right: 20px; z-index: 3;
}
#language-renderer {
width: 100%; height: 100vh; display: block; margin: 0; padding: 0; cursor: grab;
}
#section-positioner {
position: absolute; top: 0; left: 50%; transform: translateX(-50%); z-index: 11; width: 920px; padding-top: 15px;
}
#projects {
position: absolute; top: 50vh; left: 20%; transform: translateX(-50%); z-index: 11; width: 900px; height: auto; display: grid; grid-template-columns: 50% 50%; left: 50%; width: 90%;
}
#footer {
background: linear-gradient(to bottom left, rgb(41, 11, 41), rgb(44, 18, 44));
margin-bottom: 0px;
padding: 0px;
left: 30%;
position: absolute;
height: 50px;
z-index: 12;
align-self: center;
width: 40%;
padding-top: 10px;
overflow: hidden;
bottom: 0;
border-top-left-radius: 20px;
border-top-right-radius: 20px;
transition: all 0.3s ease-in-out;
transform-origin: center bottom;
transform: scale(1);
}
#footer:hover {
background: linear-gradient(to bottom left, rgb(41, 11, 41), rgb(48, 19, 48));
transform: scale(101%);
}
.description {
scale: 0.85; transform-origin: left;
}
.profile-gradient {
background: linear-gradient(to right, rgb(230, 160, 56), rgb(225, 74, 180), rgb(189, 37, 216), rgb(62, 163, 218));
width: 95px; height: 95px;
}
.gradient-overlay {
background: linear-gradient(to bottom right, rgba(0, 0, 0, 0.5), rgba(107, 29, 107, 0.3));
background: -webkit-linear-gradient(to bottom right, rgba(0, 0, 0, 0.5), rgba(107, 29, 107, 0.3) 100%);
background: -moz-linear-gradient(to bottom right, rgba(0, 0, 0, 0.5), rgba(107, 29, 107, 0.3) 100%);
position: fixed; width: 100%; height: 100%;
z-index: 1000000;
}
.devider {
position: absolute; left: 60%; top: 0; height: 100%; width: 0.4vh; background-color: rgba(209, 209, 209, 0.1);
border-radius: 20%;
}
.section {
background: rgb(15, 15, 15);
background: linear-gradient(to bottom right, rgba(15,15,16,1), rgb(44, 18, 44));
background: -webkit-linear-gradient(to bottom right, rgba(15,15,16,1), rgb(44, 18, 44));
background: -moz-linear-gradient(to bottom right, rgba(15,15,16,1), rgb(44, 18, 44));
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr="#0f0f10",endColorstr="#152137",GradientType=1);
border-radius: 4vh;
height: 100%;
padding-top: 64px;
padding-left: 35px;
padding-right: 48px;
padding-bottom: 48px;
margin-bottom: 24px;
margin-right: 1%;
transition: all 0.4s ease-in-out;
transform-origin: center;
transform: scale(1);
position: relative;
overflow: hidden;
}
.long-desc {
width: 90%;
overflow-wrap: break-word;
}
.section-card {
padding-top: 5%; padding-bottom: 10%;
margin-right: 2%;
margin-left: 2%;
margin-bottom: 0px;
}
.section:after {
width: 1px;
height: 80px;
background: linear-gradient(
rgba(0,0,0,0),
rgb(150, 73, 238),
rgba(0,0,0,0)
);
left: 0px;
position: absolute;
top: 60%;
opacity: 0%;
transition: all 0.15s ease-in-out;
content: "";
}
.section:hover:after {
top: 20%;
opacity: 100%;
}
#projects .section {
height: 20vh;
}
.section:hover {
background: linear-gradient(to bottom right, rgb(16, 16, 16), rgb(48, 18, 48));
transform: scale(101%);
box-shadow: #2702274f 0px 0px 4svh 0px;
}
.card {
width: 10%;
}
.section button {
color: white;
background-color: #e032e0;
border-radius: 120px;
height: 60px;
border: none;
width: 180px;
font-size: 22px;
transition: all 0.25s ease-in-out;
}
.progress-bar {
left: 10%; width: 90%; height: 1vh;
background: linear-gradient(to right, rgb(128, 0, 128), rgb(187, 75, 212), rgb(128, 0, 128));
background-size: 200%;
border-radius: 1vh;
animation: bar 6s linear infinite;
}
.tech-name img {
width: 3.5vh;
height: 3.5vh;
}
.section p {
color: #CED7EB;
font-weight: 400;
font-size: 24px;
margin-bottom: 32px;
}
.tech-name {
font-size: x-large;
color: #d6c7e0;
height: 1px;
transition: all 0.25s ease-in-out;
transform: scale(1);
transform-origin: right;
cursor: default;
}
.tech-name:hover {
transform: scale(102%) translateX(-0.5vh);
}
h1,h2,h3,h4,h5 {
font-weight: 900;
font-size: 36px;
color: whitesmoke;
margin-bottom: 1vh;
width: max-content;
}
button:hover {
animation-play-state: running;
scale: 105%;
}
button {
background: linear-gradient(to right, rgb(73, 0, 80), rgb(126, 0, 138), rgb(73, 0, 80));
background-size: 200%;
animation: background-pan 3s linear infinite;
animation-play-state: paused;
cursor: pointer;
}
.highlight {
animation: background-pan 3s linear infinite;
background: linear-gradient(to right, rgb(167, 0, 167), violet, rgb(228, 95, 217), rgb(167, 0, 167));
background-size: 200%;
background-clip: text;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
white-space: nowrap;
}
a.icon {
transition: all 0.2s ease-in-out;
width: 20px;
height: 20px;
display: inline-block;
margin-right: 30px;
filter: invert(100%) brightness(40%);
}
a.icon:hover {
scale: 110%;
filter: invert(100%) brightness(60%);
}
#licence {
text-align: right; right: 5%; color: rgb(170, 170, 170); padding-right: 2%;
}
#contacts {
position: absolute; height: 50%; left: 3%; bottom: 10px; display: flex;
}
.other-tech {
position: relative;left: 15%; display: flex; align-items: center; flex-direction: column;
}
.gradient-overlay div {
position: absolute;
width: fit-content; height: fit-content; animation: float 5s ease-in-out infinite;
}
.gradient-overlay img {
width: 7vh; height: 7vh; transform-origin: 50% 50%; animation: float-rotate 6s ease-in-out infinite;
filter: blur(0.5svh);
transition-duration: 0.5s;
}
.gradient-overlay img:hover {
filter: none;
scale: 1.4;
}
.rotate-away {
transform-origin: 50% 0px 50vh;
transform: rotateY(-90deg);
transition: all 2s ease-in-out;
opacity: 0%;
}
.rotated {
transform: rotateY(90deg);
position: absolute;
height: 100%;
width: 100%;
}
.rotate-in {
transform-origin: 50% 0px 50vh;
transform: rotateY(0deg);
transition: all 2s ease-in-out;
opacity: 100%;
}

58
src/scripts/background.js Normal file
View File

@@ -0,0 +1,58 @@
import * as THREE from 'three';
import { EffectComposer } from 'three/addons/postprocessing/EffectComposer.js';
import { ShaderPass } from 'three/addons/postprocessing/ShaderPass.js';
import {loadShader} from './common';
import fragmentShaderPath from '../shaders/background.glsl' assert { type: 'string' };
export async function init(canvas) {
let lastTime = performance.now();
let time = 0;
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(0, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer({antialias: false, canvas: canvas});
renderer.setSize(window.innerWidth/2, window.innerHeight);
const composer = new EffectComposer( renderer );
const uniforms = {
u_resolution: {value: new THREE.Vector2(window.innerWidth, window.innerHeight)
.multiplyScalar(window.devicePixelRatio)
},
aspect: {value: window.innerWidth/ window.innerHeight},
u_time_sin: {value: 0},
u_time: {value: 0},
u_mouse: {value: new THREE.Vector2(0.5, 0.5)},
u_scale: {value: window.innerHeight/1000}
}
const fragmentShader = await loadShader(fragmentShaderPath);
const postprocessingshader = new THREE.ShaderMaterial({
fragmentShader: fragmentShader,
uniforms
});
composer.addPass( new ShaderPass(postprocessingshader));
window.addEventListener('resize', function() {
const aspect = window.innerWidth/window.innerHeight;
postprocessingshader.uniforms.u_resolution.value = new THREE.Vector2(window.innerWidth, window.innerHeight)
.multiplyScalar(window.devicePixelRatio);
postprocessingshader.uniforms.aspect.value = aspect;
renderer.setSize(window.innerWidth, window.innerHeight);
});
window.addEventListener('mousemove', function(event) {
postprocessingshader.uniforms.u_mouse.value = new THREE.Vector2(1-event.clientX/window.innerWidth, event.clientY/window.innerHeight)
});
renderer.setAnimationLoop( animate );
function animate() {
const currentTime = performance.now();
const deltaTime = currentTime - lastTime;
lastTime = currentTime;
composer.render( scene, camera );
time += 0.0015*deltaTime;
postprocessingshader.uniforms.u_time.value = time*0.01;
}
animate();
}

7
src/scripts/common.js Normal file
View File

@@ -0,0 +1,7 @@
export async function loadShader(url) {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`Failed to load shader: ${response.statusText}`);
}
return await response.text();
}

195
src/scripts/lang.js Normal file
View File

@@ -0,0 +1,195 @@
import * as THREE from 'three';
import translations from '../translations.json' assert { type: 'json' };
import engPath from '../images/english.png'
import nldPath from '../images/dutch.jpg'
import rusPath from '../images/russian.jpg'
let language = "en";
function determineLanguage(){
const userLang = localStorage.getItem("preferredLanguage") || navigator.language || navigator.userLanguage;
switch (userLang) {
case "ru": {
language = "ru";
cube.rotation.y = 1.5707963267948966;
break;
}
case "nl": {
language = "nl";
cube.rotation.y = 4.71238898038469;
}
}
if (language != "en") setLanguage(language);
}
var elements = document.querySelectorAll('[ts]');
function setLanguage(l) {
language = l;
const arr = translations[language];
elements.forEach(function(element) {
var key = element.getAttribute('ts');
if (arr.hasOwnProperty(key)) {
element.innerHTML = arr[key];
}
});
}
const fov = 75;
const aspect = 1;
const near = 0.1;
const far = 5;
const canvas = document.querySelector('#language-renderer');
const renderer = new THREE.WebGLRenderer({antialias: false, canvas});
renderer.setSize( 90,90 );
renderer.setClearColor( 0xffffff, 0);
const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);
camera.position.z = 1.4;
const scene = new THREE.Scene();
const discardMaterial = new THREE.ShaderMaterial({
vertexShader:`
void main() {
gl_Position = vec4(1.0);
}`,
fragmentShader: `
void main() {
gl_FragColor = vec4(1.0);
discard;
}
`
});
var geometry = new THREE.BoxGeometry(1, 1, 1);
var texture = new THREE.TextureLoader();
var materials = [];
const dutch = texture.load(nldPath);
dutch.magFilter = THREE.NearestFilter;
dutch.minFilter = THREE.NearestFilter;
const english = texture.load(engPath);
english.magFilter = THREE.NearestFilter;
english.minFilter = THREE.NearestFilter;
const russian = texture.load(rusPath);
russian.magFilter = THREE.NearestFilter;
russian.minFilter = THREE.NearestFilter;
materials.push(new THREE.MeshPhongMaterial({map: dutch}));
materials.push(new THREE.MeshPhongMaterial({map: russian}));
materials.push(discardMaterial);
materials.push(discardMaterial);
materials.push(new THREE.MeshPhongMaterial({map: english}));
materials.push(new THREE.MeshPhongMaterial({map: english}));
var cube = new THREE.Mesh(geometry, materials);
determineLanguage();
scene.add(cube);
const ambientLight = new THREE.AmbientLight(0xffffff, 2.8);
scene.add(ambientLight);
let isDragging = false;
let previousX;
let velocity = 0;
const friction = 0.4;
// Define the possible rotation positions
const snapPositions = [0, Math.PI / 2, Math.PI, Math.PI * 3 / 2];
// Store the current snapped position
let currentSnapPosition = 0;
function startDrag(event) {
isDragging = true;
previousX = event.clientX || event.touches[0].clientX;
canvas.style.cursor = "grabbing";
}
function drag(event) {
if (isDragging) {
const currentX = event.clientX || event.touches[0].clientX;
velocity += (currentX - previousX) * 0.05;
previousX = currentX;
}
}
function endDrag() {
isDragging = false;
canvas.style.cursor = "grab";
snapCube();
}
function snapCube() {
// Normalize the cube's rotation to be within the range [0, 2 * PI)
let rotation = cube.rotation.y % (2 * Math.PI);
if (rotation < -Math.PI/4) {
rotation += 2 * Math.PI;
} else if (rotation > 5.49778718038469) {
rotation -= 2 * Math.PI;
}
// Calculate the closest snap position
const closestSnapPosition = snapPositions.reduce((prev, curr) => {
return Math.abs(curr - rotation) < Math.abs(prev - rotation) ? curr : prev;
}, snapPositions[0]);
// Interpolate to the closest snap position
const snapTime = 0.5; // seconds
const snapStart = rotation;
const snapEnd = closestSnapPosition;
const snapStartTime = performance.now();
function snapRender(time) {
const t = (time - snapStartTime) / (snapTime * 1000);
cube.rotation.y = snapStart + (snapEnd - snapStart) * t;
if (t < 1) {
requestAnimationFrame(snapRender);
} else {
cube.rotation.y = snapEnd;
currentSnapPosition = snapEnd;
let lang;
switch (snapEnd){
case 1.5707963267948966:
lang = "ru";
break;
case 0:
lang = "en";
break;
case 3.141592653589793:
lang = "en";
break;
case 4.71238898038469:
lang = "nl";
break;
}
if (lang != language) {
setLanguage(lang);
localStorage.setItem("preferredLanguage",language);
}
}
}
requestAnimationFrame(snapRender);
}
canvas.addEventListener('mousedown', startDrag);
canvas.addEventListener('touchstart', startDrag);
canvas.addEventListener('mousemove', drag);
canvas.addEventListener('touchmove', drag);
canvas.addEventListener("mouseleave", endDrag);
canvas.addEventListener('mouseup', endDrag);
canvas.addEventListener('touchend', endDrag);
//cube.rotation.x = 0.5;
function render(time) {
renderer.render(scene, camera);
velocity *= friction;
cube.rotation.y += velocity;
requestAnimationFrame(render);
}
requestAnimationFrame(render);

View File

@@ -0,0 +1,75 @@
uniform vec2 u_resolution;
uniform float aspect;
uniform float u_time;
uniform float u_time_sin;
uniform vec2 u_mouse;
uniform float u_scale;
// Worley noise implementation, credits to https://github.com/Erkaman
vec4 permute(vec4 x) {
return mod((34.0 * x + 1.0) * x, 289.0);
}
vec2 dist(vec2 x, vec2 y) {
return x * x + y * y;
}
vec4 dist(vec4 x, vec4 y, vec4 z) {
return x * x + y * y + z * z;
}
vec2 worley(vec3 P, float jitter) {
float K = 0.142857142857;
float Ko = 0.428571428571;
float K2 = 0.020408163265306;
float Kz = 0.166666666667;
float Kzo = 0.416666666667;
vec3 Pi = mod(floor(P), 289.0);
vec3 Pf = fract(P);
vec4 Pfx = Pf.x + vec4(0.0, -1.0, 0.0, -1.0);
vec4 Pfy = Pf.y + vec4(0.0, 0.0, -1.0, -1.0);
vec4 p = permute(Pi.x + vec4(0.0, 1.0, 0.0, 1.0));
p = permute(p + Pi.y + vec4(0.0, 0.0, 1.0, 1.0));
vec4 p1 = permute(p + Pi.z);
vec4 p2 = permute(p + Pi.z + vec4(1.0));
vec4 ox1 = fract(p1*K) - Ko;
vec4 oy1 = mod(floor(p1*K), 7.0)*K - Ko;
vec4 oz1 = floor(p1*K2)*Kz - Kzo;
vec4 ox2 = fract(p2*K) - Ko;
vec4 oy2 = mod(floor(p2*K), 7.0)*K - Ko;
vec4 oz2 = floor(p2*K2)*Kz - Kzo;
vec4 dx1 = Pfx + jitter*ox1;
vec4 dy1 = Pfy + jitter*oy1;
vec4 dz1 = Pf.z + jitter*oz1;
vec4 dx2 = Pfx + jitter*ox2;
vec4 dy2 = Pfy + jitter*oy2;
vec4 dz2 = Pf.z - 1.0 + jitter*oz2;
vec4 d1 = dist(dx1, dy1, dz1);
vec4 d2 = dist(dx2, dy2, dz2);
vec4 d = min(d1,d2);
d2 = max(d1,d2);
d.xy = (d.x < d.y) ? d.xy : d.yx;
d.xz = (d.x < d.z) ? d.xz : d.zx;
d.xw = (d.x < d.w) ? d.xw : d.wx;
d.yzw = min(d.yzw, d2.yzw);
d.y = min(d.y, d.z);
d.y = min(d.y, d.w);
d.y = min(d.y, d2.x);
return sqrt(d.xy);
}
void main() {
vec2 pixelPos = gl_FragCoord.xy / u_resolution;
pixelPos.x *= aspect;
float distanceIN = max(0.2-length(pixelPos - vec2((1.0-u_mouse.x)*aspect, 1.0-u_mouse.y)), 0.0);
pixelPos *= 10.0/u_scale;
pixelPos += u_time_sin;
float noise2 = worley(vec3(pixelPos, u_time+1.25), 1.0).x;
float noise1 = worley(vec3(pixelPos*1.1, u_time), 1.0).x;
float strengh = step(noise1, 0.07)*0.2+step(noise2, 0.04)*0.6;
strengh += distanceIN*(0.9-step(strengh, 0.01))*5.0;
gl_FragColor = vec4(strengh, strengh-0.25, strengh, 1.0);
}

38
src/translations.json Normal file
View File

@@ -0,0 +1,38 @@
{
"en": {
"hi": "Hi, I'm",
"hi_rest":", and I am<br>obsessed with development<br>since my childhood.",
"main_desctiption": "I'm a Java/Kotlin developer and just a trans girl :)",
"contact_me": "Contact me",
"licence": "Site source code license",
"tech_stack": "Programming languages",
"other_tech": "Other tech",
"devider": "<div class=\"devider\" style=\"left: 60%;\">",
"projects": "Experience and projects",
"projects_description": "I have experience with multithreaded environments and network programming, as I've worked on both commertial projects and my own open source ones, click the botton bellow to explore them",
"explore_projects": "explore"
},
"nl": {
"hi": "Hoi, ik heet",
"hi_rest":", en ik ben<br>geobsedeerd door ontwikkeling<br>sinds m'n jeugd.",
"main_desctiption": "Ik ben een Java/Kotlin ontwikkelster en net een trans meisje :)",
"licence":"Licentie voor sitebroncode",
"tech_stack": "Programmeertaalen",
"other_tech": "Anders technische",
"devider": "<div class=\"devider\" style=\"left: 55%;\">",
"projects":"Ervaring en projecten",
"projects_description": "Ik heb ervaring met multithreaded omgevingen en netwerkprogrammering, aangezien ik aan zowel commerciële projecten als m'n eigen open source projecten heb gewerkt, klik op de onderste knop om ze te verkennen",
"explore_projects": "Verkennen"
},
"ru":{
"hi": "Привет, я",
"hi_rest":", и я<br>обожаю разработку<br>с самого детства.",
"main_desctiption": "Я Java/Kotlin разработчик, да и просто транс-девушка :)",
"contact_me": "Связаться",
"licence": "Лицензия исходного кода сайта",
"tech_stack": "Языки программирования",
"other_tech": "Остальной стэк",
"devider": "<div class=\"devider\" style=\"left: 61%;\">",
"projects": "Опыт и проекты"
}
}

17
tsconfig.json Normal file
View File

@@ -0,0 +1,17 @@
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "bundler",
"jsx": "react-jsx",
"allowJs": true,
"strict": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"exclude": ["dist", "node_modules"]
}