-
-
Notifications
You must be signed in to change notification settings - Fork 161
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(web): smooth scroll, about section, cards, scroll animations
- Loading branch information
1 parent
2ef05e3
commit 15beef8
Showing
11 changed files
with
817 additions
and
5 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
<script> | ||
import { formatMap } from './anime.js' | ||
import { click } from '@/modules/click.js' | ||
export let media | ||
let hide = true | ||
function getPlayButtonText (media) { | ||
if (media.mediaListEntry) { | ||
const { status, progress } = media.mediaListEntry | ||
if (progress) { | ||
if (status === 'COMPLETED') { | ||
return 'Rewatch Now' | ||
} else { | ||
return 'Continue Now' | ||
} | ||
} | ||
} | ||
return 'Watch Now' | ||
} | ||
const playButtonText = getPlayButtonText(media) | ||
function volume (video) { | ||
video.volume = 0.1 | ||
} | ||
let muted = true | ||
function toggleMute () { | ||
muted = !muted | ||
} | ||
const noop = () => {} | ||
</script> | ||
|
||
<div class='position-absolute w-350 h-400 absolute-container top-0 bottom-0 m-auto bg-dark-light z-30 rounded overflow-hidden pointer'> | ||
<div class='banner position-relative overflow-hidden bg-black'> | ||
<img src={media.bannerImage || ' '} alt='banner' class='img-cover w-full h-full' /> | ||
{#if media.trailer?.id} | ||
<div class='material-symbols-outlined filled position-absolute z-10 top-0 right-0 p-15 font-size-22' class:d-none={hide} use:click={toggleMute}>{muted ? 'volume_off' : 'volume_up'}</div> | ||
<!-- for now we use some invidious instance, would be nice to somehow get these links outselves, this redirects straight to some google endpoint --> | ||
<!-- eslint-disable-next-line svelte/valid-compile --> | ||
<video src={`https://yewtu.be/latest_version?id=${media.trailer.id}&itag=18`} | ||
class='w-full position-absolute left-0' | ||
class:d-none={hide} | ||
playsinline | ||
preload='none' | ||
loop | ||
use:volume | ||
bind:muted | ||
on:loadeddata={() => { hide = false }} | ||
autoplay /> | ||
{/if} | ||
</div> | ||
<div class='w-full px-20'> | ||
<div class='font-size-24 font-weight-bold text-truncate d-inline-block w-full text-white' title={media.title.userPreferred}> | ||
{media.title.userPreferred} | ||
</div> | ||
<div class='d-flex flex-row pt-5'> | ||
<button class='btn btn-secondary flex-grow-1 text-dark font-weight-bold shadow-none border-0 d-flex align-items-center justify-content-center' | ||
use:click={noop} | ||
disabled={media.status === 'NOT_YET_RELEASED'}> | ||
<span class='material-symbols-outlined font-size-20 filled pr-10'> | ||
play_arrow | ||
</span> | ||
{playButtonText} | ||
</button> | ||
<button class='btn btn-square ml-10 material-symbols-outlined font-size-16 shadow-none border-0' class:filled={media.isFavourite} use:click={noop}> | ||
favorite | ||
</button> | ||
<button class='btn btn-square ml-10 material-symbols-outlined font-size-16 shadow-none border-0' class:filled={media.mediaListEntry} use:click={noop}> | ||
bookmark | ||
</button> | ||
</div> | ||
<div class='details text-white text-capitalize pt-15 pb-10 d-flex'> | ||
<span class='text-nowrap d-flex align-items-center'> | ||
{#if media.format} | ||
{formatMap[media.format]} | ||
{/if} | ||
</span> | ||
{#if media.episodes && media.episodes !== 1} | ||
<span class='text-nowrap d-flex align-items-center'> | ||
{#if media.mediaListEntry?.status === 'CURRENT' && media.mediaListEntry?.progress } | ||
{media.mediaListEntry.progress} / {media.episodes} Episodes | ||
{:else} | ||
{media.episodes} Episodes | ||
{/if} | ||
</span> | ||
{:else if media.duration} | ||
<span class='text-nowrap d-flex align-items-center'> | ||
{media.duration + ' Minutes'} | ||
</span> | ||
{/if} | ||
{#if media.season || media.seasonYear} | ||
<span class='text-nowrap d-flex align-items-center'> | ||
{[media.season?.toLowerCase(), media.seasonYear].filter(s => s).join(' ')} | ||
</span> | ||
{/if} | ||
</div> | ||
<div class='w-full h-full text-muted description overflow-hidden'> | ||
{media.description?.replace(/<[^>]*>/g, '')} | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<style> | ||
.description { | ||
display: -webkit-box !important; | ||
-webkit-line-clamp: 4; | ||
-webkit-box-orient: vertical; | ||
} | ||
.details span + span::before { | ||
content: '•'; | ||
padding: 0 .5rem; | ||
font-size: .6rem; | ||
align-self: center; | ||
white-space: normal; | ||
color: var(--dm-muted-text-color) !important; | ||
} | ||
.banner { | ||
height: 45% | ||
} | ||
.banner::after { | ||
content: ''; | ||
position: absolute; | ||
left: 0 ; bottom: 0; | ||
width: 100%; height: 100% ; | ||
background: linear-gradient(180deg, #0000 0%, #25292f00 80%, #25292fe3 95%, #25292f 100%); | ||
} | ||
@keyframes load-in { | ||
from { | ||
bottom: -1.2rem; | ||
opacity: 0; | ||
transform: scale(0.95); | ||
} | ||
to { | ||
bottom: 0; | ||
opacity: 1; | ||
transform: scale(1); | ||
} | ||
} | ||
.absolute-container { | ||
animation: 0.3s ease 0s 1 load-in; | ||
left: -100%; | ||
right: -100%; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
<script> | ||
import PreviewCard from './PreviewCard.svelte' | ||
import { formatMap, statusColorMap } from './anime.js' | ||
import { hoverClick } from '@/modules/click.js' | ||
export let media | ||
export let preview = false | ||
const noop = () => {} | ||
function setHoverState (state) { | ||
preview = state | ||
} | ||
</script> | ||
|
||
<div class='d-flex p-20 position-relative first-check' use:hoverClick={[noop, setHoverState]}> | ||
{#if preview} | ||
<PreviewCard {media} /> | ||
{/if} | ||
<div class='item d-flex flex-column h-full pointer content-visibility-auto'> | ||
<img loading='lazy' src={media.coverImage.extraLarge || ''} alt='cover' class='cover-img w-full rounded' style:--color={media.coverImage.color || '#1890ff'} /> | ||
<div class='text-white font-weight-very-bold font-size-16 pt-15 title overflow-hidden'> | ||
{#if media.mediaListEntry?.status} | ||
<div style:--statusColor={statusColorMap[media.mediaListEntry.status]} class='list-status-circle d-inline-flex overflow-hidden mr-5' title={media.mediaListEntry.status} /> | ||
{/if} | ||
{media.title.userPreferred} | ||
</div> | ||
<div class='d-flex flex-row mt-auto pt-10 font-weight-medium justify-content-between w-full text-muted'> | ||
<div class='d-flex align-items-center' style='margin-left: -3px'> | ||
<span class='material-symbols-outlined font-size-24 pr-5'>calendar_month</span> | ||
{media.seasonYear || 'N/A'} | ||
</div> | ||
<div class='d-flex align-items-center'> | ||
{formatMap[media.format]} | ||
<span class='material-symbols-outlined font-size-24 pl-5'>monitor</span> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
|
||
<style> | ||
.first-check:first-child :global(.absolute-container) { | ||
left: -48% !important | ||
} | ||
.title { | ||
display: -webkit-box; | ||
-webkit-line-clamp: 2; | ||
-webkit-box-orient: vertical; | ||
} | ||
img { | ||
height: 27rem; | ||
} | ||
.item { | ||
animation: 0.3s ease 0s 1 load-in; | ||
width: 19rem; | ||
contain-intrinsic-height: 36.7rem; | ||
} | ||
.cover-img { | ||
background-color: var(--color) !important; | ||
} | ||
.list-status-circle { | ||
background: var(--statusColor); | ||
height: 1.1rem; | ||
width: 1.1rem; | ||
border-radius: 50%; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export const formatMap = { | ||
TV: 'TV Series', | ||
TV_SHORT: 'TV Short', | ||
MOVIE: 'Movie', | ||
SPECIAL: 'Special', | ||
OVA: 'OVA', | ||
ONA: 'ONA', | ||
MUSIC: 'Music', | ||
undefined: 'N/A', | ||
null: 'N/A' | ||
} | ||
|
||
export const statusColorMap = { | ||
CURRENT: 'rgb(61,180,242)', | ||
PLANNING: 'rgb(247,154,99)', | ||
COMPLETED: 'rgb(123,213,85)', | ||
PAUSED: 'rgb(250,122,122)', | ||
REPEATING: '#3baeea', | ||
DROPPED: 'rgb(232,93,117)' | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,4 +9,8 @@ hr { | |
|
||
.h-vh-half { | ||
height: 50vh; | ||
} | ||
|
||
:root { | ||
--container-xl-max-width: 150rem | ||
} |
Oops, something went wrong.