Fermer

janvier 20, 2020

Recréer le boutonpoussoir Arduino à l'aide de SVG et20 minutes de lecture


À propos de l'auteur

Uri Shaked est le co-fondateur de Wokwi, une plate-forme d'enseignement de l'Arduino, de l'IoT et de l'électronique. Il co-organise les groupes de rencontre IoT Makers et JavaScript Israel,…
En savoir plus sur
Uri

HTML est livré avec un tas de contrôles d'entrée, et il y a des tonnes de bibliothèques de composants qui incluent de nombreux contrôles standard tels que des cases à cocher et des boutons radio. Mais que se passe-t-il lorsque vous avez besoin de quelque chose d'inhabituel?

Dans cet article, vous allez apprendre à créer des composants HTML personnalisés qui imitent des objets physiques, tels que le bouton-poussoir Arduino. Nous allons dessiner le composant dans Inkscape à partir de zéro, optimiser le code SVG généré pour le Web et l'envelopper comme un composant Web autonome en utilisant la bibliothèque légère lit-element en accordant une attention particulière à l'accessibilité et à la convivialité mobile

Aujourd'hui, je vais vous emmener à travers le voyage de la création d'un composant HTML qui imite un composant bouton-poussoir momentané qui est couramment utilisé avec Arduino et dans les projets électroniques. Nous utiliserons des technologies telles que SVG, Web Components et lit-element et apprendrons à rendre le bouton accessible grâce à une supercherie JavaScript-CSS.

Commençons!

D'Arduino à HTML: Le besoin d'un composant de bouton-poussoir

Avant de commencer le voyage, explorons ce que nous allons créer et, plus important encore, pourquoi. Je crée un simulateur Arduino open source en JavaScript appelé avr8js . Ce simulateur est capable d'exécuter du code Arduino et je vais l'utiliser dans une série de tutoriels et de cours qui enseignent aux fabricants comment programmer pour Arduino.

Le simulateur lui-même ne prend en charge que l'exécution du programme – il exécute l'instruction de code par et met à jour son état interne et un tampon mémoire selon la logique du programme. Pour interagir avec le programme Arduino, vous devez créer des composants électroniques virtuels qui peuvent envoyer des entrées au simulateur ou réagir à ses sorties.

L'exécution du simulateur seul est très similaire à l'exécution de JavaScript de manière isolée. Vous ne pouvez pas vraiment interagir avec l'utilisateur à moins de créer également des éléments HTML et de les accrocher au code JavaScript via le DOM.

Ainsi, en plus du simulateur du processeur, je travaille également sur une bibliothèque de composants HTML qui imitent le matériel physique, en commençant par les deux premiers composants que vous trouverez dans presque tous les projets électroniques: une LED et un bouton-poussoir.

 La LED et les éléments de bouton-poussoir en action
La LED et les éléments de bouton-poussoir en action ( Grand aperçu )

La LED est relativement simple, car elle n'a que deux états de sortie: on et off. Dans les coulisses, il utilise un filtre SVG pour créer l'effet d'éclairage.

Le bouton-poussoir est plus intéressant. Il a également deux états, mais il doit réagir aux entrées des utilisateurs et mettre à jour son état en conséquence, et c'est de là que vient le défi, comme nous le verrons bientôt. Mais d'abord, clouons les exigences de notre composant que nous allons créer.

Définition des exigences pour le bouton-poussoir

Notre composant ressemblera à un bouton-poussoir de 12 mm. Ces boutons sont très courants dans les kits de démarrage électroniques et sont livrés avec des capuchons de plusieurs couleurs, comme vous pouvez le voir sur la photo ci-dessous:

 Simon Game avec boutons-poussoirs jaune, rouge, bleu et vert
Simon Game avec jaune, rouge , Boutons poussoirs bleu et vert ( Grand aperçu )

En termes de comportement, le bouton poussoir doit avoir deux états: pressé et relâché. Ceux-ci sont similaires aux événements HTML mousedown / mouseup, mais nous devons nous assurer que les boutons poussoirs peuvent également être utilisés à partir d'appareils mobiles et sont accessibles aux utilisateurs sans souris.

Comme nous utiliserons l'état du bouton poussoir comme entrée pour Arduino, il n'est pas nécessaire de prendre en charge les événements "clic" ou "double clic". Il appartient au programme Arduino exécuté dans la simulation de décider comment agir sur l'état du bouton, et les boutons physiques ne génèrent pas d'événements de clic.

Si vous souhaitez en savoir plus, consultez une conférence que j'ai eue avec Benjamin Gruenbaum à SmashingConf Freiburg en 2019: « Anatomy of a Click ».

Pour résumer nos exigences, notre bouton-poussoir doit:

  1. ressembler au bouton-poussoir physique 12 mm;
  2. avoir deux états distincts: enfoncés et relâchés, et ils doivent être visuellement discernables;
  3. prennent en charge l'interaction avec la souris, les appareils mobiles et sont accessibles aux utilisateurs du clavier;
  4. prennent en charge différentes couleurs de capuchons (au moins rouge, vert, bleu, jaune,

Maintenant que nous avons défini les exigences, nous pouvons commencer à travailler sur l'implémentation.

SVG For The Win

La plupart des composants Web sont implémentés en utilisant une combinaison de CSS et HTML. Lorsque nous avons besoin de graphiques plus complexes, nous utilisons généralement des images raster, au format JPG ou PNG (ou GIF si vous vous sentez nostalgique).

Dans notre cas, cependant, nous utiliserons une autre approche: les graphiques SVG. SVG se prête beaucoup plus facilement aux graphiques complexes que CSS (oui, je sais, vous pouvez créer des choses fascinantes avec CSS, mais cela ne veut pas dire que cela devrait). Mais ne vous inquiétez pas, nous n'abandonnons pas entièrement le CSS. Cela nous aidera à styliser les boutons poussoirs, et même à les rendre accessibles.

SVG a un autre gros avantage, par rapport aux images graphiques raster: il est très facile à manipuler à partir de JavaScript et peut être stylisé via CSS. Cela signifie que nous pouvons fournir une seule image pour le bouton et utiliser JavaScript pour personnaliser le capuchon de couleur et des styles CSS pour indiquer l'état du bouton.

Enfin, SVG est juste un document XML, qui peut être édité avec des éditeurs de texte, et incorporé directement dans HTML, ce qui en fait une solution parfaite pour créer des composants HTML réutilisables. Êtes-vous prêt à dessiner notre bouton-poussoir?

Dessin du bouton-poussoir avec Inkscape

Inkscape est mon outil préféré pour créer des graphiques vectoriels SVG. Il est gratuit et regorge de fonctionnalités puissantes, telles qu'une grande collection de préréglages de filtre intégrés, de suivi de bitmap et d'opérations binaires de chemin. J'ai commencé à utiliser Inkscape pour créer de l'art PCB mais au cours des deux dernières années, j'ai commencé à l'utiliser pour la plupart de mes tâches d'édition graphique.

Dessiner le bouton-poussoir dans Inkscape est assez simple. Nous allons dessiner une illustration de dessus du bouton et de ses quatre fils métalliques qui le connectent à d'autres parties, comme suit:

  1. Rectangle gris foncé 12 × 12 mm pour le boîtier en plastique, avec des coins légèrement arrondis pour le rendre plus doux .
  2. Plus petit, 10,5 × 10,5 rectangle gris clair pour le couvercle en métal.
  3. Quatre cercles plus sombres, un dans chaque coin pour les broches qui maintiennent le bouton ensemble.
  4. Un grand cercle au milieu, c'est le contour du capuchon du bouton.
  5. Un petit cercle au milieu pour le haut du capuchon du bouton.
  6. Quatre rectangles gris clair en forme de "T" pour les fils métalliques du bouton.

Et le résultat, légèrement agrandi:

 Notre croquis de bouton poussoir dessiné à la main
Notre croquis de bouton poussoir dessiné à la main ( Grand aperçu )

Comme touche finale, nous ajouterons un peu de magie de dégradé SVG à le contour du bouton, pour lui donner une sensation 3D:

 Ajout d'un remplissage dégradé pour créer une sensation 3D
Ajout d'un dégradé f mal pour créer une sensation 3D ( Grand aperçu )

Voilà! Nous avons les visuels, maintenant nous devons les obtenir sur le Web.

D'Inkscape au Web SVG

Comme je l'ai mentionné ci-dessus, les SVG sont assez simples à intégrer dans HTML – vous pouvez simplement coller le contenu du fichier SVG dans votre document HTML, ouvrez-le dans un navigateur et il sera affiché sur votre écran. Vous pouvez le voir en action dans l'exemple CodePen suivant:

Voir le stylo Bouton-poussoir SVG en HTML par @Uri Shaked

Voir le stylo Bouton-poussoir SVG en HTML par @Uri Shaked

Cependant, les fichiers SVG enregistrés à partir d'Inkscape contiennent beaucoup de bagages inutiles tels que la version d'Inkscape et la position de la fenêtre lors de la dernière sauvegarde du fichier. Dans de nombreux cas, il y a aussi des éléments vides, des dégradés et des filtres inutilisés, et ils gonflent tous la taille du fichier, et rendent plus difficile de travailler avec lui dans HTML.

Heureusement, Inkscape peut nettoyer la majeure partie du désordre pour nous. Voici comment procéder:

  1. Allez dans le menu Fichier et cliquez sur Nettoyer le document . (Cela supprimera les définitions inutilisées de votre document.)
  2. Allez à nouveau dans Fichier et cliquez sur Enregistrer sous… . Lors de l'enregistrement, sélectionnez SVG optimisé ( *. Svg ) dans la liste déroulante Enregistrer sous le type .
  3. Vous verrez une boîte de dialogue «Sortie SVG optimisée» avec trois onglets. Cochez toutes les options, à l'exception de «Conserver les données de l'éditeur», «Conserver les définitions non référencées» et «Conserver les ID créés manuellement…».
( Grand aperçu )

La suppression de toutes ces choses créera un fichier SVG plus petit et plus facile à utiliser. Dans mon cas, le fichier est passé de 4593 octets à seulement 2080 octets, soit moins de la moitié de la taille. Pour les fichiers SVG plus complexes, cela peut être une énorme économie de bande passante et peut faire une différence notable dans le temps de chargement de votre page Web.

Le SVG optimisé est également beaucoup plus facile à lire et à comprendre. Dans l'extrait suivant, vous devriez être capable de repérer facilement les deux rectangles qui composent le corps du bouton poussoir:




  
  
  
  



Vous pouvez même raccourcir davantage le code, par exemple, en modifiant la largeur de trait du premier rectangle de 1.0003 à seulement 1 . Cela ne fait pas une différence significative dans la taille du fichier, mais il rend le code plus facile à lire.

En général, un passage manuel sur le fichier SVG généré est toujours utile. Dans de nombreux cas, vous pouvez supprimer des groupes vides ou appliquer des transformations matricielles, ainsi que simplifier les coordonnées du dégradé en les mappant de «l'espace utilisateur lors de l'utilisation» (coordonnées globales) à la «boîte englobante d'objet» (par rapport à l'objet). Ces optimisations sont facultatives, mais vous obtenez du code plus facile à comprendre et à gérer.

À partir de ce moment, nous allons ranger Inkscape et travailler avec la représentation textuelle de l'image SVG.

Création d'un composant Web réutilisable

Jusqu'à présent, nous avons obtenu les graphiques de notre bouton-poussoir, prêts à être insérés dans notre simulateur. Nous pouvons facilement personnaliser la couleur du bouton en modifiant l'attribut fill du petit cercle et la couleur de départ du dégradé du plus grand cercle.

Notre prochain objectif est de transformer notre bouton-poussoir en un Composant Web réutilisable qui peut être personnalisé en transmettant un attribut de couleur et réagit à l'interaction de l'utilisateur (événements de presse / relâchement). Nous utiliserons lit-element une petite bibliothèque qui simplifie la création de composants Web.

lit-element excelle dans la création de petites bibliothèques de composants autonomes. Il est construit en plus de la norme des composants Web, qui permet à ces composants d'être consommés par n'importe quelle application Web, quel que soit le cadre utilisé: Angular, React, Vue ou Vanilla JS pourraient tous utiliser notre composant.

Création de composants dans lit-element se fait en utilisant une syntaxe basée sur une classe, avec une méthode render () qui renvoie le code HTML de l'élément. Un peu similaire à React, si vous le connaissez. Cependant, contrairement à react, lit-element utilise le standard Javascript avec les littéraux de modèle balisés pour définir le contenu du composant.

Voici comment créer un simple bonjour- composant mondial :

 import {customElement, html, LitElement} de 'lit-element';

@customElement ('hello-world')
la classe d'exportation HelloWorldElement étend LitElement {
  render () {
    retourner html`
      

        Bonjour le monde!       

    "   } }

Ce composant peut ensuite être utilisé n'importe où dans votre code HTML en écrivant simplement .

Remarque : En fait, notre bouton-poussoir nécessite juste un peu plus de code: nous devons déclarer une propriété d'entrée pour la couleur, en utilisant la décoratrice @property () (et avec une valeur par défaut de rouge), et collez le code SVG dans notre méthode render () en remplaçant le couleur du capuchon du bouton avec la valeur de la propriété color ( voir l'exemple ). Les bits importants se trouvent à la ligne 5, où nous définissons la propriété color: @property () color = 'red'; Aussi, à la ligne 35 (où nous utilisons cette propriété pour définir la couleur de remplissage du cercle qui fait la coiffe du bouton), en utilisant la syntaxe littérale du modèle JavaScript, écrite comme $ {color} :


Making It Interactive

La dernière pièce du puzzle serait de faire le bouton interactif. Il y a deux aspects que nous devons considérer: la réponse visuelle à l'interaction ainsi que la réponse programmatique à l'interaction.

Pour la partie visuelle, nous pouvons simplement inverser la remplissage en dégradé du contour du bouton, ce qui créera l'illusion sur laquelle le bouton a été pressé:

 Inverser le gradient du contour du bouton
Inverser le gradient du contour du bouton ( Grand aperçu )

Le dégradé pour le contour du bouton est défini par le code SVG suivant, où $ {color} est remplacé par la couleur du bouton par lit-element comme expliqué ci-dessus:

  
  
  
  
  

Une approche pour l'apparence du bouton pressé serait de définir un deuxième dégradé, d'inverser l'ordre des couleurs et de l'utiliser comme remplissage du cercle chaque fois que le bouton est pressé. Cependant, il existe une astuce intéressante qui nous permet de réutiliser le même dégradé: nous pouvons faire pivoter l'élément svg de 180 degrés à l'aide d'une transformation SVG:


L'attribut transform indique à SVG que nous voulons faire pivoter le cercle de 180 degrés, et que la rotation doit se produire autour du point (6, 6) qui est le centre du cercle (défini par cx et cy ). Les transformations SVG affectent également le remplissage de la forme, et donc notre dégradé sera également tourné.

Nous voulons uniquement inverser le dégradé lorsque le bouton est enfoncé, donc au lieu d'ajouter l'attribut transform directement sur l'élément comme nous l'avons fait ci-dessus, nous allons en fait définir une classe CSS pour cet élément, puis profiter du fait que les attributs SVG peuvent être définis via CSS, mais en utilisant une syntaxe légèrement différente: [19659093] transform: rotation (180deg);
origine de transformation: 6px 6px;

Ces deux règles CSS font exactement la même chose que la transformation que nous avions ci-dessus – faire pivoter le cercle de 180 degrés autour de son centre en (6, 6). Nous voulons que ces règles soient appliquées uniquement lorsque le bouton est enfoncé, nous allons donc ajouter un nom de classe CSS à notre cercle:


Et maintenant nous pouvons utiliser la: pseudo-classe CSS active pour appliquer une transformation à la button-contour chaque fois que l'élément SVG est cliqué:

 svg: active .button-contour {
  transformer: tourner (180deg);
  origine de transformation: 6px 6px;
}

lit-element nous permet d'attacher une feuille de style à notre composant en la déclarant dans un getter statique à l'intérieur de notre classe de composant, à l'aide d'un modèle littéral étiqueté:

 static get styles () {
  return css`
    svg: active .button-contour {
      transformer: tourner (180deg);
      origine de transformation: 6px 6px;
    }
  "
}

Tout comme le modèle HTML, cette syntaxe nous permet d'injecter des valeurs personnalisées à notre code CSS, même si nous n'en avons pas besoin ici. lit-element s'occupe également de créer le Shadow DOM pour notre composant, afin que le CSS n'affecte que les éléments de notre composant et ne saigne pas aux autres parties de l'application.

Maintenant, qu'en est-il du comportement programmatique du bouton lorsqu'il est pressé? Nous voulons déclencher un événement afin que les utilisateurs de notre composant puissent comprendre à chaque fois que l'état du bouton change. Une façon de le faire est d'écouter les événements mousedown et mouseup sur l'élément SVG et de déclencher les événements «bouton-presse» / ​​«bouton-libération» en conséquence. Voici à quoi cela ressemble avec la syntaxe lit-element :

 render () {
  const {color} = this;
  retourner html`
     this.dispatchEvent (nouvel événement ('bouton-pression'))}
      @mouseup = $ {() => this.dispatchEvent (nouvel événement ('libération de bouton'))}
      ...
    
  "
}

Cependant, ce n'est pas la meilleure solution, comme nous le verrons sous peu. Mais d'abord, jetez un coup d'œil au code que nous avons obtenu jusqu'à présent:

 import {customElement, css, html, LitElement, property} from 'lit-element';

@customElement ('wokwi-pushbutton')
la classe d'exportation PushbuttonElement étend LitElement {
  @property () color = 'red';

  styles get statiques () {
    return css`
      svg: active .button-contour {
        transformer: tourner (180deg);
        origine de transformation: 6px 6px;
      }
    "
  }

  render () {
    const {color} = this;
    retourner html`
       this.dispatchEvent (nouvel événement ('bouton-pression'))}
        @mouseup = $ {() => this.dispatchEvent (nouvel événement ('libération de bouton'))}
        largeur = "18 mm"
        hauteur = "12 mm"
        version = "1.1"
        viewBox = "- 3 0 18 12"
        xmlns = "http://www.w3.org/2000/svg"
      >
        
          
            
            
            
            
          
        
        
        
        
          
          
          
          
        
        
           
          
          
          
        
        
          
          
        
      
     »;
  }
}

Vous pouvez cliquer sur chacun des boutons et voir comment ils réagissent. Le rouge a même des écouteurs d'événements (définis dans index.html ), donc quand vous cliquez dessus, vous devriez voir des messages écrits sur la console. Mais attendez, que se passe-t-il si vous souhaitez utiliser le clavier à la place?

Rendre le composant accessible et adapté aux mobiles

Hourra! Nous avons créé un composant de bouton-poussoir réutilisable avec SVG et élément éclairé !

Avant de nous déconnecter de notre travail, nous devons examiner quelques problèmes. Tout d'abord, le bouton n'est pas accessible aux personnes qui utilisent le clavier. De plus, le comportement sur mobile est incohérent – les boutons semblent enfoncés lorsque vous maintenez votre doigt dessus, mais les événements JavaScript ne sont pas déclenchés si vous maintenez votre doigt pendant plus d'une seconde.

Commençons par aborder le clavier problème. Nous pourrions rendre le bouton accessible au clavier en ajoutant un attribut tabindex à l'élément svg, le rendant focalisable. Une meilleure alternative, à mon avis, consiste simplement à envelopper le bouton avec un élément

SPACE_KEY est une constante qui équivaut à 32, et vers le haut / vers le bas sont deux méthodes de classe qui envoient le bouton-poussoir et événements de libération de bouton :

 @property () pressé = faux;

privé vers le bas () {
  si (! this.pressed) {
    this.pressed = true;
    this.dispatchEvent (nouvel événement ('bouton-pression'));
  }
}

privé () {
  si (this.pressed) {
    this.pressed = false;
    this.dispatchEvent (nouvel événement ('bouton-libération'));
  }
}
  • Vous pouvez trouver le code source complet ici .

Nous l'avons fait!

Ce fut un assez long voyage qui a commencé par définir les exigences et dessiner l'illustration du bouton dans Inkscape, est passé par la conversion de notre fichier SVG en un composant Web réutilisable en utilisant lit-element et après nous être assuré qu'il est accessible et adapté aux mobiles, nous nous sommes retrouvés avec près de 100 lignes de code d'un délicieux composant de bouton-poussoir virtuel. [19659005] Ce bouton n'est qu'un composant unique dans une bibliothèque open-source de composants électroniques virtuels que je construis. Vous êtes invité à jeter un œil au code source ou à consulter le livre d'histoires en ligne où vous pouvez voir et interagir avec tous les composants disponibles.

Et enfin, si vous êtes intéressé dans Arduino, jetez un œil au cours de programmation Simon pour Arduino Je suis en train de construire, où vous pouvez également voir le bouton-poussoir en action.

Jusqu'à la prochaine fois, alors!

 Éditorial fracassant [19659137] (dm, il) </span data-recalc-dims=



Source link

Revenir vers le haut