mirror of
https://github.com/hyprwm/hyprland-website.git
synced 2024-12-22 18:29:48 +01:00
.
This commit is contained in:
parent
e617e175b5
commit
a94b30e176
14 changed files with 50 additions and 250 deletions
3
.vscode/extensions.json
vendored
Executable file
3
.vscode/extensions.json
vendored
Executable file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"recommendations": ["bradlc.vscode-tailwindcss", "svelte.svelte-vscode"]
|
||||||
|
}
|
|
@ -1,27 +0,0 @@
|
||||||
import { generate } from 'critical'
|
|
||||||
|
|
||||||
generate({
|
|
||||||
inline: true,
|
|
||||||
base: 'build/',
|
|
||||||
src: 'index.html',
|
|
||||||
target: 'index-critical.html',
|
|
||||||
width: 1300,
|
|
||||||
height: 900
|
|
||||||
})
|
|
||||||
// generate({
|
|
||||||
// inline: true,
|
|
||||||
// base: 'build/',
|
|
||||||
// src: 'index.html',
|
|
||||||
// target: 'index.c.html',
|
|
||||||
|
|
||||||
// dimensions: [
|
|
||||||
// {
|
|
||||||
// width: 1200,
|
|
||||||
// height: 900
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// width: 480,
|
|
||||||
// height: 900
|
|
||||||
// }
|
|
||||||
// ]
|
|
||||||
// })
|
|
|
@ -1,22 +0,0 @@
|
||||||
parent_path=$( cd "$(dirname "${BASH_SOURCE[0]}")" ; pwd -P )
|
|
||||||
|
|
||||||
cd "$parent_path"
|
|
||||||
|
|
||||||
find "../static/imgs/profile_pictures/" -type f \
|
|
||||||
\( -iname "*.jpg" -o -iname "*.png" -o -iname "*.gif" -o -iname "*.bmp" -o -iname "*.jpeg" -o -iname "*.webp" \) -not -name "generated_*" -print0 |
|
|
||||||
|
|
||||||
while IFS= read -r -d '' filepath; do
|
|
||||||
echo "$filepath" gets blurred
|
|
||||||
|
|
||||||
directory=$(dirname "$filepath")
|
|
||||||
filename=$(basename "$filepath")
|
|
||||||
|
|
||||||
|
|
||||||
for SIZE in 100x100 64x64 48x48 32x32
|
|
||||||
do
|
|
||||||
generated_filename="${directory}/generated_${SIZE}-${filename}"
|
|
||||||
|
|
||||||
magick "$filepath" --resize "${SIZE}" "${generated_filename}"
|
|
||||||
done
|
|
||||||
|
|
||||||
done
|
|
|
@ -96,6 +96,7 @@ export function getBlurredPath(path) {
|
||||||
return `${path.substring(0, path.lastIndexOf('/'))}/generated_${path.split('/').at(-1)}`
|
return `${path.substring(0, path.lastIndexOf('/'))}/generated_${path.split('/').at(-1)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Get a random item from an array */
|
||||||
export function getRandom(array) {
|
export function getRandom(array) {
|
||||||
return array.at(Math.floor(Math.random() * array.length))
|
return array.at(Math.floor(Math.random() * array.length))
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,29 @@ Lt. Dixon Piper:
|
||||||
That's really f***ed up.
|
That's really f***ed up.
|
||||||
|
|
||||||
MacGruber:
|
MacGruber:
|
||||||
Thanks.`
|
Thanks.`,
|
||||||
|
|
||||||
|
`MacGruber:
|
||||||
|
Looks like you're keeping your bod pretty tight.
|
||||||
|
|
||||||
|
Frank Korver:
|
||||||
|
You're looking pretty good yourself.
|
||||||
|
|
||||||
|
MacGruber:
|
||||||
|
Well, everday's a workout when you gotta carry around a 20 pound python in your jeans.
|
||||||
|
|
||||||
|
Frank Korver:
|
||||||
|
You and your dick comments.
|
||||||
|
|
||||||
|
MacGruber:
|
||||||
|
It's fun to say them.
|
||||||
|
|
||||||
|
Frank Korver:
|
||||||
|
It's fun to hear them.
|
||||||
|
|
||||||
|
MacGruber:
|
||||||
|
That's why I say them.
|
||||||
|
|
||||||
|
Frank Korver:
|
||||||
|
And that's why I listen.`
|
||||||
]
|
]
|
||||||
|
|
|
@ -6,10 +6,11 @@
|
||||||
import '@fontsource-variable/work-sans'
|
import '@fontsource-variable/work-sans'
|
||||||
import '@fontsource/ibm-plex-mono/500.css'
|
import '@fontsource/ibm-plex-mono/500.css'
|
||||||
import { quotes } from '$lib/components/Quotes'
|
import { quotes } from '$lib/components/Quotes'
|
||||||
|
import { getRandom } from '$lib/Helper.mjs'
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
if (import.meta.env.PROD) {
|
if (import.meta.env.PROD) {
|
||||||
console.log(quotes.at(Math.floor(Math.random() * quotes.length)))
|
console.log(getRandom(quotes))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -162,7 +162,8 @@
|
||||||
image: '/imgs/profile_pictures/jacekpoz.svg',
|
image: '/imgs/profile_pictures/jacekpoz.svg',
|
||||||
coordinates: [180, 730],
|
coordinates: [180, 730],
|
||||||
size: 80,
|
size: 80,
|
||||||
class: 'outline-yellow-500 bg-orange-700'
|
class: 'outline-yellow-500 bg-orange-700',
|
||||||
|
quote: '"Piss blob"'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -76,7 +76,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
// Nesecarry as the load image load event might not get fired when its already loaded
|
// Nesecarry as the load image event might not get fired when its already loaded ( for example after a page reload )
|
||||||
hasImageLoaded = hasImageLoaded || imageElement.complete
|
hasImageLoaded = hasImageLoaded || imageElement.complete
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
/** @type {string | undefined} */
|
/** @type {string | undefined} */
|
||||||
export let containerClass = undefined
|
export let containerClass = undefined
|
||||||
/** @type {string}
|
/** @type {string}
|
||||||
* The path to the image. Usually the file within `static`, but can also be an URL
|
* The path to the image. Usually the file within `static`, but can also be an URL. Defaults to `generated_<image>`
|
||||||
*/
|
*/
|
||||||
export let blurredBackground = undefined
|
export let blurredBackground = undefined
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
<script>
|
|
||||||
import { onMount } from 'svelte'
|
|
||||||
import { createNoise2D } from 'simplex-noise'
|
|
||||||
import { match } from 'ts-pattern'
|
|
||||||
import clsx from 'clsx'
|
|
||||||
import { getIsMobile } from '$lib/Helper.mjs'
|
|
||||||
|
|
||||||
// Currently this is unused. I left it in here, in case it would be useful in the future
|
|
||||||
|
|
||||||
const maxSize = 24
|
|
||||||
const minSize = 7
|
|
||||||
const size = Math.max(Math.random() * maxSize, minSize)
|
|
||||||
/** How much the fireflies can vanish into the edges of the screen. Include their invisible padding for mouse detection. */
|
|
||||||
const edgeClip = maxSize * 8
|
|
||||||
const noiseY = createNoise2D()
|
|
||||||
const noiseX = createNoise2D()
|
|
||||||
const SPEED = Math.random() * 5 + 2
|
|
||||||
|
|
||||||
let classes = clsx(size > maxSize / 2 ? 'bg-primary/70' : 'bg-blue-500/70')
|
|
||||||
|
|
||||||
let x = 0
|
|
||||||
let y = 0
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
x = window.innerWidth / (Math.random() * 4) - maxSize * 6
|
|
||||||
y = window.innerHeight / (Math.random() * 4) + 100
|
|
||||||
|
|
||||||
// The animation is way too heavy for mobile
|
|
||||||
if (getIsMobile()) return
|
|
||||||
|
|
||||||
let animationId
|
|
||||||
let i = 0
|
|
||||||
|
|
||||||
animate()
|
|
||||||
|
|
||||||
return () => cancelAnimationFrame(animationId)
|
|
||||||
|
|
||||||
async function animate() {
|
|
||||||
x += match(x)
|
|
||||||
.when(
|
|
||||||
(x_) => x_ > window.innerWidth + edgeClip,
|
|
||||||
() => -10
|
|
||||||
)
|
|
||||||
.when(
|
|
||||||
(x) => x < -edgeClip,
|
|
||||||
() => 10
|
|
||||||
)
|
|
||||||
.otherwise(() => noiseX(i, 1) * SPEED)
|
|
||||||
y += match(y)
|
|
||||||
.when(
|
|
||||||
(y) => y > window.innerHeight + edgeClip,
|
|
||||||
() => -10
|
|
||||||
)
|
|
||||||
.when(
|
|
||||||
(y) => y < -edgeClip,
|
|
||||||
() => 10
|
|
||||||
)
|
|
||||||
.otherwise(() => noiseY(i, 1) * SPEED)
|
|
||||||
|
|
||||||
i += 0.005
|
|
||||||
|
|
||||||
animationId = requestAnimationFrame(animate)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="firefly pointer-events-auto absolute left-0 top-0 z-0 hidden p-24 opacity-50 transition-opacity hover:opacity-100 max-sm:[contain:strict] md:block"
|
|
||||||
style:--x={x + 'px'}
|
|
||||||
style:--y={y + 'px'}
|
|
||||||
style="--size:{size}px; --fadeDelay: {Math.random() * 6 - 3}s"
|
|
||||||
>
|
|
||||||
<div class={clsx('firefly-inner', classes)} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="postcss">
|
|
||||||
.firefly {
|
|
||||||
/* transform: translate3d(50px, calc(var(--x) * 200px), 0px); */
|
|
||||||
transform: translate3d(var(--x, 5), var(--y, 2), 0px);
|
|
||||||
contain: strict;
|
|
||||||
}
|
|
||||||
|
|
||||||
.firefly-inner {
|
|
||||||
min-height: var(--size);
|
|
||||||
min-width: var(--size);
|
|
||||||
border-radius: 50%;
|
|
||||||
contain: layout size style;
|
|
||||||
box-shadow:
|
|
||||||
0px 0px 25px theme(colors.emerald.400),
|
|
||||||
0px 0px 12px theme(colors.sky.400);
|
|
||||||
animation: fade 3s ease-in-out infinite alternate;
|
|
||||||
animation-delay: var(--fadeDelay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade {
|
|
||||||
0%,
|
|
||||||
40%,
|
|
||||||
66% {
|
|
||||||
opacity: 0%;
|
|
||||||
}
|
|
||||||
99%,
|
|
||||||
20% {
|
|
||||||
opacity: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -30,6 +30,7 @@
|
||||||
const MIN_LIFESPAN_TILE = 800
|
const MIN_LIFESPAN_TILE = 800
|
||||||
const MAX_TILES_PER_CLICK = 15
|
const MAX_TILES_PER_CLICK = 15
|
||||||
const MIN_TILES_PER_CLICK = 2
|
const MIN_TILES_PER_CLICK = 2
|
||||||
|
/** How fast the user has to click to progress */
|
||||||
const CLICK_EACH_MS = 400
|
const CLICK_EACH_MS = 400
|
||||||
const ASCENION_FALLOFF = -ASCENION_CLICKS / 20
|
const ASCENION_FALLOFF = -ASCENION_CLICKS / 20
|
||||||
|
|
||||||
|
@ -40,8 +41,10 @@
|
||||||
switchMap((value) =>
|
switchMap((value) =>
|
||||||
merge(
|
merge(
|
||||||
of(value),
|
of(value),
|
||||||
|
|
||||||
|
/** If no new value comes in, start decreasing the progress */
|
||||||
interval(CLICK_EACH_MS + 100).pipe(
|
interval(CLICK_EACH_MS + 100).pipe(
|
||||||
take(ASCENION_CLICKS),
|
take(ASCENION_CLICKS), // Prevent this interval from running forever
|
||||||
map(() => ASCENION_FALLOFF)
|
map(() => ASCENION_FALLOFF)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -49,10 +52,12 @@
|
||||||
scan((level, value) => Math.min(ASCENION_CLICKS, Math.max(level + value, 0))),
|
scan((level, value) => Math.min(ASCENION_CLICKS, Math.max(level + value, 0))),
|
||||||
startWith(0)
|
startWith(0)
|
||||||
)
|
)
|
||||||
|
/** How many clicks are left in percent */
|
||||||
const relativeLevel$ = clickLevel$.pipe(map((clicks) => clicks / ASCENION_CLICKS))
|
const relativeLevel$ = clickLevel$.pipe(map((clicks) => clicks / ASCENION_CLICKS))
|
||||||
const cubibRelativeLevel$ = relativeLevel$.pipe(map(cubicInOut))
|
/** Tween/Ease the percents for a nicer look */
|
||||||
|
const cubicRelativeLevel$ = relativeLevel$.pipe(map(cubicInOut))
|
||||||
const expoRelativeLevel$ = relativeLevel$.pipe(map(expoInOut))
|
const expoRelativeLevel$ = relativeLevel$.pipe(map(expoInOut))
|
||||||
// const hasAscended$ = of(true)
|
|
||||||
const hasAscended$ = relativeLevel$.pipe(
|
const hasAscended$ = relativeLevel$.pipe(
|
||||||
filter((level) => level >= 1),
|
filter((level) => level >= 1),
|
||||||
first(),
|
first(),
|
||||||
|
@ -64,7 +69,8 @@
|
||||||
const tiles$ = click$.pipe(
|
const tiles$ = click$.pipe(
|
||||||
switchMap(() =>
|
switchMap(() =>
|
||||||
merge(
|
merge(
|
||||||
of(Math.floor(lerp(MIN_TILES_PER_CLICK, MAX_TILES_PER_CLICK, $cubibRelativeLevel$))),
|
of(Math.floor(lerp(MIN_TILES_PER_CLICK, MAX_TILES_PER_CLICK, $cubicRelativeLevel$))),
|
||||||
|
// Remove the tiles after a timeout, if no new ones came in
|
||||||
timer(MAX_LIFESPAN_TILE)
|
timer(MAX_LIFESPAN_TILE)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
|
@ -75,9 +81,9 @@
|
||||||
startWith([])
|
startWith([])
|
||||||
)
|
)
|
||||||
|
|
||||||
$: hue = lerp(200, 130, $cubibRelativeLevel$)
|
$: hue = lerp(200, 130, $cubicRelativeLevel$)
|
||||||
$: scale = lerp(0.9, 2, $cubibRelativeLevel$)
|
$: scale = lerp(0.9, 2, $cubicRelativeLevel$)
|
||||||
$: translateY = lerp(0, 10, $cubibRelativeLevel$)
|
$: translateY = lerp(0, 10, $cubicRelativeLevel$)
|
||||||
|
|
||||||
/** @type {HTMLDivElement} */
|
/** @type {HTMLDivElement} */
|
||||||
let containerElement
|
let containerElement
|
||||||
|
@ -109,7 +115,7 @@
|
||||||
<div class="pointer-events-none absolute left-1/2 top-1/2 -z-10">
|
<div class="pointer-events-none absolute left-1/2 top-1/2 -z-10">
|
||||||
{#each $tiles$ as _}
|
{#each $tiles$ as _}
|
||||||
<GitTile
|
<GitTile
|
||||||
lifeSpan={lerp(MIN_LIFESPAN_TILE, MAX_LIFESPAN_TILE, $cubibRelativeLevel$)}
|
lifeSpan={lerp(MIN_LIFESPAN_TILE, MAX_LIFESPAN_TILE, $cubicRelativeLevel$)}
|
||||||
maxSpeed={lerp(10, 38, $expoRelativeLevel$)}
|
maxSpeed={lerp(10, 38, $expoRelativeLevel$)}
|
||||||
minSpeed={lerp(1, 9, $expoRelativeLevel$)}
|
minSpeed={lerp(1, 9, $expoRelativeLevel$)}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -13,8 +13,6 @@
|
||||||
function toggleExpanded() {
|
function toggleExpanded() {
|
||||||
isExpanded = !isExpanded
|
isExpanded = !isExpanded
|
||||||
}
|
}
|
||||||
|
|
||||||
//! TODO close mobile menu on navigation
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header
|
<header
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
<script>
|
|
||||||
const circlesAmount = 10
|
|
||||||
/** In millisseconds */
|
|
||||||
const animationDuration = 8000
|
|
||||||
|
|
||||||
const circles = Array.from({ length: circlesAmount }, () => 1)
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param node {HTMLElement}
|
|
||||||
* @param param1
|
|
||||||
*/
|
|
||||||
function animateElement(node, { delay, index, amount }) {
|
|
||||||
const delayFrames = Array.from({ length: index }).map(() => ({
|
|
||||||
scale: 0
|
|
||||||
}))
|
|
||||||
node.animate([{ scale: CSS.number(0) }, { scale: CSS.number(3), opacity: 0 }], {
|
|
||||||
iterations: Infinity,
|
|
||||||
duration: animationDuration,
|
|
||||||
delay: animationDuration / (amount - index + 1) + animationDuration / (amount - index + 1),
|
|
||||||
easing: 'cubic-bezier(1, 0.1 , 0.9, 1)',
|
|
||||||
fill: 'backwards'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="wrapper">
|
|
||||||
{#each circles as _, index}
|
|
||||||
<div
|
|
||||||
class="circle"
|
|
||||||
style:--percent={((index + 1) / circles.length) * 100 + '%'}
|
|
||||||
style:--index={index}
|
|
||||||
style:--amount={circles.length}
|
|
||||||
/>
|
|
||||||
{/each}
|
|
||||||
<!-- use:animateElement={{ index, amount: circles.length }} -->
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style lang="postcss">
|
|
||||||
.wrapper {
|
|
||||||
position: absolute;
|
|
||||||
top: 40px;
|
|
||||||
right: 40px;
|
|
||||||
width: 400px;
|
|
||||||
aspect-ratio: 1;
|
|
||||||
filter: drop-shadow(0 0 44px blue);
|
|
||||||
/* background: red; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.circle {
|
|
||||||
position: absolute;
|
|
||||||
inset: 0;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
opacity: 0.05;
|
|
||||||
background: radial-gradient(
|
|
||||||
closest-side,
|
|
||||||
transparent,
|
|
||||||
color-mix(in hsl, theme(colors.blue.500), theme(colors.pink.500) var(--percent)),
|
|
||||||
transparent 90%
|
|
||||||
);
|
|
||||||
transition: all 2200ms;
|
|
||||||
|
|
||||||
.wrapper:hover & {
|
|
||||||
opacity: 1;
|
|
||||||
transition: all 1200ms ease-in;
|
|
||||||
}
|
|
||||||
|
|
||||||
animation: loop infinite backwards;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes loop {
|
|
||||||
from {
|
|
||||||
scale: 0;
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
scale: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -12,6 +12,7 @@
|
||||||
let enabled = false
|
let enabled = false
|
||||||
|
|
||||||
function setEnabled({ detail }) {
|
function setEnabled({ detail }) {
|
||||||
|
// Show the effect when the user scrolls in and keep it enabled until the user scrolls up from it again
|
||||||
const { inView, scrollDirection } = detail
|
const { inView, scrollDirection } = detail
|
||||||
const isScrollingUp = scrollDirection.vertical === 'up'
|
const isScrollingUp = scrollDirection.vertical === 'up'
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue