Add video copmenents

This commit is contained in:
Sam Carlton 2022-04-27 14:29:21 -05:00
parent cd3b3f13a2
commit 6acaee1b5a
3 changed files with 173 additions and 0 deletions

View file

@ -0,0 +1,63 @@
---
import Poster from './poster.astro'
const {
video,
width = '325px',
classes = 'w-full flex-shrink-0 flex-grow-0 border-2 border-transparent rounded-2xl overflow-hidden'
} = Astro.props
const cardClasses = `video-card ${ classes }`
---
<div
class={ cardClasses }
style={ `max-width: ${ width }; flex-basis: ${ width }; scroll-snap-align: start;` }
>
<a
href={video.endpoint}
class=""
>
<div class="video-card-container relative overflow-hidden bg-black">
<div class="video-card-image ratio-wrapper">
<div class="relative overflow-hidden w-full pb-16/9">
<Poster video={video} />
</div>
</div>
<div
style="--gradient-from-color: rgba(0, 0, 0, 1); --gradient-to-color: rgba(0, 0, 0, 0.7)"
class="video-card-overlay absolute inset-0 flex justify-between items-start bg-gradient-to-tr from-black to-transparent p-4"
>
<div class="play-circle w-8 h-8 bg-white-2 flex justify-center items-center outline-0 rounded-full ease">
<svg
viewBox="0 0 18 18"
style="width:18px;height:18px;margin-left:3px"
>
<path
fill="currentColor"
d="M15.562 8.1L3.87.225c-.818-.562-1.87 0-1.87.9v15.75c0 .9 1.052 1.462 1.87.9L15.563 9.9c.584-.45.584-1.35 0-1.8z"
/>
</svg>
</div>
{ ( video.tags.includes('benchmark') ) ?
<div
class="video-pill h-5 text-xs bg-white-2 flex justify-center items-center outline-0 rounded-full ease px-2"
>
Benchmark
</div> : ''
}
</div>
<!-- Video Text Content -->
<div class="video-card-content absolute inset-0 flex items-end py-4 px-6">
<div class="w-full text-sm text-left whitespace-normal">{ video.name }</div>
</div>
</div>
</a>
</div>
<script>
import 'lazysizes'
</script>

View file

@ -0,0 +1,31 @@
---
const {
video
} = Astro.props
const webpSource = {
...video.thumbnail,
srcset: video.thumbnail.srcset.replaceAll('ytimg.com/vi/', 'ytimg.com/vi_webp/').replace(/.png|.jpg|.jpeg/g, '.webp')
}
const mergedSources = {
webp: webpSource,
jpeg: video.thumbnail
}
---
<picture>
{ Object.entries( mergedSources ).map( ([ key, source ]) => (
<source
sizes={ source.sizes }
data-srcset={ source.srcset }
type={ `image/${ key }` }
>
) ) }
<img
data-src={ video.thumbnail.src }
alt={ video.name }
class="absolute inset-0 h-full w-full object-cover lazyload"
>
</picture>

View file

@ -0,0 +1,79 @@
---
import Card from './card.astro'
const {
videos,
cardWidth = '325',
classes = ''
} = Astro.props
// Math.random should be unique because of its seeding algorithm.
// Convert it to base 36 (numbers + letters), and grab the first 9 characters
// after the decimal.
const uid = Math.random().toString(36).substr(2, 9)
const rowId = `row-${ uid }`
const rowSelector = `#${ rowId }`
---
<div class="video-row relative w-full ${ classes }">
<div
id={ rowId }
class="video-row-contents flex overflow-x-auto whitespace-no-wrap py-2 space-x-6"
style="scroll-snap-type:x mandatory;"
>
{ videos.map(video => (
<Card
key={ video.id }
video={ video }
cardWidth={ cardWidth }
/>
)) }
</div>
<button
class="scroll-button absolute left-0 h-10 w-10 flex justify-center items-center transform -translate-y-1/2 -translate-x-1/2 bg-darker rounded-full"
style="top:50%;"
distance={ cardWidth * -1 }
scroll-target={ rowSelector }
aria-label="Scroll to previous videos"
>
<svg viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5 text-gray-400" style="transform: scaleX(-1);">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path>
</svg>
</button>
<button
class="scroll-button absolute right-0 h-10 w-10 flex justify-center items-center transform -translate-y-1/2 translate-x-1/2 bg-darker rounded-full"
style="top:50%;"
distance={ cardWidth }
scroll-target={ rowSelector }
aria-label="Scroll to next videos"
>
<svg viewBox="0 0 20 20" fill="currentColor" class="h-5 w-5 text-gray-400">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd"></path>
</svg>
</button>
</div>
<script is:inline>
function scrollHorizontalCarousel ( event ) {
event.stopPropagation()
// console.log('event.target', event.currentTarget)
// console.log('distance', event.currentTarget.getAttribute('distance'))
const distance = Number(event.currentTarget.getAttribute('distance'))
const scrollTarget = document.querySelector(event.currentTarget.getAttribute('scroll-target'))
scrollTarget.scrollBy({ left: distance, behavior: 'smooth' })
}
// Add Click listeners to all buttons
Array.from( document.querySelectorAll(`button.scroll-button`) ).forEach( button => {
// console.log('button', button)
button.addEventListener('click', scrollHorizontalCarousel)
})
</script>