Skip to content

Commit a849175

Browse files
committed
Refactor aspect ratio on MainMedia to contain string representation for image
1 parent 9682a6c commit a849175

7 files changed

Lines changed: 79 additions & 27 deletions

File tree

dotcom-rendering/fixtures/manual/trails.ts

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,10 @@ export const selfHostedLoopVideo54Card = {
706706
height: 400,
707707
},
708708
],
709-
aspectRatio: 5 / 4,
709+
aspectRatio: {
710+
numberRepresentation: 5 / 4,
711+
stringRepresentation: '5:4',
712+
},
710713
duration: 30,
711714
image: 'https://media.guim.co.uk/6537e163c9164d25ec6102641f6a04fa5ba76560/0_210_5472_3283/master/5472.jpg',
712715
},
@@ -730,7 +733,10 @@ export const selfHostedLoopVideo45Card = {
730733
height: 720,
731734
},
732735
],
733-
aspectRatio: 4 / 5,
736+
aspectRatio: {
737+
numberRepresentation: 4 / 5,
738+
stringRepresentation: '4:5',
739+
},
734740
},
735741
} satisfies DCRFrontCard;
736742

@@ -747,7 +753,10 @@ export const selfHostedLoopVideo53Card = {
747753
height: 720,
748754
},
749755
],
750-
aspectRatio: 5 / 3,
756+
aspectRatio: {
757+
numberRepresentation: 5 / 3,
758+
stringRepresentation: '5:3',
759+
},
751760
},
752761
} satisfies DCRFrontCard;
753762

@@ -764,7 +773,10 @@ export const selfHostedLoopVideo916Card = {
764773
height: 720,
765774
},
766775
],
767-
aspectRatio: 9 / 16,
776+
aspectRatio: {
777+
numberRepresentation: 9 / 16,
778+
stringRepresentation: '9:16',
779+
},
768780
},
769781
} satisfies DCRFrontCard;
770782

@@ -781,7 +793,10 @@ export const selfHostedLoopVideo169Card = {
781793
height: 720,
782794
},
783795
],
784-
aspectRatio: 16 / 9,
796+
aspectRatio: {
797+
numberRepresentation: 16 / 9,
798+
stringRepresentation: '16:9',
799+
},
785800
},
786801
} satisfies DCRFrontCard;
787802

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ const mainSelfHostedVideo: MainMedia = {
8484
height: 1080,
8585
},
8686
],
87-
aspectRatio: 16 / 9,
87+
aspectRatio: { numberRepresentation: 16 / 9, stringRepresentation: '16:9' },
8888
image: `https://i.guim.co.uk/img/media/2eb01d138eb8fba6e59ce7589a60e3ff984f6a7a/0_0_1920_1080/1920.jpg?width=1200&quality=45&dpr=2&s=none`,
8989
duration: 100,
9090
};

dotcom-rendering/src/components/SelfHostedVideo.island.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import {
2525
} from '../lib/video';
2626
import { palette } from '../palette';
2727
import type { RoleType } from '../types/content';
28-
import type { VideoPlayerFormat } from '../types/mainMedia';
28+
import type { AspectRatio, VideoPlayerFormat } from '../types/mainMedia';
2929
import type { RenderingTarget } from '../types/renderingTarget';
3030
import { Caption } from './Caption';
3131
import { CardPicture, type Props as CardPictureProps } from './CardPicture';
@@ -185,15 +185,18 @@ const dispatchOphanAttentionEvent = (
185185
document.dispatchEvent(event);
186186
};
187187

188-
const getOptimisedPosterImage = (mainImage: string): string => {
188+
const getOptimisedPosterImage = (
189+
mainImage: string,
190+
aspectRatio: string,
191+
): string => {
189192
// This only runs on the client
190193
const resolution = window.devicePixelRatio >= 2 ? 'high' : 'low';
191194

192195
return generateImageURL({
193196
mainImage,
194197
imageWidth: 940, // The widest a video can be: flexible special container, giga-boosted slot
195198
resolution,
196-
aspectRatio: '5:4',
199+
aspectRatio,
197200
});
198201
};
199202

@@ -284,7 +287,7 @@ type Props = {
284287
atomId: string;
285288
uniqueId: string;
286289
videoStyle: VideoPlayerFormat;
287-
aspectRatio: number;
290+
aspectRatio: AspectRatio;
288291
posterImage: string;
289292
fallbackImage: CardPictureProps['mainImage'];
290293
fallbackImageSize: CardPictureProps['imageSize'];
@@ -880,13 +883,15 @@ export const SelfHostedVideo = ({
880883

881884
/** The aspect ratio of the video will be clamped within the specified range */
882885
const aspectRatioOfVisibleVideo = getAspectRatioOfVisibleVideo(
883-
aspectRatio,
886+
aspectRatio.numberRepresentation,
884887
minAspectRatio,
885888
maxAspectRatio,
886889
);
887890

888-
const isVideoCroppedAtTopBottom = aspectRatio < aspectRatioOfVisibleVideo;
889-
const isVideoCroppedAtLeftRight = aspectRatio > aspectRatioOfVisibleVideo;
891+
const isVideoCroppedAtTopBottom =
892+
aspectRatio.numberRepresentation < aspectRatioOfVisibleVideo;
893+
const isVideoCroppedAtLeftRight =
894+
aspectRatio.numberRepresentation > aspectRatioOfVisibleVideo;
890895

891896
const isGreyBarsAtSidesOnDesktop =
892897
containerAspectRatioDesktop !== undefined &&
@@ -899,7 +904,7 @@ export const SelfHostedVideo = ({
899904
const AudioIcon = isMuted ? SvgAudioMute : SvgAudio;
900905

901906
const optimisedPosterImage = showPosterImage
902-
? getOptimisedPosterImage(posterImage)
907+
? getOptimisedPosterImage(posterImage, aspectRatio.stringRepresentation)
903908
: undefined;
904909

905910
return (
@@ -922,7 +927,7 @@ export const SelfHostedVideo = ({
922927
>
923928
<div
924929
css={figureStyles(
925-
aspectRatio,
930+
aspectRatio.numberRepresentation,
926931
aspectRatioOfVisibleVideo,
927932
isGreyBarsAtSidesOnDesktop,
928933
isGreyBarsAtTopAndBottomOnDesktop,
@@ -935,7 +940,7 @@ export const SelfHostedVideo = ({
935940
sources={optimisedSources}
936941
atomId={atomId}
937942
uniqueId={uniqueId}
938-
aspectRatio={aspectRatio}
943+
aspectRatio={aspectRatio.numberRepresentation}
939944
width={width}
940945
height={height}
941946
videoStyle={videoStyle}

dotcom-rendering/src/lib/video.test.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,10 @@ describe('video', () => {
169169
width: 480,
170170
aspectRatio: '5:3',
171171
};
172-
expect(getAspectRatioFromSources([testSource])).toEqual(5 / 3);
172+
expect(getAspectRatioFromSources([testSource])).toEqual({
173+
numberRepresentation: 5 / 3,
174+
stringRepresentation: '5:3',
175+
});
173176
});
174177

175178
it('should calculate the aspect ratio from the width and height if aspect ratio is missing', () => {
@@ -179,7 +182,10 @@ describe('video', () => {
179182
width: 480,
180183
aspectRatio: undefined,
181184
};
182-
expect(getAspectRatioFromSources([testSource])).toEqual(2 / 3);
185+
expect(getAspectRatioFromSources([testSource])).toEqual({
186+
numberRepresentation: 2 / 3,
187+
stringRepresentation: '2:3',
188+
});
183189
});
184190

185191
it('should return the default aspect ratio if the aspect ratio is undefined and width is 0', () => {
@@ -189,7 +195,10 @@ describe('video', () => {
189195
width: 0,
190196
aspectRatio: undefined,
191197
};
192-
expect(getAspectRatioFromSources([testSource])).toEqual(5 / 4);
198+
expect(getAspectRatioFromSources([testSource])).toEqual({
199+
numberRepresentation: 5 / 4,
200+
stringRepresentation: '5:4',
201+
});
193202
});
194203

195204
it('should return the default aspect ratio if the aspect ratio is undefined and height is 0', () => {
@@ -199,7 +208,10 @@ describe('video', () => {
199208
width: 480,
200209
aspectRatio: undefined,
201210
};
202-
expect(getAspectRatioFromSources([testSource])).toEqual(5 / 4);
211+
expect(getAspectRatioFromSources([testSource])).toEqual({
212+
numberRepresentation: 5 / 4,
213+
stringRepresentation: '5:4',
214+
});
203215
});
204216
});
205217

dotcom-rendering/src/lib/video.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import type { VideoAssets } from '../types/content';
44
export type CustomPlayEventDetail = { uniqueId: string };
55

66
/** We expect all videos to include dimensions since the field was added to FEMediaAsset */
7-
export const DEFAULT_ASPECT_RATIO = 5 / 4;
7+
const DEFAULT_ASPECT_RATIO_NUMBER = 5 / 4;
8+
const DEFAULT_ASPECT_RATIO_STRING = '5:4';
89

910
export const customSelfHostedVideoPlayAudioEventName =
1011
'self-hosted-video:play-with-audio';
@@ -77,7 +78,9 @@ export const convertFEMediaAssetsToVideoAssets = (
7778
* We use the first source to calculate aspect ratio, but we could use any of the sources.
7879
* We make an assumption that all sources will have the same aspect ratio.
7980
*/
80-
export const getAspectRatioFromSources = (sources: Source[]): number => {
81+
export const getAspectRatioFromSources = (
82+
sources: Source[],
83+
): { numberRepresentation: number; stringRepresentation: string } => {
8184
const firstSource = sources[0];
8285

8386
if (firstSource?.aspectRatio !== undefined) {
@@ -88,15 +91,24 @@ export const getAspectRatioFromSources = (sources: Source[]): number => {
8891
width > 0 &&
8992
height > 0
9093
) {
91-
return width / height;
94+
return {
95+
numberRepresentation: width / height,
96+
stringRepresentation: `${width}:${height}`,
97+
};
9298
}
9399
}
94100

95101
if (!firstSource || firstSource.width === 0 || firstSource.height === 0) {
96-
return DEFAULT_ASPECT_RATIO;
102+
return {
103+
numberRepresentation: DEFAULT_ASPECT_RATIO_NUMBER,
104+
stringRepresentation: DEFAULT_ASPECT_RATIO_STRING,
105+
};
97106
}
98107

99-
return firstSource.width / firstSource.height;
108+
return {
109+
numberRepresentation: firstSource.width / firstSource.height,
110+
stringRepresentation: `${firstSource.width}:${firstSource.height}`,
111+
};
100112
};
101113

102114
export const getSubtitleAsset = (assets: VideoAssets[]): string | undefined =>

dotcom-rendering/src/model/enhanceCards.test.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,10 @@ describe('Enhance Cards', () => {
276276
videoStyle: 'Loop',
277277
atomId: 'atomID',
278278
sources: [],
279-
aspectRatio: 5 / 4,
279+
aspectRatio: {
280+
numberRepresentation: 5 / 4,
281+
stringRepresentation: '5:4',
282+
},
280283
duration: 151,
281284
};
282285

dotcom-rendering/src/types/mainMedia.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ type Media = {
77
type: 'YoutubeVideo' | 'SelfHostedVideo' | 'Audio' | 'Gallery';
88
};
99

10+
export type AspectRatio = {
11+
numberRepresentation: number;
12+
stringRepresentation: string;
13+
};
14+
1015
/** For displaying embedded, playable videos directly in cards */
1116
export type YoutubeVideo = Media & {
1217
type: 'YoutubeVideo';
@@ -28,7 +33,7 @@ type SelfHostedVideo = Media & {
2833
videoStyle: VideoPlayerFormat;
2934
atomId: string;
3035
sources: Source[];
31-
aspectRatio: number;
36+
aspectRatio: AspectRatio;
3237
duration: number;
3338
subtitleSource?: string;
3439
image?: string;

0 commit comments

Comments
 (0)