Da grade ao player
Uma página de perfil ou um resultado de busca mostra os posts como uma grade de miniaturas. Tocar em uma deve abri-la em tela cheia, deixar o usuário seguir deslizando pelo resto e, quando ele fechar o player, deixá-lo no post em que parou, não no post em que começou.
Experimente
Todas as versões importam ./api, que faz o papel do seu backend: posts é a lista que um perfil ou uma busca carregaria, no formato do ContentItem do player, e thumbnailOf escolhe a imagem que uma célula da grade mostra. Troque os dois pelos seus próprios dados.
import { cdnUrl } from '@reelkit/example-data';
// Stands in for your backend: the posts a profile or a search result would
// load. Each one has the shape of `ContentItem` from the reel player of your
// framework, so the list goes to the player as it is.
export interface Post {
id: string;
media: {
id: string;
type: 'image' | 'video';
src: string;
poster?: string;
aspectRatio: number;
}[];
author: { name: string; avatar: string };
likes: number;
description: string;
}
const kAuthors = ['Alex Johnson', 'Sarah Miller', 'Mike Chen', 'Emma Davis'];
const pad = (n: number) => String(n).padStart(2, '0');
export const posts: Post[] = Array.from({ length: 12 }, (_, i) => {
const isVideo = i % 4 === 0;
const n = (i % (isVideo ? 3 : 9)) + 1;
return {
id: `post-${i + 1}`,
media: [
isVideo
? {
id: `video-${i + 1}`,
type: 'video' as const,
src: cdnUrl(`samples/videos/video-${pad(n)}.mp4`),
poster: cdnUrl(`samples/videos/video-poster-${pad(n)}.jpg`),
aspectRatio: 16 / 9,
}
: {
id: `image-${i + 1}`,
type: 'image' as const,
src: cdnUrl(`samples/images/image-${pad(n)}.jpg`),
aspectRatio: 2 / 3,
},
],
author: {
name: kAuthors[i % kAuthors.length],
avatar: cdnUrl(`samples/avatars/avatar-${pad((i % 8) + 1)}.jpg`),
},
likes: 120 + i * 37,
description: `Post ${i + 1}`,
};
});
/** The picture a grid cell shows: a video's poster, or the image itself. */
export const thumbnailOf = (post: Post) =>
post.media[0].poster ?? post.media[0].src;A mídia de exemplo só funciona em reelkit.dev
cdnUrl monta links para cdn.reelkit.dev, que só entrega seus arquivos aos sites do ReelKit. No seu app essas imagens e vídeos não carregam, então aponte media e avatar para os seus próprios arquivos antes de copiar este arquivo.
Abra um post, deslize ou aperte ↓ algumas vezes e feche com Escape: a grade rola até o post em que você parou e a miniatura dele recebe o foco.
Por que funciona
- O player abre onde o usuário tocou.
initialIndexrecebe o índice da miniatura e a lista inteira vai paracontent, então o usuário pode continuar deslizando além do post que escolheu. As duas são props do player em React, Vue e Angular. - A grade sabe onde o usuário parou. O callback de troca de slide informa cada post que o usuário alcança, e a receita guarda o último. Ele aparece entre os callbacks, eventos e outputs do player.
- O foco volta para a miniatura certa. Ao fechar, o player devolve o foco ao elemento que o abriu, como manda a sua acessibilidade. Essa devolução acontece depois que o handler de fechamento rodou, então um foco definido dentro do handler seria desfeito. A receita espera uma tarefa, rola a miniatura do último post até ficar visível e coloca o foco nela.
- As miniaturas são botões. Cada célula é um
<button>com rótulo, então a grade funciona com Tab e Enter, um leitor de tela anuncia o post que ela abre e o player tem um elemento focável para devolver o foco, como descreve a seção de acessibilidade. - Uma célula da grade precisa de imagem, não de vídeo.
thumbnailOfusa oposterde um vídeo, um campo de MediaItem, e uma imagem como ela é, então a grade nunca carrega um vídeo que não vai tocar. - Quer o post aberto na barra de endereço? O player com estado na URL coloca o post visível na URL, para ele poder ser compartilhado e fechado com o botão voltar.
Próximos passos
- Galeria com apresentação - a mesma grade abrindo um Lightbox que roda como apresentação de slides
- Reel Player - todas as props, slots e partes do playerReel Player - todas as props, slots e partes do playerReel Player - todas as props, slots e partes do player