Apresentação Aplicação Apresentação

Olá, meu nome é Dmitry Karlovsky e às vezes falo em conferências, reuniões e, recentemente, eu próprio faço parte da equipe de organizadores de um deles - o PiterJS . Recentemente, tivemos um aniversário - foram realizadas 40 reuniões. Mas, em vez de relaxar e receber parabéns, nos cansamos e preparamos relatórios dos organizadores .


Testando o controle de voz


Mas isso não é suficiente para nós, por isso decidimos celebrar o grande aniversário organizando uma conferência nas margens do Neva PiterJSConf , que será realizada neste sábado, 7 de setembro de 2019. Apresse-se para se inscrever, enquanto ainda há vagas vazias, porque a participação será totalmente gratuita para você.


Fazemos tudo isso não por dinheiro, mas pela grande idéia de que o conhecimento deve ser livre. Portanto, tudo o que fazemos está disponível em código aberto . Estamos felizes em compartilhar nossas melhores práticas, conhecimentos e experiências com outras pessoas. E instamos a cooperação de organizadores de outras cidades para criar uma plataforma aberta para organizar reuniões tecnológicas regularmente. Junte-se a nós como organizador , parceiro , palestrante , voluntário , patrono ou apenas um ouvinte.


Enquanto isso, estou oferecendo uma história sobre o aplicativo da web de apresentação $hyoo_slides que eu uso em todas as minhas apresentações. A gravação de vídeo está disponível no YouTube , mas nem tudo está lá. Você pode ler esta história como um artigo ou abri-la na interface do próprio aplicativo . Em seguida, vou lhe dizer o quanto isso pode fazer e como funciona.


Interface do ouvinte


Apresentação de escuta


Aqui está a interface que o público vê durante a performance. Não há nada supérfluo nele.


O nome e o número do slide são exibidos na parte superior. Os ouvintes podem ter perguntas. E gravando rapidamente esse número, eles poderão nomear o nome após o discurso e, assim, salvar o público de uma espera tediosa, quando o palestrante encontrará um slide no qual a pergunta está sendo feita.


Abaixo, você pode prestar atenção à barra de progresso, mostrando aos ouvintes tardios o quanto eles perderam. E para todo mundo - quanto resta até o fim. É calculado não pelo número de slides, mas pelo volume do discurso narrado.


Olha como eu posso


A idéia básica é deixar o palestrante se concentrar no conteúdo e não se preocupar com o design. O relatório não precisa de belezas especiais e animações espetaculares. Caso contrário, o design chamará a atenção para si mesmo. E o conteúdo corre o risco de passar pelos ouvidos.


Porque eu sou o Batman!


No entanto, o design deve ser elegante para não estragar a impressão do relatório. Portanto, o design do aplicativo é simples, não cativante e, mais importante, consistente com as recomendações dos comitês do programa.


Interface de alto-falante


A interface do alto-falante é dividida em duas partes.


Apresentação do apresentador


À esquerda está o que os ouvintes veem. E à direita estão as anotações do orador. Eles ajudarão você a lembrar de um pensamento perdido, sem se afastar da platéia e sem forçá-los por um longo ... hum ... isso ... uma pausa.


O principal é o conteúdo


Portanto, no nosso caso, o conteúdo é escrito como um artigo no formato MarkDown e apresentado em algumas páginas do GitHub. E o aplicativo da web cuida do resto.


 #       #       

Após o discurso, a transcrição do texto do relatório geralmente é apresentada na forma de um artigo sobre alguns Habré . Eles podem fazer isso por um mês, dois, meio ano. A tarefa é uma tradução ingrata da fala em texto. Mas, como a fonte dos slides já está no formato de remarcação e contém os comentários do palestrante, eles podem ser publicados imediatamente neste formulário.


Estilos de texto


O texto sem formatação é exibido apenas para o apresentador. E todos os tipos de fotos, listas, tabelas, citações etc. são visíveis para todos.


 - ** - ** ** - ~~~~ - `````` 

  • Sotaque
  • Sotaque forte
  • Excluir

Obviamente, várias ferramentas de formatação em linha estão disponíveis.


Código fonte


Obviamente, blocos de código-fonte também são suportados e são pintados em todas as cores do arco-íris. Assim como você gosta.


 ```javascript const hello = ()=> <body> Hello, "world"! </body> ``` 

 const hello = ()=> <body> Hello, "world"! </body> 

Tabelas


Comparação de várias coisas irá ajudá-lo tabelas. Por exemplo, vamos ver por que $hyoo_slides melhor que seus concorrentes mais próximos - shwr.me e slides do google


 | | shwr.me | google slides | slides.hyoo.ru | |--------------------------|---------|---------------|----------------| |   MarkDown | - | - | + | |   | - | + | + | |   | - | - | + | |  | - | + | + | 

shwr.meslides do googleslides.hyoo.ru
Fonte no MarkDown--+
Modo de painel duplo-++
Interruptor deslizante automático--+
Offline-++

Como você pode ver, $hyoo_slides vence os concorrentes em todas as frentes. Exceto aqueles que não estão incluídos na tabela, é claro.


Bem, lano, as mesas são chatas.


Imagens


Segure o gato.


 ![](https://github.com/nin-jin/slides/raw/master/slides/cat.gif) 

Cat


Observe que o plano de fundo dos slides é levemente cinza. Portanto, é melhor preparar as imagens não em um fundo branco, mas com transparência, para que não haja um retângulo branco desagradável nas fotos. Isso é feito para que as áreas brancas pareçam contrastadas e não se fundam com o fundo.


Vídeo


Você pode postar vídeos, páginas da web e qualquer outro conteúdo externo usando a mesma sintaxe do MarkDown usada para inserir imagens.


 ![ ](https://www.youtube.com/embed/exfBX2pb7AQ?autoplay=1) 

Público Alvo


Por exemplo, inseri um vídeo que ilustra que as interfaces modernas são tão simples e convenientes que até um macaco pode lidar com elas.


Navegação pelo teclado


Você pode alternar slides com setas no teclado. Mas para não ser conectado ao laptop, mas para andar livremente pelo palco, você precisará de um cabo de extensão de rádio para o seu dedo. Ele é um clicker.


Setas


Mas e se o clicker estiver quebrado?


Frases de código


Você provavelmente acha que, na sala, tenho um cossaco maltratado que troca os slides em vez de mim? No entanto, isso não é verdade.


  • Além disso, por favor.
  • De volta , por favor.
  • Slide número 5, seja gentil.
  • No começo , por favor.
  • No final , por favor.
  • Encontre o "gato", seja gentil.
  • Repita , por favor.
  • Cale a boca , seja gentil.
  • Por favor continue .
  • Apague a luz , por favor.

Repita, por favor. Uma voz de cima repete a última frase.


Sim, os slides podem controlar completamente a voz, deixando as mãos livres para gestos. Ele usa API Web padrão para reconhecimento e síntese de voz.


Mas repetir essas frases de código dez vezes seguidas é chato, portanto $hyoo_slides pode analisar as anotações do orador e, quando você diz a última palavra, alterne o slide automaticamente.


Gestos com os dedos


Ok, complicando a situação. Alguém depois de ouvir seu discurso, decidiu ver seus slides do tablet enquanto andava de metrô para casa.


Gestos


Não há teclado. Os trens são barulhentos. Aqui, gestos comuns dos dedos vêm em socorro.


Offline


Mas então ele chama pelo túnel e sua conexão desaparece.


Sem rede


Não importa, temos o Aplicativo Web Progressivo da Web 2.0 HTML5 com funcionalidade completa, mesmo quando não há Internet.


Impressão em PDF


Mas aqui os organizadores chegam até você e dizem: "Queremos um PDF".


Impressão


Qual pdf? Temos aqui o aplicativo Web progressivo interativo multimídia Web2.0 HTML5. No entanto, eles explicam que o aplicativo está hoje e amanhã não está mais lá. E se houver, ele quer dinheiro. E se você não quiser, os slides já poderão ser alterados além do reconhecimento. E o PDF está silenciosamente no arquivo com exatamente o conteúdo que corresponde ao vídeo gravado durante a apresentação.


Bem, não importa, pressione Ctrl+P , selecione "Imprimir em PDF" e obtenha o que você precisa. Isso é feito simplesmente - o evento onbeforeprint é onbeforeprint e, quando ocorre, em vez de apenas o slide atual, todos os slides são renderizados. E depois da onafterprint , todos, exceto o atual, os slides são excluídos.


Nisso, as listas de recursos estão encerradas.


Como criar uma apresentação


Tentar $hyoo_slides é fácil. Você precisará de readme.md com seu conteúdo e imagens. Também nas proximidades, você precisará copiar e colar index.html , que redireciona para o aplicativo Web e abre sua apresentação nele. E também offline.js para suporte offline.



Lembre-se de que este index.html fornecerá ao aplicativo todos os arquivos acessíveis no domínio em que você coloca a coisa toda. O GitHub Pages é uma opção muito conveniente e segura. Eu mesmo uso.


Outras aplicações


Se você gostou deste aplicativo, pode dar uma olhada em outros aplicativos interessantes implementados na estrutura $ mol. Eles são tão leves que até algumas dúzias não têm medo de carregá-los todos de uma vez em um slide.


Galeria de aplicações


Mas sobre eles de alguma forma mais tarde ...


Exemplos de Apresentação


Você pode aprender mais sobre a estrutura em uma apresentação separada. Você pode se aprofundar em uma apresentação no PPR. E você pode levantar a cortina do futuro em uma apresentação sobre a quantização de cálculos.



Todos eles usam $ hyoo_slides para exibir. Espero que em breve haja mais apresentações desse tipo.


Estrutura de aplicação


E agora, vamos abrir um pouco o capô e ver como o aplicativo está organizado e como fazer o mesmo em apenas uma noite.


 $hyoo_slides_page $mol_view sub / <= Listener <= Speaker 

 export class $hyoo_slides_page extends $mol_view { sub() { return [ this.Listener() , this.Speaker() , ] } } 

Aqui está uma descrição de nível superior de uma única tela no view.tree e código TypeScript equivalente. Aqui declaramos o componente $hyoo_slides_page , que estende o componente base $mol_view . Este componente tem uma sub . Tudo o que retorna essa propriedade será renderizado dentro do componente. Portanto, nós o redefinimos, passando como valor uma matriz de dois elementos: Listener - um componente para a saída de um slide para ouvintes e Speaker - um componente de um painel de alto-falantes adicional.


Alternar layout da página


Além da descrição da estrutura, também podemos aplicar a lógica do programa que permite que quaisquer propriedades sejam calculadas dinamicamente.


 sub() { const role = this.role() return [ this.Listener() , ... ( role === 'speaker' ) ? [ this.Speaker() ] : [] , ] } 

Aqui a lógica é simples: sempre exibimos slides para ouvintes, mas o painel do alto-falante é mostrado apenas se a função atual for speaker - speaker . Se a função mudar, o layout do aplicativo também será alterado devido à magia da programação reativa a objetos.


Encaminhamento


$mol_state_arg a função do parâmetro address, por meio da API reativa especial $mol_state_arg .


 role() : 'speaker' | 'listener' { return $mol_state_arg.value( 'role' ) || 'speaker' } 

Por qualquer motivo, o endereço foi alterado - a função será extraída automaticamente e transmitida para esse método.


Estrutura da interface do ouvinte


Vamos descrever a interface do ouvinte.


 Listener $mol_page title <= title tools / <= Slide_switcher body / <= Listener_content <= Progress 

Ele usa o componente padrão $mol_page que desenha uma página típica com um cabeçalho e um corpo. No cabeçalho, há uma área em que o nome da página é exibido. Através da propriedade title , você pode especificar o que enviar para lá. O que fizemos ao associar sua propriedade title à nossa propriedade com o mesmo nome. Agora, alterando nossa propriedade, temos controle total sobre o que será exibido na página como um título.


À direita no cabeçalho, há uma área de saída para ferramentas adicionais - tools . Nele, produzimos Slides_switcher - um componente para exibir o número do slide e alternar entre os slides adjacentes.


E, finalmente, como o body da página no body exibimos o conteúdo do slide e a barra de progresso.


Estrutura de troca de página


Como implementar Slide_switcher ? Basta usar o componente padrão $mol_paginator .


 Slide_switcher $mol_paginator value?val <=> slide?val 

Tudo o que ele tem é um value propriedade mutável, que associamos bilateralmente à nossa propriedade que contém o número do slide atual. Não há importações, retornos de chamada, eventos e outros tipos de lixo. Essas duas linhas são tudo o que é necessário para que uma opção de página de trabalho apareça na sua página.


Estrutura do conteúdo do slide


Para exibir o conteúdo do slide, usamos novamente o componente padrão $mol_text .


 Listener_content $mol_text uri_base <= uri_base text <= listener_content 

Ele pega o markdown e o processa. Como os links neste texto serão relativos ao arquivo de origem, e não ao nosso aplicativo, passamos o link para a propriedade uri_base, com relação à qual todos os caminhos serão resolvidos.


Estrutura do indicador de progresso


Como você provavelmente já adivinhou, também há um componente padrão para exibir o progresso - $mol_portion .


 Progress $mol_portion portion <= progress 

 portion: [ 0 .. 1 ] 

Alimentamos um número de 0 a 1 e obtemos um indicador para esse compartilhamento.


Estrutura da interface do alto-falante


Temos algo mais interessante na interface do palestrante. As ferramentas exibidas no cabeçalho não são anexadas à página atual de forma alguma - elas são comuns a todo o aplicativo. Portanto, em vez de codificá-los aqui, colocaremos apenas o slot speaker_tools através do qual transferiremos a lista de componentes de fora.


 Speaker $mol_page head <= speaker_tools /$mol_view body / <= Speaker_content 

Estrutura de aplicação


Agora suba de nível e crie um componente de aplicativo $hyoo_slides que use o componente de página.


 $hyoo_slides $mol_view Page!index $hyoo_slides_page - ... plugins / <= Nav <= Touch <= Speech_next - ... 

Qualquer componente $mol_view possui uma propriedade plugins através da qual lógica adicional pode ser conectada a ele. Os plug-ins de plug-in vivem no mesmo nó DOM que o próprio componente. O componente os inicia durante sua renderização. E quando quase deixa de ser renderizado - os plugins são destruídos automaticamente.


Também anunciamos a propriedade Page , que para cada índice retorna uma instância separada do componente $hyoo_slides_page que desenvolvemos anteriormente.


Configuração de página externa


 Page!index $hyoo_slides_page role <= role slide?val <=> page_slide!index?val speaker_tools / <= Speech_toggle <= Speech_text <= Open_listener 

Passamos a propriedade de role para o subcomponente como está. A propriedade slide do componente de página é conectada por comunicação bidirecional com a propriedade page_slide do aplicativo. Observe que page_slide aceita não apenas o novo valor opcional, mas também o índice da página. Isso permite que você retorne um número para cada página. Finalmente, no slot speaker_tools que anunciamos anteriormente, colocamos três componentes para ajudar a gerenciar os slides.


Estrutura do interruptor de controle de voz


Implementamos o Speech_toggle através do componente padrão $mol_check_icon , que desenha um ícone. Quando você clica nele, alterna o sinalizador checked . E o estado atual é exibido alterando a cor do ícone.


 Speech_toggle $mol_check_icon Icon <= Speech_toggle_icon $mol_icon_microphone checked?flag <=> speech_enabled?flag 

Pegamos o ícone do $mol_icon , onde dos 4000 ícones criados no estilo de design de material ascético, é fácil encontrar o ícone certo.


Estrutura do botão de abertura da janela secundária


Tudo é simples aqui. Este botão será o link $mol_link . Ela pode definir a propriedade uri com um endereço, ou pode fazer algo mais astuto e apenas corrigir o endereço atual, substituindo alguns parâmetros pelo arg .


 Listener_open $mol_link target \_blank arg * role \listener slide null sub / <= Listener_open_icon $mol_icon_external 

Aqui, apagamos o número do slide do endereço para que a janela escrava o retirasse do armazenamento local, e não do endereço. Isso garantirá que as janelas sejam sincronizadas umas com as outras. Eles também indicaram que o papel deveria ser um "ouvinte". Dentro do link, colocamos um ícone em vez de texto.


Plugins


Os plug-ins podem expandir significativamente os recursos do componente. Vamos usá-los ao máximo.


 plugins / <= Nav <= Touch <= Speech_next <= Speech_prev <= Speech_start <= Speech_end - ... 

Todos os plugins utilizados por nós podem ser divididos em 3 categorias: navegação pelo teclado, controle por gestos e controle por voz.


Navegação pelo teclado


Através do $mol_nav , é fácil implementar a navegação do teclado na vertical e na horizontal. Tudo o que é necessário é fornecer ao plug-in uma lista de chaves pelas quais ele alternará e comunicação bidirecional com o valor atual.


 Nav $mol_nav keys_y <= slide_keys keys_x <= slide_keys current_y?val <=> slide?val current_x?val <=> slide?val 

 slide_keys: [ 0 , 1 , 2 , 3 , ... , 30 ] ^ slide 

Gestos com os dedos


Para rastreamento de dedos, existe um $mol_touch . Com ele, você pode ampliar, deslocar e deslizar. É a última oportunidade que nos interessa agora.


 Touch $mol_touch swipe_to_left?event <=> go_next?event swipe_to_right?event <=> go_prev?event 

 go_next( event? : Event ) { this.slide( this.slide() + 1 ) } 

Existem dois tipos de furto. Por exemplo, deslize para a esquerda ou direita de qualquer parte da tela e deslize devido à borda direita ou esquerda da tela em direção ao centro. No código apresentado, penduramos nossos manipuladores no primeiro tipo de furto.


Controle de voz


Para controle de voz, use o $mol_speech . É necessário criar uma instância do plug-in para cada versão da ação.


 Sing $mol_speech event_catch?val <=> sing?val patterns / \sing( \S+?)* \( \S+?)* 

O plug-in aceita um manipulador de ações e um conjunto de padrões, após a detecção dos quais, um evento será acionado. Você pode usar colchetes de captura nos padrões para obter as palavras correspondentes ao seu conteúdo no manipulador.


Interruptor deslizante automático


Por padrão, $mol_speech requer tratamento discreto. Por exemplo, você deve dizer não "cantar", mas "cantar, por favor". Você pode substituir a propriedade suffix para alterar ou remover completamente essa palavra de código.


 Speech_next_auto $mol_speech event_catch?val <=> go_next?val suffix \ patterns <= speech_next_auto_patterns 

Por exemplo, para implementar a troca automática de slides, não precisamos de palavras mágicas. Mas geraremos um conjunto de padrões dinamicamente, com base na análise do conteúdo do texto do palestrante.


Lançamento do aplicativo


Tendo um componente de aplicativo, você pode instancia-lo manualmente como qualquer classe comum. Mas usaremos a inicialização automática através do atributo especial mol_view_root .


 <body mol_view_root="$hyoo_slides"> <script src="web.js" charset="utf-8"></script> </body> 

O nome do atributo é o nome do componente. A renderização dessa maneira, é claro, pode ser absolutamente qualquer componente.


Offline


Para adicionar suporte offline, inclua o módulo mol/offline/install no pacote.


 include \/mol/offline/install 

Ele gera automaticamente um ServiceWorker, que armazena em cache todas as solicitações. E se a rede estiver indisponível, ela retornará dados do cache. Esta não é a implementação mais legal, mas para casos simples em que você não deseja se preocupar, será necessário.


Modo de impressão


Anteriormente, eu disse que, durante a impressão, é necessário renderizar todas as páginas, mas não é necessário monitorar manualmente onbeforeprint e depois da onafterprint , porque temos uma programação totalmente reativa; portanto, usaremos o estado reativo $mol_print , que nos fornece um sinalizador reativo ao qual podemos amarre a renderização.


 sub() { if( !this.$.$mol_print.active() ) { return [ this.Page( this.slide() ) ] } return $mol_range2( index => this.Page( index ) , ()=> this.slide_keys().length , ) } 

Aqui, retornamos apenas uma página se o sinalizador active não for levantado. Caso contrário, retornamos uma matriz lenta que calcula seu comprimento e elementos de acordo com as fórmulas fornecidas.


Epílogo


Como resultado, obtivemos um aplicativo da web moderno com várias funcionalidades e um peso de apenas 35kb. Adicionar manifesto e haverá um aplicativo da Web progressivo completo. Obviamente, muitos detalhes não foram considerados. Você pode vê-los no código no github. Para todas as perguntas, escreva telegramas no chat.


Esses slides estão no aplicativo: slides.hyoo.ru
Fontes de aplicação: hyoo-ru / slides.hyoo.ru
Exemplos de apresentações: nin-jin / slides
Bate-papo por telegrama: @mam_mol

$hyoo_slides feliz se você tentar fazer sua apresentação com $hyoo_slides . E ficarei muito feliz se você ajudar a torná-lo ainda melhor do que é agora. Obrigado pela atenção!

Source: https://habr.com/ru/post/pt465763/


All Articles