mirror of
https://github.com/hyprwm/hyprland-website.git
synced 2024-12-23 02:39:48 +01:00
stuff
This commit is contained in:
parent
0d85f7b54d
commit
bfd6e0e968
27 changed files with 696 additions and 296 deletions
|
@ -56,6 +56,7 @@
|
||||||
"interactjs": "^1.10.18",
|
"interactjs": "^1.10.18",
|
||||||
"prettier-plugin-tailwindcss": "^0.4.1",
|
"prettier-plugin-tailwindcss": "^0.4.1",
|
||||||
"remeda": "^1.24.0",
|
"remeda": "^1.24.0",
|
||||||
|
"rxjs": "^7.8.1",
|
||||||
"simplex-noise": "^4.0.1",
|
"simplex-noise": "^4.0.1",
|
||||||
"svelte-inview": "^4.0.1",
|
"svelte-inview": "^4.0.1",
|
||||||
"ts-pattern": "^5.0.4"
|
"ts-pattern": "^5.0.4"
|
||||||
|
|
|
@ -26,6 +26,9 @@ dependencies:
|
||||||
remeda:
|
remeda:
|
||||||
specifier: ^1.24.0
|
specifier: ^1.24.0
|
||||||
version: 1.24.0
|
version: 1.24.0
|
||||||
|
rxjs:
|
||||||
|
specifier: ^7.8.1
|
||||||
|
version: 7.8.1
|
||||||
simplex-noise:
|
simplex-noise:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
|
@ -2147,6 +2150,12 @@ packages:
|
||||||
queue-microtask: 1.2.3
|
queue-microtask: 1.2.3
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
|
/rxjs@7.8.1:
|
||||||
|
resolution: {integrity: sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==}
|
||||||
|
dependencies:
|
||||||
|
tslib: 2.6.1
|
||||||
|
dev: false
|
||||||
|
|
||||||
/sade@1.8.1:
|
/sade@1.8.1:
|
||||||
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
|
resolution: {integrity: sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==}
|
||||||
engines: {node: '>=6'}
|
engines: {node: '>=6'}
|
||||||
|
@ -2520,7 +2529,6 @@ packages:
|
||||||
|
|
||||||
/tslib@2.6.1:
|
/tslib@2.6.1:
|
||||||
resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
|
resolution: {integrity: sha512-t0hLfiEKfMUoqhG+U1oid7Pva4bbDPHYfJNiB7BiIjRkj1pyC++4N3huJfqY6aRH6VTB0rvtzQwjM4K6qpfOig==}
|
||||||
dev: true
|
|
||||||
|
|
||||||
/tsutils@3.21.0(typescript@5.1.6):
|
/tsutils@3.21.0(typescript@5.1.6):
|
||||||
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
/* eslint-disable no-useless-escape */
|
||||||
import { inview } from 'svelte-inview'
|
import { inview } from 'svelte-inview'
|
||||||
import { pick } from 'remeda'
|
import { pick } from 'remeda'
|
||||||
// const mappingAnimate = {
|
// const mappingAnimate = {
|
||||||
|
@ -19,6 +20,9 @@ import { pick } from 'remeda'
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
export function animateIn(node, options) {
|
export function animateIn(node, options) {
|
||||||
|
// Do nothing on mobile
|
||||||
|
if (getIsMobile()) return { destroy: () => undefined }
|
||||||
|
|
||||||
const observer = inview(node, { unobserveOnEnter: true, threshold: options.threshold ?? 0.4 })
|
const observer = inview(node, { unobserveOnEnter: true, threshold: options.threshold ?? 0.4 })
|
||||||
|
|
||||||
options.duration ??= 840
|
options.duration ??= 840
|
||||||
|
@ -73,3 +77,44 @@ export function animateIn(node, options) {
|
||||||
export function lerp(start, end, given) {
|
export function lerp(start, end, given) {
|
||||||
return (1 - given) * start + given * end
|
return (1 - given) * start + given * end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} t A number between 0 and 1
|
||||||
|
* @param {number | undefined} strength
|
||||||
|
*/
|
||||||
|
export function easeInT(t, strength) {
|
||||||
|
return t ** (strength ?? 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} t A number between 0 and 1
|
||||||
|
* @param {number | undefined} strength
|
||||||
|
*/
|
||||||
|
export function easeOutT(t, strength) {
|
||||||
|
return 1 - (1 - t ** (strength ?? 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
// easeOutT(0.5) //?
|
||||||
|
// easeOutT(0.99) //?
|
||||||
|
// easeOutT(0.2) //?
|
||||||
|
// easeOutT(0) //?
|
||||||
|
// easeOutT(1) //?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Taken from https://stackoverflow.com/questions/11381673/detecting-a-mobile-browser/11381730#11381730
|
||||||
|
*/
|
||||||
|
export function getIsMobile() {
|
||||||
|
let check = false
|
||||||
|
;(function (a) {
|
||||||
|
if (
|
||||||
|
/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(
|
||||||
|
a
|
||||||
|
) ||
|
||||||
|
/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(
|
||||||
|
a.substr(0, 4)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
check = true
|
||||||
|
})(navigator.userAgent || navigator.vendor || window.opera)
|
||||||
|
return check
|
||||||
|
}
|
||||||
|
|
|
@ -4,10 +4,10 @@
|
||||||
|
|
||||||
/** @type {[string, string, string, string]} */
|
/** @type {[string, string, string, string]} */
|
||||||
let developers = [
|
let developers = [
|
||||||
['Fufexan', 'Supporting Developer', 'cyan', 'https://github.com/fufexan'],
|
['Fufexan', 'Core Developer', 'cyan', 'https://github.com/fufexan'],
|
||||||
['VDawg', 'Webdesign-and dev', 'teal', 'https://github.com/Visual-Dawg'],
|
['NotAShelf', 'Core Member', 'teal', 'https://github.com/NotAShelf'],
|
||||||
['System-x64', 'Webdev', 'green', 'https://github.com/System-x64'],
|
['VDawg', 'Webdesign-and dev', 'green', 'https://github.com/Visual-Dawg'],
|
||||||
['That one calculator', 'Package Maintaner', 'lime', 'https://github.com/ThatOneCalculator']
|
['System-x64', 'Webdev', 'lime', 'https://github.com/System-x64']
|
||||||
]
|
]
|
||||||
function createRole(role, color) {
|
function createRole(role, color) {
|
||||||
return `<span class='text-${color}-500'><span class='text-${color}-600'>[ </span>${role}<span class='text-${color}-600'> ]</span></span>`
|
return `<span class='text-${color}-500'><span class='text-${color}-600'>[ </span>${role}<span class='text-${color}-600'> ]</span></span>`
|
||||||
|
@ -15,13 +15,13 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<footer
|
<footer
|
||||||
class="bg-black/50 mt-16 md:mt-24 lg:mt-32 border-t border-blue-500 relative flex items-center justify-center w-screen"
|
class="bg-black/50 mt-16 md:mt-24 lg:mt-32 border-t border-blue-400/50 relative flex items-center justify-center max-w-screen"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="flex flex-wrap gap-12 justify-between px-8 py-14 max-w-5xl text-slate-300 items-start"
|
class="flex flex-wrap gap-12 justify-between px-8 py-14 max-w-5xl text-slate-300 items-start"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4 rounded-lg">
|
||||||
<div class="text-cyan-600 text-sm uppercase font-bold">> Developers</div>
|
<div class="text-slate-400 text-sm uppercase font-bold">Developers</div>
|
||||||
<ul class="flex flex-col gap-3 font-medium">
|
<ul class="flex flex-col gap-3 font-medium">
|
||||||
<li>
|
<li>
|
||||||
<a href="https://github.com/vaxerski">
|
<a href="https://github.com/vaxerski">
|
||||||
|
@ -37,26 +37,26 @@
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
<li>
|
<li>
|
||||||
and our <a href="https://github.com/hyprwm/Hyprland/graphs/contributors" target="_blank"
|
<a href="https://github.com/hyprwm/Hyprland/graphs/contributors" target="_blank"
|
||||||
><span class="text-indigo-400">fellow contributors</span></a
|
>and our <span class="text-indigo-400">fellow contributors</span></a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="text-cyan-600 font-bold text-sm uppercase">Links</div>
|
<div class="text-slate-400 font-bold text-sm uppercase">Links</div>
|
||||||
<ul class="flex flex-col font-medium gap-3">
|
<ul class="flex flex-col font-medium gap-3">
|
||||||
<li><a href="wiki.hyprland.org/">Wiki</a></li>
|
<li><a href="https://wiki.hyprland.org/">Wiki</a></li>
|
||||||
<li>
|
<li>
|
||||||
<a href="https://wiki.hyprland.org/Getting-Started/Master-Tutorial/">Get started</a>
|
<a href="https://wiki.hyprland.org/Getting-Started/Master-Tutorial/">Get started</a>
|
||||||
</li>
|
</li>
|
||||||
<li>Hall of fame</li>
|
<li><a href="/wall_of_fame">Hall of fame</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col gap-4">
|
<div class="flex flex-col gap-4">
|
||||||
<div class="text-cyan-600 text-sm uppercase font-bold" font-bold>Socials</div>
|
<div class="text-slate-400 text-sm uppercase font-bold" font-bold>Socials</div>
|
||||||
<ul class="flex gap-6">
|
<ul class="flex gap-6">
|
||||||
<li class="">
|
<li class="">
|
||||||
<a
|
<a
|
||||||
|
@ -72,7 +72,7 @@
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex gap-4 flex-wrap text-sm text-slate-300 w-full">
|
<div class="flex gap-4 flex-wrap text-sm text-slate-400 font-medium w-full">
|
||||||
<div>Hyprland is licensed under the BSD 3-Clause "New" or "Revised" License.</div>
|
<div>Hyprland is licensed under the BSD 3-Clause "New" or "Revised" License.</div>
|
||||||
<div>© Hyprland Development 2023.</div>
|
<div>© Hyprland Development 2023.</div>
|
||||||
<div>Doki doki waku waku.</div>
|
<div>Doki doki waku waku.</div>
|
||||||
|
@ -90,7 +90,7 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: -450px;
|
top: -450px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
width: 100vw;
|
width: 100%;
|
||||||
height: 900px;
|
height: 900px;
|
||||||
z-index: -10;
|
z-index: -10;
|
||||||
background: radial-gradient(105vw 450px at 50% 50%, theme(colors.blue.600 / 80%), transparent);
|
background: radial-gradient(105vw 450px at 50% 50%, theme(colors.blue.600 / 80%), transparent);
|
||||||
|
|
64
src/lib/components/GitTile.svelte
Executable file
64
src/lib/components/GitTile.svelte
Executable file
|
@ -0,0 +1,64 @@
|
||||||
|
<script>
|
||||||
|
import { easeOutT, lerp } from '$lib/Helper.mjs'
|
||||||
|
import { createNoise2D } from 'simplex-noise'
|
||||||
|
import { onMount } from 'svelte'
|
||||||
|
|
||||||
|
/** Lifespan in milliseconds */
|
||||||
|
export let lifeSpan = 1500
|
||||||
|
export let maxSpeed = 20
|
||||||
|
export let minSpeed = 4
|
||||||
|
export let maxOpacity = 1
|
||||||
|
export let scale = 1
|
||||||
|
|
||||||
|
const isDescending = Math.random() > 0.8
|
||||||
|
const wobbliness = lerp(0.0001, 0.004, Math.random())
|
||||||
|
|
||||||
|
const speed = Math.random() * (maxSpeed - minSpeed) + minSpeed
|
||||||
|
|
||||||
|
let x = Math.random() * 30 - 30
|
||||||
|
let y = Math.random() * 2
|
||||||
|
let lifeRemaining = lifeSpan
|
||||||
|
$: lifePercentage = lifeRemaining / lifeSpan
|
||||||
|
let timestamp = Date.now()
|
||||||
|
|
||||||
|
const noiseY = createNoise2D()
|
||||||
|
const noiseX = createNoise2D()
|
||||||
|
|
||||||
|
const colors = ['#0e4429', '#006d32', '#26a641', '#39d353']
|
||||||
|
const color = colors.at(Math.ceil(colors.length * Math.random()))
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
let animationId
|
||||||
|
let i = 0
|
||||||
|
|
||||||
|
animate()
|
||||||
|
|
||||||
|
async function animate() {
|
||||||
|
const deltaTime = (timestamp - Date.now()) / 17 // One frame should last roughly 17ms for 60fps
|
||||||
|
|
||||||
|
x += noiseX(i, 1) * speed * deltaTime * easeOutT(lifePercentage)
|
||||||
|
y += noiseY(i, 1) * speed * deltaTime * easeOutT(lifePercentage)
|
||||||
|
|
||||||
|
i += wobbliness * deltaTime
|
||||||
|
|
||||||
|
lifeRemaining -= Date.now() - timestamp
|
||||||
|
timestamp = Date.now()
|
||||||
|
|
||||||
|
if (lifeRemaining <= -1) return
|
||||||
|
|
||||||
|
animationId = requestAnimationFrame(animate)
|
||||||
|
}
|
||||||
|
|
||||||
|
return () => cancelAnimationFrame(animationId)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="absolute w-6 h-6 rounded-md"
|
||||||
|
style:translate={`${x}px ${y}px`}
|
||||||
|
style:background={color}
|
||||||
|
style:opacity={(lifeRemaining / lifeSpan - (1 - maxOpacity)) ** 5}
|
||||||
|
style:scale={isDescending ? (lifeRemaining / lifeSpan - (1 - scale)) ** 2 : undefined}
|
||||||
|
style:top={50 + (Math.random() * 5 - 5) + '%'}
|
||||||
|
style:left={50 + (Math.random() * 5 - 5) + '%'}
|
||||||
|
></div>
|
Binary file not shown.
Before Width: | Height: | Size: 75 KiB |
31
src/lib/images/logos/hyprland-color.svg
Executable file
31
src/lib/images/logos/hyprland-color.svg
Executable file
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 515.34 673.26">
|
||||||
|
<defs>
|
||||||
|
<style>
|
||||||
|
.cls-1 {
|
||||||
|
mix-blend-mode: difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-2 {
|
||||||
|
isolation: isolate;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cls-3 {
|
||||||
|
fill: url(#linear-gradient);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<linearGradient id="linear-gradient" x1="8.93" y1="572.38" x2="572.68" y2="102.08" gradientUnits="userSpaceOnUse">
|
||||||
|
<stop offset="0" stop-color="#00a2f8"/>
|
||||||
|
<stop offset="1" stop-color="#00e5cf"/>
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<g class="cls-2">
|
||||||
|
<g id="Layer_2" data-name="Layer 2">
|
||||||
|
<g id="Layer_1-2" data-name="Layer 1">
|
||||||
|
<g class="cls-1">
|
||||||
|
<path class="cls-3" d="m288.53,0c1.99,2.11,3.26,3.13,4.14,4.42,15.97,23.63,31.7,47.44,47.91,70.91,9.33,13.51,19.26,26.61,29.22,39.67,9.63,12.65,19.8,24.88,29.44,37.53,11.15,14.63,22.45,29.18,32.81,44.36,13.27,19.45,26.64,38.94,38.12,59.44,9.76,17.43,17.56,36.05,25.02,54.64,5.28,13.16,8.82,27.06,12.6,40.78,1.75,6.36,2.24,13.07,3.26,19.62,1.26,8.02,3.4,16.04,3.53,24.08.35,20.94,2.17,41.95-1.48,62.8-4.02,22.99-10.75,45-20.76,66.23-10.12,21.45-22.38,41.26-37.39,59.59-13.6,16.61-29.57,30.33-46.84,42.91-12.68,9.23-26.09,17.07-40.36,23.3-12.84,5.6-26.07,10.09-39.69,13.89-30.75,8.56-61.93,10.44-93.33,8.23-18.93-1.33-38.08-3.65-56.11-10.46-14.82-5.6-29.75-11.13-43.92-18.13-11.19-5.52-21.91-12.44-31.73-20.15-12.88-10.11-25.52-20.81-36.67-32.74-9.99-10.68-18.64-22.87-26.4-35.31-8.18-13.13-15.39-27.01-21.58-41.2-6.69-15.32-11.01-31.45-14.53-47.97-5.48-25.71-3.71-51.44-2.59-77.09.64-14.73,4.53-29.47,8.26-43.86,3.93-15.18,8.68-30.26,14.44-44.84,5.77-14.6,12.47-28.96,20.14-42.65,9.63-17.18,20.25-33.85,31.2-50.23,9.94-14.88,20.68-29.24,31.47-43.52,8.69-11.5,18.17-22.41,26.97-33.83,8.9-11.55,17.46-23.36,26.07-35.13,9.11-12.46,18.29-24.87,27.09-37.55,11.16-16.07,21.91-32.43,32.97-48.57,1.58-2.31,3.88-4.14,5.84-6.19.39.22.78.44,1.18.66.08,1.77.23,3.54.23,5.31.01,26.33.15,52.66-.17,78.99-.05,3.86-1.62,8.15-3.72,11.46-8.5,13.45-17.19,26.8-26.38,39.79-8.71,12.31-18.12,24.13-27.22,36.16-7.5,9.91-14.97,19.83-22.52,29.7-5.24,6.85-10.74,13.5-15.86,20.44-7.16,9.72-14.35,19.45-21.03,29.5-8.06,12.12-15.99,24.36-23.23,36.97-5.18,9.02-9.26,18.69-13.59,28.17-2.4,5.26-4.61,10.64-6.36,16.14-3.1,9.76-5.58,19.71-8.68,29.47-8.72,27.42-6.87,55.63-4.92,83.5.99,14.15,6.11,28.15,10.4,41.89,6.01,19.24,16.32,36.3,27.95,52.74,7.94,11.23,16.95,21.38,27.14,30.36,8.39,7.38,17.5,14.17,27.07,19.92,10.89,6.54,22.23,12.77,34.12,17.07,12.69,4.59,26.1,7.99,39.48,9.68,15.93,2.01,32.16,1.58,48.25,2.34,14.94.7,29.43-2.29,43.93-5.14,18.41-3.62,35.23-11.56,51.58-20.26,19.55-10.4,35.98-25.13,50.37-41.73,14.71-16.97,27.06-36.05,34.92-57,8.29-22.1,15.2-44.97,14.15-69.26-.57-13.13.15-26.34-1.06-39.39-.89-9.61-3.62-19.11-6.16-28.5-2.98-11.03-6.03-22.1-10.16-32.73-4.11-10.59-9.36-20.75-14.52-30.9-4.57-8.99-9.32-17.92-14.66-26.46-6.5-10.39-13.38-20.59-20.68-30.43-11.05-14.9-22.74-29.32-33.91-44.12-13.08-17.33-26.13-34.68-38.77-52.33-10.91-15.22-21.31-30.81-31.71-46.39-1.67-2.5-3-5.79-3.03-8.72-.23-28.49-.15-56.98-.13-85.47,0-.95.24-1.91.58-4.44Z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
BIN
src/lib/images/vaxry-github.webp
Executable file
BIN
src/lib/images/vaxry-github.webp
Executable file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
|
@ -6,12 +6,10 @@
|
||||||
import '@fontsource/ibm-plex-mono/500.css'
|
import '@fontsource/ibm-plex-mono/500.css'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col min-h-screen overflow-x-hidden">
|
<Navbar />
|
||||||
<Navbar />
|
|
||||||
|
|
||||||
<main class="mx-auto w-full flex flex-col">
|
<main class="mx-auto w-full overflow-hidden flex flex-col">
|
||||||
<slot />
|
<slot />
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import Community from './CommunitySlice.svelte'
|
import Community from './CommunitySlice.svelte'
|
||||||
import FeaturesSlice from './FeaturesSlice.svelte'
|
import FeaturesSlice from './FeaturesSlice.svelte'
|
||||||
import HallOfFameSlice from './HallOfFameSlice.svelte'
|
import WallOfFameSlice from './WallOfFameSlice.svelte'
|
||||||
import Hero from './Hero.svelte'
|
import Hero from './Hero.svelte'
|
||||||
import InstallSlice from './InstallSlice.svelte'
|
import InstallSlice from './InstallSlice.svelte'
|
||||||
import PreviewRiceSlice from './PreviewRiceSlice.svelte'
|
import PreviewRiceSlice from './PreviewRiceSlice.svelte'
|
||||||
|
@ -15,11 +15,11 @@
|
||||||
<Hero />
|
<Hero />
|
||||||
|
|
||||||
<div class="-mt-8 gap-20 md:gap-[16rem] flex flex-col items-center">
|
<div class="-mt-8 gap-20 md:gap-[16rem] flex flex-col items-center">
|
||||||
<PreviewRiceSlice class="mb-52" />
|
<PreviewRiceSlice class="mb-12" />
|
||||||
|
|
||||||
<FeaturesSlice />
|
<FeaturesSlice />
|
||||||
|
|
||||||
<HallOfFameSlice />
|
<WallOfFameSlice />
|
||||||
|
|
||||||
<Community />
|
<Community />
|
||||||
|
|
||||||
|
|
|
@ -58,10 +58,10 @@
|
||||||
class: 'outline-slate-200'
|
class: 'outline-slate-200'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: '/imgs/profile_pictures/outfoxxed.webp',
|
image: '/imgs/profile_pictures/kcrmson.webp',
|
||||||
coordinates: [53, 399],
|
coordinates: [53, 399],
|
||||||
size: 75,
|
size: 75,
|
||||||
class: 'outline-orange-500'
|
class: 'outline-sky-500'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: '/imgs/profile_pictures/loseardes77.gif',
|
image: '/imgs/profile_pictures/loseardes77.gif',
|
||||||
|
@ -107,14 +107,14 @@
|
||||||
image: '/imgs/profile_pictures/7.webp',
|
image: '/imgs/profile_pictures/7.webp',
|
||||||
coordinates: [273, 687],
|
coordinates: [273, 687],
|
||||||
size: 52,
|
size: 52,
|
||||||
quote: '"Meds"',
|
quote: '"meds"',
|
||||||
class: 'outline-cyan-500'
|
class: 'outline-cyan-500'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: '/imgs/profile_pictures/kcrmson.webp',
|
image: '/imgs/profile_pictures/outfoxxed.webp',
|
||||||
coordinates: [648, 364],
|
coordinates: [648, 364],
|
||||||
size: 80,
|
size: 80,
|
||||||
class: 'outline-sky-500'
|
class: 'outline-orange-500'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: '/imgs/profile_pictures/kirottum.webp',
|
image: '/imgs/profile_pictures/kirottum.webp',
|
||||||
|
@ -235,9 +235,9 @@
|
||||||
width: 9rem;
|
width: 9rem;
|
||||||
height: 9rem;
|
height: 9rem;
|
||||||
transition:
|
transition:
|
||||||
rotate 480ms cubic-bezier(0.5, 0, 0.5, 1.5),
|
rotate 480ms cubic-bezier(0.5, 0, 0.5, 1.1),
|
||||||
scale 440ms cubic-bezier(1, -1.4, 0, 2),
|
scale 420ms cubic-bezier(1, 0.1, 0, 2),
|
||||||
filter 240ms;
|
filter 840ms;
|
||||||
filter: drop-shadow(0px 0px 0px cyan) drop-shadow(0px 0px 0px blue);
|
filter: drop-shadow(0px 0px 0px cyan) drop-shadow(0px 0px 0px blue);
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
<script>
|
|
||||||
import { spring } from 'svelte/motion';
|
|
||||||
|
|
||||||
let count = 0;
|
|
||||||
|
|
||||||
const displayed_count = spring();
|
|
||||||
$: displayed_count.set(count);
|
|
||||||
$: offset = modulo($displayed_count, 1);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {number} n
|
|
||||||
* @param {number} m
|
|
||||||
*/
|
|
||||||
function modulo(n, m) {
|
|
||||||
// handle negative numbers
|
|
||||||
return ((n % m) + m) % m;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="counter">
|
|
||||||
<button on:click={() => (count -= 1)} aria-label="Decrease the counter by one">
|
|
||||||
<svg aria-hidden="true" viewBox="0 0 1 1">
|
|
||||||
<path d="M0,0.5 L1,0.5" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<div class="counter-viewport">
|
|
||||||
<div class="counter-digits" style="transform: translate(0, {100 * offset}%)">
|
|
||||||
<strong class="hidden" aria-hidden="true">{Math.floor($displayed_count + 1)}</strong>
|
|
||||||
<strong>{Math.floor($displayed_count)}</strong>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button on:click={() => (count += 1)} aria-label="Increase the counter by one">
|
|
||||||
<svg aria-hidden="true" viewBox="0 0 1 1">
|
|
||||||
<path d="M0,0.5 L1,0.5 M0.5,0 L0.5,1" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.counter {
|
|
||||||
display: flex;
|
|
||||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
margin: 1rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter button {
|
|
||||||
width: 2em;
|
|
||||||
padding: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
border: 0;
|
|
||||||
background-color: transparent;
|
|
||||||
touch-action: manipulation;
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter button:hover {
|
|
||||||
background-color: var(--color-bg-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 25%;
|
|
||||||
height: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
path {
|
|
||||||
vector-effect: non-scaling-stroke;
|
|
||||||
stroke-width: 2px;
|
|
||||||
stroke: #444;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter-viewport {
|
|
||||||
width: 8em;
|
|
||||||
height: 4em;
|
|
||||||
overflow: hidden;
|
|
||||||
text-align: center;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter-viewport strong {
|
|
||||||
position: absolute;
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
font-weight: 400;
|
|
||||||
color: var(--color-theme-1);
|
|
||||||
font-size: 4rem;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counter-digits {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden {
|
|
||||||
top: -100%;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
</style>
|
|
|
@ -1,11 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import { json } from '@sveltejs/kit'
|
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import interact from 'interactjs'
|
|
||||||
import { createEventDispatcher, getContext, onMount } from 'svelte'
|
import { createEventDispatcher, getContext, onMount } from 'svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
import { contextId } from './CommunitySlice.svelte'
|
import { contextId as ctxId } from './CommunitySlice.svelte'
|
||||||
import { lerp } from '$lib/Helper.mjs'
|
import { getIsMobile, lerp } from '$lib/Helper.mjs'
|
||||||
import { inview } from 'svelte-inview'
|
import { inview } from 'svelte-inview'
|
||||||
|
|
||||||
/** @type {string} */
|
/** @type {string} */
|
||||||
|
@ -20,6 +18,10 @@
|
||||||
/** @type {string | undefined} */
|
/** @type {string | undefined} */
|
||||||
export let quote = undefined
|
export let quote = undefined
|
||||||
|
|
||||||
|
/** @type {symbol}*/
|
||||||
|
export let contextId = ctxId
|
||||||
|
export let isAnimating = true
|
||||||
|
|
||||||
const { biggestSize, getSectionElement } = getContext(contextId)
|
const { biggestSize, getSectionElement } = getContext(contextId)
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -36,33 +38,39 @@
|
||||||
let hasEnteredView = false
|
let hasEnteredView = false
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
let interactionjs = interact(imageElement).draggable({
|
if (getIsMobile()) return
|
||||||
inertia: { resistance: lerp(5, 200, relativeSize) },
|
|
||||||
listeners: {
|
|
||||||
move({ dx, dy }) {
|
|
||||||
dragCoordinates.update(([x, y]) => {
|
|
||||||
x += dx
|
|
||||||
y += dy
|
|
||||||
return [x, y]
|
|
||||||
})
|
|
||||||
},
|
|
||||||
|
|
||||||
start(event) {
|
let interactionjs
|
||||||
dispatch('dragStart', event)
|
|
||||||
|
import('interactjs').then(({ default: interact }) => {
|
||||||
|
interactionjs = interact(imageElement).draggable({
|
||||||
|
inertia: { resistance: lerp(5, 200, relativeSize) },
|
||||||
|
listeners: {
|
||||||
|
move({ dx, dy }) {
|
||||||
|
dragCoordinates.update(([x, y]) => {
|
||||||
|
x += dx
|
||||||
|
y += dy
|
||||||
|
return [x, y]
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
start(event) {
|
||||||
|
dispatch('dragStart', event)
|
||||||
|
},
|
||||||
|
end(event) {
|
||||||
|
dispatch('dragEnd', event)
|
||||||
|
}
|
||||||
},
|
},
|
||||||
end(event) {
|
modifiers: [
|
||||||
dispatch('dragEnd', event)
|
interact.modifiers.restrictRect({
|
||||||
}
|
restriction: getSectionElement,
|
||||||
},
|
endOnly: true
|
||||||
modifiers: [
|
})
|
||||||
interact.modifiers.restrictRect({
|
]
|
||||||
restriction: getSectionElement,
|
})
|
||||||
endOnly: true
|
|
||||||
})
|
|
||||||
]
|
|
||||||
})
|
})
|
||||||
|
|
||||||
return () => interactionjs.off()
|
return () => interactionjs?.off?.()
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -72,10 +80,13 @@
|
||||||
style="width: {size}px; height: {size}px;--delay: {delay}ms;"
|
style="width: {size}px; height: {size}px;--delay: {delay}ms;"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-0 w-full h-full group opacity-0 select-none touch-none"
|
class={clsx(
|
||||||
|
'absolute inset-0 w-full h-full group select-none touch-none',
|
||||||
|
isAnimating && 'opacity-0'
|
||||||
|
)}
|
||||||
style:translate={`calc( ${$dragCoordinates[0]}px ) ${$dragCoordinates[1]}px`}
|
style:translate={`calc( ${$dragCoordinates[0]}px ) ${$dragCoordinates[1]}px`}
|
||||||
use:inview={{ unobserveOnEnter: true, threshold: 0.4 }}
|
use:inview={{ unobserveOnEnter: true, threshold: 0.4 }}
|
||||||
class:_animate={hasEnteredView}
|
class:_animate={isAnimating && hasEnteredView}
|
||||||
on:inview_enter={() => setTimeout(() => (hasEnteredView = true), 750)}
|
on:inview_enter={() => setTimeout(() => (hasEnteredView = true), 750)}
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<img
|
<img
|
||||||
src={image}
|
src={image}
|
||||||
alt="Rice desktop"
|
alt="Rice desktop"
|
||||||
class="w-full nice-hover object-cover object-top rounded-xl overflow-hidden shadow-2xl hover:scale-[1.01] {imageClass}"
|
class="max-sm:[xmask-image:none] w-full nice-hover object-cover object-top rounded-xl overflow-hidden shadow-2xl hover:scale-[1.01] {imageClass}"
|
||||||
/>
|
/>
|
||||||
<img src={image} alt="Rice desktop" aria-hidden="true" class="rice-bg" />
|
<img src={image} alt="Rice desktop" aria-hidden="true" class="rice-bg" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -30,7 +30,7 @@
|
||||||
transition: all 540ms cubic-bezier(0.1, -0.81, 0.31, 2);
|
transition: all 540ms cubic-bezier(0.1, -0.81, 0.31, 2);
|
||||||
}
|
}
|
||||||
.rice-bg {
|
.rice-bg {
|
||||||
@apply w-[calc(100%-24px)] pointer-events-none transition-[filter] duration-500 absolute left-3 brightness-150 rounded-3xl -z-10 saturate-[5] h-full blur-2xl -bottom-10 opacity-50;
|
@apply pointer-events-none absolute -bottom-10 left-3 -z-10 h-full w-[calc(100%-24px)] rounded-3xl opacity-50 blur-2xl brightness-150 saturate-[5] transition-[filter] duration-500 max-sm:hidden;
|
||||||
|
|
||||||
.rice:hover & {
|
.rice:hover & {
|
||||||
@apply brightness-200;
|
@apply brightness-200;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
<script>
|
<script>
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
import { getContext } from 'svelte'
|
import { getContext, onMount } from 'svelte'
|
||||||
import { mouseContext } from './FeaturesSlice.svelte'
|
import { mouseContext } from './FeaturesSlice.svelte'
|
||||||
import { spring } from 'svelte/motion'
|
import { spring } from 'svelte/motion'
|
||||||
import Title from '$lib/components/Title.svelte'
|
import { getIsMobile } from '$lib/Helper.mjs'
|
||||||
export let title
|
export let title
|
||||||
export let color = 'cyan'
|
export let color = 'cyan'
|
||||||
|
|
||||||
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
/** @type HTMLDivElement */
|
/** @type HTMLDivElement */
|
||||||
let container
|
let container
|
||||||
|
let isMobile = false
|
||||||
|
|
||||||
const fillX = spring(999, { damping: 0.9, stiffness: 0.021, precision: 0.3 })
|
const fillX = spring(999, { damping: 0.9, stiffness: 0.021, precision: 0.3 })
|
||||||
const fillY = spring(999, { damping: 0.9, stiffness: 0.021, precision: 0.3 })
|
const fillY = spring(999, { damping: 0.9, stiffness: 0.021, precision: 0.3 })
|
||||||
const borderX = spring(999, { damping: 0.9, stiffness: 0.03, precision: 0.3 })
|
const borderX = spring(999, { damping: 0.9, stiffness: 0.03, precision: 0.3 })
|
||||||
|
@ -27,7 +29,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
isMobile = getIsMobile()
|
||||||
|
})
|
||||||
|
|
||||||
function updateGradient() {
|
function updateGradient() {
|
||||||
|
if (isMobile) return
|
||||||
|
|
||||||
const { x: rectX, y: rectY, width, height } = container.getBoundingClientRect()
|
const { x: rectX, y: rectY, width, height } = container.getBoundingClientRect()
|
||||||
|
|
||||||
const normX = $mouseX - rectX
|
const normX = $mouseX - rectX
|
||||||
|
@ -55,7 +63,7 @@
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={clsx('card min-h-[20rem] ', $$restProps.class)}
|
class={clsx('card min-h-[20rem] group', $$restProps.class)}
|
||||||
style:--x={$fillX}
|
style:--x={$fillX}
|
||||||
style:--y={$fillY}
|
style:--y={$fillY}
|
||||||
style:--borderX={$borderX}
|
style:--borderX={$borderX}
|
||||||
|
@ -70,19 +78,19 @@
|
||||||
class:purpleGradient={color === 'purple'}
|
class:purpleGradient={color === 'purple'}
|
||||||
role="contentinfo"
|
role="contentinfo"
|
||||||
>
|
>
|
||||||
<div class="p-8 md:p-12 z-10 w-full h-full">
|
<div class="p-8 sm:p-12 z-10 w-full h-full flex flex-col justify-end">
|
||||||
<h1 class="text-5xl font-bold mb-6 text-white">{title}</h1>
|
<h1 class="text-5xl font-bold mb-6 text-white">{title}</h1>
|
||||||
|
|
||||||
<slot>Nothing in the slot here</slot>
|
<slot>Nothing in the slot here</slot>
|
||||||
</div>
|
</div>
|
||||||
<div class="gradient" />
|
<div class="gradient max-sm:hidden" />
|
||||||
<div class="gradient_black" />
|
<div class="gradient_black max-sm:hidden" />
|
||||||
<div class="border-gradient" />
|
<div class="border-gradient max-sm:hidden" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.card {
|
.card {
|
||||||
@apply relative flex h-full w-full items-center justify-center rounded-3xl bg-slate-900 transition-colors duration-300 hover:bg-blue-900;
|
@apply relative flex h-full w-full items-end justify-end rounded-3xl bg-slate-950 transition-colors duration-300 md:bg-slate-900 md:hover:bg-blue-900;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
contain: paint style layout;
|
contain: paint style layout;
|
||||||
}
|
}
|
||||||
|
@ -114,6 +122,7 @@
|
||||||
top: 0%;
|
top: 0%;
|
||||||
content: '';
|
content: '';
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
filter: brightness(1.2) saturate(2);
|
||||||
contain: strict;
|
contain: strict;
|
||||||
background: radial-gradient(
|
background: radial-gradient(
|
||||||
320px circle at calc(var(--borderX) * 1px) calc(var(--borderY) * 1px),
|
320px circle at calc(var(--borderX) * 1px) calc(var(--borderY) * 1px),
|
||||||
|
@ -149,6 +158,7 @@
|
||||||
translate: -25% 0%;
|
translate: -25% 0%;
|
||||||
transform-origin: top left;
|
transform-origin: top left;
|
||||||
left: 50%;
|
left: 50%;
|
||||||
|
opacity: 0%;
|
||||||
transition: all 820ms;
|
transition: all 820ms;
|
||||||
content: '';
|
content: '';
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
@ -162,6 +172,10 @@
|
||||||
.card:hover & {
|
.card:hover & {
|
||||||
scale: 1 1;
|
scale: 1 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.group:hover & {
|
||||||
|
opacity: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,18 +4,16 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import FeatureCard from './FeatureCard.svelte'
|
import FeatureCard from './FeatureCard.svelte'
|
||||||
import { setContext } from 'svelte'
|
import { setContext, onMount } from 'svelte'
|
||||||
import { writable } from 'svelte/store'
|
import { writable } from 'svelte/store'
|
||||||
import PluginsIcon from '~icons/gg/arrange-back'
|
import PluginsIcon from '~icons/gg/arrange-back'
|
||||||
import ActiveGitIcon from '~icons/gg/git-branch'
|
|
||||||
import ShortcutsIcon from '~icons/gg/push-chevron-right-o'
|
import ShortcutsIcon from '~icons/gg/push-chevron-right-o'
|
||||||
import BleedingEdgeIcon from '~icons/gg/controller'
|
import BleedingEdgeIcon from '~icons/gg/controller'
|
||||||
import Title from '$lib/components/Title.svelte'
|
import Title from '$lib/components/Title.svelte'
|
||||||
|
import Hypractive from './Hypractive.svelte'
|
||||||
|
import { getIsMobile } from '$lib/Helper.mjs'
|
||||||
|
|
||||||
/**
|
let isMobile = false
|
||||||
* type {{name: string, github: string}}
|
|
||||||
*/
|
|
||||||
let createdBy
|
|
||||||
|
|
||||||
const context = setContext(mouseContext, {
|
const context = setContext(mouseContext, {
|
||||||
x: writable(0),
|
x: writable(0),
|
||||||
|
@ -26,6 +24,10 @@
|
||||||
/** @type HTMLDivElement */
|
/** @type HTMLDivElement */
|
||||||
let featuresContainer
|
let featuresContainer
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
isMobile = getIsMobile()
|
||||||
|
})
|
||||||
|
|
||||||
function onMouseEnter() {
|
function onMouseEnter() {
|
||||||
featuresContainer.addEventListener('mousemove', trackMouse)
|
featuresContainer.addEventListener('mousemove', trackMouse)
|
||||||
context.isHoverCards.set(true)
|
context.isHoverCards.set(true)
|
||||||
|
@ -49,41 +51,61 @@
|
||||||
<div
|
<div
|
||||||
class="grid lg:grid-cols-2 lg:grid-rows-2 w-full gap-6 text-lg text-white/70 font-medium flex-wrap group"
|
class="grid lg:grid-cols-2 lg:grid-rows-2 w-full gap-6 text-lg text-white/70 font-medium flex-wrap group"
|
||||||
role="contentinfo"
|
role="contentinfo"
|
||||||
on:mouseenter={onMouseEnter}
|
on:mouseenter={!isMobile && onMouseEnter}
|
||||||
on:mouseleave={onMouseLeave}
|
on:mouseleave={!isMobile && onMouseLeave}
|
||||||
bind:this={featuresContainer}
|
bind:this={featuresContainer}
|
||||||
>
|
>
|
||||||
<FeatureCard title="Smooth" class="row-span-2">
|
<FeatureCard title="Smooth" class="row-span-2">
|
||||||
<p>
|
<p class="max-w-[60ch]">
|
||||||
Transition from windows and workspaces smoothly, without abrupt changes. Instant input with
|
Transition from windows and workspaces smoothly, with great animations. High performance.
|
||||||
a custom WSLroot patch included
|
Instant input.
|
||||||
</p></FeatureCard
|
</p></FeatureCard
|
||||||
>
|
>
|
||||||
<FeatureCard title="Easy to configure" color="purple">
|
<FeatureCard title="Easy to configure" color="purple">
|
||||||
<p>
|
<p class="max-w-[60ch]">
|
||||||
Live reloading config. Easy plain-text format. Sensible defaults. Great documentation.
|
Live reloading config. Easy plain-text format. Sensible defaults. Great documentation.
|
||||||
</p></FeatureCard
|
</p>
|
||||||
>
|
|
||||||
|
<div class="absolute _wrapper inset-0 select-none" aria-hidden>
|
||||||
|
<div
|
||||||
|
class="absolute text-[440px] -bottom-10 text-slate-500 _configure -right-40 md:right-0 font-mono"
|
||||||
|
>
|
||||||
|
{'<>'}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</FeatureCard>
|
||||||
<FeatureCard class="" title="Dynamic tiling">
|
<FeatureCard class="" title="Dynamic tiling">
|
||||||
<p>
|
<p class="max-w-[60ch]">
|
||||||
Automatic tiling which just works. Supports multiple fine-tuneable layouts.
|
Automatic tiling which just works. Supports multiple fine-tuneable layouts.
|
||||||
</p></FeatureCard
|
</p>
|
||||||
>
|
<div class="absolute _wrapper inset-0 select-none" aria-hidden>
|
||||||
|
<div
|
||||||
|
class="absolute text-[280px] text-slate-500 font-extrabold gap-y-4 [line-height:1] -z-10 bottom-[20px] tiling right-0 md:right-8 font-mono tiles"
|
||||||
|
>
|
||||||
|
<div class="tile" style={''}>[ ]</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</FeatureCard>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-14 flex-wrap justify-center flex gap-8">
|
<div class="mt-14 z-10 flex-wrap justify-center flex sm:flex-row flex-col gap-8">
|
||||||
<div class="icon-feature">
|
<a
|
||||||
|
href="https://github.com/hyprland-community/awesome-hyprland#plugins"
|
||||||
|
target="_blank"
|
||||||
|
class="icon-feature hover:underline"
|
||||||
|
>
|
||||||
<PluginsIcon class="h-8 w-8" />
|
<PluginsIcon class="h-8 w-8" />
|
||||||
Plugin system
|
Plugin system
|
||||||
</div>
|
</a>
|
||||||
<div class="icon-feature">
|
<Hypractive />
|
||||||
<ActiveGitIcon class="h-8 w-8" />
|
<a
|
||||||
Hypractive development
|
href="https://wiki.hyprland.org/Configuring/Binds/#global-keybinds"
|
||||||
</div>
|
target="_blank"
|
||||||
<div class="icon-feature">
|
class="icon-feature hover:underline"
|
||||||
|
>
|
||||||
<ShortcutsIcon class="h-8 w-8" />
|
<ShortcutsIcon class="h-8 w-8" />
|
||||||
Global shortcuts for apps
|
Global shortcuts for apps
|
||||||
</div>
|
</a>
|
||||||
<div class="icon-feature">
|
<div class="icon-feature">
|
||||||
<BleedingEdgeIcon class="h-8 w-8" />Bleeding edge tech
|
<BleedingEdgeIcon class="h-8 w-8" />Bleeding edge tech
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,6 +114,72 @@
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.icon-feature {
|
.icon-feature {
|
||||||
@apply flex items-center justify-center gap-3 font-bold opacity-60;
|
@apply flex items-center justify-center gap-3 font-bold text-slate-400;
|
||||||
|
}
|
||||||
|
|
||||||
|
._configure {
|
||||||
|
@apply bg-gradient-to-tl from-pink-500 to-blue-500 bg-clip-text text-blue-700;
|
||||||
|
line-height: 1;
|
||||||
|
z-index: -1;
|
||||||
|
transition: all 850ms ease-in-out;
|
||||||
|
color: rgb(255, 121, 170);
|
||||||
|
opacity: 0.4;
|
||||||
|
color: transparent;
|
||||||
|
text-shadow:
|
||||||
|
10px -10px 40px theme(colors.pink.700 / 20),
|
||||||
|
5px 5px 20px cyan,
|
||||||
|
-10px 10px 40px theme(colors.blue.700 / 20);
|
||||||
|
filter: saturate(2) drop-shadow(8px 8px 20px theme(colors.pink.700))
|
||||||
|
drop-shadow(-8px -8px 20px theme(colors.blue.700));
|
||||||
|
|
||||||
|
._wrapper:hover & {
|
||||||
|
color: transparent;
|
||||||
|
opacity: 0.6;
|
||||||
|
filter: saturate(2) drop-shadow(8px 8px 12px theme(colors.pink.700))
|
||||||
|
drop-shadow(-8px -8px 12px theme(colors.blue.700));
|
||||||
|
text-shadow:
|
||||||
|
15px -15px 40px theme(colors.pink.700 / 80),
|
||||||
|
8px 8px 20px cyan,
|
||||||
|
-15px 15px 40px theme(colors.blue.700 / 40);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tile {
|
||||||
|
/* Animate a pulse animation for the glow effect */
|
||||||
|
/* Use different colors for the different windows */
|
||||||
|
background: radial-gradient(ellipse, var(--color1, cyan) 50%, var(--color2, magenta));
|
||||||
|
background-clip: text;
|
||||||
|
color: transparent;
|
||||||
|
letter-spacing: -55px;
|
||||||
|
text-shadow:
|
||||||
|
-5px 5px 8px color-mix(in srgb, var(--color1, magenta), transparent 90%),
|
||||||
|
5px -5px 8px color-mix(in srgb, color-mix(in srgb, var(--color1, rgb(0, 187, 255)), black 20%), transparent
|
||||||
|
10%),
|
||||||
|
0px 0px 15px var(--color2, magenta);
|
||||||
|
|
||||||
|
filter: saturate(1) drop-shadow(8px 8px 24px var(--color2, blue))
|
||||||
|
drop-shadow(
|
||||||
|
-8px -8px 24px color-mix(in srgb, var(--color1, rgb(0, 187, 255)), rgba(0, 0, 0, 0.056) 80%)
|
||||||
|
);
|
||||||
|
opacity: 0.4;
|
||||||
|
transition: all 850ms ease-in-out;
|
||||||
|
|
||||||
|
._wrapper:hover & {
|
||||||
|
opacity: 0.7;
|
||||||
|
text-shadow:
|
||||||
|
-15px 15px 0px color-mix(in srgb, var(--color1, cyan), transparent 60%),
|
||||||
|
15px -15px 8px color-mix(in srgb, color-mix(in srgb, var(--colo1r, magenta), rgb(0, 0, 111)
|
||||||
|
50%), transparent 30%),
|
||||||
|
0px 0px 15px var(--color2, magenta);
|
||||||
|
|
||||||
|
filter: saturate(2) drop-shadow(8px 8px 24px var(--color2, blue))
|
||||||
|
drop-shadow(
|
||||||
|
-8px -8px 24px color-mix(in srgb, var(--color1, magenta), rgba(0, 0, 0, 0.056) 20%)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tiles {
|
||||||
|
filter: drop-shadow(0px 0px 5px rgb(0, 191, 255));
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -3,29 +3,40 @@
|
||||||
import { createNoise2D } from 'simplex-noise'
|
import { createNoise2D } from 'simplex-noise'
|
||||||
import { match } from 'ts-pattern'
|
import { match } from 'ts-pattern'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
|
import { getIsMobile } from '$lib/Helper.mjs'
|
||||||
|
|
||||||
// Idea: Boid behavior
|
// Idea: Boid behavior
|
||||||
|
|
||||||
const maxSize = 12
|
const maxSize = 18
|
||||||
const size = Math.max(Math.random() * maxSize, 6)
|
const size = Math.max(Math.random() * maxSize, 6)
|
||||||
/** How much the fireflies can vanish into the edges of the screen. Include their invisible padding for mouse detection. */
|
/** How much the fireflies can vanish into the edges of the screen. Include their invisible padding for mouse detection. */
|
||||||
const edgeClip = maxSize * 8
|
const edgeClip = maxSize * 8
|
||||||
const noiseY = createNoise2D()
|
const noiseY = createNoise2D()
|
||||||
const noiseX = createNoise2D()
|
const noiseX = createNoise2D()
|
||||||
|
const SPEED = Math.random() * 5 + 2
|
||||||
|
|
||||||
let classes = clsx(Math.random() > 0.5 ? 'bg-primary/70' : 'bg-sky-500/70')
|
let classes = clsx(Math.random() > 0.5 ? 'bg-primary/70' : 'bg-blue-500/70')
|
||||||
|
|
||||||
let x = 0
|
let x = 0
|
||||||
let y = 0
|
let y = 0
|
||||||
|
|
||||||
|
// TODO add mouse following behaviour - flock behaviour
|
||||||
|
// A couple following the mouse throughout the website
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
x = window.innerWidth / 2 - maxSize * 6
|
x = window.innerWidth / (Math.random() * 4) - maxSize * 6
|
||||||
y = window.innerHeight / 2 + 100
|
y = window.innerHeight / (Math.random() * 4) + 100
|
||||||
|
|
||||||
|
// The animation is way too heavy for mobile
|
||||||
|
if (getIsMobile()) return
|
||||||
|
|
||||||
let animationId
|
let animationId
|
||||||
let i = 0
|
let i = 0
|
||||||
|
|
||||||
animate()
|
animate()
|
||||||
|
|
||||||
|
return () => cancelAnimationFrame(animationId)
|
||||||
|
|
||||||
async function animate() {
|
async function animate() {
|
||||||
x += match(x)
|
x += match(x)
|
||||||
.when(
|
.when(
|
||||||
|
@ -36,7 +47,7 @@
|
||||||
(x) => x < -edgeClip,
|
(x) => x < -edgeClip,
|
||||||
() => 10
|
() => 10
|
||||||
)
|
)
|
||||||
.otherwise(() => noiseX(i, 1) * 5)
|
.otherwise(() => noiseX(i, 1) * SPEED)
|
||||||
y += match(y)
|
y += match(y)
|
||||||
.when(
|
.when(
|
||||||
(y) => y > window.innerHeight + edgeClip,
|
(y) => y > window.innerHeight + edgeClip,
|
||||||
|
@ -46,22 +57,22 @@
|
||||||
(y) => y < -edgeClip,
|
(y) => y < -edgeClip,
|
||||||
() => 10
|
() => 10
|
||||||
)
|
)
|
||||||
.otherwise(() => noiseY(i, 1) * 5)
|
.otherwise(() => noiseY(i, 1) * SPEED)
|
||||||
|
|
||||||
i += 0.005
|
i += 0.005
|
||||||
|
|
||||||
animationId = requestAnimationFrame(animate)
|
animationId = requestAnimationFrame(animate)
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => cancelAnimationFrame(animationId)
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="absolute p-24 top-0 left-0 firefly pointer-events-auto opacity-50 hover:opacity-100 transition-opacity z-0"
|
class="absolute hidden max-sm:[contain:strict] md:block p-24 top-0 left-0 firefly pointer-events-auto opacity-50 hover:opacity-100 transition-opacity z-0"
|
||||||
style="--x:{x}px; --y:{y}px;--size:{size}px; --fadeDelay: {Math.random() * 6 - 3}s"
|
style:--x={x + 'px'}
|
||||||
|
style:--y={y + 'px'}
|
||||||
|
style="--size:{size}px; --fadeDelay: {Math.random() * 6 - 3}s"
|
||||||
>
|
>
|
||||||
<div class="firefly-inner {classes}" />
|
<div class={clsx('firefly-inner', classes)} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
@ -72,12 +83,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.firefly-inner {
|
.firefly-inner {
|
||||||
background-color: theme(colors.sky.400 / 70%);
|
|
||||||
min-height: var(--size);
|
min-height: var(--size);
|
||||||
min-width: var(--size);
|
min-width: var(--size);
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
contain: layout;
|
contain: layout size style;
|
||||||
box-shadow: 0px 0px 25px theme(colors.emerald.400), 0px 0px 12px theme(colors.sky.400);
|
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: fade 3s ease-in-out infinite alternate;
|
||||||
animation-delay: var(--fadeDelay);
|
animation-delay: var(--fadeDelay);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,37 +1,36 @@
|
||||||
<script>
|
<script>
|
||||||
|
import { getIsMobile } from '$lib/Helper.mjs'
|
||||||
import Button from '$lib/components/Button.svelte'
|
import Button from '$lib/components/Button.svelte'
|
||||||
import Logo from '$lib/images/logo.png'
|
import Logo from '$lib/images/logos/hyprland-color.svg'
|
||||||
|
import { onMount } from 'svelte'
|
||||||
import Firefly from './Firefly.svelte'
|
import Firefly from './Firefly.svelte'
|
||||||
import { inview } from 'svelte-inview'
|
import { inview } from 'svelte-inview'
|
||||||
|
|
||||||
let isVisible = true
|
let isVisible = true
|
||||||
let hadBeenInvisble = false
|
let isMobile = false
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
isMobile = getIsMobile()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
class="w-full relative flex flex-col items-center justify-center min-h-screen h-max"
|
class="w-full relative flex flex-col items-center justify-center min-h-[100svh] overflow-x-hidden h-max"
|
||||||
use:inview
|
use:inview
|
||||||
on:inview_change={({ detail: { inView } }) => {
|
on:inview_change={({ detail: { inView } }) => {
|
||||||
isVisible = inView
|
isVisible = inView
|
||||||
hadBeenInvisble = hadBeenInvisble && inView
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<!-- Hero text and logo -->
|
<!-- Hero text and logo -->
|
||||||
<div class="flex h-screen min-h-max justify-center flex-col items-center z-10">
|
<div class="flex h-screen min-h-max justify-center flex-col items-center z-10">
|
||||||
<div class="text-center items-center flex flex-col gap-6 mb-8">
|
<div class="text-center -mt-20 items-center flex flex-col gap-6 mb-8">
|
||||||
<img src={Logo} alt="Hyprland Logo" class="w-32 mb-4 ani-in fill-mode-backwards" />
|
<img src={Logo} alt="Hyprland Logo" class="h-36 mb-4 ani-in fill-mode-backwards" />
|
||||||
<div class="relative ani-in fill-mode-backwards [animation-delay:584ms]">
|
<div class="relative ani-in fill-mode-backwards [animation-delay:584ms]">
|
||||||
<h1
|
<h1
|
||||||
class="text-7xl p-2 font-bold bg-clip-text text-transparent font-london hyprgradient tracking-wider"
|
class="text-5xl md:text-7xl p-2 font-bold bg-clip-text text-transparent font-london hyprgradient tracking-wider md:tracking-widest"
|
||||||
>
|
>
|
||||||
Hyprland
|
Hyprland
|
||||||
</h1>
|
</h1>
|
||||||
<div
|
|
||||||
aria-hidden="true"
|
|
||||||
class="text-7xl top-0 pointer-events-none p-2 font-bold title-shadow absolute font-london tracking-wider -z-10"
|
|
||||||
>
|
|
||||||
Hyprland
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2
|
<h2
|
||||||
|
@ -46,22 +45,22 @@
|
||||||
<a href="https://wiki.hyprland.org/Getting-Started/Installation/">
|
<a href="https://wiki.hyprland.org/Getting-Started/Installation/">
|
||||||
<Button size="lg">Install</Button>
|
<Button size="lg">Install</Button>
|
||||||
</a>
|
</a>
|
||||||
<Button type="fancyOutline" size="lg">Github</Button>
|
<a href="https://wiki.hyprland.org/Getting-Started/">
|
||||||
|
<Button type="fancyOutline" size="lg">Wiki</Button>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Fireflies -->
|
<!-- Fireflies -->
|
||||||
{#if isVisible}
|
{#if isVisible}
|
||||||
<div
|
<div
|
||||||
class="absolute animate-in fade-in-0 duration-75 pointer-events-none max-w-screen inset-0 overflow-hidden z-0"
|
class="absolute animate-in fade-in-0 [animation-delay:900ms] [animation-duration:4500ms] fill-mode-backwards pointer-events-none max-w-screen inset-0 overflow-hidden -z-10"
|
||||||
>
|
>
|
||||||
<div class="bg-gradient-to-t from-black z-10 w-full h-52 absolute bottom-0" />
|
<div class="bg-gradient-to-t from-black z-10 w-full h-52 absolute bottom-0" />
|
||||||
|
|
||||||
{#await new Promise( (resolve) => setTimeout(() => resolve(), hadBeenInvisble ? 0 : 1440) ) then _}
|
{#each { length: 40 } as _}
|
||||||
{#each { length: 40 } as _}
|
<Firefly />
|
||||||
<Firefly />
|
{/each}
|
||||||
{/each}
|
|
||||||
{/await}
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
|
@ -82,7 +81,6 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- Gradient background //-->
|
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
@ -93,15 +91,6 @@
|
||||||
animation: move var(--duration, 50s) ease-in-out var(--offset, 0ms) infinite alternate both;
|
animation: move var(--duration, 50s) ease-in-out var(--offset, 0ms) infinite alternate both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title-shadow {
|
|
||||||
text-shadow:
|
|
||||||
8px 9px 32px theme(colors.secondary / 10%),
|
|
||||||
-8px -9px 32px theme(colors.primary / 20%),
|
|
||||||
1px 0px 3px theme(colors.purple.500 / 50%),
|
|
||||||
0px 9px 16px theme(colors.black / 50%);
|
|
||||||
animate: title_effect 1s ease infinite alternate;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes move {
|
@keyframes move {
|
||||||
0% {
|
0% {
|
||||||
transform: translate3d(
|
transform: translate3d(
|
||||||
|
@ -144,6 +133,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.ani-in {
|
.ani-in {
|
||||||
@apply animate-in ease-in-out slide-in-from-bottom-4 fade-in-0 [animation-duration:800ms];
|
@apply animate-in fade-in-0 slide-in-from-bottom-4 ease-in-out [animation-duration:800ms];
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
183
src/routes/Hypractive.svelte
Executable file
183
src/routes/Hypractive.svelte
Executable file
|
@ -0,0 +1,183 @@
|
||||||
|
<script>
|
||||||
|
import ActiveGitIcon from '~icons/gg/git-branch'
|
||||||
|
import VaxryImage from '$lib/images/vaxry-github.webp'
|
||||||
|
|
||||||
|
import {
|
||||||
|
Subject,
|
||||||
|
interval,
|
||||||
|
map,
|
||||||
|
of,
|
||||||
|
scan,
|
||||||
|
startWith,
|
||||||
|
switchMap,
|
||||||
|
merge,
|
||||||
|
timer,
|
||||||
|
timeInterval,
|
||||||
|
filter,
|
||||||
|
first,
|
||||||
|
take
|
||||||
|
} from 'rxjs'
|
||||||
|
import GitTile from '$lib/components/GitTile.svelte'
|
||||||
|
import { lerp } from '$lib/Helper.mjs'
|
||||||
|
import { cubicInOut, expoInOut } from 'svelte/easing'
|
||||||
|
import DiscordProfilePicture from './DiscordProfilePicture.svelte'
|
||||||
|
import { setContext } from 'svelte'
|
||||||
|
|
||||||
|
const click$ = new Subject()
|
||||||
|
|
||||||
|
const ASCENION_CLICKS = 69
|
||||||
|
const MAX_LIFESPAN_TILE = 2500
|
||||||
|
const MIN_LIFESPAN_TILE = 800
|
||||||
|
const MAX_TILES_PER_CLICK = 15
|
||||||
|
const MIN_TILES_PER_CLICK = 2
|
||||||
|
const CLICK_EACH_MS = 400
|
||||||
|
const ASCENION_FALLOFF = -ASCENION_CLICKS / 20
|
||||||
|
|
||||||
|
const clickLevel$ = click$.pipe(
|
||||||
|
timeInterval(),
|
||||||
|
filter(({ interval }) => interval < CLICK_EACH_MS),
|
||||||
|
map(() => 1),
|
||||||
|
switchMap((value) =>
|
||||||
|
merge(
|
||||||
|
of(value),
|
||||||
|
interval(CLICK_EACH_MS + 100).pipe(
|
||||||
|
take(ASCENION_CLICKS),
|
||||||
|
map(() => ASCENION_FALLOFF)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
scan((level, value) => Math.min(ASCENION_CLICKS, Math.max(level + value, 0))),
|
||||||
|
startWith(0)
|
||||||
|
)
|
||||||
|
const relativeLevel$ = clickLevel$.pipe(map((clicks) => clicks / ASCENION_CLICKS))
|
||||||
|
const cubibRelativeLevel$ = relativeLevel$.pipe(map(cubicInOut))
|
||||||
|
const expoRelativeLevel$ = relativeLevel$.pipe(map(expoInOut))
|
||||||
|
// const hasAscended$ = of(true)
|
||||||
|
const hasAscended$ = relativeLevel$.pipe(
|
||||||
|
filter((level) => level >= 1),
|
||||||
|
first(),
|
||||||
|
map(() => true),
|
||||||
|
startWith(false)
|
||||||
|
)
|
||||||
|
|
||||||
|
// Only emit on mouseUp to prevent emitting when the level decreases due to no user interaction
|
||||||
|
const tiles$ = click$.pipe(
|
||||||
|
switchMap(() =>
|
||||||
|
merge(
|
||||||
|
of(Math.floor(lerp(MIN_TILES_PER_CLICK, MAX_TILES_PER_CLICK, $cubibRelativeLevel$))),
|
||||||
|
timer(MAX_LIFESPAN_TILE)
|
||||||
|
)
|
||||||
|
),
|
||||||
|
scan(
|
||||||
|
(acc, value) => (value === 0 ? [] : [...acc, ...Array.from({ length: value }, () => 1)]),
|
||||||
|
[]
|
||||||
|
),
|
||||||
|
startWith([])
|
||||||
|
)
|
||||||
|
|
||||||
|
$: hue = lerp(200, 130, $cubibRelativeLevel$)
|
||||||
|
$: scale = lerp(0.9, 2, $cubibRelativeLevel$)
|
||||||
|
|
||||||
|
/** @type {HTMLDivElement} */
|
||||||
|
let containerElement
|
||||||
|
|
||||||
|
const vaxrySize = 220
|
||||||
|
const contextId = Symbol('hypractive context')
|
||||||
|
setContext(contextId, {
|
||||||
|
biggestSize: vaxrySize * 1.2, // Make it lighter to drag
|
||||||
|
getSectionElement: () => containerElement
|
||||||
|
})
|
||||||
|
|
||||||
|
function onClick() {
|
||||||
|
click$.next(1)
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div class="relative overflow-visible">
|
||||||
|
<button
|
||||||
|
class="flex hover:underline text-slate-400 gap-3 font-bold items-center active:scale-95 transition-colors drop-shadow-lg shadow-black"
|
||||||
|
on:click={onClick}
|
||||||
|
style:color={$relativeLevel$ > 0 ? `hsl(${hue} 64% 53%)` : undefined}
|
||||||
|
style:scale={$relativeLevel$ > 0 ? scale : undefined}
|
||||||
|
>
|
||||||
|
<ActiveGitIcon class="h-8 w-8" />
|
||||||
|
<span class="transition-colors"> Hypractive development </span>
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<div class="absolute left-1/2 top-1/2 -z-10 pointer-events-none">
|
||||||
|
{#each $tiles$ as _}
|
||||||
|
<GitTile
|
||||||
|
lifeSpan={lerp(MIN_LIFESPAN_TILE, MAX_LIFESPAN_TILE, $cubibRelativeLevel$)}
|
||||||
|
maxSpeed={lerp(10, 38, $expoRelativeLevel$)}
|
||||||
|
minSpeed={lerp(1, 9, $expoRelativeLevel$)}
|
||||||
|
/>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="mask" bind:this={containerElement}>
|
||||||
|
{#if $hasAscended$}
|
||||||
|
<div
|
||||||
|
class="animate-in slide-in-from-bottom-[500px] fade-in-0 slide-in-from-left-20 [animation-duration:2.5s] vaxx-wrapper zoom-in-95 absolute bottom-[240px] left-1/2 z-50 -translate-x-[100px] rounded-full aspect-square"
|
||||||
|
style:width={vaxrySize + 'px'}
|
||||||
|
>
|
||||||
|
<DiscordProfilePicture
|
||||||
|
image={VaxryImage}
|
||||||
|
size={vaxrySize}
|
||||||
|
coordinates={[0, 0]}
|
||||||
|
class="outline-orange-300"
|
||||||
|
{contextId}
|
||||||
|
isAnimating={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
|
||||||
|
<!-- Rising sun -->
|
||||||
|
<div
|
||||||
|
class="bg-gradient"
|
||||||
|
style:opacity={$hasAscended$ ? 1 : $relativeLevel$}
|
||||||
|
style="--relativeLevel: {$hasAscended$ ? 1 : $expoRelativeLevel$ - 0.2}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style lang="postcss">
|
||||||
|
.bg-gradient {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -100%;
|
||||||
|
left: 50%;
|
||||||
|
translate: -50% calc(var(--relativeLevel) * -60%);
|
||||||
|
z-index: -10;
|
||||||
|
transition:
|
||||||
|
opacity 550ms,
|
||||||
|
translate 1.5s ease-in;
|
||||||
|
background: radial-gradient(
|
||||||
|
closest-side,
|
||||||
|
theme(colors.yellow.200),
|
||||||
|
theme(colors.orange.300 / 50%),
|
||||||
|
theme(colors.red.800 / 0%)
|
||||||
|
);
|
||||||
|
width: 150vw;
|
||||||
|
height: 800px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vaxx-wrapper {
|
||||||
|
animation-timing-function: cubic-bezier(0.05, -0.82, 0.165, 1);
|
||||||
|
pointer-events: auto;
|
||||||
|
filter: drop-shadow(0px 0px 10px theme(colors.orange.200))
|
||||||
|
drop-shadow(0px 0px 40px theme(colors.orange.300));
|
||||||
|
}
|
||||||
|
|
||||||
|
.mask {
|
||||||
|
position: absolute;
|
||||||
|
pointer-events: none;
|
||||||
|
bottom: 0%;
|
||||||
|
z-index: 10;
|
||||||
|
left: 50%;
|
||||||
|
translate: -50% 0%;
|
||||||
|
width: 150vw;
|
||||||
|
height: 1000px;
|
||||||
|
/* background: linear-gradient(0deg, black 50%, white 50%); */
|
||||||
|
/* mask-image: linear-gradient(0deg, transparent 50%, white 50%); */
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -23,16 +23,16 @@
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="flex flex-col md:flex-row md:gap-4 gap-2 items-center">
|
<div class="flex group flex-col md:flex-row md:gap-4 gap-2 items-center">
|
||||||
<div
|
<div
|
||||||
class="flex flex-col gap-3 justify-center items-center text-primary text-lg font-medium rounded-full w-32 h-32"
|
class="flex group-focus-within:-translate-y-1 transition-transform flex-col gap-3 justify-center items-center text-primary text-lg font-medium rounded-full w-32 h-32"
|
||||||
>
|
>
|
||||||
<img src={image} alt="Arch Logo" />{name}
|
<img src={image} alt="Arch Logo" />{name}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex flex-col relative font-mono mb-2">
|
<div class="flex flex-col relative font-mono mb-2">
|
||||||
<button
|
<button
|
||||||
class="flex text-base transition-all min-w-[18rem] items-center font-medium rounded-full border-primary border py-3 pl-6 pr-6 gap-4 justify-center group active:scale-[1.01]"
|
class="flex text-base transition-transform min-w-[18rem] items-center font-medium rounded-full border-primary border py-3 pl-6 pr-6 gap-4 justify-center active:scale-[1.01]"
|
||||||
on:click={$$slots.default ? undefined : copyCommand}
|
on:click={$$slots.default ? undefined : copyCommand}
|
||||||
>
|
>
|
||||||
<slot>
|
<slot>
|
||||||
|
@ -42,14 +42,14 @@
|
||||||
<span>{command}</span>
|
<span>{command}</span>
|
||||||
</div>
|
</div>
|
||||||
<ClipboardIcon
|
<ClipboardIcon
|
||||||
class="group-hover:opacity-80 group-active:opacity-100 opacity-0 w-6 h-6 hover:!opacity-100 transition-opacity"
|
class="group-hover:opacity-80 text-white group-active:opacity-100 opacity-0 w-6 h-6 hover:!opacity-100 transition-opacity duration-100"
|
||||||
/>
|
/>
|
||||||
</div></slot
|
</div>
|
||||||
>
|
</slot>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="text-green-400 [translate:-50%_0px] select-none pointer-events-none absolute -top-8 w-full left-1/2 hidden max-w-max"
|
class="text-green-400 [translate:-50%_0px] select-none pointer-events-none absolute md:-top-8 max-md:-bottom-6 bg-black/10 backdrop-blur rounded-full z-20 px-2 w-full left-1/2 hidden max-w-max"
|
||||||
class:copy={isShowingCopied}
|
class:copy={isShowingCopied}
|
||||||
>
|
>
|
||||||
Copied to clipboard ✔
|
Copied to clipboard ✔
|
||||||
|
|
|
@ -10,31 +10,44 @@
|
||||||
import Title from '$lib/components/Title.svelte'
|
import Title from '$lib/components/Title.svelte'
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section>
|
<section class="pb-6">
|
||||||
<Title class="mb-8">
|
<Title class="mb-8">
|
||||||
<span slot="title">Install now</span><span slot="subtitle"> For your favourite distro </span>
|
<span slot="title">Install now</span><span slot="subtitle"> For your favourite distro </span>
|
||||||
</Title>
|
</Title>
|
||||||
|
|
||||||
<div class="flex flex-col md:gap-6 gap-12 items-center" use:animateIn={{ slide: 24, fade: 0 }}>
|
<div class="flex flex-col md:gap-6 gap-12 items-center" use:animateIn={{ slide: 24, fade: 0 }}>
|
||||||
<InstallButton name="Arch" command="pacman -S hyprland" image={archLogo}
|
<div
|
||||||
><div slot="extra">
|
class="md:outline md:outline-1 flex flex-col gap-12 md:gap-6 md:outline-blue-500 md:from-blue-500/40 md:to-transparent md:bg-gradient-to-tr md:shadow-xl md:p-8 md:rounded-3xl"
|
||||||
AUR git version: <a href="https://aur.archlinux.org/packages/hyprland-git/">hyprland-git</a>
|
|
||||||
</div></InstallButton
|
|
||||||
>
|
|
||||||
<InstallButton name="NixOs" image={nixLogo}
|
|
||||||
><a
|
|
||||||
href="https://wiki.hyprland.org/Nix/"
|
|
||||||
target="_blank"
|
|
||||||
class="flex gap-4 items-center justify-between w-full">See instructions <LinkOutIcon /></a
|
|
||||||
></InstallButton
|
|
||||||
>
|
|
||||||
<InstallButton name="FreeBSD" command="pkg install hyprland" image={bsdLogo} />
|
|
||||||
<InstallButton name="openSuse" command="zypper in hyprland" image={suseLogo}
|
|
||||||
><div slot="extra">or install “hyprland” via YaST2 Software.</div></InstallButton
|
|
||||||
>
|
>
|
||||||
|
<InstallButton name="Arch" command="pacman -S hyprland" image={archLogo}
|
||||||
|
><div slot="extra">
|
||||||
|
AUR git version: <a
|
||||||
|
class="hover:underline hover:text-white"
|
||||||
|
target="_blank"
|
||||||
|
href="https://aur.aachlinux.org/packages/hyprland-git/">hyprland-git</a
|
||||||
|
>
|
||||||
|
</div></InstallButton
|
||||||
|
>
|
||||||
|
<InstallButton name="NixOs" image={nixLogo}
|
||||||
|
><a
|
||||||
|
href="https://wiki.hyprland.org/Nix/"
|
||||||
|
target="_blank"
|
||||||
|
class="flex hover:underline gap-4 items-center justify-between w-full"
|
||||||
|
>See instructions <LinkOutIcon /></a
|
||||||
|
></InstallButton
|
||||||
|
>
|
||||||
|
<InstallButton name="FreeBSD" command="pkg install hyprland" image={bsdLogo} />
|
||||||
|
<InstallButton name="openSuse" command="zypper in hyprland" image={suseLogo}
|
||||||
|
><div slot="extra">or install “hyprland” via YaST2 Software.</div></InstallButton
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
<a href="https://wiki.hyprland.org/Getting-Started/Installation/#packages" class="mt-10">
|
<a
|
||||||
<Button size="lg" type="fancyOutline">Install more</Button>
|
target="_blank"
|
||||||
|
href="https://wiki.hyprland.org/Getting-Started/Installation/#packages"
|
||||||
|
class="mt-10"
|
||||||
|
>
|
||||||
|
<Button size="lg" type="fancyOutline">Install other</Button>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { page } from '$app/stores'
|
import { page } from '$app/stores'
|
||||||
import logo from '$lib/images/logo.png'
|
import logo from '$lib/images/logos/hyprland-color.svg'
|
||||||
import GithubIcon from '~icons/ri/github-fill'
|
import GithubIcon from '~icons/ri/github-fill'
|
||||||
import DiscordIcon from '~icons/prime/discord'
|
import DiscordIcon from '~icons/prime/discord'
|
||||||
import MenuIcon from '~icons/mingcute/menu-line'
|
import MenuIcon from '~icons/mingcute/menu-line'
|
||||||
|
@ -18,9 +18,10 @@
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
href="/"
|
href="/"
|
||||||
class="flex gap-2 font-london tracking-wider lg:px-4 py-1 text-sm rounded-full lg:bg-black/50 items-center font-bold text-white"
|
class="flex gap-4 font-london tracking-wider lg:px-4 py-1 text-sm rounded-full lg:bg-black/10 items-center lg:backdrop-blur font-bold text-white"
|
||||||
>
|
>
|
||||||
<img src={logo} alt="Hyprland Logo" class="w-6" /><span class="lg:block hidden">Hyprland</span
|
<img src={logo} alt="Hyprland Logo" class="w-6" /><span
|
||||||
|
class="lg:block lg:mt-1 tracking-widest text-xl hidden">Hyprland</span
|
||||||
></a
|
></a
|
||||||
>
|
>
|
||||||
|
|
||||||
|
@ -46,7 +47,7 @@
|
||||||
<a href="https://wiki.hyprland.org">Wiki</a>
|
<a href="https://wiki.hyprland.org">Wiki</a>
|
||||||
</li>
|
</li>
|
||||||
<li aria-current={$page.url.pathname === '/about' ? 'page' : undefined}>
|
<li aria-current={$page.url.pathname === '/about' ? 'page' : undefined}>
|
||||||
<a href="/#">Wall of fame</a>
|
<a href="/wall_of_fame">Wall of fame</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul
|
<ul
|
||||||
|
@ -90,7 +91,7 @@
|
||||||
|
|
||||||
/* Desktop classes */
|
/* Desktop classes */
|
||||||
@media screen(lg) {
|
@media screen(lg) {
|
||||||
@apply relative flex-row rounded-full p-6 pl-5;
|
@apply relative flex h-min w-max flex-row rounded-full bg-black/40 p-2 pl-5 outline outline-primary/10;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
<script>
|
|
||||||
import { inview } from 'svelte-inview'
|
import { inview } from 'svelte-inview'
|
||||||
import previewRice from '$lib/videos/end_4_rice_intro.mp4'
|
import previewRice from '$lib/videos/end_4_rice_intro.mp4'
|
||||||
import previewRiceThumbnail from '$lib/videos/end_4_thumbnail.png'
|
import previewRiceThumbnail from '$lib/videos/end_4_thumbnail.png'
|
||||||
import AudioIcon from '~icons/mingcute/volume-line'
|
import AudioIcon from '~icons/mingcute/volume-line'
|
||||||
import MuteIcon from '~icons/mingcute/volume-mute-line'
|
import MuteIcon from '~icons/mingcute/volume-mute-line'
|
||||||
|
import PauseIcon from '~icons/mingcute/pause-circle-line'
|
||||||
import clsx from 'clsx'
|
import clsx from 'clsx'
|
||||||
|
import { onMount } from 'svelte'
|
||||||
|
import { getIsMobile } from '$lib/Helper.mjs'
|
||||||
|
|
||||||
/** @type HTMLVideoElement */
|
/** @type HTMLVideoElement */
|
||||||
let videoElement
|
let videoElement
|
||||||
|
@ -12,21 +14,37 @@
|
||||||
let isVisible = false
|
let isVisible = false
|
||||||
let isShowingControls = false
|
let isShowingControls = false
|
||||||
let isMuted = true
|
let isMuted = true
|
||||||
|
let isPaused = false
|
||||||
|
|
||||||
|
$: console.log({ isVisible })
|
||||||
|
|
||||||
function toggleMute() {
|
function toggleMute() {
|
||||||
isMuted = !isMuted
|
isMuted = !isMuted
|
||||||
}
|
}
|
||||||
function togglePlay() {
|
function togglePlay() {
|
||||||
videoElement.paused ? videoElement.play() : videoElement.pause()
|
videoElement.paused ? videoElement.play() : videoElement.pause()
|
||||||
|
isPaused = videoElement.paused
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeFullscreen() {
|
||||||
|
videoElement.requestFullscreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const isMobile = getIsMobile()
|
||||||
|
|
||||||
|
if (isMobile) {
|
||||||
|
//
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<section
|
<section
|
||||||
class="max-w-7xl px-1 -mb-4 lg:px-8 w-full relative animate-in [animation-delay:1700ms] fade-in-0 fill-mode-backwards [animation-duration:2000ms] slide-in-from-bottom-10 z-20 {$$restProps.class}"
|
class="max-w-[1400px] px-1 relative -mb-4 lg:px-8 w-full animate-in [animation-delay:1700ms] fade-in-0 fill-mode-backwards [animation-duration:2000ms] slide-in-from-bottom-10 {$$restProps.class}"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class={clsx(
|
class={clsx(
|
||||||
'rounded-xl group overflow-hidden border-sky-400 border-2 transition-all [transition-duration:1460ms] mx-3',
|
'rounded-xl group relative overflow-hidden border-sky-400 border-2 transition-all [transition-duration:1460ms] mx-3 shadow-2xl shadow-cyan-400/40',
|
||||||
!isVisible && 'opacity-20 scale-90'
|
!isVisible && 'opacity-20 scale-90'
|
||||||
)}
|
)}
|
||||||
role="banner"
|
role="banner"
|
||||||
|
@ -39,6 +57,7 @@
|
||||||
isVisible = false
|
isVisible = false
|
||||||
videoElement.pause()
|
videoElement.pause()
|
||||||
}}
|
}}
|
||||||
|
on:inview_leave={() => (isVisible = false)}
|
||||||
on:mouseenter={() => (isShowingControls = true)}
|
on:mouseenter={() => (isShowingControls = true)}
|
||||||
on:mouseleave={() => (isShowingControls = false)}
|
on:mouseleave={() => (isShowingControls = false)}
|
||||||
>
|
>
|
||||||
|
@ -52,6 +71,7 @@
|
||||||
preload="auto"
|
preload="auto"
|
||||||
poster={previewRiceThumbnail}
|
poster={previewRiceThumbnail}
|
||||||
on:click={togglePlay}
|
on:click={togglePlay}
|
||||||
|
on:dblclick={makeFullscreen}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
class={clsx(
|
class={clsx(
|
||||||
|
@ -60,7 +80,7 @@
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
class="absolute p-2 h-10 bg-black/5 rounded-full w-10 bottom-4 right-8 opacity-70 hover:opacity-100"
|
class="absolute p-2 h-10 bg-black/5 rounded-full w-10 bottom-4 right-4 opacity-70 hover:opacity-100"
|
||||||
on:click|stopPropagation={toggleMute}
|
on:click|stopPropagation={toggleMute}
|
||||||
>
|
>
|
||||||
{#if isMuted}
|
{#if isMuted}
|
||||||
|
@ -69,15 +89,22 @@
|
||||||
<AudioIcon class="h-full w-full" />
|
<AudioIcon class="h-full w-full" />
|
||||||
{/if}
|
{/if}
|
||||||
</button>
|
</button>
|
||||||
|
{#if isPaused}
|
||||||
|
<div
|
||||||
|
class="absolute h-14 rounded-full -translate-x-1/2 -translate-y-1/2 w-14 top-1/2 left-1/2 opacity-80 hover:opacity-100 pointer-events-none"
|
||||||
|
>
|
||||||
|
<PauseIcon class="h-full w-full" />
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="preview-rice-bg" aria="hidden" />
|
<div class="preview-rice-bg overflow-x-hidden" aria="hidden" />
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
.preview-rice-bg {
|
.preview-rice-bg {
|
||||||
@apply absolute inset-0 -top-20 -z-10 w-screen opacity-50;
|
@apply absolute inset-0 -top-40 -z-10 w-full opacity-50;
|
||||||
/* background-color: red; */
|
/* background-color: red; */
|
||||||
background-image: radial-gradient(min(150vw, 1400px) 50%, theme(colors.sky.500), transparent);
|
background-image: radial-gradient(closest-side, theme(colors.sky.500), transparent);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
<div class="px-4 -mb-40 z-20">
|
<div class="px-4 -mb-40 z-20">
|
||||||
<Title>
|
<Title>
|
||||||
<span slot="pre"> Memorials of the ricing legends </span>
|
<span slot="pre"> Memorials of the ricing legends </span>
|
||||||
<span slot="title">Hall of Fame</span>
|
<span slot="title">Wall of Fame</span>
|
||||||
</Title>
|
</Title>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -20,23 +20,23 @@
|
||||||
class="w-full -mt-24 max-w-[1100px] flex relative flex-col gap-16 lg:gap-24 items-center justify-end overflow-hidden md:px-16 [perspective:100px]"
|
class="w-full -mt-24 max-w-[1100px] flex relative flex-col gap-16 lg:gap-24 items-center justify-end overflow-hidden md:px-16 [perspective:100px]"
|
||||||
use:animateIn={{ slide: 24, fade: 0.5, duration: 800 }}
|
use:animateIn={{ slide: 24, fade: 0.5, duration: 800 }}
|
||||||
>
|
>
|
||||||
<a class="absolute bottom-24 left-1/2 z-20 -translate-x-1/2" href="/#">
|
<a class="absolute bottom-24 left-1/2 z-20 -translate-x-1/2" href="/wall_of_fame">
|
||||||
<Button size="lg" type="fancyOutline">Go to Hall of Fame</Button>
|
<Button size="lg" type="fancyOutline">Go to Wall of Fame</Button>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="bg-blue-500 w-full [translate:0px_0px_-100px] aspect-square rounded-[50%] absolute top-0 inset-x-0 -z-30 blur-[200px]"
|
class="w-full [translate:0px_40px_-10px] md:[translate:0px_0px_-40px] absolute top-0 inset-0 -z-30 atmosphere"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<FameRicePreview
|
<FameRicePreview
|
||||||
image="/imgs/ricingcomp1/lauroro.jpg"
|
image="/imgs/ricingcomp1/lauroro.jpg"
|
||||||
containerClass="[translate:0px_0px_-100px] -mb-[30%] hover:[translate:0px_0px_-98px] transition-all duration-500"
|
containerClass="[translate:0px_50px_-100px] -mb-[30%] hover:[translate:0px_0px_-98px] transition-all duration-500"
|
||||||
imageClass="[mask-image:linear-gradient(black,black_45%,transparent_65%)] opacity-50 hover:opacity-60"
|
imageClass="[mask-image:linear-gradient(black,black_45%,transparent_65%)] opacity-50 hover:opacity-60"
|
||||||
/>
|
/>
|
||||||
<FameRicePreview
|
<FameRicePreview
|
||||||
image="/imgs/ricingcomp1/amadeus.png"
|
image="/imgs/ricingcomp1/amadeus.png"
|
||||||
containerClass="[translate:0px_0px_-40px] hover:[translate:0px_0px_-38px] -mb-[30%] duration-500 transition-all group"
|
containerClass="[translate:0px_50px_-40px] hover:[translate:0px_0px_-38px] -mb-[30%] duration-500 transition-all group"
|
||||||
imageClass="[mask-image:linear-gradient(black,black_50%,transparent_75%)] opacity-80 group-hover:opacity-100 transition-all duration-500"
|
imageClass="md:[mask-image:linear-gradient(black,black_50%,transparent_75%)] [mask-image:linear-gradient(black,black_10%,transparent_75%)] opacity-80 group-hover:opacity-100 transition-all duration-500"
|
||||||
/>
|
/>
|
||||||
<FameRicePreview
|
<FameRicePreview
|
||||||
image="/imgs/ricingcomp1/flicko.png"
|
image="/imgs/ricingcomp1/flicko.png"
|
||||||
|
@ -48,8 +48,12 @@
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<style lang="postcss">
|
<style lang="postcss">
|
||||||
|
.atmosphere {
|
||||||
|
background: radial-gradient(closest-side, theme(colors.blue.500), transparent);
|
||||||
|
}
|
||||||
|
|
||||||
.glow {
|
.glow {
|
||||||
@apply h-[200px] lg:h-[400px];
|
@apply h-[400px] lg:h-[400px];
|
||||||
width: 100%;
|
width: 100%;
|
||||||
/* min-width: 8800px; */
|
/* min-width: 8800px; */
|
||||||
position: absolute;
|
position: absolute;
|
|
@ -39,6 +39,15 @@ body {
|
||||||
border-radius: 24px;
|
border-radius: 24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* optimize mobile */
|
||||||
|
.animate-in,
|
||||||
|
.animate-out,
|
||||||
|
.ani-in {
|
||||||
|
@media only screen and (max-width: 640px) {
|
||||||
|
animation: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@keyframes pop {
|
@keyframes pop {
|
||||||
0% {
|
0% {
|
||||||
scale: 0.98;
|
scale: 0.98;
|
||||||
|
|
1
src/routes/wall_of_fame/+page.js
Executable file
1
src/routes/wall_of_fame/+page.js
Executable file
|
@ -0,0 +1 @@
|
||||||
|
export const prerender = true
|
7
src/routes/wall_of_fame/+page.svelte
Executable file
7
src/routes/wall_of_fame/+page.svelte
Executable file
|
@ -0,0 +1,7 @@
|
||||||
|
<div class="h-screen flex items-center justify-center p-8 overflow-hidden">
|
||||||
|
<img
|
||||||
|
src="https://i.giphy.com/media/H8w9SE95izloQ/giphy.webp"
|
||||||
|
alt="Under construction"
|
||||||
|
class="w-full max-w-4xl"
|
||||||
|
/>
|
||||||
|
</div>
|
Loading…
Reference in a new issue