mirror of
https://github.com/ThatGuySam/doesitarm.git
synced 2026-05-18 06:44:46 -07:00
Add video copmenents
This commit is contained in:
parent
cd3b3f13a2
commit
6acaee1b5a
3 changed files with 173 additions and 0 deletions
63
src/components/video/card.astro
Normal file
63
src/components/video/card.astro
Normal 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>
|
||||
31
src/components/video/poster.astro
Normal file
31
src/components/video/poster.astro
Normal 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>
|
||||
79
src/components/video/row.astro
Normal file
79
src/components/video/row.astro
Normal 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>
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue