mirror of
https://github.com/hyprwm/hyprland-website.git
synced 2024-11-17 10:55:58 +01:00
d982e5761d
* some progress, updating packages * migrate to SvelteKit 2 * progress * more stuff * hy3 banner * add links to features * fix distro option extra image * update community section * add plugins page link to plugins slice * community more profiles * add more community profiles * fix RSS not showing in prod (#45) * plugin page: better banner hover playback * improve community slice intro timing * remove fillter texts * improve command button * plugin install command wording improvment * footer adjustments * add dwindle-autogroup * stuff * community profile pictures hosted by Discord :P * fix autoplay previewRice Chrome * navbar: no entry delay * small community profile changes * optimize plugins layout * fix sorting * improve card performance * clean up test content from .md files * did more stuff * change desc of some plugins * work on design and layout * make main bg darker Creates less banding and looks a bit better, while also providing better contrast * nicer trim text * more stuff * fix messup * update plugins readme * add a profile picture * plugins: add gradient bg * remove placeholder plugins * plugins: improve mobile layout * community: small stuff * remove csgo vulkan fix logo * plugins: fix bg jumping on Firefox * plugin slug: improve animation staggering * small css fixes * pluginsSlice: animate only with slide Opacity change looks a bit off here * community: hide errored images --------- Co-authored-by: Vaxry <vaxry@vaxry.net>
205 lines
6.7 KiB
Svelte
205 lines
6.7 KiB
Svelte
<script>
|
|
import PatternBackground from '$lib/PatternBackground.svelte'
|
|
import IconPlugin from '~icons/mingcute/plugin-2-line'
|
|
import IconIpc from '~icons/mingcute/hexagon-line'
|
|
import IconLinkOut from '~icons/mingcute/external-link-line'
|
|
import IconSlideLeft from '~icons/mingcute/align-arrow-left-line'
|
|
import clsx from 'clsx'
|
|
import Video from '$lib/components/Video.svelte'
|
|
import { animateIn } from '$lib/Helper.mjs'
|
|
import { Subject, debounceTime, map, tap, throttle, throttleTime } from 'rxjs'
|
|
import { onMount } from 'svelte'
|
|
import { fade } from 'svelte/transition'
|
|
import Button from '$lib/components/Button.svelte'
|
|
|
|
/** @type {HTMLVideoElement[]}*/
|
|
const videos = []
|
|
let activeIndex = 0
|
|
let isHoveringVideo = false
|
|
const isVideoCroppedInput$ = new Subject()
|
|
/** @type {import('rxjs').Subject<boolean>}*/
|
|
const isVideoCropped$ = isVideoCroppedInput$.pipe(
|
|
debounceTime(100),
|
|
map(
|
|
() =>
|
|
window.innerWidth > 1024 && // LG breakpoint
|
|
window.innerWidth < 2200 // Video is fully visible
|
|
)
|
|
)
|
|
|
|
const items = [
|
|
{
|
|
icon: IconPlugin,
|
|
title: 'Plugins.',
|
|
description:
|
|
'Customize everything with official and community extensions. Write your own easily with C++',
|
|
poster: '/videos/outfoxxed_thumb.webp',
|
|
src: '/videos/outfoxxed',
|
|
subtext: `
|
|
Setup by <a href="https://github.com/outfoxxed/" target="_blank">outfoxxed</a> using <a href="https://github.com/outfoxxed/hy3" target="_blank">hy3</a> and <a href="https://github.com/VortexCoyote/hyprfocus" target="_blank">hyprfocus</a>`
|
|
},
|
|
{
|
|
icon: IconIpc,
|
|
title: 'Bindings and IPC.',
|
|
description: 'Control your desktop with your favourite languages or simply via IPC.',
|
|
poster: '/videos/aylur_thumb.png',
|
|
src: '/videos/aylur',
|
|
subtext: `Setup by <a href="https://github.com/Aylur/dotfiles" target="_blank">Aylur</a>, creator of
|
|
<a href="https://github.com/Aylur/ags" target="_blank">Ags</a> using Ags to control Hyprland
|
|
via IPC.`
|
|
}
|
|
]
|
|
|
|
function setActiveItem(index) {
|
|
activeIndex = index
|
|
}
|
|
|
|
function onPlay(currentIndex) {
|
|
videos.filter((_, index) => index !== currentIndex).forEach((video) => video.play())
|
|
}
|
|
function onPause(activeIndex, currentIndex) {
|
|
// Prevent infinite loop when active video gets paused and other videos also get paused as a result
|
|
if (currentIndex !== activeIndex) return
|
|
|
|
videos.filter((_, index) => index !== currentIndex).forEach((video) => video.pause())
|
|
}
|
|
function toggleVideoSlide() {
|
|
isHoveringVideo ? slideVideoOut() : slideVideoIn()
|
|
}
|
|
function slideVideoIn() {
|
|
isHoveringVideo = true
|
|
}
|
|
function slideVideoOut() {
|
|
if (!isHoveringVideo) return
|
|
isHoveringVideo = false
|
|
}
|
|
onMount(() => {
|
|
isVideoCroppedInput$.next(0)
|
|
})
|
|
</script>
|
|
|
|
<svelte:window on:resize={() => isVideoCroppedInput$.next(0)} />
|
|
|
|
<section class="relative z-0 flex min-h-max w-full flex-col items-center py-20">
|
|
<div
|
|
class="mx-auto grid max-w-7xl grid-cols-1 gap-8 transition-all lg:grid-cols-2 lg:gap-12"
|
|
use:animateIn={{ slide: 24 }}
|
|
>
|
|
<div
|
|
class={clsx(
|
|
'z-10 flex flex-col gap-10 px-5 transition-transform delay-75 duration-300 sm:px-6',
|
|
isHoveringVideo && '-translate-x-36'
|
|
)}
|
|
>
|
|
<div class="txt-shadow_ mt-8 flex flex-col gap-6">
|
|
<h2 class=" text-6xl font-bold">Unlock full power</h2>
|
|
<p class="text-lg font-bold text-slate-300">
|
|
Get the latest features Linux offers. Have full control over your workflow by customizing
|
|
and extending it how you want.
|
|
</p>
|
|
</div>
|
|
|
|
<div class="flex h-full flex-col gap-4">
|
|
{#each items as { icon, title, description }, index}
|
|
{@const isActive = index === activeIndex}
|
|
<button
|
|
class={clsx(
|
|
'flex gap-3 rounded-xl px-4 py-4 outline-0 outline-cyan-400/50 transition-all sm:-ml-4',
|
|
isActive && 'bg-blue-300/5 shadow-md outline outline-1 backdrop-blur-sm '
|
|
)}
|
|
on:mouseenter={() => setActiveItem(index)}
|
|
>
|
|
<svelte:component this={icon} class="h-8 w-8 shrink-0 text-primary" />
|
|
<p
|
|
class={clsx(
|
|
'txt-shadow_ text-left text-lg font-medium transition-colors ',
|
|
isActive ? 'text-slate-300' : 'text-slate-400'
|
|
)}
|
|
>
|
|
<span class="font-bold text-white">{title}</span>
|
|
{description}
|
|
</p>
|
|
</button>
|
|
{/each}
|
|
</div>
|
|
|
|
<Button type="fancyOutline" size="lg" class="max-w-max"
|
|
><a href="/plugins/">Checkout more plugins</a></Button
|
|
>
|
|
|
|
<div class="-mt-5 hidden gap-1 lg:mt-12 lg:flex lg:flex-col">
|
|
<a
|
|
class="txt-shadow_ flex w-max max-w-max shrink-0 items-center gap-3 rounded font-bold text-slate-400 hover:underline"
|
|
href="https://github.com/hyprland-community/awesome-hyprland"
|
|
target="_blank"
|
|
>
|
|
<div>
|
|
Also see <span class="text-cyan-500">Awesome Hyprland</span>
|
|
</div>
|
|
<IconLinkOut />
|
|
</a>
|
|
<p class="font-medium text-slate-400">
|
|
A list of plugins, bindings and more by the community
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Prevent the video from making the container big on small phones. 300px seem to work well for the text -->
|
|
<div
|
|
class={clsx(
|
|
'relative z-10 w-full min-w-0 transition-transform sm:h-[25rem] sm:px-4 md:h-[30rem] lg:h-[37rem] lg:px-0',
|
|
isHoveringVideo && '-translate-x-56'
|
|
)}
|
|
>
|
|
{#if $isVideoCropped$}
|
|
<button
|
|
on:click={toggleVideoSlide}
|
|
class:rotate-180={isHoveringVideo}
|
|
class="group absolute -left-6 top-1/2 z-50 rounded-full bg-blue-400/5 p-2 outline outline-white/10 backdrop-blur-sm transition-transform"
|
|
out:fade
|
|
>
|
|
<IconSlideLeft
|
|
class="h-6 w-6 opacity-70 transition-all group-hover:-translate-x-0.5 group-hover:opacity-100"
|
|
/>
|
|
</button>
|
|
{/if}
|
|
|
|
<div class="h-full w-full" role="complementary">
|
|
{#each items as { src, poster }, index}
|
|
<Video
|
|
sources={[src + '.mp4']}
|
|
{poster}
|
|
autoplay
|
|
muted
|
|
bind:videoElement={videos[index]}
|
|
class="z-10 aspect-video origin-left object-cover object-left shadow-xl shadow-cyan-700/50 outline-2 outline-cyan-500 duration-500 sm:h-[inherit] sm:rounded-lg sm:outline"
|
|
playButtonClass=" lg:left-32 xl:left-1/2"
|
|
hidden={index !== activeIndex}
|
|
on:pause={() => onPause(activeIndex, index)}
|
|
on:play={() => onPlay(index)}
|
|
videoClass="h-[inherit] aspect-video"
|
|
/>
|
|
{/each}
|
|
</div>
|
|
<div
|
|
class="px-2 text-sm font-medium text-slate-300 sm:px-0 sm:pt-5 md:text-base [&>a:hover]:text-cyan-300 [&>a:hover]:underline [&>a]:font-bold"
|
|
>
|
|
{@html items[activeIndex].subtext}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<PatternBackground class="absolute inset-0 h-[110%] w-full text-slate-800 opacity-40" />
|
|
</section>
|
|
|
|
<style lang="postcss">
|
|
.txt-shadow_ {
|
|
text-shadow:
|
|
0px 0px 12px theme(colors.black / 90%),
|
|
0px 0px 24px theme(colors.black / 50%);
|
|
}
|
|
|
|
.slideToLeft {
|
|
margin-left: -15rem;
|
|
}
|
|
</style>
|