Vom Raster zum Player
Eine Profilseite oder ein Suchergebnis zeigt Beiträge als Raster von Vorschaubildern. Ein Tippen auf eines sollte es im Vollbild öffnen, den Nutzer durch den Rest weiterwischen lassen und ihn beim Schließen des Players bei dem Beitrag lassen, an dem er aufgehört hat, statt bei dem, mit dem er angefangen hat.
Ausprobieren
Jede Version importiert ./api, das für dein Backend steht: posts ist die Liste, die ein Profil oder eine Suche laden würde, in der Form von ContentItem des Players, und thumbnailOf wählt das Bild, das eine Rasterzelle zeigt. Ersetze beides durch deine eigenen Daten.
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;Die Beispielmedien funktionieren nur auf reelkit.dev
cdnUrl baut Links zu cdn.reelkit.dev, das seine Dateien nur an die Seiten von ReelKit ausliefert. In deiner App laden diese Bilder und Videos nicht, also lass media und avatar auf deine eigenen Dateien zeigen, bevor du diese Datei kopierst.
Öffne einen Beitrag, wische ein paarmal oder drücke ↓ und schließe dann mit Escape: Das Raster scrollt zu dem Beitrag, bei dem du aufgehört hast, und sein Vorschaubild hat den Fokus.
Warum es funktioniert
- Der Player öffnet dort, wo der Nutzer getippt hat.
initialIndexnimmt den Index des Vorschaubilds, und die ganze Liste geht ancontent, sodass der Nutzer über den gewählten Beitrag hinaus weiterwischen kann. Beides sind Props des Players in React, Vue und Angular. - Das Raster weiß, wo der Nutzer aufgehört hat. Der Callback für den Slidewechsel meldet jeden Beitrag, den der Nutzer erreicht, und das Rezept behält den letzten. Er steht bei den Callbacks, Events und Outputs des Players.
- Der Fokus kommt zum richtigen Vorschaubild zurück. Beim Schließen gibt der Player den Fokus an das Element zurück, das ihn geöffnet hat; das ist sein Vertrag zur Barrierefreiheit. Diese Rückgabe passiert erst, nachdem der Close-Handler gelaufen ist, also würde ein im Handler gesetzter Fokus wieder rückgängig gemacht. Das Rezept wartet einen Task, scrollt dann das Vorschaubild des letzten Beitrags ins Bild und fokussiert es.
- Vorschaubilder sind Buttons. Jede Zelle ist ein
<button>mit Label, sodass das Raster mit Tab und Enter funktioniert, ein Screenreader den Beitrag nennt, den sie öffnet, und der Player ein fokussierbares Element hat, an das er den Fokus zurückgeben kann, wie sein Abschnitt zur Barrierefreiheit beschreibt. - Eine Rasterzelle braucht ein Bild, kein Video.
thumbnailOfnimmt bei einem Video dasposter, ein Feld von MediaItem, und ein Bild so, wie es ist, sodass das Raster nie ein Video lädt, das es nicht abspielt. - Soll der geöffnete Beitrag in der Adresszeile stehen? Der Player mit URL-State schreibt den sichtbaren Beitrag in die URL, sodass er sich teilen und mit der Zurück-Taste schließen lässt.
Nächste Schritte
- Galerie als Diashow - dasselbe Raster öffnet eine Lightbox, die als Diashow abläuft
- Reel Player - jedes Prop, jeder Slot und jeder Teil des PlayersReel Player - jedes Prop, jeder Slot und jeder Teil des PlayersReel Player - jedes Prop, jeder Slot und jeder Teil des Players