5 points par GN⁺ 6 시간 전 | 2 commentaires | Partager sur WhatsApp
  • Même un bouton aussi simple que la rotation d’une photo peut changer radicalement l’expérience utilisateur selon la manière dont il gère les saisies répétées rapides
  • L’iPhone mémorise les appuis multiples de rotation à 90 degrés et enchaîne la rotation suivante dès que l’animation est terminée
  • Le Nothing Phone/Android confirme les taps par retour haptique et son, mais ignore les taps suivants effectués pendant l’animation de rotation
  • Lorsqu’il faut faire pivoter plusieurs photos de documents, même une UI de retouche photo occasionnelle doit permettre des actions plus rapides et prévisibles
  • Plutôt que de forcer l’utilisateur à attendre la fin de l’animation, un bouton devrait accepter les entrées via une mise en tampon des taps, ou en interrompant/accélérant l’animation

Comment le bouton de rotation des photos gère les saisies répétées

  • Le bouton de rotation d’une photo est un contrôle standard qui, lorsqu’on l’actionne une fois, effectue généralement une rotation de 90 degrés dans le sens antihoraire, puis répète la même action à chaque nouvel appui
  • L’animation de rotation montre le changement d’orientation de la photo et aide l’utilisateur à ne pas perdre ses repères
  • Si l’on appuie rapidement 8 fois pour effectuer des rotations de 90 degrés, l’image devrait faire deux tours complets et revenir à son orientation initiale, comme ce que les ingénieurs appellent un « no op »
  • Sur iPhone, cette attente se vérifie en pratique
    • Il mémorise les taps rapides
    • Une fois la rotation précédente terminée, il exécute la rotation suivante en attente
  • Sur Nothing Phone/Android, le résultat est différent
    • Le bouton fournit une confirmation du tap par retour haptique et sonore
    • Si l’animation de rotation précédente n’est pas terminée, le nouveau tap est ignoré

Même une UI occasionnelle a besoin d’une gestion d’entrée plus robuste pour les tâches répétitives

  • Le handicap situationnel est l’idée que le handicap ne concerne pas seulement certaines personnes, mais que chacun peut effectivement se retrouver en situation de handicap dans un contexte donné
  • La prise de photos relève généralement d’un usage occasionnel, mais l’appareil photo d’un téléphone peut se tromper d’orientation lorsque l’on photographie vers le bas
  • Si l’on prend plusieurs photos de documents en mode paysage puis qu’il faut les faire pivoter une par une, l’utilisateur peut devoir faire tourner des dizaines de photos
  • Dans ce contexte, il est plus agréable et moins fastidieux qu’un bouton réagisse de façon prévisible même si l’on appuie trois fois à la vitesse souhaitée
  • Sur une durée suffisamment longue ou auprès d’un grand nombre d’utilisateurs, même une interface occasionnelle rencontre des moments où elle doit être traitée plus sérieusement
    • Cette « puissance utilisateur situationnelle » apparaît aussi dans des cas comme la retouche photo sur mobile ou GarageBand
  • La solution n’est pas nécessairement une mise en tampon des taps
    • Un tap interruptif peut aussi arrêter ou accélérer l’animation
    • L’essentiel est de ne pas obliger l’utilisateur à attendre la fin de l’animation

2 commentaires

 
GN⁺ 5 시간 전
Avis sur Hacker News
  • Que faire si l’utilisateur clique trop de fois par erreur, ou s’il pense que son premier clic n’a pas été pris en compte ?
    Je me souviens encore d’une keynote où Steve Jobs montrait à quel point l’affichage des documents PDF était devenu plus rapide dans le nouveau macOS. Les ingénieurs avaient prévu un bouton pour faire défiler le PDF à l’écran, mais Jobs a appuyé dessus une fois de trop par erreur et a dit quelque chose comme « ça va le faire défiler jusqu’au bout deux fois ? » ; et, effectivement, l’action avait été mise en file d’attente. Il a donc fallu remonter en haut et attendre la fin du deuxième défilement
    Jobs s’en est sorti en disant que « même en comptant le temps de parcourir le document une deuxième fois, c’est plus rapide que les PDF dans l’ancien OS »

    • Le debouncing existe pour une raison. Il y a des cas où appuyer deux fois sur un bouton doit déclencher deux exécutions, et des cas où ce ne doit pas être le cas. Distinguer quelle option est préférable selon la situation n’a rien de simple
      Il faut au minimum réfléchir au traitement adapté à chaque contexte. Dans une UI, certains boutons relèvent clairement d’un côté, d’autres clairement de l’autre, mais pour certains c’est ambigu ; si les deux comportements peuvent se défendre, on finit par obtenir une UI incohérente
      Je ne connais pas vraiment de bonne solution

    • D’après l’article :

      The Nothing Phone button gives you a tap confirmation via both haptics and sound, and then ignores the tap if a previous rotation is still animating.

      C’est ça, le problème. Le nombre de fois où l’app indique que l’entrée du bouton a été enregistrée doit être le même que le nombre d’actions réellement effectuées. Le debouncing est une bonne pratique, mais si on l’utilise, il ne faut pas donner de feedback pour les taps qui ont été filtrés

    • J’ai été assez dérouté par le passage « et si l’utilisateur clique trop de fois par erreur, ou pense que le premier clic n’a pas été enregistré ? », parce que ça m’a immédiatement fait penser à l’accessibilité. J’ai tout de suite imaginé une personne qui a des tremblements et qui veut appuyer une seule fois, mais finit par appuyer deux fois
      Et il y a aussi des gens qui double-cliquent sur tous les boutons. Désactiver un bouton de soumission dans onclick pour gérer ce cas est très courant

    • Je ne suis plus le fanboy Apple/Mac/Jobs que j’ai pu être, mais les présentations Apple qui donnaient l’impression d’être menées par quelqu’un qui voulait montrer quelque chose de génial me manquent
      Les présentations Apple récentes sont tellement rigides et déshumanisées, avec une impression de gens en costume aux commandes, que je n’arrive même pas à les regarder jusqu’au bout. Tout le monde a l’air de robots qui cachent toute émotion et toute humanité, de peur d’être renvoyés s’ils s’écartent du script sacré
      C’est peut-être hors sujet, mais ça me rappelle à quel point même les improvisations un peu brouillonnes de Jobs pouvaient être agréables à suivre

    • Ce n’est clairement pas une situation où l’on peut dire « et dans ce cas alors ? ». Pour deux raisons :

      1. « The Nothing Phone button gives you a tap confirmation via both haptics and sound, and then ignores the tap […] »
      2. Il y a une bonne raison d’appuyer 3 fois de suite sur ce bouton
  • Je veux bien soutenir l’argument qu’on voit ailleurs du type « et le debouncing alors ? », et l’auteur ne devrait pas simplement l’ignorer
    Mais je n’aime pas non plus le mème you had one job, et j’ai envie de m’opposer à son usage irréfléchi. La plupart du temps, ce mème est faux, et c’est généralement pareil pour les boutons. Dans une interface utilisateur courante, un bouton donné remplit simultanément plusieurs des rôles suivants :

    • communiquer ce qui se passe quand on appuie dessus
    • parfois communiquer l’état actuel d’une partie du système ; par exemple, un bouton qui active ou désactive un mode indique visuellement le mode actuel
    • exécuter l’action voulue au clic
    • parfois indiquer que la commande a été reçue et qu’elle est en cours d’exécution ; par exemple, comme dans le cas cité dans l’article, on peut désactiver le bouton pendant l’animation de rotation pour éviter la confusion
    • Derrière le mème you had one job, on pourrait presque toujours ajouter « parce que j’ai refusé de prendre en compte la complexité réelle de ton travail »
    • Très bon point, et j’apprécie particulièrement l’accent mis sur le fait que les attentes varient d’une personne à l’autre quant à ce qu’est ou n’est pas un bouton. Chacun des points décrit respectivement un bouton avec libellé, un bouton à bascule, un vrai bouton et un indicateur de progression. Selon l’utilisateur, tout cela peut être un « bouton »
    • Si la question est « et le debouncing alors ? », ne suffirait-il pas d’exécuter la fonction du bouton au relâchement du toucher, plutôt qu’au début du toucher ?
  • L’expression « une seule tâche » ne convient pas vraiment à un bouton. Un bouton ne doit pas seulement être cliquable : il doit faire plusieurs choses
    Il y a le feedback au clic, le feedback au survol, l’état de chargement, l’état désactivé, et toutes les combinaisons de tout cela. Ça peut devenir très frustrant. Par exemple, si vous appuyez sur un bouton connecté à un service backend et qu’il n’y a aucun feedback visuel, vous ne savez pas si le bouton a bien été pressé. S’il n’y a pas non plus d’état de chargement, vous ne savez pas si quelque chose est en cours en arrière-plan, et vous finissez par appuyer plusieurs fois

  • L’auteur veut que, quelle que soit la vitesse, trois clics déclenchent toujours la même fonction. Il veut pouvoir faire défiler rapidement des photos et les faire pivoter chacune de manière prévisible, ce qui est légitime

    And it would be so much more predictable and pleasant if you could just tap the button three times at any pace you wanted without thinking, without paying attention, without getting your UI blocked by an animation that no longer helps you.

L’auteur invoque l’accessibilité
Cela dit, on peut aussi imaginer l’argument exactement inverse. Par exemple, une personne ayant un trouble moteur ou la maladie de Parkinson pourrait préférer un comportement où, une fois l’intention déjà confirmée, les clics excessifs sont ignorés
Concevoir correctement ce genre de chose est délicat

  • iOS propose une option d’accessibilité appelée Ignore Repeats, mais comme c’est un réglage global du système, cela semble être une meilleure approche. Les personnes qui ont besoin de ce type de correction peuvent aussi en bénéficier dans des endroits comme le clavier à l’écran, sans que tout le monde doive ralentir sa saisie

  • Je ne pense pas que chaque widget d’UI doive aller jusque-là
    Ça pourrait sans doute être géré par un réglage à l’échelle de l’appareil. Par exemple, ignorer des appuis répétés effectués en moins de 100 ms à moins de 50 px les uns des autres

  • Entièrement d’accord. Même sans aller jusqu’à la maladie de Parkinson, quand on voit des personnes pas extrêmement âgées mais déjà d’un certain âge utiliser un téléphone et un écran tactile, on constate souvent qu’il leur est difficile d’appuyer sur un petit bouton au bon endroit et d’avoir la sensation « j’ai bien appuyé »
    Donc, du point de vue de l’accessibilité, le comportement du Nothing Phone me semble bien mieux adapté. Ces utilisateurs ne cliquent pas 6 fois en comptant pour placer une image à un emplacement précis. Et en plus, cliquer 8 fois à l’avance pour revenir exactement à la position actuelle n’a pas beaucoup de sens
    Dans ce cas, le mode de pensée ressemble plutôt à : « cliquer, attendre, comparer avec la position voulue, puis cliquer à nouveau ». À l’inverse, un bouton sensible qui bufferise les entrées risque de provoquer des dépassements : on va trop loin, puis on revient trop en arrière. C’est similaire au fait de rater sans cesse l’endroit voulu en faisant défiler une liste
    L’approche de l’iPhone convient davantage aux jeunes ou aux passionnés de technologie qui veulent aller vite sans attendre. C’est comme avec un clavier d’ordinateur, où la latence permet de saisir plusieurs caractères avant même que le premier apparaisse à l’écran

  • J’ai déjà utilisé un appareil avec un bouton physique : quand on appuyait dessus, il faisait bip et ajoutait 30 secondes au temps. Mais parfois, il faisait bip sans ajouter 30 secondes, et d’autres fois, il ajoutait 30 secondes sans faire de bruit. Il fallait donc toujours plisser les yeux devant l’afficheur sombre pour vérifier si l’action avait bien eu lieu
    Je trouvais que c’était une conception particulièrement mauvaise, mais depuis, j’ai vu d’innombrables boutons purement logiciels reproduire exactement ce comportement cassé. Le changement de couleur du bouton à l’écran et l’exécution réelle de l’action demandée ne sont que vaguement liés. Pourquoi ? Comment est-ce seulement implémenté ?

    • On appelle ça le problème des deux actions
      On écrit du code impératif qui émet deux commandes, et chacune peut échouer indépendamment
      Il existe beaucoup de façons de faire semblant d’avoir « traité » le problème
      D’abord, tous les tests passeront, donc la plupart des développeurs peuvent arrêter d’y penser immédiatement
      On peut aussi se dire qu’il suffit d’attraper l’exception et de la logger, mais ça ne corrige rien
      On peut le faire tourner un moment en production pour voir si des problèmes apparaissent. Si un problème finit par survenir, le développeur réessaiera ; la deuxième fois, ça marchera probablement, et il pourra encore arrêter d’y penser
      Il y a quelques jours, il y a aussi eu une grande discussion sur le pattern outbox. L’idée est de découper la première action en deux moitiés traitées atomiquement, et de confier la seconde au lecteur
      À mon avis, si ce problème continue d’apparaître dans le monde réel, c’est parce que les développeurs sont dans un état de superposition quantique entre « ça n’arrive pas », « je l’ai corrigé » et « on ne peut pas le corriger »
    • C’est très courant à cause de deux caractéristiques de conception que partagent la plupart des frameworks d’UI :
      Le code qui change la couleur d’un bouton fait partie du comportement interne du composant « bouton », donc il n’a pas besoin d’être réimplémenté pour chaque bouton. Mais cela signifie aussi qu’il est en partie séparé du code qui exécute l’action réelle. Si le gestionnaire on click contient une vérification de dernier recours comme dans l’article original — « ne pas faire pivoter l’image si l’animation de rotation est en cours » — il n’existe souvent aucun moyen de dire au bouton d’annuler son changement de couleur. À l’inverse, le gestionnaire on click peut s’exécuter même si l’animation de changement de couleur ne s’est pas jouée correctement
      Un bouton change généralement de couleur quand on enfonce le bouton de la souris, mais l’action est exécutée quand on le relâche. Cette approche donne volontairement la possibilité de faire glisser le pointeur hors du bouton tout en maintenant l’appui pour annuler au dernier moment, et sur mobile, l’interaction peut être réinterprétée comme un défilement plutôt que comme un clic. Dans d’autres cas, cela augmente simplement les occasions où l’action est bloquée alors que la couleur a déjà changé
    • Je vois ça assez régulièrement dans les ascenseurs. Si on appuie très brièvement sur le bouton, la lumière s’allume pendant l’appui, mais en réalité l’entrée du bouton n’est pas enregistrée
    • Le changement de couleur d’un bouton montre que l’appui a réussi. Si ce retour n’est pas immédiat, la plupart des gens sont conditionnés à réessayer. C’est particulièrement important pour les personnes dont le contrôle moteur est faible
      C’est totalement indépendant du fait que cet appui soit une entrée utile dans l’état actuel du logiciel. Un logiciel bien écrit devrait savoir qu’il ne peut pas accepter l’entrée et aurait dû désactiver le bouton ; même un logiciel raisonnablement bien fait devrait fournir un retour presque immédiat indiquant que l’action est en cours de traitement ou a été annulée
    • C’est probablement dû au manque de tests et à l’hypothèse que les échecs d’action sont si rares qu’ils ne valent pas la peine d’être pris en compte. Mais ce genre de pattern rend l’interface difficile à utiliser avec confiance et efficacité
  • Les gens oublient souvent que l’animation n’est qu’un élément d’accompagnement, et qu’elle n’est pas une fin en soi
    Les animations existent pour masquer les temps de chargement et fluidifier le passage d’un état à un autre. C’est pour cela qu’on les utilise
    Ce savoir a fini par disparaître, et désormais on a du code qui doit attendre la fin d’une animation
    Encore un exemple étonnant de culte du cargo

    • J’aimerais développer l’explication « masquer les temps de chargement et fluidifier le passage d’un état à un autre ». Bien utilisées, les animations montrent qu’un changement d’état est directement provoqué par une action spécifique de l’utilisateur, et suggèrent aussi comment l’annuler ou le modifier
      En réalité, je ne suis pas d’accord avec le terme « masquer ». Sur un écran tactile, faire apparaître instantanément quelque chose sans indice sur la raison de son apparition est clairement un antipattern
    • Les animations ne servent pas uniquement à cela. Elles contribuent aussi de manière créative au ressenti quand on utilise une app
    • Apple le savait autrefois. La société ajoutait des animations après la disparition d’un élément, mais évitait les animations avant d’afficher un élément
      L’ancien Apple comprenait que le design ne se limitait pas à faire joli. L’Apple actuel façon verre ne se soucie que de l’apparence en démo
    • Les animations me semblent presque toujours inutiles. Je les désactive partout où une app ou un système le permet
    • J’ai désactivé toutes les animations sur Android et c’est bien plus agréable. Je déteste particulièrement cette animation d’overscroll où tout l’écran s’étire quand on essaie de faire défiler trop loin
  • En voyant la première comparaison, honnêtement, je pense que le problème vient de l’exemple de l’iPhone. Chaque fois qu’on appuie sur le bouton de rotation, le bouton et le curseur sous l’image disparaissent puis réapparaissent en fondu ; c’est un comportement que j’ai vu dans plusieurs apps iOS et qui m’agace sans fin. En particulier, l’app Captures d’écran est une grosse source de frustration pour moi
    Si un élément d’UX peut être manipulé avant et après une interaction, qu’il s’agisse d’une transformation ou d’un traitement, il devrait rester visible pendant toute la durée de l’opération. Quel gain UX y a-t-il à masquer ces boutons pendant la rotation sur iPhone ? Ça ne rend même pas mieux visuellement. Bien sûr, les logiciels Apple récents ont sacrifié les véritables améliorations UX sur l’autel de l’apparence
    Cela dit, je suis d’accord avec l’auteur sur le fait que ce genre de tap devrait être traité indépendamment de l’animation

    • Ce serait bien que les apps logicielles aient des règles de tape-out, comme les puces informatiques. Quand on conçoit une puce, un programme examine la conception et la compare à un règlement de 300 pages du genre « les pistes du métal X et du métal Y ne doivent pas être à moins de Z distance »
      On pourrait faire quelque chose de similaire pour l’UX : un ensemble de contraintes de design patterns qui déclencherait un avertissement si l’on essaie de sortir un produit avec des défauts UX bien connus
  • Ça me rappelle l’époque où j’avais implémenté BabyButton, conçu pour être utilisé par un bébé. Au lieu du clic classique, j’utilisais l’événement touchdown, ce qui permettait à l’enfant de voir immédiatement que quelque chose s’était produit, sans problème s’il maintenait le bouton trop longtemps ou bougeait le doigt en le gardant appuyé
    La question de savoir s’il faut créer des systèmes pour cette tranche d’âge est un tout autre sujet, mais j’ai trouvé que c’était un bon défi de conception pour répondre aux besoins de l’utilisateur

    • C’est intéressant de voir à quel point nous nous sommes habitués au fait que les boutons d’interface graphique ne s’exécutent qu’au relâchement du bouton de la souris, avec des comportements précis comme sortir de la zone du bouton puis y revenir en maintenant l’appui
      Dans le monde réel, plus de 99 % des boutons font leur travail dès qu’on les enfonce. Mais dans une GUI, un bouton qui se comporterait ainsi semblerait étrange
  • Le véritable article qui se rapproche le plus de ce que l’auteur veut dire est celui-ci : https://aresluna.org/show-your-hands-honor/

  • Pendant un appel, quand on appuie sur le bouton marche/arrêt de l’écran de l’iPhone, est-ce qu’il arrive que cela mette fin à l’appel, et d’autres fois que cela éteigne seulement l’écran ?
    Je n’ai toujours pas compris le schéma, mais il m’est arrivé plusieurs fois d’appuyer sur ce bouton avant de mettre l’iPhone dans ma poche et de raccrocher par erreur

    • En mode haut-parleur/mains libres, cela éteint seulement l’écran. Quand on le tient à l’oreille, l’écran s’éteint automatiquement, donc ils semblent supposer qu’on n’appuiera pas sur le bouton de verrouillage. Le problème, c’est que parfois l’écran reste allumé à cause d’un bug, ou qu’on l’utilise comme en mains libres dans une pièce silencieuse
 
GN⁺ 6 시간 전
Commentaires sur Lobste.rs
  • C’est une légère pique, mais si l’on parle de bonne UI/UX, une vidéo intégrée sans contrôles ni indication est ce qu’il y a de pire.
    Beaucoup de gens désactivent la lecture automatique par défaut, et je suis resté un bon moment devant deux images presque identiques en me demandant : « alors, qu’est-ce qui change ? »

    • Je me suis dit « il y avait une vidéo ? », donc je crois que je l’ai ratée aussi.
    • Je ne vois pas pourquoi ce serait « le pire ». Est-ce que tu as juste continué à te dire « et alors ? » sans descendre un peu pour lire l’explication du problème ?
    • Sur ce sujet, il faut reconnaître à GitHub le mérite d’afficher des contrôles de lecture sur les GIF animés. On ne voit presque jamais ça ailleurs.
    • Ça peut aussi dépendre du navigateur. Sur Vivaldi sous Android, je voyais un gros bouton de lecture et une barre de progression.
  • Je suis entièrement d’accord avec « ne faites jamais attendre l’utilisateur jusqu’à la fin d’une animation ».
    Dans une app, la commande de l’utilisateur doit toujours passer avant le fait que ce soit joli.

  • Je pense que ce principe s’applique aussi aux jeux. Dans certains jeux, il y a un très court délai entre l’ouverture d’un menu et le moment où les entrées sont enregistrées.
    C’est le genre de problème où, dans un jeu avec une animation de menu sophistiquée, si l’on appuie rapidement sur pause puis sur la flèche bas, le deuxième élément devrait-il être sélectionné une fois le menu affiché ?
    Dans les jeux, la mise en mémoire tampon des entrées est un sujet subtil, mais pour la navigation dans les menus, elle donne rarement une mauvaise impression.

  • La vidéo transmettait assez mal l’information. Il fallait la regarder attentivement pour remarquer le moment où le bouton était pressé plusieurs fois de suite.
    Sur le fond, il n’est même pas évident que le téléphone Android se comporte vraiment mal. Je comprends la frustration de vouloir appuyer rapidement 8 fois pour obtenir le résultat souhaité, mais cela me fait penser à la détection des doubles-clics accidentels dans les OS de bureau.
    Au final, cela ressemble surtout à un écart entre ce que le fabricant considère comme utilisable et ce que l’utilisateur ressent comme pratique. À choisir, je trouve presque plus distrayant que l’iPhone affiche le bouton « Done » même pendant l’animation.

  • Il est difficile de dire qu’Android a complètement tort. Il m’est déjà arrivé d’exécuter une action deux fois par erreur à cause d’une UI qui répondait lentement.
    La meilleure solution serait peut-être de désactiver le bouton jusqu’à la fin de l’animation.

    • Dans ce cas, on retombe exactement sur le problème montré dans l’article. Il devient presque impossible de faire une rotation de 90 degrés dans le sens antihoraire sans regarder l’écran.
      Le « triple clic » ne fonctionne pas, et les clics supplémentaires pendant l’animation sont ignorés. Cliquer, regarder l’écran en attendant la fin de l’animation, puis recliquer et attendre encore est lent et demande beaucoup d’attention à l’utilisateur.
      Une meilleure solution semble être de fournir un retour immédiat dans l’UI. On pourrait rendre immédiatement l’état du bouton indiquant que le clic a été pris en compte, ou redessiner temporairement l’écran très vite pour montrer la progression actuelle avant de lancer l’animation complète plus lente.
  • Je suis fortement d’accord avec tout l’article. J’ai envie de dire que c’est un cas où l’animation viole le serment d’Hippocrate.
    Le premier principe de l’animation devrait être « d’abord, ne pas nuire », autrement dit « d’abord, ne pas gêner les entrées de l’utilisateur ».

  • Avez-vous déjà eu affaire à un encodeur rotatif qui n’arrive pas à suivre ? Le bouton de volume de mon ampli casque ne fait rien si je le tourne trop vite.
    Si j’étais président pendant une journée…

  • Chaque fois que je vois ce genre de chose, je me demande comment mon propre toolkit GUI se comporterait. Mon toolkit traite deux clics rapides comme un double-clic, un comportement emprunté à la plateforme Windows, et cela rend parfois fou.
    Le double-clic en lui-même est une convention courante et il a une valeur distincte du clic. Idéalement, les événements de clic devraient être rendus idempotents afin que deux occurrences ne posent pas de problème. Par exemple, si un clic sélectionne un élément et qu’un double-clic exécute l’action par défaut, sélectionner deux fois le même élément n’a rien de nuisible. Mais dans la réalité, ce n’est pas toujours le cas.
    Le problème est que si l’on clique très vite sur un bouton, celui-ci peut ne s’exécuter qu’une seule fois, puis le reste part en événement de double-clic qui ne fait rien. On obtient donc un comportement où la moitié des clics rapides est ignorée.
    À cause de ce problème, j’ai créé un booléen appelé triggersOnMultiClick ; lorsqu’il est réglé sur true, il émet aussi des événements de déclenchement pour les clics multiples rapides comme les doubles-clics. Toutefois, pour des raisons de compatibilité ascendante, j’ai laissé la valeur par défaut à false. Comme il est temps de sortir une nouvelle version majeure, et que l’argument de l’article me semble valable, je compte maintenant faire passer la valeur par défaut à true.
    Je pourrais laisser une note du genre : « Ajouté le 2 juillet 2021, valeur par défaut false. Le 5 juillet 2026 (v13.0), la valeur par défaut a été changée en true afin que tous les clics sur les boutons déclenchent par défaut l’action. Pour retrouver l’ancien comportement, surchargez l’événement de double-clic ou définissez triggersOnMultiClick = false après l’appel au constructeur parent. »
    Un comportement similaire peut aussi apparaître par hasard côté implémentation des animations. Si l’objet contient une variable de position d’animation et que le clic en définit la valeur, il y a grosso modo deux options quand on clique deux fois. Soit sauter le reste de l’animation et passer directement à l’état interne suivant, soit ignorer l’événement pour préserver la fluidité visuelle, avec quelque chose comme if(animationCounter) return;. Le développeur Android évoqué dans l’article semble avoir choisi la seconde option.
    Côté Apple, ils utilisent probablement une troisième approche : une file d’attente des animations en attente, dans laquelle les événements sont placés. Ce qui m’intrigue, c’est de savoir si l’état interne change au moment de la mise en file, au moment de l’achèvement, ou si l’image est réellement tournée par animation. Si l’on interrompt l’animation en plein milieu et que l’on enregistre, peut-on obtenir une image tournée de 45 degrés ? Si c’était moi, je mettrais à jour l’EXIF de façon atomique par pas de 90 degrés, et je ferais tourner l’animation de transition séparément.
    Il peut y avoir plusieurs choix raisonnables entre simplicité d’implémentation, fidélité visuelle et comportement de l’UI. Personnellement, j’aime aussi l’approche où le deuxième appui ne attend pas l’animation et fait immédiatement passer au nouvel état. Je ne pense pas que j’irais jusqu’à créer une file d’attente d’animations.
    C’est amusant de modifier le code à peu près à la même période. La dernière modification était aussi un 2 juillet, et celle-ci tombe par hasard le 5 juillet. J’aime consigner ce genre d’historique directement dans les commentaires de documentation. C’est agréable à relire plus tard, comme un petit souvenir, quand on revient changer quelque chose.
    Apple fournit probablement une file d’attente d’animations par défaut, mais le moment où l’état change reste un problème distinct. Sur le Web, je mettrais sans doute l’état à jour de façon atomique, avec une animation purement visuelle séparée, comme une transition CSS transform. Cela éviterait aussi les recalculs de layout, donc ce serait probablement simple et efficace à implémenter. J’aimerais tester un jour si le fait de changer les noms de classe plus vite que l’animation provoque un saut ou une mise en file d’attente.

  • C’est peut-être l’âge, mais il m’est déjà arrivé plusieurs fois d’être agacé par ce genre de comportement après avoir tapé deux fois par erreur.
    Utiliser un bouton au même endroit, ou un double-tap, comme mécanisme de confirmation est horrible. Si une confirmation est vraiment nécessaire, il ne faut pas la rendre facile à valider par accident.
    Cela dit, dans cet exemple, accepter les entrées rapides successives me semble être une bonne idée. Dans d’autres cas, ce ne sera pas forcément vrai. Certains boutons physiques empêchent intentionnellement d’appuyer deux fois jusqu’à ce que quelque chose soit « terminé » ; ce n’est pas toujours une conception consciente, mais c’est parfois le bon choix.
    Beaucoup de gens doivent utiliser des appareils lents ou défectueux, et en cas de problèmes de santé comme des tremblements de la main ou des doigts, limiter les entrées peut avoir des avantages.
    Cet exemple me semble être un cas où les deux points de vue peuvent se défendre. Il y a des situations où devoir attendre est encore plus frustrant, et il y en a clairement d’autres où l’on aimerait qu’il y ait une limitation des entrées, que ce soit à cause d’une animation ou d’une autre condition.

  • Les résultats de recherche dans les navigateurs mobiles qui se mettent à jour sous mon doigt et déplacent ailleurs l’option que j’allais toucher sont une source d’agacement vraiment incessante.
    J’ai fini par m’entraîner à attendre davantage, mais il est absurde qu’une interaction UI doive être sensible à des tâches asynchrones en arrière-plan dont le temps d’achèvement varie selon la qualité de la réception.