Stories Core

O motor por trás de @reelkit/react-stories-player. TypeScript puro, sem dependência de framework. Use para montar players de stories em Angular, Vue ou JavaScript puro.

Independente de framework
TypeScript puro, nenhuma dependência de framework de DOM
Navegação em dois níveis
Grupos e, dentro de cada grupo, os stories
Timer com RAF
Avanço automático por requestAnimationFrame, com pausa e retomada
Progresso em canvas
Barra segmentada pronta para telas Retina, com janela deslizante
Zonas de toque
Detecção configurável de toque à esquerda e à direita
Sinais reativos
Construído sobre as primitivas de sinal de @reelkit/core

Instalação

bash

Controlador do Stories

createStoriesController(config, events?) cuida da navegação entre grupos e stories. Acompanha o estado de pausa, lembra o último story visto de cada grupo e dispara callbacks a cada transição.

Configuração (StoriesControllerConfig)

PropriedadeTipoPadrãoDescrição
groupCountnumberobrigatórioNúmero total de grupos de stories
storyCountsnumber[]obrigatórioQuantidade de stories em cada grupo
initialGroupIndexnumber0Índice do grupo inicial
initialStoryIndexnumberresumeStoryIndex(initialGroupIndex), senão 0Índice do story inicial dentro do grupo. Informar um valor vence qualquer coisa lembrada; deixe de fora e o grupo de abertura retoma como todos os outros.
defaultImageDurationnumber5000Duração padrão, em ms, do avanço automático dos stories de imagem
resumeStoryIndex(groupIndex: number) => numberundefinedStory em que um grupo ainda não visitado abre, limitado a um story que o grupo tenha

Eventos (StoriesControllerEvents)

EventoTipoDescrição
onStoryChange(groupIndex, storyIndex) => voidDisparado quando o story ativo muda
onGroupChange(groupIndex) => voidDisparado quando o grupo ativo muda
onStoryViewed(groupIndex, storyIndex) => voidDisparado quando um story fica visível
onStoryComplete(groupIndex, storyIndex) => voidDisparado quando o timer do story termina (antes de avançar)
onComplete() => voidDisparado quando o último story do último grupo acaba
onClose() => voidDisparado quando o overlay deve fechar

Estado (sinais reativos)

SinalTipoDescrição
state.activeGroupIndexSignal<number>Índice do grupo ativo no momento
state.activeStoryIndexSignal<number>Índice do story ativo dentro do grupo
state.isPausedSignal<boolean>Se o avanço automático está pausado

Métodos

MétodoTipoDescrição
nextStory()() => voidAvança dentro do grupo; ao chegar ao fim, passa ao grupo seguinte
prevStory()() => voidVolta dentro do grupo; ao chegar ao início, passa ao grupo anterior
nextGroup()() => voidMuda para o próximo grupo, retomando no último story visto
prevGroup()() => voidMuda para o grupo anterior, retomando no último story visto
goToGroup(index)(number) => voidSalta direto para um grupo pelo índice
pause()() => voidPausa o avanço automático
resume()() => voidRetoma o avanço automático
onStoryTimerComplete()() => voidChamado quando o timer termina; dispara onStoryComplete e então avança
getLastStoryIndex(groupIndex)(number) => numberOnde o grupo abre: o story em que foi deixado nesta sessão, senão o que resumeStoryIndex indicar
reportInitialView()() => voidRegistra, uma única vez, como visto o story em que o player abriu. Chame depois da montagem, não durante a renderização.

Exemplo

typescript

Controlador de timer

createTimerController(config) conduz o avanço automático com um laço de requestAnimationFrame. O sinal de progresso (de 0 a 1) alimenta a barra. Pausar e retomar preservam a posição exata.

Configuração (TimerControllerConfig)

PropriedadeTipoPadrãoDescrição
durationnumberobrigatórioDuração padrão em milissegundos
onComplete() => voidundefinedChamado quando o timer chega a 100%

Estado

SinalTipoDescrição
progressSignal<number>Sinal de progresso (de 0 a 1)
isRunningSignal<boolean>Se o timer está rodando agora

Métodos

MétodoTipoDescrição
start(duration?)(number?) => voidInicia (ou reinicia) o timer, com duração alternativa opcional
pause()() => voidCongela o progresso na posição atual
resume()() => voidContinua da posição congelada
reset()() => voidZera o progresso e para
dispose()() => voidLibera os recursos

Exemplo

typescript

Renderizador de progresso em Canvas

createCanvasProgressRenderer(config?) desenha barras de progresso segmentadas em um canvas. Ajusta a escala para telas Retina, mede o contêiner com ResizeObserver e passa a uma janela deslizante quando os segmentos não cabem.

Configuração (CanvasProgressRendererConfig)

PropriedadeTipoPadrãoDescrição
gapnumber2Espaço em pixels entre os segmentos
barHeightnumber2Altura da barra em pixels
minSegmentWidthnumber8Largura mínima do segmento antes de a janela deslizante entrar em cena
bgColorstring'rgba(255,255,255,0.3)'Cor de fundo dos segmentos ainda não preenchidos
fillColorstring'#ffffff'Cor de preenchimento dos segmentos concluídos e do ativo

Métodos

MembroTipoDescrição
attach(canvas)(HTMLCanvasElement) => voidLiga a um elemento canvas; inicia o ResizeObserver no elemento pai
draw(totalStories, activeIndex, progress)(number, number, number) => voidDesenha a barra de progresso para o estado informado
widthnumber (readonly)Largura medida no momento, em pixels de CSS
dispose()() => voidLibera o ResizeObserver e o estado interno

Exemplo

typescript

Itens já vistos

createStoriesViewedState(controller, groups) lê um ViewedStateController do core nos termos que um player usa — grupos, autores, índices de story — sem que o armazenamento precise saber de nada disso. Devolve um StoriesViewedState. Monte o armazenamento com a mesma chave da barra de endereços, acompanhado por grupo, e a entrada guardada fica idêntica ao parâmetro de um link compartilhado.

ParâmetroTipoDescrição
controllerViewedStateController<TwoAxisPosition>Armazenamento do core montado com a mesma chave da barra de endereços, espalhado junto de twoAxisViewedTracking para que cada grupo tenha sua entrada
groups() => StoriesGroup<T>[]Lê os grupos atuais. É um getter, então um feed que pagina ou muda de ordem depois da configuração é medido na hora da chamada.

StoriesViewedState

MétodoTipoDescrição
viewedCounts()() => Map<string, number>Stories vistos por grupo, com o id do autor como chave — o formato que StoriesRingList recebe em viewedState
resumeStoryIndex(groupIndex)(number) => numberPrimeiro story ainda não visto, ou 0 quando o grupo já foi assistido até o fim
markViewed(groupIndex, storyIndex)(number, number) => voidRegistra um story como visto. Ligue este método ao onStoryViewed.

Exemplo

typescript

A entrada nomeia o story mais distante alcançado, e não um total de visualizações, então uma chave endereçada por id mantém o lugar do grupo mesmo que o feed mude de ordem, enquanto um story removido do meio de um grupo encurta a contagem e acende o anel de novo.

Funções utilitárias

Funções puras para detectar as zonas de toque e para a matemática da barra de progresso.

FunçãoTipoDescrição
getTapAction(tapX, containerWidth, splitRatio?)(number, number, number?) => 'prev' | 'next'Decide, pela posição, se um toque aciona 'prev' ou 'next'. O splitRatio padrão é 0.3.
getSegments(totalStories, activeIndex, progress)(number, number, number) => SegmentState[]Calcula o estado e a porcentagem preenchida de cada segmento da barra de progresso
getVisibleWindow(totalStories, activeIndex, progress, containerWidth, minSegmentWidth?, gap?)(number, number, number, number, number?, number?) => VisibleWindowCalcula a janela deslizante de segmentos visíveis quando a quantidade total passa da capacidade do contêiner

Tipos

Todas as definições de tipo exportadas por @reelkit/stories-core.

typescript