Controlling videos with Alpinejs

I wrote this tutorial on Wednesday, August 26, 2020

Alpinejs is a tiny Javascript framework that lets us sprikle in different behaviour that you would usually see in big frameworks like Vuejs - but at a much lower cost. Load in the Alpinejs script from a CDN and the full 6.4kb libary is yours.

Recently I've been building a client website that didn't need a big system on the back end - and the goal is just to host it off Netlify in the end. We could of gone down the road of creating Vue components (as I reallly 💕 Vue!) but decided to give Alpine a try as all I really needed to do is make the page a bit reactive.

Controlling Videos

Videos in HTML5 are simple to get up and running - and come with some AMAZING features. Check out the article on MDN about videos to see what I mean.

Our designer created an idea for a component that had a video on it - the feature list is:

  • No controls
  • Play icon on the video which disappears when clicked
  • When video clicked it'll toggle playing / pausing

Using Alpinejs this was pretty hard to work out. Here is my solution:

<div class="flex flex-col rounded-lg shadow-lg overflow-hidden" x-data="{ play: false }" x-init="$watch('play', (value) => {
    if (value) {
        $refs.video.play()
    } else {
        $refs.video.pause()
    }
})">
<div class="flex-shrink-0 relative">
    <video x-ref="video" @click="play = !play">
        <source src="https://test-videos.co.uk/vids/bigbuckbunny/mp4/h264/360/Big_Buck_Bunny_360_10s_5MB.mp4">
        </video>
        <div @click="play = true" x-show="!play" x-transition:leave="transition ease-in duration-300" x-transition:leave-start="opacity-100 transform scale-100" x-transition:leave-end="opacity-0 transform scale-90" class="absolute inset-0 w-full h-full flex items-center justify-center">
            <svg class="h-20 w-20 text-indigo-500" fill="currentColor" viewBox="0 0 84 84">
                <circle opacity="0.9" cx="42" cy="42" r="42" fill="white"></circle>
                <path d="M55.5039 40.3359L37.1094 28.0729C35.7803 27.1869 34 28.1396 34 29.737V54.263C34 55.8604 35.7803 56.8131 37.1094 55.9271L55.5038 43.6641C56.6913 42.8725 56.6913 41.1275 55.5039 40.3359Z"></path>
            </svg>
        </div>
    </div>
</div>

You can view a demo here on CodePen

See the Pen Alpine.js controlling a video by jake (@jakeywr) on CodePen.

The magic is done by a couple of cool features of Alpinejs:

x-ref allowing us to reference our video tag inside our component.

x-init allows us to write an expression - in this case we target our video reference ($refs.video) and start and stop (or pause!) when we toggle the play state.

Created with Jigsaw, hosted on Netlify.