Bonjour, je m'appelle Dmitry Karlovsky et je parle parfois lors de conférences, réunions, et aussi, récemment, j'entre moi-même dans l'équipe des organisateurs de l'un d'entre eux - PiterJS . Récemment, nous avons célébré un anniversaire - 40 réunions ont eu lieu. Mais au lieu de se détendre et de recevoir des félicitations, nous nous sommes fatigués et nous avons préparé les rapports des organisateurs .

Mais cela ne nous suffit pas, nous avons donc décidé de célébrer un grand anniversaire en organisant une conférence sur les rives de la Neva PiterJSConf , qui se tiendra ce samedi 7 septembre 2019. Dépêchez-vous de vous inscrire, alors qu'il y a encore des sièges vides, car la participation à celle-ci vous sera totalement gratuite.
Nous faisons tout cela non pas pour de l'argent, mais pour la grande idée que la connaissance devrait être gratuite. Par conséquent, tout ce que nous faisons est disponible en Open Source . Nous sommes heureux de partager nos meilleures pratiques, connaissances et expériences avec les autres. Et nous demandons instamment la coopération des organisateurs d'autres villes pour créer une plate-forme ouverte pour l'organisation régulière de réunions technologiques. Rejoignez-nous en tant qu'organisateur , partenaire , conférencier , bénévole , mécène ou simplement auditeur.
En attendant, je vous propose une histoire sur l'application Web de présentation $hyoo_slides
que j'utilise pour toutes mes présentations. L'enregistrement vidéo est disponible sur YouTube , mais tout n'est pas là. Vous pouvez lire cette histoire sous forme d'article ou l' ouvrir dans l'interface de l'application elle-même . Ensuite, je vais vous dire combien cela peut faire et comment cela fonctionne.
Interface d'écoute
Présentation d'écoute
Voici l'interface que le public voit lors de la représentation. Il n'y a rien de superflu là-dedans.
Le nom et le numéro de la diapositive sont affichés en haut. Les auditeurs peuvent avoir des questions. Et en enregistrant rapidement ce numéro, ils pourront le nommer après le discours et ainsi sauver le public d'une attente fastidieuse, lorsque l'orateur trouvera une diapositive sur laquelle la question est posée.
Ci-dessous, vous pouvez faire attention à la barre de progression, montrant aux derniers auditeurs combien ils ont manqué. Et pour tout le monde - combien reste-t-il à la fin. Il est calculé non pas par le nombre de diapositives, mais par le volume du discours narré.
Regardez comment je peux
L'idée de base est de laisser l'orateur se concentrer sur le contenu et ne pas se soucier de la conception. Le rapport n'a pas besoin du tout de beautés spéciales et d'animations spectaculaires. Sinon, le design attirera l'attention sur lui-même. Et le contenu court le risque de voler au-delà des oreilles.

Mais le design doit néanmoins être soigné pour ne pas gâcher l'impression du reportage. Par conséquent, la conception de l'application est simple, pas entraînante et, surtout, conforme aux recommandations des comités de programme.
Interface haut-parleur
L'interface de l'orateur est divisée en deux parties.
Présentation du présentateur
À gauche, ce que les auditeurs voient. Et à droite se trouvent les notes de l'orateur. Ils vous aideront à vous souvenir d'une pensée perdue, sans vous détourner du public et sans les forcer pendant une longue ... euh ... c'est ... une pause.
L'essentiel est le contenu
Par conséquent, dans notre cas, le contenu est écrit sous forme d'article au format MarkDown et présenté sur certaines pages GitHub. Et l'application Web s'occupe du reste.
# #
Après le discours, la transcription textuelle du rapport est souvent présentée sous la forme d'un article sur certains Habré . Ils peuvent le faire pendant un mois, deux, six mois. La tâche est une traduction ingrate de la parole en texte. Mais, étant donné que la source des diapositives est déjà au format Markdown et contient les commentaires du conférencier, elles peuvent être immédiatement publiées sous cette forme.
Styles de texte
Le texte brut est affiché uniquement pour le présentateur. Et toutes sortes d'images, de listes, de tableaux, de citations, etc. sont visibles par tous.
- ** - ** ** - ~~~~ - ``````
Bien sûr, divers outils de formatage en ligne sont disponibles.
Code source
Les blocs de code source, bien sûr, sont également pris en charge et sont peints dans toutes les couleurs de l'arc-en-ciel. Comme vous l'aimez.
```javascript const hello = ()=> <body> Hello, "world"! </body> ```
const hello = ()=> <body> Hello, "world"! </body>
Des tables
La comparaison de diverses choses vous aidera dans les tableaux. Par exemple, voyons pourquoi $hyoo_slides
meilleur que ses concurrents les plus proches - shwr.me et google slides
| | shwr.me | google slides | slides.hyoo.ru | |--------------------------|---------|---------------|----------------| | MarkDown | - | - | + | | | - | + | + | | | - | - | + | | | - | + | + |
Comme vous pouvez le voir, $hyoo_slides
bat les concurrents sur tous les fronts. À l'exception de ceux qui ne sont pas inclus dans le tableau, bien sûr.
Eh bien lano, les tables sont ennuyeuses.
Les photos
Tenez le chat.


Notez que l'arrière-plan des diapositives est légèrement gris. Par conséquent, il est préférable de préparer les images non pas sur un fond blanc, mais avec transparence afin qu'il n'y ait pas de rectangle blanc désagréable autour des images. Cette opération est effectuée de manière à ce que les zones blanches soient contrastées et ne fusionnent pas avec l'arrière-plan.
Vidéo
Vous pouvez publier des vidéos, des pages Web et tout autre contenu externe en utilisant la même syntaxe MarkDown que pour l'insertion d'images.

Public cible
Par exemple, j'ai inséré une vidéo illustrant que les interfaces modernes sont si simples et pratiques que même un singe peut les gérer.
Navigation au clavier
Vous pouvez changer de diapos avec des flèches sur le clavier. Mais pour ne pas être attaché à l'ordinateur portable, mais pour marcher librement autour de la scène, vous aurez besoin d'une rallonge radio pour votre doigt. C'est un clicker.

Mais que faire si le clicker est cassé?
Phrases de code
Vous pensez probablement que dans la pièce, j'ai quelque part un Cosaque mal géré qui change de diapositives à ma place? Mais ce n'est pas le cas.
- De plus, s'il vous plaît.
- De retour , s'il vous plaît.
- Diapositive numéro 5, soyez gentil.
- Au début , s'il vous plaît.
- À la fin , s'il vous plaît.
- Trouvez le "chat", soyez gentil.
- Répétez , s'il vous plaît.
- Tais-toi , sois gentil.
- Veuillez continuer .
- Éteignez la lumière , s'il vous plaît.
Répétez, s'il vous plaît. Une voix d'en haut répète la dernière phrase.
Oui, les diapositives peuvent contrôler complètement la voix, laissant vos mains libres pour les gestes. Il utilise une API Web standard pour la reconnaissance et la synthèse vocales.
Mais répéter ces phrases de code dix fois de suite est ennuyeux, donc $hyoo_slides
peut analyser les notes du locuteur et lorsque vous dites le dernier mot, changez automatiquement de diapositive.
Gestes des doigts
D'accord, compliquant la situation. Quelqu'un après avoir écouté votre discours, a décidé de voir vos diapositives depuis la tablette tout en rentrant chez vous dans le métro.

Il n'y a pas de clavier. Les trains sont bruyants. Ici, les gestes des doigts ordinaires viennent à la rescousse.
Hors ligne
Mais ensuite il appelle dans le tunnel et sa connexion disparaît.

Cela n'a pas d'importance, nous avons une application Web progressive Web2.0 HTML5 avec toutes les fonctionnalités même lorsqu'il n'y a pas Internet.
Impression PDF
Mais ici, les organisateurs viennent vers vous et vous disent: "Nous voulons un PDF."

Quel pdf? Nous avons ici l'application Web progressive multimédia interactive Web2.0 HTML5. Cependant, ils vous expliquent que la candidature est aujourd'hui et demain elle n'est plus là. Et s'il y en a, il veut de l'argent. Et si vous ne le souhaitez pas, les diapositives peuvent déjà être modifiées au-delà de la reconnaissance. Et le PDF est tranquillement dans l'archive avec exactement le contenu qui correspond à la vidéo enregistrée pendant la performance.
Eh bien, peu importe, appuyez sur Ctrl+P
, sélectionnez "Imprimer au format PDF" et obtenez ce dont vous avez besoin. Cela se fait simplement - l'événement onbeforeprint
est onbeforeprint
et, lorsqu'il se produit, au lieu de simplement la diapositive actuelle, toutes les diapositives sont rendues. Et après onafterprint
, toutes sauf la version actuelle, les diapositives sont supprimées.
Sur ce point, les listes de fonctionnalités sont désormais terminées.
Comment créer une présentation
Essayer $hyoo_slides
est facile. Vous aurez besoin de readme.md
avec votre contenu et vos images. Également à proximité, vous devrez copier-coller index.html
, qui redirige vers l'application Web et y ouvre votre présentation. Et aussi offline.js pour un support hors ligne.
Gardez à l'esprit que ce index.html
donnera à l'application tous les fichiers accessibles depuis le domaine où vous avez placé le tout. GitHub Pages est une option très pratique et sûre. Je l'utilise moi-même.
Autres applications
Si vous avez aimé cette application, vous pouvez jeter un œil à d'autres applications intéressantes implémentées sur le framework $ mol. Ils sont si légers que même quelques dizaines n'ont pas peur de les charger tous en même temps sur une seule glissière.
Galerie d'applications
Mais à leur sujet en quelque sorte plus tard ...
Exemples de présentation
Vous pouvez en savoir plus sur le framework lors d'une présentation séparée. Vous pouvez approfondir une présentation sur le PPR. Et vous pouvez lever le rideau de l'avenir dans une présentation sur la quantification des calculs.
Ils utilisent tous $ hyoo_slides pour afficher. J'espère que bientôt il y aura plus de telles présentations.
Structure d'application
Et maintenant, ouvrons un peu le capot et voyons comment l'application est organisée, et comment faire notre similaire en une seule soirée.
$hyoo_slides_page $mol_view sub / <= Listener <= Speaker
export class $hyoo_slides_page extends $mol_view { sub() { return [ this.Listener() , this.Speaker() , ] } }
Voici une description de haut niveau d'un seul écran dans view.tree et du code TypeScript équivalent. Ici, nous déclarons le composant $hyoo_slides_page
, qui étend le composant de base $mol_view
. Ce composant a une sub
propriété. Tout ce qui renvoie cette propriété sera rendu à l'intérieur du composant. Par conséquent, nous le redéfinissons, en passant comme valeur un tableau de deux éléments: Listener
- un composant pour la sortie d'une diapositive aux écouteurs et Speaker
- un composant d'un panneau de haut-parleur supplémentaire.
Changer la mise en page
En plus de la description de la structure, nous pouvons également appliquer une logique de programme qui permet de calculer dynamiquement toutes les propriétés.
sub() { const role = this.role() return [ this.Listener() , ... ( role === 'speaker' ) ? [ this.Speaker() ] : [] , ] }
Ici, la logique est simple: nous affichons toujours des diapositives pour les auditeurs, mais le panneau des haut-parleurs n'est affiché que si le rôle actuel est speaker
- speaker
. Si le rôle change, la présentation de l'application changera également en raison de la magie de la programmation réactive aux objets.
Acheminement
Nous prendrons le rôle du paramètre d'adresse, via l'API réactive spéciale $mol_state_arg
.
role() : 'speaker' | 'listener' { return $mol_state_arg.value( 'role' ) || 'speaker' }
Pour une raison quelconque, l'adresse a changé - le rôle en sera extrait automatiquement et transmis à cette méthode.
Structure d'interface d'écoute
Décrivons l'interface d'écoute.
Listener $mol_page title <= title tools / <= Slide_switcher body / <= Listener_content <= Progress
Il utilise le composant standard $mol_page
qui dessine une page typique avec un en-tête et un corps. Dans l'en-tête, il y a une zone où le nom de la page est affiché. Grâce à la propriété title
, vous pouvez spécifier ce qui doit y être affiché. Ce que nous avons fait en associant sa propriété title
à notre propriété du même nom. Maintenant, en changeant notre propriété, nous avons un contrôle total sur ce qui sera affiché sur la page en tant que titre.
À droite dans l'en-tête, il y a une zone de sortie pour des outils supplémentaires - tools
. Dans ce document, nous Slides_switcher
- un composant pour afficher le numéro de diapositive et basculer entre les diapositives adjacentes.
Et enfin, en tant que body
page en body
nous affichons le contenu de la diapositive et de la barre de progression.
Structure du commutateur de page
Comment implémenter Slide_switcher
? Utilisez simplement le composant standard $mol_paginator
.
Slide_switcher $mol_paginator value?val <=> slide?val
Tout ce qu'il a, c'est une value
propriété mutable, que nous associons bilatéralement à notre propriété contenant le numéro de la diapositive en cours. Aucune importation, rappel, événement et autre corbeille. Ces deux lignes sont tout ce qui est nécessaire pour qu'un commutateur de page de travail apparaisse sur votre page.
Structure du contenu des diapositives
Pour afficher le contenu de la diapositive, nous utilisons à nouveau le composant standard $mol_text
.
Listener_content $mol_text uri_base <= uri_base text <= listener_content
Il prend le markdown
et le rend. Étant donné que les liens dans ce texte seront relatifs au fichier source et non à notre application, nous transmettons le lien à la propriété uri_base, pour laquelle tous les chemins seront résolus.
Structure des indicateurs de progrès
Comme vous l'avez probablement déjà deviné, il existe également un composant standard pour afficher la progression - $mol_portion
.
Progress $mol_portion portion <= progress
portion: [ 0 .. 1 ]
Nous lui donnons un nombre de 0 à 1 et obtenons un indicateur rempli pour cette part.
Structure d'interface de haut-parleur
Nous avons quelque chose de plus intéressant dans l'interface du haut-parleur. Les outils affichés dans l'en-tête ne sont en aucun cas attachés à la page en cours - ils sont communs à l'ensemble de l'application. Par conséquent, au lieu de les coder en dur ici, nous speaker_tools
uniquement le slot speaker_tools
travers lequel nous transférerons la liste des composants de l'extérieur.
Speaker $mol_page head <= speaker_tools /$mol_view body / <= Speaker_content
Structure d'application
$hyoo_slides
maintenant d'un niveau et créez un composant d'application $hyoo_slides
qui utilise le composant de page.
$hyoo_slides $mol_view Page!index $hyoo_slides_page - ... plugins / <= Nav <= Touch <= Speech_next - ...
Tout composant $mol_view
possède une propriété de plugins
par laquelle une logique supplémentaire peut lui être connectée. Les plugins plugins vivent sur le même noeud DOM que le composant lui-même. Le composant les initie lors de son rendu. Et quand environ cesse d'être rendu - les plugins sont détruits automatiquement.
Nous avons également annoncé la propriété Page
, qui pour chaque index renvoie une instance distincte du composant $hyoo_slides_page
nous avons développé précédemment.
Configuration de page externe
Page!index $hyoo_slides_page role <= role slide?val <=> page_slide!index?val speaker_tools / <= Speech_toggle <= Speech_text <= Open_listener
Nous transmettons la propriété de role
au sous-composant tel quel. La propriété slide
du composant page est connectée par communication bidirectionnelle avec la propriété page_slide
de l'application. Notez que page_slide
accepte non seulement la nouvelle valeur facultative, mais aussi l'index de page. Cela vous permet de renvoyer un numéro pour chaque page. Enfin, dans le slot speaker_tools
nous avons annoncé précédemment, nous avons mis trois composants pour aider à gérer les diapositives.
Structure du commutateur de commande vocale
Nous implémentons Speech_toggle
via le composant standard $mol_check_icon
, qui dessine une icône. Lorsque vous cliquez dessus, il bascule le drapeau checked
. Et l'état actuel est affiché en changeant la couleur de l'icône.
Speech_toggle $mol_check_icon Icon <= Speech_toggle_icon $mol_icon_microphone checked?flag <=> speech_enabled?flag
Nous avons pris l'icône du $mol_icon
, où sur 4000 icônes faites dans le style de conception de matériel ascétique, il est facile de trouver la bonne.
Structure du bouton d'ouverture de la fenêtre esclave
Ici, tout est simple. Ce bouton sera le lien $mol_link
. Elle peut définir la propriété uri
avec une adresse, ou elle peut faire quelque chose de plus astucieux et simplement corriger l'adresse actuelle, en remplaçant certains paramètres via arg
.
Listener_open $mol_link target \_blank arg * role \listener slide null sub / <= Listener_open_icon $mol_icon_external
Ici, nous avons effacé le numéro de diapositive de l'adresse afin que la fenêtre esclave le prenne dans la mémoire locale, et non dans l'adresse. Cela garantira que les fenêtres se synchronisent les unes avec les autres. Ils ont également indiqué que le rôle devrait être un «auditeur». À l'intérieur du lien, nous mettons une icône à la place du texte.
Plugins
Les plugins peuvent étendre considérablement les capacités du composant. Nous les utiliserons au maximum.
plugins / <= Nav <= Touch <= Speech_next <= Speech_prev <= Speech_start <= Speech_end - ...
Tous les plugins que nous utilisons peuvent être divisés en 3 catégories: navigation clavier, contrôle gestuel et contrôle vocal.
Navigation au clavier
Grâce à $mol_nav
il est facile d'implémenter la navigation au clavier verticalement et horizontalement. Tout ce qui est nécessaire est de fournir au plug-in une liste de clés par lesquelles il basculera et une communication bidirectionnelle à la valeur actuelle.
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
Gestes des doigts
Pour le suivi des doigts, il existe un $mol_touch
. Avec lui, vous pouvez zoomer, faire un panoramique et glisser. C'est la dernière opportunité qui nous intéresse maintenant.
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 ) }
Il existe deux types de balayage. Par exemple, balayez vers la gauche ou la droite depuis n'importe quelle partie de l'écran et balayez en raison du bord droit ou gauche de l'écran vers le centre. Dans le code présenté, nous avons suspendu nos gestionnaires sur le premier type de balayage.
Commande vocale
Pour le contrôle vocal, utilisez le $mol_speech
. Il est nécessaire de créer une instance du plugin pour chaque version de l'action.
Sing $mol_speech event_catch?val <=> sing?val patterns / \sing( \S+?)* \( \S+?)*
Le plugin accepte un gestionnaire d'actions et un ensemble de modèles, lors de la détection de ceux-ci, un événement sera déclenché. Vous pouvez utiliser des crochets de capture dans les modèles pour obtenir les mots correspondant à leur contenu dans le gestionnaire.
Interrupteur coulissant automatique
Par défaut, $mol_speech
nécessite une gestion polie. Par exemple, vous ne devriez pas dire «chanter», mais «chanter, s'il vous plaît». Vous pouvez remplacer la propriété du suffix
pour modifier ou supprimer complètement ce mot de code.
Speech_next_auto $mol_speech event_catch?val <=> go_next?val suffix \ patterns <= speech_next_auto_patterns
Par exemple, pour implémenter la commutation automatique des diapositives, nous n'avons pas besoin de mots magiques. Mais nous allons générer un ensemble de modèles de manière dynamique, basé sur l'analyse du contenu du texte du locuteur.
Lancement de l'application
Ayant un composant d'application, vous pouvez l'instancier manuellement comme n'importe quelle classe ordinaire. Mais nous utiliserons le lancement automatique via l'attribut spécial mol_view_root
.
<body mol_view_root="$hyoo_slides"> <script src="web.js" charset="utf-8"></script> </body>
Le nom d'attribut est le nom du composant. Le rendu de cette manière, bien sûr, peut être absolument n'importe quel composant.
Hors ligne
Pour ajouter un support hors ligne, incluez simplement le module mol/offline/install
dans le bundle.
include \/mol/offline/install
Il déclenche automatiquement un ServiceWorker, qui met en cache toutes les demandes. Et si le réseau n'est pas disponible, il renvoie les données du cache. Ce n'est pas l'implémentation la plus cool, mais pour les cas simples où vous ne voulez pas vous embêter, cela suffira.
Mode d'impression
Plus tôt, j'ai dit que lors de l'impression, vous devez rendre toutes les pages, mais il n'est pas nécessaire de surveiller manuellement onbeforeprint
et après onafterprint
, car nous avons une programmation entièrement réactive, nous utiliserons donc l'état réactif $mol_print
, qui nous donne un indicateur réactif auquel nous pouvons lier le rendu.
sub() { if( !this.$.$mol_print.active() ) { return [ this.Page( this.slide() ) ] } return $mol_range2( index => this.Page( index ) , ()=> this.slide_keys().length , ) }
Ici, nous ne renvoyons qu'une seule page si le drapeau active
n'est pas levé. Sinon, nous retournons un tableau paresseux qui calcule sa longueur et ses éléments selon les formules données.
Épilogue
En conséquence, nous avons obtenu une application Web moderne avec un tas de fonctionnalités et un poids de seulement 35 Ko. Ajoutez un manifeste et il y aura une application Web progressive à part entière. Bien sûr, de nombreux détails n'ont pas été pris en compte. Vous pouvez les voir dans le code sur le github. Pour toutes les questions, écrivez des télégrammes dans le chat.
Ces diapositives sont dans l'application: slides.hyoo.ru
Sources d'application: hyoo-ru / slides.hyoo.ru
Exemples de présentation: nin-jin / slides
Chat télégramme: @mam_mol
Je serai heureux si vous essayez de faire votre présentation avec $hyoo_slides
. Et je serai très heureux si vous aidez à le rendre encore meilleur qu'aujourd'hui. Merci de votre attention!