Skip to content

Commit f8bf3f7

Browse files
committed
Optimise poster image
1 parent 0a2727c commit f8bf3f7

File tree

3 files changed

+31
-16
lines changed

3 files changed

+31
-16
lines changed

dotcom-rendering/src/components/Card/Card.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -891,11 +891,11 @@ export const Card = ({
891891
>
892892
<LoopVideo
893893
src={media.mainMedia.videoId}
894+
atomId={media.mainMedia.atomId}
895+
uniqueId={uniqueId}
894896
height={media.mainMedia.height}
895897
width={media.mainMedia.width}
896-
image={media.mainMedia.image ?? ''}
897-
uniqueId={uniqueId}
898-
atomId={media.mainMedia.atomId}
898+
posterImage={media.mainMedia.image ?? ''}
899899
fallbackImage={media.mainMedia.image ?? ''}
900900
fallbackImageSize={imageSize}
901901
fallbackImageLoading={imageLoading}

dotcom-rendering/src/components/LoopVideo.importable.tsx

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
submitComponentEvent,
99
} from '../client/ophan/ophan';
1010
import { getZIndex } from '../lib/getZIndex';
11+
import { generateImageURL } from '../lib/image';
1112
import { useIsInView } from '../lib/useIsInView';
1213
import { useShouldAdapt } from '../lib/useShouldAdapt';
1314
import type { CustomPlayEventDetail } from '../lib/video';
@@ -60,13 +61,24 @@ const dispatchOphanAttentionEvent = (
6061
document.dispatchEvent(event);
6162
};
6263

64+
const getOptimisedPosterImage = (mainImage: string): string => {
65+
const resolution = window.devicePixelRatio >= 2 ? 'high' : 'low';
66+
67+
return generateImageURL({
68+
mainImage,
69+
imageWidth: 940, // The widest a looping video can be: Flexible special, giga-boosted
70+
resolution,
71+
aspectRatio: '5:4',
72+
});
73+
};
74+
6375
type Props = {
6476
src: string;
6577
atomId: string;
6678
uniqueId: string;
67-
width: number;
6879
height: number;
69-
image: string;
80+
width: number;
81+
posterImage: string;
7082
fallbackImage: CardPictureProps['mainImage'];
7183
fallbackImageSize: CardPictureProps['imageSize'];
7284
fallbackImageLoading: CardPictureProps['loading'];
@@ -78,9 +90,9 @@ export const LoopVideo = ({
7890
src,
7991
atomId,
8092
uniqueId,
81-
width,
8293
height,
83-
image,
94+
width,
95+
posterImage,
8496
fallbackImage,
8597
fallbackImageSize,
8698
fallbackImageLoading,
@@ -94,9 +106,7 @@ export const LoopVideo = ({
94106
const [isMuted, setIsMuted] = useState(true);
95107
const [showPlayIcon, setShowPlayIcon] = useState(false);
96108
const [preloadPartialData, setPreloadPartialData] = useState(false);
97-
const [posterImage, setPosterImage] = useState<string | undefined>(
98-
undefined,
99-
);
109+
const [showPosterImage, setShowPosterImage] = useState<boolean>(false);
100110
const [currentTime, setCurrentTime] = useState(0);
101111
const [playerState, setPlayerState] =
102112
useState<(typeof PLAYER_STATES)[number]>('NOT_STARTED');
@@ -135,11 +145,11 @@ export const LoopVideo = ({
135145
.catch((error: Error) => {
136146
// Autoplay failed
137147
logAndReportError(src, error);
138-
setPosterImage(image);
148+
setShowPosterImage(true);
139149
setPlayerState('PAUSED_BY_BROWSER');
140150
});
141151
}
142-
}, [src, image]);
152+
}, [src]);
143153

144154
const pauseVideo = (
145155
reason: Extract<
@@ -381,9 +391,9 @@ export const LoopVideo = ({
381391
isAutoplayAllowed === false ||
382392
(isInView === false && !hasBeenInView)
383393
) {
384-
setPosterImage(image);
394+
setShowPosterImage(true);
385395
}
386-
}, [isAutoplayAllowed, isInView, hasBeenInView, image]);
396+
}, [isAutoplayAllowed, isInView, hasBeenInView]);
387397

388398
/**
389399
* We almost always want to preload some of the video data. If a user has prefers-reduced-motion
@@ -506,6 +516,10 @@ export const LoopVideo = ({
506516

507517
const AudioIcon = isMuted ? SvgAudioMute : SvgAudio;
508518

519+
const optimisedPosterImage = showPosterImage
520+
? getOptimisedPosterImage(posterImage)
521+
: undefined;
522+
509523
return (
510524
<figure
511525
ref={setNode}
@@ -519,7 +533,7 @@ export const LoopVideo = ({
519533
uniqueId={uniqueId}
520534
width={width}
521535
height={height}
522-
posterImage={posterImage}
536+
posterImage={optimisedPosterImage}
523537
FallbackImageComponent={FallbackImageComponent}
524538
currentTime={currentTime}
525539
setCurrentTime={setCurrentTime}

dotcom-rendering/src/components/LoopVideo.stories.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ export const Default: Story = {
2727
atomId: 'test-atom-1',
2828
height: 720,
2929
width: 900,
30-
image: 'https://media.guim.co.uk/9bdb802e6da5d3fd249b5060f367b3a817965f0c/0_0_1800_1080/master/1800.jpg',
30+
posterImage:
31+
'https://media.guim.co.uk/9bdb802e6da5d3fd249b5060f367b3a817965f0c/0_0_1800_1080/master/1800.jpg',
3132
fallbackImage: '',
3233
},
3334
};

0 commit comments

Comments
 (0)