Skip to content

Commit

Permalink
feat(template): support multi-speaker on the TalkBranded template (#958)
Browse files Browse the repository at this point in the history
  • Loading branch information
HugoGresse authored Apr 29, 2024
1 parent c236992 commit 0dd12ba
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 55 deletions.
4 changes: 2 additions & 2 deletions app/templates/talks/talkBranded/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,12 @@ export default function BrandedTalkPage() {
startingDate,
location,
logoUrl,
speaker: {
speakers: [{
pictureUrl: speakerPicture,
name: speakersNames,
company: speakersCompany,
job: speakersJob,
},
}],
};

const encodedParams = encodeObjectValues({
Expand Down
4 changes: 2 additions & 2 deletions remotion/compositions/templates/talk/Talks.composition.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ export const TalksComposition: React.FC = () => {
location: '5 Place Jules Ferry, 69006.',
logoUrl:
'https://user-images.githubusercontent.com/72607059/233019842-047a34a4-77c1-4200-adc8-c70a6daf8f10.svg',
speaker: {
speakers: [{
pictureUrl:
'https://res.cloudinary.com/startup-grind/image/upload/c_fill,dpr_2.0,f_auto,g_center,h_250,q_auto:good,w_250/v1/gcs/platform-data-goog/events/20200911_094649_MbC4W4N.jpg',
name: 'Julien Landuré',
company: 'Zenika Nantes',
job: 'CTO / GDE',
},
}],
}}
/>
</Folder>
Expand Down
17 changes: 12 additions & 5 deletions remotion/compositions/templates/talk/branded/BrandedSpeaker.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import {
AbsoluteFill,
interpolate,
Expand All @@ -15,22 +16,28 @@ type BrandedSpeakerProps = {
name: string;
company?: string;
job?: string;
offsetY?: number;
avatarSize?: number;
iconStyle?: React.CSSProperties;
};

export const BrandedSpeaker = ({
pictureUrl,
name,
company,
job,
offsetY = 0,
avatarSize = 200,
iconStyle,
}: BrandedSpeakerProps) => {
const frame = useCurrentFrame();
const {fps} = useVideoConfig();

const slideIn = spring({
frame,
fps,
from: -300,
to: 0,
from: -300 - offsetY,
to: 0 + offsetY,
durationInFrames: 30,
});

Expand Down Expand Up @@ -61,8 +68,8 @@ export const BrandedSpeaker = ({
<AvatarWithCaption
avatarPictureUrl={pictureUrl}
avatarStyle={{
width: 200,
height: 200,
width: avatarSize,
height: avatarSize,
border: 'none',
borderRadius: `${blobRadius1}% ${blobRadius2}% ${blobRadius3}% ${blobRadius4}% / ${blobRadius5}% ${blobRadius5}% ${blobRadius2}% ${blobRadius6}%`,
boxShadow: '20px 20px 0 white',
Expand All @@ -74,7 +81,7 @@ export const BrandedSpeaker = ({
top: slideIn,
}}
>
<BrandedSpeakerInfos name={name} company={company} job={job} />
<BrandedSpeakerInfos name={name} company={company} job={job} iconStyle={iconStyle}/>
</AvatarWithCaption>
</AbsoluteFill>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import React from 'react';
import {interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion';

import {Text} from '../../../../design/atoms/Text';
Expand All @@ -7,12 +8,14 @@ type BrandedSpeakerInfosProps = {
name: string;
company?: string;
job?: string;
iconStyle ?: React.CSSProperties;
};

export const BrandedSpeakerInfos = ({
name,
company,
job,
iconStyle,
}: BrandedSpeakerInfosProps) => {
const frame = useCurrentFrame();
const {fps} = useVideoConfig();
Expand Down Expand Up @@ -72,7 +75,7 @@ export const BrandedSpeakerInfos = ({
}}
caption={company}
iconifyId="mdi:company"
iconStyle={{width: 35}}
iconStyle={{width: 35, ...iconStyle}}
/>
)}
{job && (
Expand All @@ -86,7 +89,7 @@ export const BrandedSpeakerInfos = ({
}}
caption={job}
iconifyId="mdi:user"
iconStyle={{width: 35, height: 35}}
iconStyle={{width: 35, height: 35, ...iconStyle}}
/>
)}
</div>
Expand Down
88 changes: 52 additions & 36 deletions remotion/compositions/templates/talk/branded/TalkBranded.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,56 @@ export const TalkBranded = ({
startingDate,
location,
logoUrl,
speaker,
}: z.infer<typeof TalkBrandedSchema>) => (
<AbsoluteFill
style={{
backgroundColor,
fontFamily,
}}
>
<Sequence name="Noise Background">
<BackgroundCircleNoise speed={0.01} circleRadius={5} maxOffset={20} />
</Sequence>
<Sequence name="Logo">
<BrandedLogo logoUrl={logoUrl} borderColor={backgroundColor} />
</Sequence>
<Sequence name="Speaker" from={10}>
<BrandedSpeaker
pictureUrl={
speaker.pictureUrl || staticFile('/images/common/defaultAvatar.svg')
}
name={speaker.name}
company={speaker.company}
job={speaker.job}
/>
</Sequence>
<Sequence name="Title" from={40}>
<BrandedTitle title={title} />
</Sequence>
<Sequence name="Details" from={50}>
<BrandedDetails startingDateTime={startingDate} location={location} />
</Sequence>
{location && (
<Sequence name="Location" from={55}>
<BrandedLocation location={location} />
speakers,
}: z.infer<typeof TalkBrandedSchema>) => {

const speakersData = speakers;
const baseOffsetY = speakersData.length > 1 ? -50 : 0;
const avatarSize = speakersData.length > 1 ? 150 : 200;
const speakerIconStyle : React.CSSProperties | undefined = speakersData.length > 1 ? { fontSize: "2rem"} : undefined;

return (
<AbsoluteFill
style={{
backgroundColor,
fontFamily,
}}
>
<Sequence name="Noise Background">
<BackgroundCircleNoise speed={0.01} circleRadius={5} maxOffset={20} />
</Sequence>
<Sequence name="Logo">
<BrandedLogo logoUrl={logoUrl} borderColor={backgroundColor} />
</Sequence>
<Sequence name="Speaker" from={10}>
{speakersData.map((speaker, index) => {
return (
<BrandedSpeaker
key={index}
pictureUrl={
speaker.pictureUrl || staticFile('/images/common/defaultAvatar.svg')
}
name={speaker.name}
company={speaker.company}
job={speaker.job}
offsetY={index * 200 + baseOffsetY}
avatarSize={avatarSize}
iconStyle={speakerIconStyle}
/>
);
})}
</Sequence>
<Sequence name="Title" from={40}>
<BrandedTitle title={title} />
</Sequence>
<Sequence name="Details" from={50}>
<BrandedDetails startingDateTime={startingDate} location={location} />
</Sequence>
)}
</AbsoluteFill>
);
{location && (
<Sequence name="Location" from={55}>
<BrandedLocation location={location} />
</Sequence>
)}
</AbsoluteFill>
);
}
14 changes: 8 additions & 6 deletions remotion/compositions/templates/talk/talks.types.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import {zColor} from '@remotion/zod-types';
import {z} from 'zod';

export const TalkBrandedSpeakerSchema = z.object({
pictureUrl: z.string(),
name: z.string(),
company: z.string().optional(),
job: z.string().optional(),
})

export const TalkBrandedSchema = z.object({
backgroundColor: zColor(),
title: z.string(),
startingDate: z.date(),
location: z.string().optional(),
logoUrl: z.string(),
speaker: z.object({
pictureUrl: z.string(),
name: z.string(),
company: z.string().optional(),
job: z.string().optional(),
}),
speakers: z.array(TalkBrandedSpeakerSchema),
});
4 changes: 2 additions & 2 deletions src/data/config/templates/talkBrandedConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export const TalkBrandedConfig: CompositionProps = {
location: '5 Place Jules Ferry, 69006.',
logoUrl:
'https://user-images.githubusercontent.com/72607059/233019842-047a34a4-77c1-4200-adc8-c70a6daf8f10.svg',
speaker: {
speakers: [{
pictureUrl:
'https://res.cloudinary.com/startup-grind/image/upload/c_fill,dpr_2.0,f_auto,g_center,h_250,q_auto:good,w_250/v1/gcs/platform-data-goog/events/20200911_094649_MbC4W4N.jpg',
name: 'Julien Landuré',
company: 'Zenika Nantes',
job: 'CTO / GDE',
},
}],
},
};

0 comments on commit 0dd12ba

Please sign in to comment.