community slice
1
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
old
|
||||
.svelte-kit
|
||||
build
|
||||
|
||||
# Logs
|
||||
logs
|
||||
|
|
46
package.json
|
@ -4,7 +4,7 @@
|
|||
"description": "Website for Hyprland - Hyprland - A wayland compositor with the looks.",
|
||||
"repository": "github:hyprwm/hyprland-website",
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"dev": "echo 'Remove no-index for production!' && vite dev",
|
||||
"build": "vite build",
|
||||
"preview": "vite preview",
|
||||
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
||||
|
@ -26,34 +26,34 @@
|
|||
"node": ">=16.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fontsource/fira-mono": "^4.5.10",
|
||||
"@iconify/json": "^2.2.88",
|
||||
"@neoconfetti/svelte": "^1.0.0",
|
||||
"@sveltejs/adapter-auto": "^2.0.0",
|
||||
"@sveltejs/kit": "^1.20.4",
|
||||
"@iconify/json": "^2.2.95",
|
||||
"@interactjs/types": "^1.10.17",
|
||||
"@sveltejs/adapter-auto": "^2.1.0",
|
||||
"@sveltejs/adapter-static": "^2.0.3",
|
||||
"@sveltejs/kit": "^1.22.3",
|
||||
"autoprefixer": "^10.4.14",
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte": "^2.30.0",
|
||||
"postcss": "^8.4.25",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.10.1",
|
||||
"svelte": "^4.0.0",
|
||||
"svelte-check": "^3.4.3",
|
||||
"tailwindcss": "^3.3.2",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^4.3.6"
|
||||
"eslint": "^8.46.0",
|
||||
"eslint-config-prettier": "^8.9.0",
|
||||
"eslint-plugin-svelte": "^2.32.4",
|
||||
"postcss": "^8.4.27",
|
||||
"prettier": "^3.0.0",
|
||||
"prettier-plugin-svelte": "^3.0.3",
|
||||
"svelte": "^4.1.1",
|
||||
"svelte-add": "2023.6.28-0.0",
|
||||
"svelte-check": "^3.4.6",
|
||||
"tailwindcss": "^3.3.3",
|
||||
"tailwindcss-animate": "^1.0.6",
|
||||
"typescript": "^5.1.6",
|
||||
"unplugin-icons": "^0.16.5",
|
||||
"vite": "^4.4.7"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"clsx": "^1.2.1",
|
||||
"less": "^4.1.3",
|
||||
"clsx": "^2.0.0",
|
||||
"interactjs": "^1.10.17",
|
||||
"remeda": "^1.24.0",
|
||||
"sass": "^1.64.1",
|
||||
"simplex-noise": "^4.0.1",
|
||||
"svelte-inview": "^4.0.1",
|
||||
"tailwindcss-animate": "^1.0.6",
|
||||
"ts-pattern": "^5.0.1",
|
||||
"unplugin-icons": "^0.16.3"
|
||||
"ts-pattern": "^5.0.4"
|
||||
}
|
||||
}
|
||||
|
|
1144
pnpm-lock.yaml
|
@ -4,6 +4,8 @@
|
|||
<meta charset="utf-8" />
|
||||
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<!-- ! Remember to remove this once done -->
|
||||
<meta name="robots" content="noindex" />
|
||||
<style></style>
|
||||
%sveltekit.head%
|
||||
</head>
|
||||
|
|
|
@ -14,7 +14,7 @@ import { pick } from 'remeda'
|
|||
*
|
||||
* Slide: Slide in in pixels.
|
||||
*
|
||||
* @param {{fade?: number, zoom?: number, slide?: number, duration?: number, threshold?: number}} options
|
||||
* @param {{fade?: number, zoom?: number, slide?: number, duration?: number, delay?: number, threshold?: number}} options
|
||||
* @param { HTMLElement } node
|
||||
* @returns
|
||||
*/
|
||||
|
@ -23,10 +23,10 @@ export function animateIn(node, options) {
|
|||
|
||||
options.duration ??= 840
|
||||
|
||||
const effects = Object.entries(pick(options, ['fade', 'zoom', 'slide']))
|
||||
const effects = Object.entries(pick(options, ['fade', 'zoom', 'slide', 'duration']))
|
||||
|
||||
const style = effects
|
||||
.map(([effect, value], _, all) => {
|
||||
.map(([effect, value]) => {
|
||||
if (effect === 'slide') return `translate: 0px ${value}px`
|
||||
|
||||
if (effect === 'fade') return `opacity: ${value}`
|
||||
|
@ -41,20 +41,35 @@ export function animateIn(node, options) {
|
|||
|
||||
node.style = style
|
||||
|
||||
let timeoutId
|
||||
|
||||
node.addEventListener('inview_enter', callback)
|
||||
|
||||
function callback() {
|
||||
timeoutId = setTimeout(
|
||||
effects.forEach(([effect]) => {
|
||||
if (effect === 'slide') node.style.translate = '0 0'
|
||||
else if (effect === 'fade') node.style.opacity = '1'
|
||||
else if (effect === 'zoom') node.style.scale = '1 1'
|
||||
})
|
||||
if (effect === 'slide') node.style.removeProperty('translate')
|
||||
else if (effect === 'fade') node.style.removeProperty('opacity')
|
||||
else if (effect === 'zoom') node.style.removeProperty('scale')
|
||||
}),
|
||||
options.delay ?? 0
|
||||
)
|
||||
}
|
||||
|
||||
return { destroy: observer.destroy }
|
||||
return {
|
||||
destroy: () => {
|
||||
observer.destroy()
|
||||
clearTimeout(timeoutId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// export function animateIn(styles) {
|
||||
// const inview = inview()
|
||||
// // return ({ details: { invView, scrollDirection: vertical, node } }) => {}
|
||||
// }
|
||||
/**
|
||||
* @param {number} start
|
||||
* @param {number} end
|
||||
* @param {number} given
|
||||
* @returns
|
||||
*/
|
||||
export function lerp(start, end, given) {
|
||||
return (1 - given) * start + given * end
|
||||
}
|
||||
|
|
|
@ -1,3 +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>
|
||||
<br />
|
||||
</footer>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import Community from './Community.svelte'
|
||||
import Community from './CommunitySlice.svelte'
|
||||
import FeaturesSlice from './FeaturesSlice.svelte'
|
||||
import HallOfFameSlice from './HallOfFameSlice.svelte'
|
||||
import Hero from './Hero.svelte'
|
||||
|
@ -14,8 +14,8 @@
|
|||
<Hero />
|
||||
|
||||
<div class="-mt-8 mx-auto gap-[16rem] flex flex-col items-center">
|
||||
<div class="px-8 lg:px-32">
|
||||
<PreviewRiceSlice />
|
||||
<div class="px-8 mx-auto flex flex-col items-center lg:px-32">
|
||||
<PreviewRiceSlice class="mb-52" />
|
||||
|
||||
<FeaturesSlice />
|
||||
</div>
|
||||
|
|
|
@ -1,59 +0,0 @@
|
|||
<script lang="ts">
|
||||
import Button from '$lib/components/Button.svelte'
|
||||
import DiscordIcon from '~icons/prime/discord'
|
||||
</script>
|
||||
|
||||
<section class="relative overflow-hidden w-screen min-h-max h-[850px]">
|
||||
<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>
|
||||
|
||||
<div class="flex flex-col w-full items-center">
|
||||
<div class="w-28 h-28"><DiscordIcon class="h-full w-full" /></div>
|
||||
|
||||
<a href="https://discord.com/invite/hQ9XvMUjjr">
|
||||
<Button type="fancyOutline">Join us on Discord</Button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class=" absolute inset-0 w-[1024px]">
|
||||
<div class="_bg-color bg-yellow-500 top-[146px] right-[17px] w-[359px] h-[207px] opacity-20" />
|
||||
<div class="_bg-color bg-orange-500 top-[411px] right-0 w-[400px] h-[300px] opacity-30" />
|
||||
<div class="_bg-color bg-purple-500 opacity-30 w-[321px] h-[295px] top-[209px] left-[368px]" />
|
||||
<div class="_bg-color bg-cyan-500 opacity-30 w-[363px] h-[250px] left-[402px] top-[462px]" />
|
||||
<div class="_bg-color bg-red-500 opacity-30 w-[323px] h-[482px] left-[53px] top-[179px]" />
|
||||
<div class="_bg-color bg-fuchsia-500 opacity-30 w-[243px] h-[167px] left-[135px] top-[596px]" />
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style lang="sass">
|
||||
// taken from https://codepen.io/mikegolus/pen/Jegvym?editors=1100
|
||||
$quantity: 6
|
||||
|
||||
._bg-color
|
||||
position: absolute
|
||||
animation: ease 200s alternate infinite
|
||||
pointer-events: none
|
||||
animation: drift ease alternate infinite
|
||||
filter: blur(80px)
|
||||
border-radius: 50%
|
||||
z-index: -50
|
||||
|
||||
|
||||
// Randomize Motion
|
||||
@for $i from 1 through $quantity
|
||||
$steps: random(12) + 16
|
||||
|
||||
._bg-color:nth-child(#{$i})
|
||||
// animation-name: move#{$i}
|
||||
animation-duration: random(6000) + 50000ms
|
||||
animation-delay: 0ms, random(8000) + 500ms
|
||||
|
||||
@keyframes move#{$i}
|
||||
@for $step from 0 through $steps
|
||||
#{$step * (100 / $steps)}%
|
||||
transform: translateX(random(50) - 50px) translateY(random(50) - 50px) scale(calc(random(5) / 100 + 0.95))
|
||||
|
||||
|
||||
</style>
|
263
src/routes/CommunitySlice.svelte
Normal file
|
@ -0,0 +1,263 @@
|
|||
<script context="module">
|
||||
export const contextId = Symbol('community context')
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import Button from '$lib/components/Button.svelte'
|
||||
import DiscordIcon from '~icons/prime/discord'
|
||||
import DiscordProfilePicture from './DiscordProfilePicture.svelte'
|
||||
import clsx from 'clsx'
|
||||
import { animateIn } from '$lib/Helper.mjs'
|
||||
import { setContext } from 'svelte'
|
||||
|
||||
let sectionElement
|
||||
let isDraggingChan = false
|
||||
|
||||
/** @type {{image: string coordinates: [number, number] containerClass: string}[], size: number, quote?: string } */
|
||||
const profiles = [
|
||||
{
|
||||
image: '/imgs/profile_pictures/vaxry.gif',
|
||||
coordinates: [187, 296],
|
||||
size: 172,
|
||||
class: 'outline-red-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/fufexan.webp',
|
||||
coordinates: [735, 441],
|
||||
size: 164,
|
||||
class: 'outline-yellow-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/raf-notashelf.webp',
|
||||
coordinates: [391, 615],
|
||||
size: 149,
|
||||
class: 'outline-orange-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/Mathisbuilder.png',
|
||||
coordinates: [568, 568],
|
||||
size: 120,
|
||||
class: 'outline-amber-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/dani_666..webp',
|
||||
coordinates: [525, 764],
|
||||
size: 80,
|
||||
class: 'outline-red-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/end_4.webp',
|
||||
coordinates: [648, 709],
|
||||
size: 128,
|
||||
class: 'outline-cyan-400'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/ardishco.webp',
|
||||
coordinates: [65, 208],
|
||||
size: 100,
|
||||
class: 'outline-slate-200'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/outfoxxed.webp',
|
||||
coordinates: [53, 399],
|
||||
size: 75,
|
||||
class: 'outline-orange-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/beardwarrior.webp',
|
||||
coordinates: [24, 341],
|
||||
size: 49,
|
||||
class: 'outline-amber-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/captainiveau.webp',
|
||||
coordinates: [47, 86],
|
||||
size: 48,
|
||||
class: 'outline-red-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/etrigan63.webp',
|
||||
coordinates: [135, 538],
|
||||
size: 93,
|
||||
class: 'outline-amber-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/jsw.webp',
|
||||
coordinates: [41, 566],
|
||||
size: 49,
|
||||
class: 'outline-sky-500'
|
||||
},
|
||||
{
|
||||
image: 'imgs/chan/cool.webp',
|
||||
coordinates: [284, 533],
|
||||
size: 90,
|
||||
class: 'outline-cyan-500',
|
||||
onDragStart: ({ detail: { currentTarget } }) => {
|
||||
isDraggingChan = true
|
||||
currentTarget.src = 'imgs/chan/quirky.webp'
|
||||
},
|
||||
onDragEnd: ({ detail: { currentTarget } }) => {
|
||||
isDraggingChan = false
|
||||
currentTarget.src = 'imgs/chan/cool.webp'
|
||||
},
|
||||
onHover: ({ detail: { srcElement } }) =>
|
||||
!isDraggingChan && (srcElement.src = 'imgs/chan/love.webp')
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/7.webp',
|
||||
coordinates: [273, 687],
|
||||
size: 52,
|
||||
quote: '"Meds"',
|
||||
class: 'outline-cyan-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/kcrmson.webp',
|
||||
coordinates: [648, 364],
|
||||
size: 80,
|
||||
class: 'outline-sky-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/kirottum.webp',
|
||||
coordinates: [772, 651],
|
||||
size: 62,
|
||||
class: 'outline-purple-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/loseardes77.gif',
|
||||
coordinates: [736, 277],
|
||||
size: 87,
|
||||
class: 'outline-green-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/neoney.webp',
|
||||
coordinates: [898, 364],
|
||||
size: 68,
|
||||
class: 'outline-green-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/qwaranou.webp',
|
||||
coordinates: [873, 224],
|
||||
size: 79,
|
||||
class: 'outline-slate-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/SimplyKyle!.webp',
|
||||
coordinates: [859, 159],
|
||||
size: 39,
|
||||
class: 'outline-rose-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/sioodmy.webp',
|
||||
coordinates: [974, 107],
|
||||
size: 48,
|
||||
class: 'outline-amber-500'
|
||||
},
|
||||
{
|
||||
image: '/imgs/profile_pictures/flafy.webp',
|
||||
coordinates: [340, 790],
|
||||
size: 80,
|
||||
class: 'outline-pink-500'
|
||||
}
|
||||
]
|
||||
|
||||
setContext(contextId, {
|
||||
biggestSize: profiles.reduce(
|
||||
(previousSize, { size }) => (size > previousSize ? size : previousSize),
|
||||
1
|
||||
),
|
||||
smallestSize: profiles.reduce(
|
||||
(previousSize, { size }) => (size < previousSize ? size : previousSize),
|
||||
Number.POSITIVE_INFINITY
|
||||
),
|
||||
getSectionElement: () => sectionElement
|
||||
})
|
||||
</script>
|
||||
|
||||
<section
|
||||
class="relative flex flex-col items-center w-screen min-h-max h-[1200px] max-w-[100vw] overflow-x-hidden"
|
||||
bind:this={sectionElement}
|
||||
>
|
||||
<div use:animateIn={{ slide: 24, fade: 0 }}>
|
||||
<h1 class="text-8xl font-bold text-center mb-8">Join a great<br />community</h1>
|
||||
<div class="text-center text-lg font-extrabold text-slate-300">
|
||||
Get help from Distro Hoppers, Haiku writers,<br />Hydrohomies and human_(probably)
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col items-center gap-2 group mt-16">
|
||||
<a
|
||||
class="discord p-4"
|
||||
href="https://discord.com/invite/hQ9XvMUjjr"
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
>
|
||||
<DiscordIcon class="w-full h-full " />
|
||||
</a>
|
||||
|
||||
<a href="https://discord.com/invite/hQ9XvMUjjr">
|
||||
<Button type="fancyOutline">Join us on Discord</Button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="absolute w-[1024px]">
|
||||
<div class="flex flex-wrap gap-4 origin-bottom-right h-full">
|
||||
{#each profiles as { onDragEnd, onDragStart, onHover, ...props }}
|
||||
<DiscordProfilePicture
|
||||
{...props}
|
||||
on:dragStart={onDragStart}
|
||||
on:dragEnd={onDragEnd}
|
||||
on:hover={onHover}
|
||||
/>
|
||||
{/each}
|
||||
</div>
|
||||
|
||||
<div class="">
|
||||
<!-- Background color blobs -->
|
||||
<div
|
||||
class="_bg-color bg-yellow-500 top-[146px] right-[17px] w-[359px] h-[207px] opacity-20"
|
||||
/>
|
||||
<div class="_bg-color bg-orange-500 top-[411px] right-0 w-[400px] h-[300px] opacity-30" />
|
||||
<div
|
||||
class="_bg-color bg-purple-500 opacity-30 w-[321px] h-[295px] top-[209px] left-[368px]"
|
||||
/>
|
||||
<div class="_bg-color bg-cyan-500 opacity-30 w-[363px] h-[250px] left-[402px] top-[462px]" />
|
||||
<div class="_bg-color bg-red-500 opacity-30 w-[323px] h-[482px] left-[53px] top-[179px]" />
|
||||
<div
|
||||
class="_bg-color bg-fuchsia-500 opacity-30 w-[243px] h-[167px] left-[135px] top-[596px]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<style lang="postcss">
|
||||
.discord {
|
||||
width: 9rem;
|
||||
height: 9rem;
|
||||
transition:
|
||||
rotate 480ms cubic-bezier(0.5, 0, 0.5, 1.5),
|
||||
scale 440ms cubic-bezier(1, -1.4, 0, 2),
|
||||
filter 240ms;
|
||||
filter: drop-shadow(0px 0px 0px cyan) drop-shadow(0px 0px 0px blue);
|
||||
|
||||
&:hover,
|
||||
.group:hover & {
|
||||
scale: 1.2 1.2;
|
||||
rotate: 360deg;
|
||||
filter: drop-shadow(4px 4px 14px #0fffef7a) drop-shadow(-4px -4px 12px purple);
|
||||
animation: bounce 1s infinite;
|
||||
}
|
||||
&:active {
|
||||
scale: 1;
|
||||
transition: scale 80ms;
|
||||
}
|
||||
}
|
||||
|
||||
._bg-color {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
filter: blur(80px);
|
||||
border-radius: 50%;
|
||||
z-index: -50;
|
||||
contain: strict;
|
||||
}
|
||||
</style>
|
125
src/routes/DiscordProfilePicture.svelte
Normal file
|
@ -0,0 +1,125 @@
|
|||
<script>
|
||||
import { json } from '@sveltejs/kit'
|
||||
import clsx from 'clsx'
|
||||
import interact from 'interactjs'
|
||||
import { createEventDispatcher, getContext, onMount } from 'svelte'
|
||||
import { spring } from 'svelte/motion'
|
||||
import { contextId } from './CommunitySlice.svelte'
|
||||
import { lerp } from '$lib/Helper.mjs'
|
||||
import { inview } from 'svelte-inview'
|
||||
|
||||
/** @type {string} */
|
||||
export let image
|
||||
/** @type {string} */
|
||||
export let containerClass = ''
|
||||
/** @type {number} */
|
||||
export let size
|
||||
/** @type {[number, number]} */
|
||||
export let coordinates
|
||||
|
||||
/** @type {string | undefined} */
|
||||
export let quote = undefined
|
||||
|
||||
const { biggestSize, getSectionElement } = getContext(contextId)
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
const relativeSize = size / biggestSize
|
||||
const delay = (biggestSize - size) * 5
|
||||
const dragCoordinates = spring([0, 0], {
|
||||
damping: lerp(0.2, 0.03, relativeSize),
|
||||
stiffness: lerp(0.2, 0.01, relativeSize),
|
||||
// stiffness: lerp(0.81, 0.9, relativeSize),
|
||||
precision: 0.001
|
||||
})
|
||||
|
||||
let imageElement
|
||||
let hasEnteredView = false
|
||||
|
||||
onMount(() => {
|
||||
let 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)
|
||||
}
|
||||
},
|
||||
modifiers: [
|
||||
interact.modifiers.restrictRect({
|
||||
restriction: getSectionElement,
|
||||
endOnly: true
|
||||
})
|
||||
]
|
||||
})
|
||||
|
||||
return () => interactionjs.off()
|
||||
})
|
||||
</script>
|
||||
|
||||
<div
|
||||
class={clsx('absolute top-0 left-0 select-none touch-none ', containerClass)}
|
||||
style:translate={coordinates.map((xy) => xy + 'px').join(' ')}
|
||||
style="width: {size}px; height: {size}px;--delay: {delay}ms;"
|
||||
>
|
||||
<div
|
||||
class="absolute inset-0 w-full h-full group opacity-0 select-none touch-none"
|
||||
style:translate={`calc( ${$dragCoordinates[0]}px ) ${$dragCoordinates[1]}px`}
|
||||
use:inview={{ unobserveOnEnter: true, threshold: 0.4 }}
|
||||
class:_animate={hasEnteredView}
|
||||
on:inview_enter={() => setTimeout(() => (hasEnteredView = true), 750)}
|
||||
>
|
||||
<img
|
||||
class="w-full h-full group select-none touch-none outline-4 outline rounded-[50%] {$$restProps.class}"
|
||||
bind:this={imageElement}
|
||||
src={image}
|
||||
alt={'community profile picture'}
|
||||
aria-hidden="true"
|
||||
on:mouseenter={(event) => dispatch('hover', event)}
|
||||
class:hover:scale-125={!!quote}
|
||||
/>
|
||||
|
||||
{#if quote}
|
||||
<div
|
||||
class="absolute tracking-wide opacity-0 -top-6 px-2 py-1 rounded left-1/2 -translate-x-1/2 bg-slate-800/50 pointer-events-none font-medium text-sm group-hover:opacity-100 select-none duration-150"
|
||||
>
|
||||
{quote}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style lang="postcss">
|
||||
._animate {
|
||||
animation: reveal 440ms 1 var(--delay) both cubic-bezier(0, 1, 0.765, 3.8);
|
||||
touch-action: none;
|
||||
user-select: none;
|
||||
|
||||
img {
|
||||
transition: scale cubic-bezier(0.95, 0.82, 0.165, 2) 180ms;
|
||||
&:hover {
|
||||
scale: 1.05;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes reveal {
|
||||
from {
|
||||
opacity: 0%;
|
||||
scale: 0.72 0.72;
|
||||
}
|
||||
to {
|
||||
opacity: 100%;
|
||||
scale: 1 1;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -1,8 +1,6 @@
|
|||
<script>
|
||||
import { animateIn } from '$lib/Helper.mjs'
|
||||
|
||||
/** @type {{ name: string, url: string }} */
|
||||
export let createdBy
|
||||
/** @type {string}
|
||||
* The path to the image. Usually the file within `static`, but can also be an URL
|
||||
*/
|
||||
|
@ -13,19 +11,14 @@
|
|||
export let containerClass = undefined
|
||||
</script>
|
||||
|
||||
<div
|
||||
class="rice {containerClass} group"
|
||||
use:animateIn={{ fade: 0, duration: 1200, threshold: 0.4 }}
|
||||
>
|
||||
<div class="rice {containerClass} group">
|
||||
<div class="w-full h-full" use:animateIn={{ slide: 20, duration: 800 }}>
|
||||
<img
|
||||
src={image}
|
||||
alt="Rice desktop"
|
||||
class="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" />
|
||||
<div class="group-hover:opacity-100 opacity-0 transition-opacity absolute top-6 right-6 p-4">
|
||||
{createdBy.name}
|
||||
{createdBy.url}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -34,7 +27,7 @@
|
|||
@apply relative w-full max-w-[1100px];
|
||||
}
|
||||
.nice-hover {
|
||||
transition: transform 540ms cubic-bezier(0.1, -0.81, 0.31, 2);
|
||||
transition: all 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;
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
>
|
||||
<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" />
|
||||
|
@ -93,8 +94,8 @@
|
|||
background: black
|
||||
radial-gradient(
|
||||
circle at bottom right,
|
||||
theme(colors.neutral.900 / 30%),
|
||||
theme(colors.neutral.500 / 30%),
|
||||
theme(colors.neutral.900 / 80%),
|
||||
theme(colors.neutral.500 / 10%),
|
||||
black
|
||||
);
|
||||
}
|
||||
|
@ -115,7 +116,7 @@
|
|||
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(--color1, theme(colors.cyan.500)), transparent 70%),
|
||||
color-mix(in srgb, var(--color2, theme(colors.blue.500)), transparent 90%)
|
||||
);
|
||||
|
||||
|
|
|
@ -12,6 +12,11 @@
|
|||
import BleedingEdgeIcon from '~icons/gg/controller'
|
||||
import { animateIn } from '$lib/Helper.mjs'
|
||||
|
||||
/**
|
||||
* type {{name: string, github: string}}
|
||||
*/
|
||||
let createdBy
|
||||
|
||||
const context = setContext(mouseContext, {
|
||||
x: writable(0),
|
||||
y: writable(0),
|
||||
|
@ -36,7 +41,7 @@
|
|||
</script>
|
||||
|
||||
<section class="flex flex-col items-center">
|
||||
<div use:animateIn={{ fade: 0, slide: 24, duration: 1480, threshold: 0.4 }}>
|
||||
<div class="text-center" 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>
|
||||
|
@ -51,7 +56,7 @@
|
|||
<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
|
||||
a custom WSLroot patch included
|
||||
</p></FeatureCard
|
||||
>
|
||||
<FeatureCard title="Easy to configure" color="purple">
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
</script>
|
||||
|
||||
<section
|
||||
class="w-full relative"
|
||||
use:animateIn={{ fade: 0, slide: 24, duration: 1200, threshold: 0.1 }}
|
||||
class="w-full relative flex flex-col items-center"
|
||||
use:animateIn={{ fade: 0, slide: 24, duration: 3000, threshold: 0.1 }}
|
||||
>
|
||||
<div class="absolute inset-0">
|
||||
<div class="absolute top-0 inset-x-0 z-30">
|
||||
<div class="text-center font-extrabold mb-3 text-slate-300">
|
||||
Memorials of the ricing legends
|
||||
</div>
|
||||
|
@ -16,28 +16,30 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
class="w-full flex relative flex-col gap-16 lg:gap-24 items-center justify-end pt-16 overflow-hidden 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 px-16 [perspective:100px]"
|
||||
use:animateIn={{ slide: 24, fade: 0.5, duration: 800 }}
|
||||
>
|
||||
<a class="absolute bottom-24 left-1/2 z-20 -translate-x-1/2" href="/hall-of-fame">
|
||||
<a class="absolute bottom-24 left-1/2 z-20 -translate-x-1/2" href="/#">
|
||||
<Button size="lg" type="fancyOutline">Go to Hall of Fame</Button>
|
||||
</a>
|
||||
|
||||
<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]"
|
||||
/>
|
||||
|
||||
<FameRicePreview
|
||||
createdBy={{ name: 'flicko', url: 'http://flicko.com' }}
|
||||
image="/imgs/ricingcomp1/flicko.png"
|
||||
containerClass="[translate:0px_0px_-100px] -mb-[30%] hover:[translate:0px_0px_-70px] hover:mb-[-15%] transition-all duration-500"
|
||||
imageClass="[mask-image:linear-gradient(black_50%,transparent_95%)] "
|
||||
image="/imgs/ricingcomp1/lauroro.jpg"
|
||||
containerClass="[translate:0px_0px_-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"
|
||||
/>
|
||||
<FameRicePreview
|
||||
createdBy={{ name: 'flicko', url: 'http://flicko.com' }}
|
||||
image="/imgs/env_4 novelknock-10.png"
|
||||
containerClass="[translate:0px_0px_-40px] -mb-[30%]"
|
||||
imageClass="[mask-image:linear-gradient(black,transparent_95%)]"
|
||||
/>
|
||||
<FameRicePreview
|
||||
createdBy={{ name: 'flicko', url: 'http://flicko.com' }}
|
||||
image="/imgs/ricingcomp1/amadeus.png"
|
||||
imageClass="rounded-none [mask-image:linear-gradient(black,transparent)] rounded-t-xl h-[200px] sm:h-[250px] lg:h-[500px]"
|
||||
containerClass="[translate:0px_0px_-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"
|
||||
/>
|
||||
<FameRicePreview
|
||||
image="/imgs/ricingcomp1/flicko.png"
|
||||
imageClass="!rounded-none !rounded-t-xl [mask-image:linear-gradient(black,black_50%,transparent)] rounded-t-xl h-[200px] sm:h-[250px] lg:h-[500px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
@ -50,16 +52,16 @@
|
|||
width: 100%;
|
||||
/* min-width: 8800px; */
|
||||
position: absolute;
|
||||
opacity: 0.5;
|
||||
opacity: 0.3;
|
||||
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%
|
||||
theme(colors.pink.400),
|
||||
theme(colors.indigo.700 / 50%) 50%,
|
||||
theme(colors.indigo.950 / 0%) 80%
|
||||
);
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
</div>
|
||||
</div>
|
||||
<h2
|
||||
class="ani-in text-center mb-14 [animation-delay:944ms] fill-mode-backwards font-medium text-xl text-blue-200/60"
|
||||
class="ani-in text-center mb-10 [animation-delay:944ms] fill-mode-backwards font-medium text-xl text-blue-200/60"
|
||||
>
|
||||
Dynamic tiling Wayland compositor<br />with the looks.
|
||||
</h2>
|
||||
|
|
|
@ -6,14 +6,17 @@
|
|||
</script>
|
||||
|
||||
<header
|
||||
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"
|
||||
class="flex items-center z-30 justify-between fixed top-4 inset-x-6 rounded-full 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">
|
||||
<a
|
||||
href="/"
|
||||
class="flex gap-2 px-4 py-1 text-sm rounded-full bg-black/50 items-center font-bold tracking-wide text-white"
|
||||
>
|
||||
<img src={logo} alt="Hyprland Logo" class="w-6" />Hyprland</a
|
||||
>
|
||||
|
||||
<nav class="flex font-semibold gap-4 items-center">
|
||||
<ul class="flex gap-4 px-3 rounded-full max-h-full border-primary border-1 border h-full">
|
||||
<nav class="flex font-semibold items-center backdrop-blur pl-5 rounded-full bg-black/50">
|
||||
<ul class="flex gap-5 rounded-full items-center max-h-full h-full hover:[&_li]:text-cyan-300">
|
||||
<li>
|
||||
<a href="https://wiki.hyprland.org/Getting-Started/Master-Tutorial/">Get_started</a>
|
||||
</li>
|
||||
|
@ -21,27 +24,24 @@
|
|||
<a href="https://wiki.hyprland.org">Wiki</a>
|
||||
</li>
|
||||
<li aria-current={$page.url.pathname === '/about' ? 'page' : undefined}>
|
||||
<a href="/rices">Wall_of_fame</a>
|
||||
<a href="/#">Wall_of_fame</a>
|
||||
</li>
|
||||
</ul>
|
||||
<ul class="bg-purple-400 rounded-full flex items-center gap-3 px-2 py-1">
|
||||
<ul class="border-purple-400 border mr-2 ml-4 rounded-full flex items-center gap-3 px-4">
|
||||
<li>
|
||||
<a href="https://github.com/hyprwm/Hyprland">
|
||||
<DiscordIcon class="text-black" />
|
||||
<DiscordIcon class="w-8 h-8 p-1 rounded-full hover:bg-purple-500 hover:text-white" />
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://github.com/hyprwm/Hyprland">
|
||||
<GithubIcon class="text-black" />
|
||||
<GithubIcon class="w-8 h-8 p-1 hover:bg-purple-500 rounded-full hover:text-white" />
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<a
|
||||
class="bg-primary rounded-full px-4 py-1 text-black"
|
||||
class="bg-primary rounded-full px-4 py-1 uppercase tracking-wide text-black hover:bg-cyan-200"
|
||||
href="https://wiki.hyprland.org/Getting-Started/Installation/">Install</a
|
||||
>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
|
|
|
@ -15,10 +15,9 @@
|
|||
on:inview_enter={({ detail: { node } }) => {
|
||||
node.classList.remove('opacity-20')
|
||||
node.classList.remove('scale-90')
|
||||
// videoElement.play()
|
||||
videoElement.play()
|
||||
}}
|
||||
>
|
||||
<!--TODO Play and scale up on enter -->
|
||||
<video
|
||||
bind:this={videoElement}
|
||||
src={previewRice}
|
||||
|
|
BIN
static/imgs/chan/cool.webp
Normal file
After Width: | Height: | Size: 7 KiB |
BIN
static/imgs/chan/despair.webp
Normal file
After Width: | Height: | Size: 7.8 KiB |
BIN
static/imgs/chan/love.webp
Normal file
After Width: | Height: | Size: 6.8 KiB |
BIN
static/imgs/chan/quirky.webp
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
static/imgs/chan/sad.webp
Normal file
After Width: | Height: | Size: 5.7 KiB |
BIN
static/imgs/chan/thonk.webp
Normal file
After Width: | Height: | Size: 6.4 KiB |
BIN
static/imgs/profile_pictures/7.webp
Normal file
After Width: | Height: | Size: 2 KiB |
BIN
static/imgs/profile_pictures/Mathisbuilder.png
Normal file
After Width: | Height: | Size: 177 KiB |
BIN
static/imgs/profile_pictures/SimplyKyle!.webp
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
static/imgs/profile_pictures/System64.webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
static/imgs/profile_pictures/ardishco.webp
Normal file
After Width: | Height: | Size: 4 KiB |
BIN
static/imgs/profile_pictures/beardwarrior.webp
Normal file
After Width: | Height: | Size: 9.7 KiB |
BIN
static/imgs/profile_pictures/captainiveau.webp
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
static/imgs/profile_pictures/dani_666..webp
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
static/imgs/profile_pictures/end_4.webp
Normal file
After Width: | Height: | Size: 9.2 KiB |
BIN
static/imgs/profile_pictures/etrigan63.webp
Normal file
After Width: | Height: | Size: 8.9 KiB |
BIN
static/imgs/profile_pictures/flafy.webp
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
static/imgs/profile_pictures/fufexan.webp
Normal file
After Width: | Height: | Size: 2.3 KiB |
BIN
static/imgs/profile_pictures/jsw.webp
Normal file
After Width: | Height: | Size: 678 B |
BIN
static/imgs/profile_pictures/kcrmson.webp
Normal file
After Width: | Height: | Size: 5.5 KiB |
BIN
static/imgs/profile_pictures/kirottum.webp
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
static/imgs/profile_pictures/loseardes77.gif
Normal file
After Width: | Height: | Size: 1.5 MiB |
BIN
static/imgs/profile_pictures/neoney.webp
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
static/imgs/profile_pictures/outfoxxed.webp
Normal file
After Width: | Height: | Size: 6.5 KiB |
BIN
static/imgs/profile_pictures/qwaranou.webp
Normal file
After Width: | Height: | Size: 5.4 KiB |
BIN
static/imgs/profile_pictures/raf-notashelf.webp
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
static/imgs/profile_pictures/sioodmy.webp
Normal file
After Width: | Height: | Size: 3.5 KiB |
BIN
static/imgs/profile_pictures/vagahbond.gif
Normal file
After Width: | Height: | Size: 66 KiB |
BIN
static/imgs/profile_pictures/vaxry.gif
Normal file
After Width: | Height: | Size: 879 KiB |
|
@ -1,5 +1,5 @@
|
|||
import adapter from '@sveltejs/adapter-auto';
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
import adapter from '@sveltejs/adapter-static'
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite'
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config} */
|
||||
const config = {
|
||||
|
@ -10,6 +10,6 @@ const config = {
|
|||
adapter: adapter()
|
||||
},
|
||||
preprocess: vitePreprocess()
|
||||
};
|
||||
}
|
||||
|
||||
export default config;
|
||||
export default config
|
||||
|
|
|
@ -16,5 +16,6 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
plugins: [require('tailwindcss-animate')]
|
||||
plugins: [require('tailwindcss-animate')],
|
||||
safelist: ['animate-bounce', 'outline-amber-500']
|
||||
}
|
||||
|
|
|
@ -8,5 +8,12 @@ export default defineConfig({
|
|||
Icons({
|
||||
compiler: 'svelte'
|
||||
})
|
||||
]
|
||||
],
|
||||
build: {
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
|