feature cards, hall of fame
|
@ -3,12 +3,15 @@ module.exports = {
|
|||
extends: ['eslint:recommended', 'plugin:svelte/recommended', 'prettier'],
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
ecmaVersion: 2020,
|
||||
ecmaVersion: 'latest',
|
||||
extraFileExtensions: ['.svelte']
|
||||
},
|
||||
env: {
|
||||
browser: true,
|
||||
es2017: true,
|
||||
node: true
|
||||
},
|
||||
rules: {
|
||||
'no-unused-vars': ['off', { varsIgnorePattern: '.*' }]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -10,8 +10,9 @@ feel free
|
|||
|
||||
## Requirements
|
||||
|
||||
Install [ `Git LFS` ](https://git-lfs.com) on your system.
|
||||
`pnpm` for package management.
|
||||
|
||||
## Credits
|
||||
|
||||
[VDawg](https://github.com/Visual-Dawg) - for the updated site and design
|
||||
[System-x64](https://github.com/System-x64) - for the original site code
|
||||
|
|
|
@ -5,18 +5,12 @@ settings:
|
|||
excludeLinksFromLockfile: false
|
||||
|
||||
dependencies:
|
||||
'@chriscourses/perlin-noise':
|
||||
specifier: ^1.0.5
|
||||
version: 1.0.5
|
||||
clsx:
|
||||
specifier: ^1.2.1
|
||||
version: 1.2.1
|
||||
simplex-noise:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1
|
||||
svelte-intersection-observer-action:
|
||||
specifier: ^0.0.4
|
||||
version: 0.0.4
|
||||
svelte-inview:
|
||||
specifier: ^4.0.1
|
||||
version: 4.0.1(svelte@4.0.1)
|
||||
|
@ -112,10 +106,6 @@ packages:
|
|||
resolution: {integrity: sha512-dlR6LdS+0SzOAPx/TPRhnoi7hE251OVeT2Snw0RguNbBSbjUHdWr0l3vcUUDg26rEysT89kCbtw1lVorBXLLCg==}
|
||||
dev: false
|
||||
|
||||
/@chriscourses/perlin-noise@1.0.5:
|
||||
resolution: {integrity: sha512-AjIAlGT1M1Pc4/P3MkztzETXRI/LyGMl/fRglbY/Vgdb8Sl6Rn/yOd1XiHQD5ftiUev6i33UbReVWI95wtntpg==}
|
||||
dev: false
|
||||
|
||||
/@esbuild/android-arm64@0.17.19:
|
||||
resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==}
|
||||
engines: {node: '>=12'}
|
||||
|
@ -1846,10 +1836,6 @@ packages:
|
|||
svelte: 4.0.1
|
||||
dev: true
|
||||
|
||||
/svelte-intersection-observer-action@0.0.4:
|
||||
resolution: {integrity: sha512-Q2ukfmZI+6Ho7XHwwTq2Z/JLLE7o61cY7DRkW3nGntEkgnlT9ZiaPccm4MI1uYiRMfrYEMYPmB4+U16bJp56Uw==}
|
||||
dev: false
|
||||
|
||||
/svelte-inview@4.0.1(svelte@4.0.1):
|
||||
resolution: {integrity: sha512-8NuT/DKFiZAccDw1Z16cIsdZ7K6/BGxrUfDaFaWTCEdn3YqMj1TUAkfmQ08FQ1+INl1G+TQS+ImXIBiiISgXog==}
|
||||
peerDependencies:
|
||||
|
|
57
src/lib/Helper.mjs
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { inview } from 'svelte-inview'
|
||||
|
||||
// const mappingAnimate = {
|
||||
// slide: 'translate',
|
||||
// zoom: 'scale',
|
||||
// duration: 'transition',
|
||||
// fade: 'opacity'
|
||||
// }
|
||||
|
||||
/**
|
||||
* Fade: The initial opacity from 0 to 1.
|
||||
*
|
||||
* Zoom: The scale from 0 to 1.
|
||||
*
|
||||
* Slide: Slide in in pixels.
|
||||
*
|
||||
* @param {{fade?: number, zoom?: number, slide?: number, duration?: number, threshold?: number}} options
|
||||
* @param { HTMLElement } node
|
||||
* @returns
|
||||
*/
|
||||
export function animateIn(node, options) {
|
||||
const observer = inview(node, { unobserveOnEnter: true, threshold: options.threshold ?? 0.4 })
|
||||
|
||||
options.duration ??= 840
|
||||
|
||||
const style = Object.entries(options)
|
||||
.map(([effect, value], _, all) => {
|
||||
if (effect === 'slide') return `translate: 0px ${value}px`
|
||||
|
||||
if (effect === 'fade') return `opacity: ${value}`
|
||||
|
||||
if (effect === 'zoom') return `scale: ${value} ${value}`
|
||||
|
||||
if (effect === 'duration') {
|
||||
return `transition: all ${value}ms`
|
||||
}
|
||||
})
|
||||
.join(';')
|
||||
|
||||
node.style = style
|
||||
|
||||
node.addEventListener('inview_enter', callback)
|
||||
|
||||
function callback() {
|
||||
console.log('Callbacked!!')
|
||||
node.style.opacity = '1'
|
||||
node.style.scale = '1 1'
|
||||
node.style.translate = '0 0'
|
||||
}
|
||||
|
||||
return { destroy: observer.destroy }
|
||||
}
|
||||
|
||||
// export function animateIn(styles) {
|
||||
// const inview = inview()
|
||||
// // return ({ details: { invView, scrollDirection: vertical, node } }) => {}
|
||||
// }
|
|
@ -43,11 +43,9 @@
|
|||
transition: transform 180ms cubic-bezier(0.1, -0, 0.42, 1.8);
|
||||
}
|
||||
|
||||
/*!!! FIREFLIES IN THE BACKGROUND */
|
||||
|
||||
.fancy {
|
||||
/* background: rgba(theme(colors.black), 0.8); */
|
||||
background-clip: padding-box;
|
||||
background: theme(colors.black / 50%);
|
||||
/* background-clip: padding-box; */
|
||||
outline: 2px theme(colors.primary) solid;
|
||||
}
|
||||
|
||||
|
|
3
src/lib/components/Footer.svelte
Normal file
|
@ -0,0 +1,3 @@
|
|||
<footer class="h-96 flex items-center p-8 mt-20 border border-blue-500 rounded-3xl mx-8 mb-8">
|
||||
<p>Footer</p>
|
||||
</footer>
|
|
@ -1,4 +1,5 @@
|
|||
<script>
|
||||
import Footer from '$lib/components/Footer.svelte'
|
||||
import Navbar from './Navbar.svelte'
|
||||
import './styles.css'
|
||||
</script>
|
||||
|
@ -10,7 +11,5 @@
|
|||
<slot />
|
||||
</main>
|
||||
|
||||
<footer>
|
||||
<p>Footer</p>
|
||||
</footer>
|
||||
<Footer />
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<script>
|
||||
import Hero from './Hero.svelte';
|
||||
import Community from './Community.svelte'
|
||||
import FeaturesSlice from './FeaturesSlice.svelte'
|
||||
import HallOfFameSlice from './HallOfFameSlice.svelte'
|
||||
import Hero from './Hero.svelte'
|
||||
import PreviewRiceSlice from './PreviewRiceSlice.svelte'
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
|
@ -9,5 +13,19 @@
|
|||
|
||||
<Hero />
|
||||
|
||||
<div class="-mt-8 mx-auto gap-[16rem] flex flex-col items-center">
|
||||
<div class="px-8 lg:px-32">
|
||||
<PreviewRiceSlice />
|
||||
|
||||
<FeaturesSlice />
|
||||
</div>
|
||||
|
||||
<HallOfFameSlice />
|
||||
|
||||
<div class="px-8 lg:px-32"><Community /></div>
|
||||
</div>
|
||||
|
||||
<div class="mt-[16rem]" />
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
9
src/routes/Community.svelte
Normal file
|
@ -0,0 +1,9 @@
|
|||
<script lang="ts">
|
||||
</script>
|
||||
|
||||
<section>
|
||||
<h1 class="text-8xl font-bold text-center mb-8">Join a great community</h1>
|
||||
<div class="text-center font-extrabold text-slate-300">
|
||||
Get help from Distro Hoppers, Haiku writers, Hydrohomies and human_(probably)
|
||||
</div>
|
||||
</section>
|
171
src/routes/FeatureCard.svelte
Normal file
|
@ -0,0 +1,171 @@
|
|||
<script>
|
||||
import clsx from 'clsx'
|
||||
import { getContext } from 'svelte'
|
||||
import { mouseContext } from './FeaturesSlice.svelte'
|
||||
import { spring } from 'svelte/motion'
|
||||
export let title
|
||||
export let color = 'cyan'
|
||||
|
||||
const { x: mouseX, y: mouseY, isHoverCards } = getContext(mouseContext)
|
||||
|
||||
/** @type HTMLDivElement */
|
||||
let container
|
||||
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 borderX = spring(999, { damping: 0.9, stiffness: 0.03, precision: 0.3 })
|
||||
const borderY = spring(999, { damping: 0.9, stiffness: 0.03, precision: 0.3 })
|
||||
|
||||
const bounceBack = 2
|
||||
const soft = 0.8
|
||||
|
||||
let isMouseOver = false
|
||||
|
||||
$: {
|
||||
if (container && $mouseX !== undefined) {
|
||||
updateGradient()
|
||||
}
|
||||
}
|
||||
|
||||
function updateGradient() {
|
||||
const { x: rectX, y: rectY, width, height } = container.getBoundingClientRect()
|
||||
|
||||
const normX = $mouseX - rectX
|
||||
const normY = $mouseY - rectY
|
||||
|
||||
$borderX = normX
|
||||
$borderY = normY
|
||||
|
||||
if (!isMouseOver) {
|
||||
/* Put it in the corners again. As it is scaled by half,
|
||||
coordinates should be multiplied by two. But it looks better when they peek in more */
|
||||
fillX.set(width * 1.5, { soft: 4 })
|
||||
fillY.set(height * 1.5, { soft: 4 })
|
||||
return
|
||||
}
|
||||
|
||||
if ($mouseX < rectX) fillX.set(rectX + bounceBack, { soft })
|
||||
else if ($mouseX > rectX + width) fillX.set(rectX + width - bounceBack, { soft })
|
||||
else fillX.set(normX)
|
||||
|
||||
if ($mouseY < rectY) fillY.set(rectY + bounceBack, { soft: 1 })
|
||||
if ($mouseY > rectY + height) fillX.set(rectY - height - bounceBack, { soft })
|
||||
else fillY.set(normY)
|
||||
}
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={clsx('card min-h-[20rem] ', $$restProps.class)}
|
||||
style:--x={$fillX}
|
||||
style:--y={$fillY}
|
||||
style:--borderX={$borderX}
|
||||
style:--borderY={$borderY}
|
||||
class:isHoverCards={$isHoverCards}
|
||||
bind:this={container}
|
||||
on:mouseenter={() => (isMouseOver = true)}
|
||||
on:mouseleave={() => {
|
||||
isMouseOver = false
|
||||
updateGradient()
|
||||
}}
|
||||
class:purpleGradient={color === 'purple'}
|
||||
role="contentinfo"
|
||||
>
|
||||
<div class="p-12 z-10 w-full h-full">
|
||||
<h1 class="text-5xl font-bold mb-6 text-white">{title}</h1>
|
||||
<slot>Nothing in the slot here</slot>
|
||||
</div>
|
||||
<div class="gradient" />
|
||||
<div class="gradient_black" />
|
||||
<div class="border-gradient" />
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
.card {
|
||||
@apply rounded-3xl relative w-full h-full bg-slate-900 hover:bg-blue-900 duration-300 transition-colors flex items-center justify-center;
|
||||
z-index: 2;
|
||||
contain: paint style layout;
|
||||
}
|
||||
|
||||
.gradient_black {
|
||||
@apply absolute inset-[1px];
|
||||
z-index: 2;
|
||||
border-radius: inherit;
|
||||
contain: strict;
|
||||
background: black
|
||||
radial-gradient(
|
||||
circle at bottom right,
|
||||
theme(colors.neutral.900 / 30%),
|
||||
theme(colors.neutral.500 / 30%),
|
||||
black
|
||||
);
|
||||
}
|
||||
|
||||
.border-gradient {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
border-radius: inherit;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0%;
|
||||
transform-origin: top left;
|
||||
transition: opacity 140ms ease-in-out;
|
||||
left: 0%;
|
||||
top: 0%;
|
||||
content: '';
|
||||
pointer-events: none;
|
||||
contain: strict;
|
||||
background: radial-gradient(
|
||||
320px circle at calc(var(--borderX) * 1px) calc(var(--borderY) * 1px),
|
||||
color-mix(in srgb, var(--color1, theme(colors.cyan.500)), transparent 50%),
|
||||
color-mix(in srgb, var(--color2, theme(colors.blue.500)), transparent 90%)
|
||||
);
|
||||
|
||||
.isHoverCards & {
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.gradient {
|
||||
@apply absolute inset-0 pointer-events-none w-full h-full;
|
||||
width: calc(100% - 2px);
|
||||
border-radius: inherit;
|
||||
height: calc(100% - 2px);
|
||||
border-radius: inherit;
|
||||
margin: 1px;
|
||||
z-index: 20;
|
||||
mix-blend-mode: hard-light;
|
||||
contain: strict;
|
||||
|
||||
/* Gradient */
|
||||
&::before {
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
border-radius: inherit;
|
||||
min-width: 200%;
|
||||
min-height: 200%;
|
||||
aspect-ratio: 1 / 1;
|
||||
scale: 0.5 0.5;
|
||||
translate: -25% 0%;
|
||||
transform-origin: top left;
|
||||
left: 50%;
|
||||
transition: all 820ms;
|
||||
content: '';
|
||||
pointer-events: none;
|
||||
background: radial-gradient(
|
||||
ellipse at calc(var(--x) * 1px) calc(var(--y) * 1px),
|
||||
var(--color1, theme(colors.cyan.500 / 100%)),
|
||||
var(--color2, theme(colors.blue.700 / 40%)) 25%,
|
||||
var(--color3, theme(colors.blue.900 / 15%)) 50%
|
||||
);
|
||||
|
||||
.card:hover & {
|
||||
scale: 1 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.purpleGradient {
|
||||
--color1: theme(colors.purple.400 / 90%);
|
||||
--color2: theme(colors.indigo.800 / 90%);
|
||||
--color3: theme(colors.indigo.800 / 20%);
|
||||
}
|
||||
</style>
|
92
src/routes/FeaturesSlice.svelte
Normal file
|
@ -0,0 +1,92 @@
|
|||
<script context="module">
|
||||
export const mouseContext = Symbol('mouseContext')
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import FeatureCard from './FeatureCard.svelte'
|
||||
import { setContext } from 'svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
import PluginsIcon from '~icons/gg/arrange-back'
|
||||
import ActiveGitIcon from '~icons/gg/git-branch'
|
||||
import ShortcutsIcon from '~icons/gg/push-chevron-right-o'
|
||||
import BleedingEdgeIcon from '~icons/gg/controller'
|
||||
import { animateIn } from '$lib/Helper.mjs'
|
||||
|
||||
const context = setContext(mouseContext, {
|
||||
x: writable(0),
|
||||
y: writable(0),
|
||||
isHoverCards: writable(false)
|
||||
})
|
||||
|
||||
/** @type HTMLDivElement */
|
||||
let featuresContainer
|
||||
|
||||
function onMouseEnter() {
|
||||
featuresContainer.addEventListener('mousemove', trackMouse)
|
||||
context.isHoverCards.set(true)
|
||||
}
|
||||
function onMouseLeave() {
|
||||
featuresContainer.removeEventListener('mousemove', trackMouse)
|
||||
context.isHoverCards.set(false)
|
||||
}
|
||||
function trackMouse({ clientX, clientY }) {
|
||||
context.x.set(clientX)
|
||||
context.y.set(clientY)
|
||||
}
|
||||
</script>
|
||||
|
||||
<section class="flex flex-col items-center">
|
||||
<div use:animateIn={{ fade: 0, slide: 24, duration: 1480, threshold: 0.4 }}>
|
||||
<div class="font-extrabold mb-3 text-slate-300">TLDR</div>
|
||||
<h1 class="text-8xl font-bold mb-14">Features</h1>
|
||||
</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"
|
||||
role="contentinfo"
|
||||
on:mouseenter={onMouseEnter}
|
||||
on:mouseleave={onMouseLeave}
|
||||
bind:this={featuresContainer}
|
||||
>
|
||||
<FeatureCard title="Smooth" class="row-span-2">
|
||||
<p>
|
||||
Transition from windows and workspaces smoothly, without abrupt changes. Instant input with
|
||||
a custom wslroot patch included
|
||||
</p></FeatureCard
|
||||
>
|
||||
<FeatureCard title="Easy to configure" color="purple">
|
||||
<p>
|
||||
Live reloading config. Easy plain-text format. Sensible defaults. Great documentation.
|
||||
</p></FeatureCard
|
||||
>
|
||||
<FeatureCard class="" title="Dynamic tiling">
|
||||
<p>
|
||||
Automatic tiling which just works. Supports multiple fine-tuneable layouts.
|
||||
</p></FeatureCard
|
||||
>
|
||||
</div>
|
||||
|
||||
<div class="mt-14 flex-wrap justify-center flex gap-8">
|
||||
<div class="icon-feature">
|
||||
<PluginsIcon class="h-8 w-8" />
|
||||
Plugin system
|
||||
</div>
|
||||
<div class="icon-feature">
|
||||
<ActiveGitIcon class="h-8 w-8" />
|
||||
Hypractive development
|
||||
</div>
|
||||
<div class="icon-feature">
|
||||
<ShortcutsIcon class="h-8 w-8" />
|
||||
Global shortcuts for apps
|
||||
</div>
|
||||
<div class="icon-feature">
|
||||
<BleedingEdgeIcon class="h-8 w-8" />Bleeding edge tech
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style lang="postcss">
|
||||
.icon-feature {
|
||||
@apply flex gap-3 items-center justify-center font-bold opacity-60;
|
||||
}
|
||||
</style>
|
|
@ -58,7 +58,7 @@
|
|||
</script>
|
||||
|
||||
<div
|
||||
class="absolute p-24 top-0 left-0 firefly pointer-events-auto opacity-50 hover:opacity-100 transition-opacity"
|
||||
class="absolute 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"
|
||||
>
|
||||
<div class="firefly-inner {classes}" />
|
||||
|
|
87
src/routes/HallOfFameSlice.svelte
Normal file
|
@ -0,0 +1,87 @@
|
|||
<script lang="ts">
|
||||
import { animateIn } from '$lib/Helper.mjs'
|
||||
import Button from '$lib/components/Button.svelte'
|
||||
</script>
|
||||
|
||||
<section
|
||||
class="w-full relative"
|
||||
use:animateIn={{ fade: 0, slide: 24, duration: 1200, threshold: 0.1 }}
|
||||
>
|
||||
<div class="text-center font-extrabold mb-3 text-slate-300">Memorials of the ricing legends</div>
|
||||
<h1 class="text-8xl font-bold text-center">Hall of Fame</h1>
|
||||
|
||||
<div
|
||||
class="w-full flex relative flex-col gap-16 lg:gap-24 items-center pt-16 overflow-hidden px-16"
|
||||
>
|
||||
<div class="rice" use:animateIn={{ fade: 0, slide: 24, duration: 1200, threshold: 0.4 }}>
|
||||
<img
|
||||
src="/imgs/env_4 novelknock-10.png"
|
||||
alt="Rice desktop"
|
||||
class="w-full nice-hover rounded-xl overflow-hidden shadow-2xl hover:scale-[1.01]"
|
||||
/>
|
||||
<img
|
||||
src="/imgs/env_4 novelknock-10.png"
|
||||
alt="Rice desktop"
|
||||
aria-hidden="true"
|
||||
class="rice-bg"
|
||||
/>
|
||||
</div>
|
||||
<div class="rice" use:animateIn={{ slide: 48, duration: 1400, threshold: 0.4 }}>
|
||||
<img
|
||||
src="/imgs/ricingcomp1/amadeus.png"
|
||||
alt="Rice desktop"
|
||||
class="w-full rounded-t-xl overflow-hidden nice-hover hover:scale-[1.005] shadow-2xl object-cover object-top h-[200px] sm:h-[250px] lg:h-[500px] ] bottom-rice"
|
||||
/>
|
||||
<img
|
||||
src="/imgs/ricingcomp1/amadeus.png"
|
||||
alt="Rice desktop"
|
||||
aria-hidden="true"
|
||||
class="rice-bg clop"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<a class="absolute bottom-16 left-1/2 z-20 -translate-x-1/2" href="/hall-of-fame">
|
||||
<Button size="lg" type="fancyOutline">Go to Hall of Fame</Button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="glow" />
|
||||
</section>
|
||||
|
||||
<style lang="postcss">
|
||||
.rice {
|
||||
@apply relative w-full max-w-[1100px];
|
||||
}
|
||||
.nice-hover {
|
||||
transition: transform 540ms cubic-bezier(0.1, -0.81, 0.31, 2);
|
||||
}
|
||||
.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;
|
||||
|
||||
.rice:hover & {
|
||||
@apply brightness-200;
|
||||
}
|
||||
}
|
||||
|
||||
.bottom-rice {
|
||||
mask-image: linear-gradient(black, transparent);
|
||||
}
|
||||
|
||||
.glow {
|
||||
@apply h-[200px] lg:h-[400px];
|
||||
width: 100%;
|
||||
/* min-width: 8800px; */
|
||||
position: absolute;
|
||||
opacity: 0.8;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
pointer-events: none;
|
||||
background-image: radial-gradient(
|
||||
ellipse at bottom,
|
||||
theme(colors.cyan.500),
|
||||
theme(colors.blue.700 / 50%) 50%,
|
||||
theme(colors.blue.950 / 0%) 80%
|
||||
);
|
||||
}
|
||||
</style>
|
|
@ -1,28 +1,26 @@
|
|||
<script>
|
||||
/** eslint-disable no-unused-vars */
|
||||
import Button from '$lib/components/Button.svelte'
|
||||
import Logo from '$lib/images/logo.png'
|
||||
import Firefly from './Firefly.svelte'
|
||||
import previewRice from '$lib/videos/prasanthrangan_rice.mp4'
|
||||
import { inview } from 'svelte-inview'
|
||||
|
||||
let isVisible = true
|
||||
/** @type HTMLVideoElement */
|
||||
let videoElement
|
||||
let hadBeenInvisble = false
|
||||
</script>
|
||||
|
||||
<section
|
||||
class="w-full relative flex flex-col items-center justify-center min-h-screen h-max"
|
||||
use:inview
|
||||
on:inview={({ detail: { inView } }) => {
|
||||
on:inview_change={({ detail: { inView } }) => {
|
||||
isVisible = inView
|
||||
hadBeenInvisble = hadBeenInvisble && inView
|
||||
}}
|
||||
>
|
||||
<!-- Hero text and logo -->
|
||||
<div class="flex h-screen min-h-max justify-center flex-col items-center z-10">
|
||||
<div class="ani-in fill-mode-backwards text-center items-center flex flex-col gap-6 mb-8">
|
||||
<img src={Logo} alt="Hyprland Logo" class="w-32 mb-4 logo" />
|
||||
<div class="relative">
|
||||
<div class="text-center 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" />
|
||||
<div class="relative ani-in fill-mode-backwards [animation-delay:584ms]">
|
||||
<h1 class="text-7xl p-2 font-bold bg-clip-text text-transparent hyprgradient">Hyprland</h1>
|
||||
<div
|
||||
aria-hidden="true"
|
||||
|
@ -33,13 +31,13 @@
|
|||
</div>
|
||||
</div>
|
||||
<h2
|
||||
class="ani-in text-center mb-14 [animation-delay:344ms] fill-mode-backwards font-medium text-xl text-blue-200/60"
|
||||
class="ani-in text-center mb-14 [animation-delay:944ms] fill-mode-backwards font-medium text-xl text-blue-200/60"
|
||||
>
|
||||
Dynamic tiling Wayland compositor<br />with the looks.
|
||||
</h2>
|
||||
|
||||
<div
|
||||
class="flex gap-6 items-center animate-in fade-in-0 slide-in-from-bottom-1 [animation-delay:990ms] duration-500 fill-mode-backwards"
|
||||
class="flex gap-6 items-center animate-in fade-in-0 slide-in-from-bottom-4 [animation-delay:1390ms] duration-500 fill-mode-backwards"
|
||||
>
|
||||
<a href="https://wiki.hyprland.org/Getting-Started/Installation/">
|
||||
<Button size="lg">Install</Button>
|
||||
|
@ -48,41 +46,14 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Preview rice -->
|
||||
<div
|
||||
class="max-w-7xl relative mx-6 -mt-12 animate-in [animation-delay:1400ms] fade-in-0 fill-mode-backwards [animation-duration:1700ms] zoom-in-75"
|
||||
>
|
||||
<div
|
||||
class="rounded-xl opacity-20 overflow-hidden border-purple-400 border-2 scale-90 transition-all duration-1000"
|
||||
use:inview={{ unobserveOnEnter: true, threshold: 0.8 }}
|
||||
on:inview_enter={({ detail: { node } }) => {
|
||||
node.classList.remove('opacity-20')
|
||||
node.classList.remove('scale-90')
|
||||
videoElement.play()
|
||||
}}
|
||||
>
|
||||
<!--TODO Play and scale up on enter -->
|
||||
<video
|
||||
bind:this={videoElement}
|
||||
src={previewRice}
|
||||
disablepictureinpicture="true"
|
||||
disableremoteplayback="true"
|
||||
loop
|
||||
muted
|
||||
preload="auto"
|
||||
/>
|
||||
</div>
|
||||
<div class="preview-rice-bg" aria="hidden" />
|
||||
</div>
|
||||
|
||||
<!-- Fireflies -->
|
||||
{#if isVisible}
|
||||
<div
|
||||
class="absolute animate-in fade-in-0 duration-75 pointer-events-none max-w-screen inset-0 overflow-hidden z-0"
|
||||
>
|
||||
<!--!FIXME jaggy when hitting bottom edge -->
|
||||
<div class="bg-gradient-to-t from-black z-10 w-full h-52 absolute bottom-0" />
|
||||
|
||||
{#await new Promise((resolve) => setTimeout(() => resolve(), 940)) then _}
|
||||
{#await new Promise( (resolve) => setTimeout(() => resolve(), hadBeenInvisble ? 0 : 1440) ) then _}
|
||||
{#each { length: 40 } as _}
|
||||
<Firefly />
|
||||
{/each}
|
||||
|
@ -92,7 +63,7 @@
|
|||
|
||||
<!-- Gradient background -->
|
||||
<div
|
||||
class="absolute -z-50 animate-in fade-in-75 duration-150 max-w-screen w-screen min-h-screen h-full right-0 top-0 overflow-hidden"
|
||||
class="absolute -z-50 max-w-screen w-screen min-h-screen h-full right-0 top-0 overflow-hidden"
|
||||
>
|
||||
<div class="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2">
|
||||
<div
|
||||
|
@ -118,32 +89,13 @@
|
|||
animation: move var(--duration, 50s) ease-in-out var(--offset, 0ms) infinite alternate both;
|
||||
}
|
||||
|
||||
.logo {
|
||||
animation: logo 6s cubic-bezier(0.4, 0, 0.6, 1) infinite alternate;
|
||||
}
|
||||
.title-shadow {
|
||||
text-shadow: 8px 9px 32px theme(colors.secondary / 30%),
|
||||
-8px -9px 32px theme(colors.primary / 50%), 1px 0px 3px theme(colors.purple.500 / 50%),
|
||||
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;
|
||||
}
|
||||
|
||||
.preview-rice-bg {
|
||||
@apply w-full h-full absolute -z-10 -top-20 inset-x-0;
|
||||
/* background-color: red; */
|
||||
background-image: radial-gradient(closest-side, theme(colors.purple.500), transparent);
|
||||
}
|
||||
|
||||
@keyframes logo {
|
||||
from {
|
||||
opacity: 80%;
|
||||
}
|
||||
to {
|
||||
opacity: 100%;
|
||||
transform: scale(1.03) translateY(12px);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes title_effect {
|
||||
0% {
|
||||
transform: translateX(-99px);
|
||||
|
@ -199,6 +151,6 @@
|
|||
}
|
||||
|
||||
.ani-in {
|
||||
@apply animate-in slide-in-from-bottom-4 fade-in-0 zoom-in-95 duration-700;
|
||||
@apply animate-in ease-in-out slide-in-from-bottom-4 fade-in-0 [animation-duration:800ms];
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</script>
|
||||
|
||||
<header
|
||||
class="flex items-center p-1 z-10 justify-between text-blue-300 bg-black/50 fixed inset-4 h-7 rounded-full backdrop-blur animate-in slide-in-from-top-1 [animation-delay:1250ms] fade-in-0 duration-1000 fill-mode-backwards"
|
||||
class="flex items-center z-40 p-1 justify-between text-blue-300 bg-black/50 fixed inset-4 h-7 rounded-full backdrop-blur animate-in slide-in-from-top-1 [animation-delay:1250ms] fade-in-0 duration-1000 fill-mode-backwards"
|
||||
>
|
||||
<a href="/" class="flex gap-2 pl-2 text-sm items-center font-bold tracking-wide text-white">
|
||||
<img src={logo} alt="Hyprland Logo" class="w-6" />Hyprland</a
|
||||
|
|
41
src/routes/PreviewRiceSlice.svelte
Normal file
|
@ -0,0 +1,41 @@
|
|||
<script>
|
||||
import { inview } from 'svelte-inview'
|
||||
import previewRice from '$lib/videos/prasanthrangan_rice.mp4'
|
||||
|
||||
/** @type HTMLVideoElement */
|
||||
let videoElement
|
||||
</script>
|
||||
|
||||
<section
|
||||
class="max-w-7xl relative animate-in [animation-delay:1700ms] fade-in-0 fill-mode-backwards [animation-duration:2000ms] slide-in-from-bottom-10 z-20 {$$restProps.class}"
|
||||
>
|
||||
<div
|
||||
class="rounded-xl opacity-20 overflow-hidden border-purple-400 border-2 scale-90 transition-all [transition-duration:1460ms]"
|
||||
use:inview={{ unobserveOnEnter: true, threshold: 0.8 }}
|
||||
on:inview_enter={({ detail: { node } }) => {
|
||||
node.classList.remove('opacity-20')
|
||||
node.classList.remove('scale-90')
|
||||
// videoElement.play()
|
||||
}}
|
||||
>
|
||||
<!--TODO Play and scale up on enter -->
|
||||
<video
|
||||
bind:this={videoElement}
|
||||
src={previewRice}
|
||||
disablepictureinpicture="true"
|
||||
disableremoteplayback="true"
|
||||
loop
|
||||
muted
|
||||
preload="auto"
|
||||
/>
|
||||
</div>
|
||||
<div class="preview-rice-bg" aria="hidden" />
|
||||
</section>
|
||||
|
||||
<style lang="postcss">
|
||||
.preview-rice-bg {
|
||||
@apply w-screen max-w-7xl h-full absolute -z-10 -top-20 left-1/2 -translate-x-1/2 opacity-50;
|
||||
/* background-color: red; */
|
||||
background-image: radial-gradient(closest-side, theme(colors.purple.500), transparent);
|
||||
}
|
||||
</style>
|
|
@ -56,18 +56,15 @@ body {
|
|||
/* prettier-ignore */
|
||||
@keyframes x {
|
||||
0%,16.667%,to { opacity: 1 }
|
||||
|
||||
33%,83.333% { opacity: 0 }
|
||||
}
|
||||
/* prettier-ignore */
|
||||
@keyframes y {
|
||||
0%,16.667%,66.667%,to { opacity: 0 }
|
||||
|
||||
33.333%,50% { opacity: 1 }
|
||||
}
|
||||
/* prettier-ignore */
|
||||
@keyframes z {
|
||||
0%,50%,to { opacity: 0 }
|
||||
|
||||
66.667%,83.333% { opacity: 1 }
|
||||
}
|
||||
|
|
BIN
static/imgs/404.png
Normal file
After Width: | Height: | Size: 17 KiB |
BIN
static/imgs/env_4 novelknock-10.png
Normal file
After Width: | Height: | Size: 1.8 MiB |
BIN
static/imgs/hyprland.png
Normal file
After Width: | Height: | Size: 76 KiB |
BIN
static/imgs/img1.png
Normal file
After Width: | Height: | Size: 980 KiB |
BIN
static/imgs/img2.png
Normal file
After Width: | Height: | Size: 903 KiB |
BIN
static/imgs/img3.png
Normal file
After Width: | Height: | Size: 595 KiB |
BIN
static/imgs/img4.png
Normal file
After Width: | Height: | Size: 593 KiB |
BIN
static/imgs/img5.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
static/imgs/img6.png
Normal file
After Width: | Height: | Size: 2.3 MiB |
BIN
static/imgs/ricingcomp1/amadeus.png
Normal file
After Width: | Height: | Size: 1.7 MiB |
BIN
static/imgs/ricingcomp1/flafy.png
Normal file
After Width: | Height: | Size: 2.4 MiB |
BIN
static/imgs/ricingcomp1/flicko.png
Normal file
After Width: | Height: | Size: 817 KiB |
BIN
static/imgs/ricingcomp1/lauroro.jpg
Normal file
After Width: | Height: | Size: 607 KiB |
BIN
static/imgs/ricingcomp1/lyasm.png
Normal file
After Width: | Height: | Size: 3.1 MiB |
BIN
static/imgs/ricingcomp2/day-night.png
Executable file
After Width: | Height: | Size: 629 KiB |
BIN
static/imgs/ricingcomp2/end_4.jpg
Normal file
After Width: | Height: | Size: 642 KiB |
BIN
static/imgs/ricingcomp2/flafy.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
BIN
static/imgs/wall_4K.png
Normal file
After Width: | Height: | Size: 48 KiB |
|
@ -1,26 +0,0 @@
|
|||
<div class="wofdiv">
|
||||
<h1>Wall of Fame</h1>
|
||||
<p>The Wall of Fame documents the winning rices from past ricing competitons held on our Discord server.</p>
|
||||
</div>
|
||||
|
||||
<hr style="color: #cfe8f6; margin: 0px 10%; height: 3px; border: none; background-color: #cfe8f6;" />
|
||||
|
||||
<div class="ricewins">
|
||||
<ul>
|
||||
<li class="month" style="font-size: 2.5rem;">May 2023</li>
|
||||
<li class="win-text">#1: end_4<br><br><img src="/imgs/ricingcomp2/end_4.jpg"></li>
|
||||
<li class="win-text">#2: Flafy<br><br><img src="/imgs/ricingcomp2/flafy.png"></li>
|
||||
<li class="win-text">#3: Mathisbuilder<br><br><img src="/imgs/ricingcomp2/day-night.png"></li>
|
||||
</ul>
|
||||
<div style="height: 100px;"></div>
|
||||
<ul>
|
||||
<li class="month" style="font-size: 2.5rem;">December 2022</li>
|
||||
<li class="win-text">#1: Flafy<br><br><img src="/imgs/ricingcomp1/flafy.png"></li>
|
||||
<li class="win-text">#2: (<i>ex aequo</i>) flick0<br><br><img src="/imgs/ricingcomp1/flicko.png"></li>
|
||||
<li class="win-text">#2: (<i>ex aequo</i>) amadeus<br><br><img src="/imgs/ricingcomp1/amadeus.png"></li>
|
||||
<li class="win-text">#3: (<i>ex aequo</i>) Lyasm<br><br><img src="/imgs/ricingcomp1/lyasm.png"></li>
|
||||
<li class="win-text">#3: (<i>ex aequo</i>) lauroro<br><br><img src="/imgs/ricingcomp1/lauroro.jpg"></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<link rel="stylesheet" href="/css/rices.css"/>
|