-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Video support #139
base: dev
Are you sure you want to change the base?
Video support #139
Conversation
Thanks for getting this started! Lots of fun stuff here. Feature 1: Play videos with triggerIn terms of API, what do you think of: Checkout this lovely video. [@cr-vid]{play-video="true"} I'm inclined to avoid any mention of Feature 2: Control video progression with scrollSeems simpler to use a progress block! Controlling the play speed could always be done on the video file itself in pre-processing, right? (i.e. removing frames). I'm not quite sure what the best API for this is. I like what you have. There's also this: :::{.progress-block scroll-video="cr-vid"}
Step 1
Step 2
Step 3
Step 4
::: A few things:
|
@andrewpbray Agree with you on Feature 1! I agree that a progress block is a nice interface! While I do also agree that you can change the number of frames to tweak the output speed, I think at minimum it would be good for users to be able to pause the progression between a number of steps where they want to stop and discuss something in more detail. You could technically run duplicate frames off, but it'd be a big waste of bandwidth. Maybe something like:
These sorts of pauses would be helpful for videos that sweep over an area (eg. as events unfold over time). |
Good point - that'd be some very useful functionality. One thing I'm realizing: we have Scroll a video through a single narrative block:::{#cr-myvid}
{{< video myvid.mov >}}
:::
Step 1. [@cr-myvid]{.scroll-video} Scroll a video through a progress block:::{#cr-myvid}
{{< video myvid.mov >}}
:::
:::{.scroll-video focus-on="cr-myvid"}
Step 1.
Step 2.
Step 3.
::: This raises a few interface questions:
|
Maybe we wade into getting a working example of an image sequence and see how it turns out. That'll probably help clarify which interface makes the most sense. Looking back, my stuff above is all based on the general notion of a "video" but image sequences are a slightly different beast; there's not just one file to point to. I love the |
@jimjam-slam Here's a first pass at implementing feature 1. It's implemented generically so that One thing to decide is question 1 above. Should these be classes instead of attributes? This should be determined I think just based on what seems like the best interface. The implementation is straightforward - change this JS function to reference classes instead of attributes and then modify the lua filter so that a trigger will pass both classes and attributes to its enclosing block ( While testing this out, I did bump into this: https://developer.chrome.com/blog/autoplay/. Essentially, if the user does nothing but scroll straight down, it might not execute |
I've been tinkering this morning with tying In order words, I've been trying the "traditional" method 3. What are your thoughts on using a dedicated library for this sort of thing? It looks like the author has been working is within the last 3 mo, which is a good sign. If these video standards change over time, sure would be nice if we could take advantage of his keeping things up to date. |
I've gotta come back to your comments properly, sorry @andrewpbray! I had half an hour and banged out some rayshader code to generate a sample video. |
Okay, I've just deleted a big wall of text — turns out that apart from specific HTML boolean attributes (like the ones that actually go on video elements), where the mere presence of the boolean attribute makes it true, attributes are always supposed to have values. So maybe |
I'll try hooking this up now — if we can do it with an external lib, I'm down for that! It seems like it's handling a few tasks (ie. it's not just setting the progress as we probably would), so it probably makes sense to have a dependency handle it. On a semi-related note (which I'll spin out to a separate issue later), it might be worth us incorporating a web bundler to track our external dependencies... |
One other thing: I realised that when I set up the demo with the ship and tea videos, I wrote them inline:
As opposed to:
or:
The commit I've just pushed generalises the CSS a bit more so that it should work regardless of whether you put |
I've managed to load the video with ScrollyVideo, but the default |
a40df27 has a single scrollytelling video working (I've hardcoded it straight into the .js file, so it'll break the rest of the site). So it seems like it works conceptually! This demo just ties things to trigger progress, so when you scroll from one trigger to another, it goes from 100% to 0% and the video essentially rewinds quickly. I think for that case you'd probably want no interpolation at all (if, indeed, it is require usually!). Generalising this means working out what the JS code has to track in order to potentially advance several videos. I think it's probably worth us talking through the API in person @andrewpbray before I jump into that! |
Just summarising our discussion @andrewpbray — this was a candidate API we were looking at (but still discussing if either of us is unhappy with it!): Non-scrolling videos
One thing I'd noticed but might spin into a separate issue is that we never show a sticky until the first trigger hits. Videos are a case where you'd probably want the first sticky to be visible without having to hit a sticky first, but there might be others (in fact it might even be an appropriate default). Scrolling videos
Some considerations for scrolling video: Right now this scrolling video is hardcoded in to the JS code, but in real use it needs to be specified in the QMD. Two ways we could do that:
We might want to consider how our choice in API impacts people's ability to transition from a scrolling video to some other type of sticky (is there any impact?). |
I've added the first part of this work in 998617c and 485f235: videos that autoplay and loop. Really it's just a class to ensure that they run full-bleed; the looping and autoplay is done by the browser.
But as #132 discusses, we might want video to hold off starting until it's visible. So the next part is to trigger that manually wth JS.
I think it probably makes sense to add a shortcut, analogous to Quarto's
video
shortcode, to do this while inserting the necessary attributes (eg.preload
) on thevideo
tag. (In fact, we may end up borrowing their chortcode and tweaking it!)The last part of this is the most complicated: image sequences that progress as you scroll through the container (although I'd love to know if you can do this with a traditional video!).
Most of the implementations of this I've seen (eg. this one on
dev.to
— it uses React, but the principle should apply with vanilla JS) use acanvas
element: you preload the images by calling a function ASAP to download them, then callrequestAnimationFrame()
on scroll to update which image is showing.A user might either want to use regenerated images or ones generated by a code block in the doc — but it isn't clear to me whether there's some special treatment we can give, for example, an R code block to say "use the images emitted from this code block for a scroll video".
That said, perhaps you could have:
a. a sticky block where the image glob or image path is specified as an attribute, and then
b. a trigger attribute that specifies how far through the sequence. Or perhaps a progress block... or perhaps both are viable options?
Or maybe with a progress block (although no option to vary the speed here):
<!-- can we reuse focus-on and detect that it's scrolling? --> :::{.progress-block focus-on="cr-images"} Step 1 Step 2 Step 3 Step 4 :::
What do you think, @andrewpbray?