Skip to content

Resume looping video when re-enters viewport #14133

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

Merged
merged 6 commits into from
Jun 26, 2025
Merged

Conversation

domlander
Copy link
Contributor

@domlander domlander commented Jun 25, 2025

What does this change?

  • Ensure thumbnail image covers the full size of the video.
  • Resume video, muted, when it is scrolled back into view.
  • If user prefers reduced motion, the video now pauses when scrolled 50% out of the viewport
  • Refactors useIsInView to be able to know for certain whether an element it out of view. This is helpful because we don't want to display (and therefore download) the poster image if the video is in view and will autoplay.
  • Refactor player state.
  • Removes the hasAudio check. We don't yet receive this flag.
  • Removes the webm option. This is not yet implemented and we will only receive mp4 files for now.
  • Moves some logic up.

Why?

Minor bug fixes, code quality improvement

Screenshots

Before After
before after

Play muted video when 50% of player re-enters viewport

Screen.Recording.2025-06-25.at.16.24.42.mov

Prefers reduced motion: ON

Screen.Recording.2025-06-25.at.16.27.22.mov

Copy link

github-actions bot commented Jun 25, 2025

@github-actions github-actions bot removed the run_chromatic Runs chromatic when label is applied label Jun 25, 2025
Copy link

github-actions bot commented Jun 25, 2025

Size Change: +380 B (+0.04%)

Total Size: 1.05 MB

Filename Size Change
dotcom-rendering/dist/2909.client.web.********************.js 20.2 kB +176 B (+0.88%)
dotcom-rendering/dist/LoopVideo-importable.client.web.********************.js 5.87 kB +194 B (+3.42%)
ℹ️ View Unchanged
Filename Size Change
dotcom-rendering/dist/1160.client.web.********************.js 3.56 kB 0 B
dotcom-rendering/dist/137.client.web.********************.js 3.82 kB 0 B
dotcom-rendering/dist/1521.client.web.********************.js 2.89 kB 0 B
dotcom-rendering/dist/1931.client.web.********************.js 2.83 kB 0 B
dotcom-rendering/dist/21.client.web.********************.js 3.77 kB 0 B
dotcom-rendering/dist/2102.client.web.********************.js 10.7 kB 0 B
dotcom-rendering/dist/2244.client.web.********************.js 3.56 kB 0 B
dotcom-rendering/dist/233.client.web.********************.js 3.18 kB 0 B
dotcom-rendering/dist/2373.client.web.********************.js 4.54 kB 0 B
dotcom-rendering/dist/2400.client.web.********************.js 2.11 kB 0 B
dotcom-rendering/dist/2523.client.web.********************.js 3.9 kB 0 B
dotcom-rendering/dist/2629.client.web.********************.js 5.84 kB 0 B
dotcom-rendering/dist/3342.client.web.********************.js 3.67 kB 0 B
dotcom-rendering/dist/3944.client.web.********************.js 2.51 kB 0 B
dotcom-rendering/dist/3979.client.web.********************.js 4.18 kB +2 B (+0.05%)
dotcom-rendering/dist/4079.client.web.********************.js 11.8 kB 0 B
dotcom-rendering/dist/4183.client.web.********************.js 20.5 kB 0 B
dotcom-rendering/dist/420.client.web.********************.js 4.35 kB 0 B
dotcom-rendering/dist/4312.client.web.********************.js 3.07 kB 0 B
dotcom-rendering/dist/4324.client.web.********************.js 5.83 kB 0 B
dotcom-rendering/dist/4501.client.web.********************.js 4.29 kB 0 B
dotcom-rendering/dist/4524.client.web.********************.js 3.62 kB 0 B
dotcom-rendering/dist/4754.client.web.********************.js 7.66 kB 0 B
dotcom-rendering/dist/5117.client.web.********************.js 49.9 kB 0 B
dotcom-rendering/dist/5128.client.web.********************.js 19.8 kB +3 B (+0.02%)
dotcom-rendering/dist/5462.client.web.********************.js 157 B 0 B
dotcom-rendering/dist/5549.client.web.********************.js 3.9 kB +2 B (+0.05%)
dotcom-rendering/dist/5895.client.web.********************.js 22.8 kB 0 B
dotcom-rendering/dist/5901.client.web.********************.js 4.21 kB 0 B
dotcom-rendering/dist/5980.client.web.********************.js 5.43 kB 0 B
dotcom-rendering/dist/6085.client.web.********************.js 530 B 0 B
dotcom-rendering/dist/6232.client.web.********************.js 620 B 0 B
dotcom-rendering/dist/6255.client.web.********************.js 12 kB 0 B
dotcom-rendering/dist/6316.client.web.********************.js 5.04 kB 0 B
dotcom-rendering/dist/6317.client.web.********************.js 4.24 kB 0 B
dotcom-rendering/dist/6346.client.web.********************.js 2.75 kB 0 B
dotcom-rendering/dist/6369.client.web.********************.js 4.78 kB 0 B
dotcom-rendering/dist/6501.client.web.********************.js 65.6 kB 0 B
dotcom-rendering/dist/6504.client.web.********************.js 3.29 kB 0 B
dotcom-rendering/dist/6683.client.web.********************.js 2.87 kB 0 B
dotcom-rendering/dist/6694.client.web.********************.js 2.76 kB 0 B
dotcom-rendering/dist/6721.client.web.********************.js 3.2 kB 0 B
dotcom-rendering/dist/6843.client.web.********************.js 3.67 kB 0 B
dotcom-rendering/dist/7008.client.web.********************.js 4.7 kB 0 B
dotcom-rendering/dist/7028.client.web.********************.js 3.17 kB 0 B
dotcom-rendering/dist/7116.client.web.********************.js 23.2 kB 0 B
dotcom-rendering/dist/728.client.web.********************.js 3.6 kB 0 B
dotcom-rendering/dist/739.client.web.********************.js 528 B 0 B
dotcom-rendering/dist/7540.client.web.********************.js 2.86 kB 0 B
dotcom-rendering/dist/7678.client.web.********************.js 3.78 kB 0 B
dotcom-rendering/dist/7819.client.web.********************.js 3.87 kB 0 B
dotcom-rendering/dist/7829.client.web.********************.js 3.27 kB 0 B
dotcom-rendering/dist/7979.client.web.********************.js 2.75 kB 0 B
dotcom-rendering/dist/7986.client.web.********************.js 3.04 kB -2 B (-0.07%)
dotcom-rendering/dist/8110.client.web.********************.js 3.49 kB 0 B
dotcom-rendering/dist/8143.client.web.********************.js 16.5 kB 0 B
dotcom-rendering/dist/8361.client.web.********************.js 3.45 kB 0 B
dotcom-rendering/dist/8389.client.web.********************.js 2.63 kB 0 B
dotcom-rendering/dist/8393.client.web.********************.js 3.34 kB 0 B
dotcom-rendering/dist/8406.client.web.********************.js 438 B 0 B
dotcom-rendering/dist/8569.client.web.********************.js 5.04 kB -2 B (-0.04%)
dotcom-rendering/dist/8742.client.web.********************.js 4.86 kB 0 B
dotcom-rendering/dist/8938.client.web.********************.js 4.5 kB 0 B
dotcom-rendering/dist/9051.client.web.********************.js 3.4 kB 0 B
dotcom-rendering/dist/9226.client.web.********************.js 7.93 kB 0 B
dotcom-rendering/dist/939.client.web.********************.js 4.53 kB 0 B
dotcom-rendering/dist/9465.client.web.********************.js 5.64 kB 0 B
dotcom-rendering/dist/9599.client.web.********************.js 3.85 kB 0 B
dotcom-rendering/dist/9606.client.web.********************.js 2.69 kB 0 B
dotcom-rendering/dist/9999.client.web.********************.js 5.39 kB 0 B
dotcom-rendering/dist/Accessibility-importable.client.web.********************.js 8.48 kB 0 B
dotcom-rendering/dist/AdBlockAsk-importable.client.web.********************.js 2.99 kB 0 B
dotcom-rendering/dist/AdPortals-importable.client.web.********************.js 4.78 kB 0 B
dotcom-rendering/dist/AlreadyVisited-importable.client.web.********************.js 424 B 0 B
dotcom-rendering/dist/AppsEpic-importable.client.web.********************.js 3.64 kB +1 B (+0.03%)
dotcom-rendering/dist/AppsFooter-importable.client.web.********************.js 2.71 kB 0 B
dotcom-rendering/dist/AppsLightboxImage-importable.client.web.********************.js 2.69 kB 0 B
dotcom-rendering/dist/AppsLightboxImageStore-importable.client.web.********************.js 2.63 kB 0 B
dotcom-rendering/dist/AudioAtomWrapper-importable.client.web.********************.js 2.76 kB 0 B
dotcom-rendering/dist/AudioPlayerWrapper-importable.client.web.********************.js 6.61 kB 0 B
dotcom-rendering/dist/AustralianTerritorySwitcher-importable.client.web.********************.js 4.6 kB 0 B
dotcom-rendering/dist/Branding-importable.client.web.********************.js 2.87 kB 0 B
dotcom-rendering/dist/braze-web-sdk-core.client.web.********************.js 67.7 kB 0 B
dotcom-rendering/dist/BrazeMessaging-importable.client.web.********************.js 1.68 kB 0 B
dotcom-rendering/dist/CalloutBlockComponent-importable.client.web.********************.js 6.73 kB 0 B
dotcom-rendering/dist/CalloutEmbedBlockComponent-importable.client.web.********************.js 5.77 kB 0 B
dotcom-rendering/dist/CardCommentCount-importable.client.web.********************.js 2.67 kB 0 B
dotcom-rendering/dist/Carousel-importable.client.web.********************.js 6.67 kB 0 B
dotcom-rendering/dist/CarouselForNewsletters-importable.client.web.********************.js 4.57 kB 0 B
dotcom-rendering/dist/ChartAtom-importable.client.web.********************.js 540 B 0 B
dotcom-rendering/dist/CommentCount-importable.client.web.********************.js 2.28 kB 0 B
dotcom-rendering/dist/CrosswordComponent-importable.client.web.********************.js 2.87 kB 0 B
dotcom-rendering/dist/DiscussionApps-importable.client.web.********************.js 1.99 kB 0 B
dotcom-rendering/dist/DiscussionMeta-importable.client.web.********************.js 2.39 kB 0 B
dotcom-rendering/dist/DiscussionWeb-importable.client.web.********************.js 1.69 kB 0 B
dotcom-rendering/dist/DocumentBlockComponent-importable.client.web.********************.js 2.85 kB 0 B
dotcom-rendering/dist/Dropdown-importable.client.web.********************.js 1.72 kB 0 B
dotcom-rendering/dist/EditionSwitcherBanner-importable.client.web.********************.js 4.42 kB 0 B
dotcom-rendering/dist/EmbedBlockComponent-importable.client.web.********************.js 3.97 kB 0 B
dotcom-rendering/dist/EnhancePinnedPost-importable.client.web.********************.js 2.02 kB 0 B
dotcom-rendering/dist/FetchOnwardsData-importable.client.web.********************.js 1.73 kB 0 B
dotcom-rendering/dist/FilterKeyEventsToggle-importable.client.web.********************.js 3.71 kB 0 B
dotcom-rendering/dist/FocusStyles-importable.client.web.********************.js 619 B 0 B
dotcom-rendering/dist/FollowWrapper-importable.client.web.********************.js 2.51 kB 0 B
dotcom-rendering/dist/FootballMatchesPageWrapper-importable.client.web.********************.js 7.33 kB 0 B
dotcom-rendering/dist/FootballTablesCompetitionSelect-importable.client.web.********************.js 3.27 kB 0 B
dotcom-rendering/dist/FooterLabel-importable.client.web.********************.js 364 B 0 B
dotcom-rendering/dist/FooterReaderRevenueLinks-importable.client.web.********************.js 3.41 kB 0 B
dotcom-rendering/dist/frameworks.client.web.********************.js 20.9 kB 0 B
dotcom-rendering/dist/FrontSubNav-importable.client.web.********************.js 7.47 kB 0 B
dotcom-rendering/dist/GetCricketScoreboard-importable.client.web.********************.js 6.24 kB +1 B (+0.02%)
dotcom-rendering/dist/GetMatchNav-importable.client.web.********************.js 12 kB 0 B
dotcom-rendering/dist/GetMatchStats-importable.client.web.********************.js 8.06 kB 0 B
dotcom-rendering/dist/GetMatchTabs-importable.client.web.********************.js 2.57 kB 0 B
dotcom-rendering/dist/guardian-braze-components-banner.client.web.********************.js 15.8 kB 0 B
dotcom-rendering/dist/guardian-braze-components-end-of-article.client.web.********************.js 10.2 kB 0 B
dotcom-rendering/dist/GuideAtomWrapper-importable.client.web.********************.js 779 B 0 B
dotcom-rendering/dist/index.client.web.********************.js 46.6 kB -3 B (-0.01%)
dotcom-rendering/dist/InstagramBlockComponent-importable.client.web.********************.js 2.9 kB 0 B
dotcom-rendering/dist/InteractiveAtomMessenger-importable.client.web.********************.js 851 B 0 B
dotcom-rendering/dist/InteractiveBlockComponent-importable.client.web.********************.js 8.79 kB 0 B
dotcom-rendering/dist/InteractiveContentsBlockComponent-importable.client.web.********************.js 3.79 kB 0 B
dotcom-rendering/dist/InteractivesDisableArticleSwipe-importable.client.web.********************.js 2.18 kB 0 B
dotcom-rendering/dist/InteractivesNativePlatformWrapper-importable.client.web.********************.js 3.2 kB 0 B
dotcom-rendering/dist/KeyEventsCarousel-importable.client.web.********************.js 5.72 kB +2 B (+0.03%)
dotcom-rendering/dist/KnowledgeQuizAtom-importable.client.web.********************.js 3.23 kB 0 B
dotcom-rendering/dist/LatestLinks-importable.client.web.********************.js 7.81 kB +3 B (+0.04%)
dotcom-rendering/dist/LightboxHash-importable.client.web.********************.js 435 B 0 B
dotcom-rendering/dist/LightboxLayout-importable.client.web.********************.js 6.58 kB 0 B
dotcom-rendering/dist/LiveBlogEpic-importable.client.web.********************.js 3.59 kB 0 B
dotcom-rendering/dist/LiveblogGutterAskWrapper-importable.client.web.********************.js 2.51 kB 0 B
dotcom-rendering/dist/LiveblogNotifications-importable.client.web.********************.js 4.87 kB 0 B
dotcom-rendering/dist/Liveness-importable.client.web.********************.js 4.71 kB 0 B
dotcom-rendering/dist/ManyNewsletterSignUp-importable.client.web.********************.js 7.64 kB 0 B
dotcom-rendering/dist/MapEmbedBlockComponent-importable.client.web.********************.js 6.03 kB 0 B
dotcom-rendering/dist/Metrics-importable.client.web.********************.js 2.7 kB 0 B
dotcom-rendering/dist/MostViewedFooter-importable.client.web.********************.js 3.85 kB 0 B
dotcom-rendering/dist/MostViewedFooterData-importable.client.web.********************.js 5.95 kB 0 B
dotcom-rendering/dist/MostViewedRightWithAd-importable.client.web.********************.js 5.24 kB 0 B
dotcom-rendering/dist/OnwardsUpper-importable.client.web.********************.js 5.11 kB 0 B
dotcom-rendering/dist/PersonalityQuizAtom-importable.client.web.********************.js 3.36 kB 0 B
dotcom-rendering/dist/ProfileAtom-importable.client.web.********************.js 540 B 0 B
dotcom-rendering/dist/ProfileAtomWrapper-importable.client.web.********************.js 801 B 0 B
dotcom-rendering/dist/PulsingDot-importable.client.web.********************.js 752 B 0 B
dotcom-rendering/dist/QandaAtom-importable.client.web.********************.js 538 B 0 B
dotcom-rendering/dist/ReaderRevenueDev-importable.client.web.********************.js 470 B 0 B
dotcom-rendering/dist/readerRevenueDevUtils.client.web.********************.js 1.7 kB 0 B
dotcom-rendering/dist/RelativeTime-importable.client.web.********************.js 2.54 kB +2 B (+0.08%)
dotcom-rendering/dist/RichLinkComponent-importable.client.web.********************.js 6.14 kB 0 B
dotcom-rendering/dist/ScrollableFeature-importable.client.web.********************.js 6.82 kB 0 B
dotcom-rendering/dist/ScrollableHighlights-importable.client.web.********************.js 7.2 kB 0 B
dotcom-rendering/dist/ScrollableMedium-importable.client.web.********************.js 2.19 kB 0 B
dotcom-rendering/dist/ScrollableSmall-importable.client.web.********************.js 2.26 kB 0 B
dotcom-rendering/dist/SecureSignup-importable.client.web.********************.js 4.22 kB 0 B
dotcom-rendering/dist/SendTargetingParams-importable.client.web.********************.js 2.24 kB 0 B
dotcom-rendering/dist/sentry.client.web.********************.js 803 B 0 B
dotcom-rendering/dist/SetABTests-importable.client.web.********************.js 3.93 kB 0 B
dotcom-rendering/dist/SetAdTargeting-importable.client.web.********************.js 485 B 0 B
dotcom-rendering/dist/ShareButton-importable.client.web.********************.js 2.17 kB 0 B
dotcom-rendering/dist/shimport.client.web.********************.js 2.8 kB 0 B
dotcom-rendering/dist/ShowHideContainers-importable.client.web.********************.js 877 B 0 B
dotcom-rendering/dist/ShowMore-importable.client.web.********************.js 918 B 0 B
dotcom-rendering/dist/SignInGateMain.client.web.********************.js 1.11 kB 0 B
dotcom-rendering/dist/SignInGateMainCheckoutComplete.client.web.********************.js 2.6 kB 0 B
dotcom-rendering/dist/SignInGateSelector-importable.client.web.********************.js 5.04 kB 0 B
dotcom-rendering/dist/SlideshowCarousel-importable.client.web.********************.js 4.52 kB 0 B
dotcom-rendering/dist/SlotBodyEnd-importable.client.web.********************.js 4.91 kB 0 B
dotcom-rendering/dist/SpotifyBlockComponent-importable.client.web.********************.js 5.78 kB 0 B
dotcom-rendering/dist/StickyBottomBanner-importable.client.web.********************.js 6.13 kB +1 B (+0.02%)
dotcom-rendering/dist/SubNav-importable.client.web.********************.js 2.42 kB 0 B
dotcom-rendering/dist/TableOfContents-importable.client.web.********************.js 3.66 kB 0 B
dotcom-rendering/dist/TimelineAtom-importable.client.web.********************.js 1.23 kB 0 B
dotcom-rendering/dist/Titlepiece-importable.client.web.********************.js 13.6 kB 0 B
dotcom-rendering/dist/TopBar-importable.client.web.********************.js 8.82 kB 0 B
dotcom-rendering/dist/TopBarSupport-importable.client.web.********************.js 2.5 kB 0 B
dotcom-rendering/dist/TweetBlockComponent-importable.client.web.********************.js 1.13 kB 0 B
dotcom-rendering/dist/UnsafeEmbedBlockComponent-importable.client.web.********************.js 2.91 kB 0 B
dotcom-rendering/dist/VideoFacebookBlockComponent-importable.client.web.********************.js 6.05 kB 0 B
dotcom-rendering/dist/VineBlockComponent-importable.client.web.********************.js 3.33 kB 0 B
dotcom-rendering/dist/YoutubeBlockComponent-importable.client.web.********************.js 843 B 0 B

compressed-size-action

@domlander domlander added run_chromatic Runs chromatic when label is applied and removed dotcom-rendering labels Jun 25, 2025
@github-actions github-actions bot removed the run_chromatic Runs chromatic when label is applied label Jun 25, 2025
@domlander domlander marked this pull request as ready for review June 25, 2025 15:31
Copy link

Hello 👋! When you're ready to run Chromatic, please apply the run_chromatic label to this PR.

You will need to reapply the label each time you want to run Chromatic.

Click here to see the Chromatic project.

// not want videos to play automatically, e.g. prefers reduced motion. Otherwise,
// we do not need to download the image as the video will be autoplayed.
const posterImage =
!!prefersReducedMotion || isInView === false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we need to grab the image if the video is not in view?

Copy link
Contributor Author

@domlander domlander Jun 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this situation, where the second card has a blank space in the place of the video:
image

A little confusing, as isInView means is at least 50% in view. I wonder if there's a better name for this variable

Copy link
Contributor

@abeddow91 abeddow91 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

'PAUSED_BY_USER',
'PAUSED_BY_INTERSECTION_OBSERVER',
] as const;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like this type, it makes the intent of the loop video very easy to follow.

@domlander domlander merged commit 9fccf71 into main Jun 26, 2025
33 checks passed
@domlander domlander deleted the doml/loop-video-qa branch June 26, 2025 11:41
@prout-bot
Copy link

Seen on PROD (merged by @domlander 8 minutes and 53 seconds ago) Please check your changes!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants