mirror of
https://github.com/xzeldon/zeldon-site.git
synced 2025-07-16 03:34:36 +03:00
initial commit
This commit is contained in:
112
src/app.js
Normal file
112
src/app.js
Normal file
@ -0,0 +1,112 @@
|
||||
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);
|
||||
})();
|
9
src/css/animation.css
Normal file
9
src/css/animation.css
Normal file
@ -0,0 +1,9 @@
|
||||
@keyframes fadein {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
117
src/css/button.css
Normal file
117
src/css/button.css
Normal file
@ -0,0 +1,117 @@
|
||||
.button-container {
|
||||
margin-top: 2em;
|
||||
}
|
||||
|
||||
.button {
|
||||
cursor: pointer;
|
||||
background: #e7e7e7;
|
||||
border: 0;
|
||||
border-radius: 2px;
|
||||
padding: 1.5rem 3rem;
|
||||
font-family: inherit;
|
||||
font-variation-settings: "wght" 700;
|
||||
letter-spacing: -0.02em;
|
||||
font-size: 1em;
|
||||
position: relative;
|
||||
|
||||
padding: 1rem 1.5rem;
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
opacity: 0.5;
|
||||
transition: opacity 300ms;
|
||||
}
|
||||
|
||||
.button:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.button-inner {
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
align-items: center;
|
||||
grid-gap: 0.7em;
|
||||
}
|
||||
|
||||
.button::before,
|
||||
.button::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.button--hyperion > span {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.button--hyperion > span > span {
|
||||
overflow: hidden;
|
||||
mix-blend-mode: difference;
|
||||
}
|
||||
|
||||
.button--hyperion:hover > span > span {
|
||||
animation: MoveUpInitial 0.2s forwards, MoveUpEnd 0.2s forwards 0.2s;
|
||||
}
|
||||
|
||||
.button--hyperion::before {
|
||||
content: '';
|
||||
background: rgba(0, 0, 0, 1);
|
||||
transition: transform 0.3s cubic-bezier(0.7, 0, 0.2, 1);
|
||||
transform-origin: 100% 50%;
|
||||
}
|
||||
|
||||
.button--hyperion:hover::before {
|
||||
transform: scale3d(0,1,1);
|
||||
transform-origin: 0% 50%;
|
||||
}
|
||||
|
||||
@keyframes MoveUpInitial {
|
||||
to {
|
||||
transform: translate3d(0,-105%,0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes MoveUpEnd {
|
||||
from {
|
||||
transform: translate3d(0,100%,0);
|
||||
}
|
||||
to {
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
.spotify-icon {
|
||||
position: relative;
|
||||
fill: currentColor;
|
||||
mix-blend-mode: difference;
|
||||
}
|
||||
|
||||
.links-container {
|
||||
margin-top: 1.5em;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
grid-gap: 1em;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.link {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
letter-spacing: -0.03em;
|
||||
font-variation-settings: "wght" 500;
|
||||
font-size: 1.1em;
|
||||
mix-blend-mode: overlay;
|
||||
opacity: 0.5;
|
||||
padding-bottom: 0.2em;
|
||||
padding-left: 0.5em;
|
||||
padding-right: 0.5em;
|
||||
border-bottom: solid 2px #FFFFFF00;
|
||||
transition: opacity 300ms, border-bottom 300ms;
|
||||
}
|
||||
|
||||
.link:hover {
|
||||
opacity: 1.0;
|
||||
border-bottom: solid 2px #FFFFFF50;
|
||||
}
|
19
src/css/font.css
Normal file
19
src/css/font.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/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;
|
||||
}
|
75
src/css/style.css
Normal file
75
src/css/style.css
Normal file
@ -0,0 +1,75 @@
|
||||
* {
|
||||
user-select: none;
|
||||
-webkit-user-select: none
|
||||
}
|
||||
|
||||
html {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
display: grid;
|
||||
user-select: none;
|
||||
background: rgb(0, 0, 0);
|
||||
color: #FFF;
|
||||
touch-action: none;
|
||||
-webkit-overflow-scrolling: auto;
|
||||
overflow: hidden;
|
||||
overscroll-behavior: none;
|
||||
}
|
||||
|
||||
canvas {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.greeting {
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.clock {
|
||||
margin-top: 0
|
||||
}
|
||||
|
||||
.container {
|
||||
display: grid;
|
||||
place-items: center;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
font-size: 17px;
|
||||
}
|
||||
|
||||
canvas,
|
||||
.container {
|
||||
grid-column: 1 / -1;
|
||||
grid-row: 1 / -1
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
letter-spacing: 0.5em;
|
||||
animation: fadein 2s both cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
}
|
||||
|
||||
.content>* {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.content-info {
|
||||
transition: opacity 300ms;
|
||||
}
|
||||
|
||||
.content-info:hover {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
.button-container {
|
||||
opacity: 1.0;
|
||||
}
|
||||
|
||||
@media (max-width: 420px) {
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
BIN
src/font/Inter.woff2
Normal file
BIN
src/font/Inter.woff2
Normal file
Binary file not shown.
19
src/main.js
Normal file
19
src/main.js
Normal file
@ -0,0 +1,19 @@
|
||||
// CSS Import
|
||||
import './css/style.css';
|
||||
import './css/font.css';
|
||||
import './css/animation.css';
|
||||
import './css/button.css';
|
||||
|
||||
// JS Import
|
||||
import './app';
|
||||
|
||||
import { perspective_3d } from './app';
|
||||
import { import_js_as_module } from './utils';
|
||||
|
||||
window.onload = start;
|
||||
|
||||
async function start()
|
||||
{
|
||||
await import_js_as_module('/fluid.js');
|
||||
perspective_3d('perspective');
|
||||
}
|
38
src/utils.js
Normal file
38
src/utils.js
Normal file
@ -0,0 +1,38 @@
|
||||
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);
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user