mirror of
https://github.com/xzeldon/zeldon-site.git
synced 2025-07-16 00:54:37 +03:00
Compare commits
14 Commits
deploy
...
57e731a7b9
Author | SHA1 | Date | |
---|---|---|---|
57e731a7b9
|
|||
dc3462a864
|
|||
4a6aa94e39
|
|||
618fc16ed8
|
|||
5e6bdacdbb
|
|||
b5e8457ea5
|
|||
1bcc01bfe8
|
|||
e14b793fbc
|
|||
1c93c61309
|
|||
0fe859947b
|
|||
0eae708b22 | |||
b1acaee645
|
|||
6aecc455dd | |||
7b84c799b4
|
2
.dockerignore
Normal file
2
.dockerignore
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules
|
||||
dist
|
@ -2,7 +2,9 @@
|
||||
|
||||
See: [zeldon.ru](https://zeldon.ru).
|
||||
|
||||
My personal website. An [MIT](https://github.com/xzeldon/zeldon-site/blob/main/LICENSE) licensed, easy modifiable.
|
||||
My personal website. An [MIT](https://git.zeldon.ru/zeldon/zeldon-site/src/branch/main/LICENSE) licensed, easy modifiable.
|
||||
|
||||
Mirror on my [<img src="https://git.zeldon.ru/assets/img/logo.svg" align="center" width="20" height="20"/> Git](https://git.zeldon.ru/zeldon/zeldon-site)
|
||||
|
||||
## Dependencies
|
||||
|
||||
@ -13,7 +15,7 @@ Only [Vite](https://vitejs.dev/) for development and bundling.
|
||||
To download the repository and install dependencies, run the following commands:
|
||||
|
||||
```bash
|
||||
git clone git://github.com/xzeldon/zeldon-site.git # replace [xzeldon] with your github username if you fork first.
|
||||
git clone https://git.zeldon.ru/zeldon/zeldon-site.git
|
||||
cd zeldon-site
|
||||
npm install
|
||||
```
|
||||
@ -31,6 +33,7 @@ Your web browser should automatically open to `<ip>:<port>:<path>` default: [htt
|
||||
## Static export
|
||||
|
||||
To statically export the site, run this command:
|
||||
|
||||
```bash
|
||||
npm run build
|
||||
```
|
||||
|
14
config/Dockerfile
Normal file
14
config/Dockerfile
Normal file
@ -0,0 +1,14 @@
|
||||
FROM node:24-slim as build
|
||||
|
||||
WORKDIR /opt
|
||||
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM nginx:1.24-alpine-slim
|
||||
|
||||
COPY config/nginx.conf /etc/nginx/conf.d/default.conf
|
||||
COPY --from=build /opt/dist /usr/share/nginx/html
|
14
config/docker-compose.yml
Normal file
14
config/docker-compose.yml
Normal file
@ -0,0 +1,14 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
zeldon-site:
|
||||
image: zeldon-site:latest
|
||||
container_name: zeldon-site
|
||||
build:
|
||||
context: .
|
||||
dockerfile: config/Dockerfile
|
||||
ports:
|
||||
- "3123:80"
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ./config/nginx.conf:/etc/nginx/conf.d/default.conf:ro
|
10
config/nginx.conf
Normal file
10
config/nginx.conf
Normal file
@ -0,0 +1,10 @@
|
||||
server {
|
||||
listen 80;
|
||||
|
||||
# path to files for serve
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ /index.html;
|
||||
}
|
||||
}
|
108
index.html
108
index.html
@ -1,47 +1,58 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="Cache-Control" content="no-cache">
|
||||
<meta charset="utf-8" />
|
||||
<meta http-equiv="Cache-Control" content="no-cache" />
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta
|
||||
name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, user-scalable=no"
|
||||
/>
|
||||
<meta
|
||||
name="apple-mobile-web-app-status-bar-style"
|
||||
content="black-translucent"
|
||||
/>
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
|
||||
<link rel="icon" href="favicon/favicon.ico" sizes="any">
|
||||
<link rel="icon" href="favicon/favicon.svg" type="image/svg+xml">
|
||||
<link rel="apple-touch-icon" href="favicon/apple-touch-icon.png">
|
||||
<link rel="icon" href="favicon/favicon.ico" sizes="any" />
|
||||
<link rel="icon" href="favicon/favicon.svg" type="image/svg+xml" />
|
||||
<link rel="apple-touch-icon" href="favicon/apple-touch-icon.png" />
|
||||
|
||||
<title>zeldØƞ</title>
|
||||
<meta name="description" content="zeldon's website">
|
||||
<meta name="description" content="zeldon's website" />
|
||||
|
||||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="zeldØƞ">
|
||||
<meta property="og:description" content="zeldon's website">
|
||||
<meta property="og:url" content="https://zeldon.ru">
|
||||
<meta property="og:image" content="ogimage.jpg">
|
||||
|
||||
<!-- analytics -->
|
||||
<script async defer data-domain="zeldon.ru" src="https://analytics.zeldon.ru/js/plausible.js"></script>
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:title" content="zeldØƞ" />
|
||||
<meta property="og:description" content="zeldon's website" />
|
||||
<meta property="og:url" content="https://zeldon.ru" />
|
||||
<meta property="og:image" content="ogimage.jpg" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div class="content-info">
|
||||
<h1 class="name perspective">TIMOFEY <br>GELAZONIYA</h1>
|
||||
<h1 class="name perspective">TIMOFEY <br />GELAZONIYA</h1>
|
||||
<h4 class="greeting perspective"></h4>
|
||||
<h4 class="clock perspective"></h4>
|
||||
</div>
|
||||
<div class="button-container perspective">
|
||||
<button class="button button--hyperion" onclick="window.open('https://spotify.zeldon.ru', '_blank')"
|
||||
type="button">
|
||||
<button
|
||||
class="button button--hyperion"
|
||||
onclick="window.open('https://spotify.zeldon.ru', '_blank')"
|
||||
type="button"
|
||||
>
|
||||
<span class="button-inner">
|
||||
<svg class="spotify-icon" height="30" width="30" viewBox="0 0 170 170">
|
||||
<svg
|
||||
class="spotify-icon"
|
||||
height="30"
|
||||
width="30"
|
||||
viewBox="0 0 170 170"
|
||||
>
|
||||
<path
|
||||
d="m83.996 0.277c-46.249 0-83.743 37.493-83.743 83.742 0 46.251 37.494 83.741 83.743 83.741 46.254 0 83.744-37.49 83.744-83.741 0-46.246-37.49-83.738-83.745-83.738l0.001-0.004zm38.404 120.78c-1.5 2.46-4.72 3.24-7.18 1.73-19.662-12.01-44.414-14.73-73.564-8.07-2.809 0.64-5.609-1.12-6.249-3.93-0.643-2.81 1.11-5.61 3.926-6.25 31.9-7.291 59.263-4.15 81.337 9.34 2.46 1.51 3.24 4.72 1.73 7.18zm10.25-22.805c-1.89 3.075-5.91 4.045-8.98 2.155-22.51-13.839-56.823-17.846-83.448-9.764-3.453 1.043-7.1-0.903-8.148-4.35-1.04-3.453 0.907-7.093 4.354-8.143 30.413-9.228 68.222-4.758 94.072 11.127 3.07 1.89 4.04 5.91 2.15 8.976v-0.001zm0.88-23.744c-26.99-16.031-71.52-17.505-97.289-9.684-4.138 1.255-8.514-1.081-9.768-5.219-1.254-4.14 1.08-8.513 5.221-9.771 29.581-8.98 78.756-7.245 109.83 11.202 3.73 2.209 4.95 7.016 2.74 10.733-2.2 3.722-7.02 4.949-10.73 2.739z" />
|
||||
d="m83.996 0.277c-46.249 0-83.743 37.493-83.743 83.742 0 46.251 37.494 83.741 83.743 83.741 46.254 0 83.744-37.49 83.744-83.741 0-46.246-37.49-83.738-83.745-83.738l0.001-0.004zm38.404 120.78c-1.5 2.46-4.72 3.24-7.18 1.73-19.662-12.01-44.414-14.73-73.564-8.07-2.809 0.64-5.609-1.12-6.249-3.93-0.643-2.81 1.11-5.61 3.926-6.25 31.9-7.291 59.263-4.15 81.337 9.34 2.46 1.51 3.24 4.72 1.73 7.18zm10.25-22.805c-1.89 3.075-5.91 4.045-8.98 2.155-22.51-13.839-56.823-17.846-83.448-9.764-3.453 1.043-7.1-0.903-8.148-4.35-1.04-3.453 0.907-7.093 4.354-8.143 30.413-9.228 68.222-4.758 94.072 11.127 3.07 1.89 4.04 5.91 2.15 8.976v-0.001zm0.88-23.744c-26.99-16.031-71.52-17.505-97.289-9.684-4.138 1.255-8.514-1.081-9.768-5.219-1.254-4.14 1.08-8.513 5.221-9.771 29.581-8.98 78.756-7.245 109.83 11.202 3.73 2.209 4.95 7.016 2.74 10.733-2.2 3.722-7.02 4.949-10.73 2.739z"
|
||||
/>
|
||||
</svg>
|
||||
<span>
|
||||
<span>Sign in with Spotify</span>
|
||||
@ -49,26 +60,38 @@
|
||||
</span>
|
||||
</button>
|
||||
<div class="links-container">
|
||||
<a class="link" target="_blank" rel="noopener noreferrer" href="https://vk.com/xzeldon">
|
||||
<span class="link-text">
|
||||
vk
|
||||
</span>
|
||||
<a
|
||||
class="link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://vk.com/xzeldon"
|
||||
>
|
||||
<span class="link-text"> vk </span>
|
||||
</a>
|
||||
<a class="link" target="_blank" rel="noopener noreferrer" href="https://github.com/xzeldon">
|
||||
<span class="link-text">
|
||||
github
|
||||
</span>
|
||||
<a
|
||||
class="link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://github.com/xzeldon"
|
||||
>
|
||||
<span class="link-text"> git </span>
|
||||
</a>
|
||||
<a class="link" target="_blank" rel="noopener noreferrer" href="https://t.me/xzeldon">
|
||||
<span class="link-text">
|
||||
telegram
|
||||
</span>
|
||||
<a
|
||||
class="link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://git.zeldon.ru"
|
||||
>
|
||||
<span class="link-text"> gitea </span>
|
||||
</a>
|
||||
<a
|
||||
class="link"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
href="https://t.me/xzeldon"
|
||||
>
|
||||
<span class="link-text"> telegram </span>
|
||||
</a>
|
||||
<!-- <a class="link" target="_blank" rel="noopener noreferrer" href="https://www.instagram.com/zeeeldon">
|
||||
<span class="link-text">
|
||||
instagram
|
||||
</span>
|
||||
</a> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -76,5 +99,4 @@
|
||||
<canvas></canvas>
|
||||
<script type="module" src="./src/main.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
544
package-lock.json
generated
Normal file
544
package-lock.json
generated
Normal file
@ -0,0 +1,544 @@
|
||||
{
|
||||
"name": "zeldon-site",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "zeldon-site",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"vite": "^4.3.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.19.tgz",
|
||||
"integrity": "sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.19.tgz",
|
||||
"integrity": "sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.19.tgz",
|
||||
"integrity": "sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.19.tgz",
|
||||
"integrity": "sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.19.tgz",
|
||||
"integrity": "sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.19.tgz",
|
||||
"integrity": "sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.19.tgz",
|
||||
"integrity": "sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.19.tgz",
|
||||
"integrity": "sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.19.tgz",
|
||||
"integrity": "sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.19.tgz",
|
||||
"integrity": "sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.19.tgz",
|
||||
"integrity": "sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.19.tgz",
|
||||
"integrity": "sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.19.tgz",
|
||||
"integrity": "sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.19.tgz",
|
||||
"integrity": "sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.19.tgz",
|
||||
"integrity": "sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.17.19",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.19.tgz",
|
||||
"integrity": "sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@esbuild/android-arm": "0.17.19",
|
||||
"@esbuild/android-arm64": "0.17.19",
|
||||
"@esbuild/android-x64": "0.17.19",
|
||||
"@esbuild/darwin-arm64": "0.17.19",
|
||||
"@esbuild/darwin-x64": "0.17.19",
|
||||
"@esbuild/freebsd-arm64": "0.17.19",
|
||||
"@esbuild/freebsd-x64": "0.17.19",
|
||||
"@esbuild/linux-arm": "0.17.19",
|
||||
"@esbuild/linux-arm64": "0.17.19",
|
||||
"@esbuild/linux-ia32": "0.17.19",
|
||||
"@esbuild/linux-loong64": "0.17.19",
|
||||
"@esbuild/linux-mips64el": "0.17.19",
|
||||
"@esbuild/linux-ppc64": "0.17.19",
|
||||
"@esbuild/linux-riscv64": "0.17.19",
|
||||
"@esbuild/linux-s390x": "0.17.19",
|
||||
"@esbuild/linux-x64": "0.17.19",
|
||||
"@esbuild/netbsd-x64": "0.17.19",
|
||||
"@esbuild/openbsd-x64": "0.17.19",
|
||||
"@esbuild/sunos-x64": "0.17.19",
|
||||
"@esbuild/win32-arm64": "0.17.19",
|
||||
"@esbuild/win32-ia32": "0.17.19",
|
||||
"@esbuild/win32-x64": "0.17.19"
|
||||
}
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.24",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.24.tgz",
|
||||
"integrity": "sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "3.25.1",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.25.1.tgz",
|
||||
"integrity": "sha512-tywOR+rwIt5m2ZAWSe5AIJcTat8vGlnPFAv15ycCrw33t6iFsXZ6mzHVFh2psSjxQPmI+xgzMZZizUAukBI4aQ==",
|
||||
"dev": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.18.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "4.3.9",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.9.tgz",
|
||||
"integrity": "sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"esbuild": "^0.17.5",
|
||||
"postcss": "^8.4.23",
|
||||
"rollup": "^3.21.0"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": ">= 14",
|
||||
"less": "*",
|
||||
"sass": "*",
|
||||
"stylus": "*",
|
||||
"sugarss": "*",
|
||||
"terser": "^5.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
"sass": {
|
||||
"optional": true
|
||||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"terser": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -27,6 +27,6 @@
|
||||
"serve": "vite preview"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vite": "^2.3.7"
|
||||
"vite": "^4.3.9"
|
||||
}
|
||||
}
|
619
public/fluid.js
619
public/fluid.js
File diff suppressed because it is too large
Load Diff
98
src/app.js
98
src/app.js
@ -1,98 +0,0 @@
|
||||
import { event_listener_array, calc_delta_time } from './utils';
|
||||
|
||||
export function perspective_3d(class_name) {
|
||||
const elements = document.body.getElementsByClassName(class_name);
|
||||
|
||||
let velocity_x = 0;
|
||||
let velocity_y = 0;
|
||||
let rotation_x = 0;
|
||||
let rotation_y = 0;
|
||||
let target_rotation_x = 0;
|
||||
let target_rotation_y = 0;
|
||||
|
||||
(function update() {
|
||||
let dt = calc_delta_time();
|
||||
const ss = .08;
|
||||
|
||||
velocity_x = spring(rotation_x, target_rotation_x, velocity_x, 10, dt);
|
||||
velocity_y = spring(rotation_y, target_rotation_y, velocity_y, 10, dt);
|
||||
rotation_x += velocity_x * dt * ss;
|
||||
rotation_y += velocity_y * dt * ss;
|
||||
|
||||
const style = `perspective(700px) rotateX(${rotation_y}rad) rotateY(${rotation_x}rad)`;
|
||||
|
||||
for (const el of elements) {
|
||||
el.style.transform = style;
|
||||
}
|
||||
|
||||
requestAnimationFrame(update);
|
||||
})();
|
||||
|
||||
event_listener_array(window, ["mousemove", "touchmove"], (e) => {
|
||||
if (e.changedTouches && e.changedTouches[0]) {
|
||||
e = e.changedTouches[0];
|
||||
}
|
||||
|
||||
target_rotation_x = (e.clientX / window.innerWidth) * 2 - 1;
|
||||
target_rotation_y = -(e.clientY / window.innerHeight) * 2 + 1;
|
||||
|
||||
target_rotation_x = clamp(target_rotation_x, -0.5, 0.5);
|
||||
target_rotation_y = clamp(target_rotation_y, -0.5, 0.5);
|
||||
}, false);
|
||||
|
||||
function spring(position, target, velocity, omega, dt) {
|
||||
let n1 = velocity - (position - target) * (Math.pow(omega, 2) * dt);
|
||||
let n2 = 1 + omega * dt;
|
||||
return n1 / Math.pow(n2, 2);
|
||||
}
|
||||
function clamp(value, min, max) {
|
||||
return Math.min(Math.max(value, min), max);
|
||||
}
|
||||
}
|
||||
|
||||
(function pick_greeting() {
|
||||
const hours = new Date().getHours();
|
||||
const greeing_el = document.querySelector(".greeting");
|
||||
|
||||
if (hours < 6) {
|
||||
const data = "Good night";
|
||||
greeing_el.textContent = data;
|
||||
greeing_el.innerText = data;
|
||||
} else if (hours >= 6 && hours < 12) {
|
||||
const data = "Good morning";
|
||||
greeing_el.textContent = data;
|
||||
greeing_el.innerText = data;
|
||||
} else if (hours >= 12 && hours < 16) {
|
||||
const data = "Good afternoon";
|
||||
greeing_el.textContent = data;
|
||||
greeing_el.innerText = data;
|
||||
} else if (hours >= 16 && hours <= 23) {
|
||||
const data = "Good evening";
|
||||
greeing_el.textContent = data;
|
||||
greeing_el.innerText = data;
|
||||
} else {
|
||||
const data = "Hello";
|
||||
greeing_el.textContent = data;
|
||||
greeing_el.innerText = data;
|
||||
}
|
||||
|
||||
setTimeout(pick_greeting, 6e4);
|
||||
})();
|
||||
|
||||
(function render_time() {
|
||||
const time = new Date();
|
||||
let h = time.getHours();
|
||||
|
||||
h = h.toString().padStart(2, 0);
|
||||
let m = time.getMinutes().toString().padStart(2, 0);
|
||||
let s = time.getSeconds().toString().padStart(2, 0);
|
||||
|
||||
const clock_el = document.querySelector('.clock');
|
||||
if (!clock_el) return;
|
||||
|
||||
const formatted_date = `${h}:${m}:${s}`;
|
||||
clock_el.textContent = formatted_date;
|
||||
clock_el.innerText = formatted_date;
|
||||
|
||||
setTimeout(render_time, 1e3);
|
||||
})();
|
@ -1,9 +0,0 @@
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
@font-face {
|
||||
font-family: "Inter Var";
|
||||
font-weight: 400 900;
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
src: url("/src/font/Inter.woff2") format("woff2");
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: "Inter Var", sans-serif;
|
||||
font-size: 17px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.greeting {
|
||||
font-variation-settings: "wght" 400;
|
||||
letter-spacing: 0rem;
|
||||
line-height: 1.7rem;
|
||||
}
|
135
src/effects.js
vendored
Normal file
135
src/effects.js
vendored
Normal file
@ -0,0 +1,135 @@
|
||||
import { addEventListeners, calcDeltaTime } from "./utils";
|
||||
|
||||
/**
|
||||
* Adds 3D perspective rotation effect to elements with the specified class name.
|
||||
* The rotation is controlled by mouse/touch movement and uses spring physics for smooth animation.
|
||||
* @param {string} className - The class name of elements to apply the 3D effect to
|
||||
*/
|
||||
export const add3DRotationEffect = (className) => {
|
||||
const elements = document.body.getElementsByClassName(className);
|
||||
|
||||
const state = {
|
||||
velocity: { x: 0, y: 0 },
|
||||
rotation: { x: 0, y: 0 },
|
||||
targetRotation: { x: 0, y: 0 },
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates spring physics for smooth animation
|
||||
* @param {number} position - Current position
|
||||
* @param {number} target - Target position
|
||||
* @param {number} velocity - Current velocity
|
||||
* @param {number} omega - Angular frequency
|
||||
* @param {number} dt - Delta time
|
||||
* @returns {number} New velocity
|
||||
*/
|
||||
const spring = (position, target, velocity, omega, dt) => {
|
||||
const n1 = velocity - (position - target) * (omega ** 2 * dt);
|
||||
const n2 = 1 + omega * dt;
|
||||
return n1 / n2 ** 2;
|
||||
};
|
||||
|
||||
/**
|
||||
* Clamps a value between min and max
|
||||
* @param {number} value - Value to clamp
|
||||
* @param {number} min - Minimum value
|
||||
* @param {number} max - Maximum value
|
||||
* @returns {number} Clamped value
|
||||
*/
|
||||
const clamp = (value, min, max) => Math.min(Math.max(value, min), max);
|
||||
|
||||
/**
|
||||
* Updates rotation values and applies transform styles in animation frame
|
||||
*/
|
||||
const updateRotation = () => {
|
||||
const dt = calcDeltaTime();
|
||||
const springConstant = 0.08;
|
||||
|
||||
state.velocity.x = spring(
|
||||
state.rotation.x,
|
||||
state.targetRotation.x,
|
||||
state.velocity.x,
|
||||
10,
|
||||
dt
|
||||
);
|
||||
state.velocity.y = spring(
|
||||
state.rotation.y,
|
||||
state.targetRotation.y,
|
||||
state.velocity.y,
|
||||
10,
|
||||
dt
|
||||
);
|
||||
|
||||
state.rotation.x += state.velocity.x * dt * springConstant;
|
||||
state.rotation.y += state.velocity.y * dt * springConstant;
|
||||
|
||||
const style = `perspective(700px) rotateX(${state.rotation.y}rad) rotateY(${state.rotation.x}rad)`;
|
||||
Array.from(elements).forEach((el) => (el.style.transform = style));
|
||||
|
||||
requestAnimationFrame(updateRotation);
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles mouse/touch movement to update target rotation
|
||||
* @param {(MouseEvent|TouchEvent)} e - Mouse or touch event
|
||||
*/
|
||||
const handleMovement = (e) => {
|
||||
const event = e.changedTouches?.[0] || e;
|
||||
|
||||
state.targetRotation.x = (event.clientX / window.innerWidth) * 2 - 1;
|
||||
state.targetRotation.y = -(event.clientY / window.innerHeight) * 2 + 1;
|
||||
|
||||
state.targetRotation.x = clamp(state.targetRotation.x, -0.5, 0.5);
|
||||
state.targetRotation.y = clamp(state.targetRotation.y, -0.5, 0.5);
|
||||
};
|
||||
|
||||
addEventListeners(window, ["mousemove", "touchmove"], handleMovement, false);
|
||||
|
||||
updateRotation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates greeting text based on time of day.
|
||||
* Updates every minute.
|
||||
*/
|
||||
export const updateGreeting = () => {
|
||||
const hours = new Date().getHours();
|
||||
const greetingEl = document.querySelector(".greeting");
|
||||
if (!greetingEl) return;
|
||||
|
||||
/**
|
||||
* Gets appropriate greeting based on hour of day
|
||||
* @param {number} hours - Hour in 24-hour format
|
||||
* @returns {string} Greeting text
|
||||
*/
|
||||
const getGreeting = (hours) => {
|
||||
if (hours < 6) return "Good night";
|
||||
if (hours < 12) return "Good morning";
|
||||
if (hours < 16) return "Good afternoon";
|
||||
if (hours <= 23) return "Good evening";
|
||||
return "Hello";
|
||||
};
|
||||
|
||||
const greeting = getGreeting(hours);
|
||||
greetingEl.textContent = greeting;
|
||||
|
||||
setTimeout(updateGreeting, 60_000); // 60 seconds
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates clock display with current time in HH:MM:SS format.
|
||||
* Updates every second.
|
||||
*/
|
||||
export const updateTime = () => {
|
||||
const clockEl = document.querySelector(".clock");
|
||||
if (!clockEl) return;
|
||||
|
||||
const time = new Date();
|
||||
const formatted_date = [time.getHours(), time.getMinutes(), time.getSeconds()]
|
||||
.map((num) => num.toString().padStart(2, "0"))
|
||||
.join(":");
|
||||
|
||||
clockEl.textContent = formatted_date;
|
||||
|
||||
setTimeout(updateTime, 1000);
|
||||
};
|
29
src/main.js
29
src/main.js
@ -1,18 +1,17 @@
|
||||
// CSS Import
|
||||
import './css/style.css';
|
||||
import './css/font.css';
|
||||
import './css/animation.css';
|
||||
import './css/button.css';
|
||||
import "./styles/base.css";
|
||||
import "./styles/typography.css";
|
||||
import "./styles/animations.css";
|
||||
import "./styles/components.css";
|
||||
|
||||
// JS Import
|
||||
import './app';
|
||||
import "./effects";
|
||||
import { add3DRotationEffect, updateGreeting, updateTime } from "./effects";
|
||||
import { importJsAsModule } from "./utils";
|
||||
|
||||
import { perspective_3d } from './app';
|
||||
import { import_js_as_module } from './utils';
|
||||
const initialize = async () => {
|
||||
await importJsAsModule("/fluid.js");
|
||||
add3DRotationEffect("perspective");
|
||||
updateGreeting();
|
||||
updateTime();
|
||||
};
|
||||
|
||||
window.onload = start;
|
||||
|
||||
async function start() {
|
||||
await import_js_as_module('/fluid.js');
|
||||
perspective_3d('perspective');
|
||||
}
|
||||
window.addEventListener("load", initialize);
|
||||
|
9
src/styles/animations.css
Normal file
9
src/styles/animations.css
Normal file
@ -0,0 +1,9 @@
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
19
src/styles/typography.css
Normal file
19
src/styles/typography.css
Normal file
@ -0,0 +1,19 @@
|
||||
@font-face {
|
||||
font-family: "Inter Var";
|
||||
font-weight: 400 900;
|
||||
font-display: swap;
|
||||
font-style: normal;
|
||||
src: url("/src/assets/Inter.woff2") format("woff2");
|
||||
}
|
||||
|
||||
html {
|
||||
font-family: "Inter Var", sans-serif;
|
||||
font-size: 17px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.greeting {
|
||||
font-variation-settings: "wght" 400;
|
||||
letter-spacing: 0rem;
|
||||
line-height: 1.7rem;
|
||||
}
|
70
src/utils.js
70
src/utils.js
@ -1,31 +1,57 @@
|
||||
/** Timestamp of the last update used for delta time calculation */
|
||||
export let last_update = Date.now();
|
||||
|
||||
export function calc_delta_time() {
|
||||
let now = Date.now();
|
||||
let dt = (now - last_update) / 1e3;
|
||||
dt = Math.min(dt, 0.016);
|
||||
/**
|
||||
* Calculates the time elapsed since the last update, capped at 60fps
|
||||
* @returns {number} Delta time in seconds
|
||||
*/
|
||||
export function calcDeltaTime() {
|
||||
const now = Date.now();
|
||||
const MAX_DELTA = 0.016; // 60fps cap
|
||||
let dt = (now - last_update) / 1000;
|
||||
dt = Math.min(dt, MAX_DELTA);
|
||||
last_update = now;
|
||||
return dt;
|
||||
}
|
||||
|
||||
export function event_listener_array(whos, event_names, callback, options = null) {
|
||||
if (!Array.isArray(whos)) {
|
||||
whos = [whos];
|
||||
}
|
||||
for (const name of event_names) {
|
||||
for (const who of whos) {
|
||||
who.addEventListener(name, callback, options);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Adds event listeners to one or more elements for multiple event types
|
||||
* @param {HTMLElement|HTMLElement[]} elements - Single element or array of elements
|
||||
* @param {string[]} eventNames - Array of event names to listen for
|
||||
* @param {Function} callback - Event handler function
|
||||
* @param {(boolean|AddEventListenerOptions|null)} [options=null] - Event listener options
|
||||
*/
|
||||
export function addEventListeners(
|
||||
elements,
|
||||
eventNames,
|
||||
callback,
|
||||
options = null
|
||||
) {
|
||||
// Convert single element to array if needed
|
||||
const elementArray = Array.isArray(elements) ? elements : [elements];
|
||||
|
||||
export async function import_js_as_module(url) {
|
||||
return new Promise((resole, reject) => {
|
||||
const body = document.getElementsByTagName('body')[0];
|
||||
const script = document.createElement('script');
|
||||
script.type = 'module';
|
||||
script.src = url;
|
||||
script.onload = resole;
|
||||
body.appendChild(script);
|
||||
// Add event listeners to each element for each event name
|
||||
eventNames.forEach((eventName) => {
|
||||
elementArray.forEach((element) => {
|
||||
element.addEventListener(eventName, callback, options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Imports a JavaScript file as an ES module by injecting a script tag
|
||||
* @param {string} url - URL of the JavaScript file to import
|
||||
* @returns {Promise<void>} Resolves when the script has loaded
|
||||
*/
|
||||
export const importJsAsModule = async (url) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
const body = document.querySelector("body");
|
||||
const script = document.createElement("script");
|
||||
|
||||
script.type = "module";
|
||||
script.src = url;
|
||||
script.onload = resolve;
|
||||
|
||||
body.appendChild(script);
|
||||
});
|
||||
};
|
||||
|
88
yarn.lock
88
yarn.lock
@ -1,88 +0,0 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
colorette@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
|
||||
integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
|
||||
|
||||
esbuild@^0.12.8:
|
||||
version "0.12.9"
|
||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.9.tgz#bed4e7087c286cd81d975631f77d47feb1660070"
|
||||
integrity sha512-MWRhAbMOJ9RJygCrt778rz/qNYgA4ZVj6aXnNPxFjs7PmIpb0fuB9Gmg5uWrr6n++XKwwm/RmSz6RR5JL2Ocsw==
|
||||
|
||||
fsevents@~2.3.2:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
|
||||
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
|
||||
|
||||
function-bind@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
|
||||
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
|
||||
|
||||
has@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
|
||||
integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
|
||||
dependencies:
|
||||
function-bind "^1.1.1"
|
||||
|
||||
is-core-module@^2.2.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.4.0.tgz#8e9fc8e15027b011418026e98f0e6f4d86305cc1"
|
||||
integrity sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
nanoid@^3.1.23:
|
||||
version "3.1.23"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.23.tgz#f744086ce7c2bc47ee0a8472574d5c78e4183a81"
|
||||
integrity sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==
|
||||
|
||||
path-parse@^1.0.6:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
|
||||
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
|
||||
|
||||
postcss@^8.3.4:
|
||||
version "8.3.5"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.5.tgz#982216b113412bc20a86289e91eb994952a5b709"
|
||||
integrity sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==
|
||||
dependencies:
|
||||
colorette "^1.2.2"
|
||||
nanoid "^3.1.23"
|
||||
source-map-js "^0.6.2"
|
||||
|
||||
resolve@^1.20.0:
|
||||
version "1.20.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975"
|
||||
integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==
|
||||
dependencies:
|
||||
is-core-module "^2.2.0"
|
||||
path-parse "^1.0.6"
|
||||
|
||||
rollup@^2.38.5:
|
||||
version "2.52.2"
|
||||
resolved "https://registry.yarnpkg.com/rollup/-/rollup-2.52.2.tgz#a7e90d10ddae3e8472c2857bd9f44b09ef34a47a"
|
||||
integrity sha512-4RlFC3k2BIHlUsJ9mGd8OO+9Lm2eDF5P7+6DNQOp5sx+7N/1tFM01kELfbxlMX3MxT6owvLB1ln4S3QvvQlbUA==
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
||||
|
||||
source-map-js@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
|
||||
integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
|
||||
|
||||
vite@^2.3.7:
|
||||
version "2.3.8"
|
||||
resolved "https://registry.yarnpkg.com/vite/-/vite-2.3.8.tgz#42e3e03953859fd410e4e6ab3d1cca0aab2adc3c"
|
||||
integrity sha512-QiEx+iqNnJntSgSF2fWRQvRey9pORIrtNJzNyBJXwc+BdzWs83FQolX84cTBo393cfhObrtWa6180dAa4NLDiQ==
|
||||
dependencies:
|
||||
esbuild "^0.12.8"
|
||||
postcss "^8.3.4"
|
||||
resolve "^1.20.0"
|
||||
rollup "^2.38.5"
|
||||
optionalDependencies:
|
||||
fsevents "~2.3.2"
|
Reference in New Issue
Block a user