Journal De la difficulté à obtenir un rendu SVG, voire HTML, cohérent entre les différentes plates‐formes

53
20
oct.
2016

Citoyennes et citoyens bonsoir,

Je vous écris en ce 29 Vendémiaire de l’an 225 de la République pour vous faire part de ma frustration quant au rendu des navigateurs modernes, en particulier au niveau de l’anticrénelage.

Je vous prie d’avance de m’excuser pour les éventuelles fautes d’inattention que je ferai lors de la rédaction de ce journal ; au moment où je l’écris, il est déjà 8,75 heures décimales passées.

Voici mon problème : j’ai dernièrement été occupé à réaliser une bibliothèque JavaScript qui devait me permettre de dessiner et animer des horloges dans un navigateur, en SVG. Dans mon cas, une horloge peut se résumer à quelques lignes droites pour les aiguilles, auxquelles on imprime une rotation, ainsi que des chiffres et des traits distribués eux aussi par rotation autour du point central du cadran.

Le standard SVG permet facilement de spécifier un transform="rotate(90)" à tout élément et, dans le même temps, le standard CSS 3 comporte lui aussi une propriété transform: rotate(90deg); assez bien prise en charge aujourd’hui, ce qui multiplie les possibilités… pas toujours de manière très heureuse, comme nous le verrons tout à l’heure.

Étant plus versé dans le CSS que le SVG, je me suis d’abord naturellement tourné vers la méthode fournie par ce standard pour orienter mes aiguilles et placer mes chiffres. Testant mon code principalement avec Chromium, tout semblait aller pour le mieux.

Étape suivante, afin d’ajouter un peu de profondeur aux horloges, j’essaie d’ajouter un peu d’ombre portée aux aiguilles. Et, là, stupeur ! Celles‐ci disparaissent purement et simplement dans Chromium. Je lance Firefox, le navigateur de Mozilla donne un résultat correspondant à mes attentes en cela que les aiguilles paraissent bien, mais celui‐ci ne supportant pas la propriété transform-origin, les rotations ne se font pas, comme prévu, par rapport au centre de mes cadrans.

CSS-rotate

Qu’à cela ne tienne, après un peu de recherche je remplaçai mes instructions CSS par des attributs sur les éléments SVG. Simultanément, les aiguilles se voient correctement positionnées dans Firefox et réapparaissent dans Chromium ! Après plusieurs essais, il semblerait que Webkit et Blink rendent invisibles les éléments SVG soumis à la fois à un transform et à un filter en CSS.

Fier de mon résultat, je partage mon travail sur la tribune et les remarques arrivent sans tarder, captures d’écran à l’appui :
aliasing

L’anticrénelage est périodiquement désactivé ! Diverses solutions fonctionnent sur certains navigateurs, d’autres désactivent totalement l’anticrénelage :
aliasing

Ou le désactivent périodiquement, de manière moins gênante :
aliasing

Les navigateurs différents sur une même plate‐forme ne donnent pas toujours le même résultat. Ici, Safari et Firefox sur Mac OS X :
aliasing

Ou rendent tout flou :
flou

Et les mêmes navigateurs sur différentes plates‐formes donnent des résultats différents !

Et pas seulement sur le rendu SVG. Là où new Date("1985-08-18 12:13:14") donne un objet Date en heure locale sous GNU/Linux et Mac OS X, cet appel ne renvoie qu’une « date invalide » sous Windows. Le format à utiliser étant 1985-08-18T12:13:14.

Aujourd’hui encore, le problème d’anticrénelage aléatoire n’est toujours pas réglé : la seule solution que j’avais trouvée était d’appliquer une ombre très légère, quasi invisible, sur les aiguilles, mais cela a le fâcheux effet de les faire disparaître sur Safari sous Mac OS X.

J’ai donc désactivé cette mesure, ce qui fait que vous pourriez rencontrer les mêmes problèmes en visitant la page suivante d’exemple pour le projet en question :
ssz.fr/borda

Si c’est le cas, je vous serai reconnaissant de m’en parler dans les commentaires, voire de suggérer des solutions !

J’écrirai probablement prochainement un nouveau journal au sujet de ce projet et de la formidable heure décimale. En attendant, vous pouvez retrouver les sources sur mon GitHub.

  • # Crédits

    Posté par (page perso) . Évalué à 9.

    Je tiens à remercier NedFlanders< chrisix< et cbo< sans qui le débuggage de ce projet aurait été bien plus difficile, et à qui l'on doit les captures d'écran présentes dans ce journal !

  • # jeux de tests

    Posté par (page perso) . Évalué à 10.

    Ce qui a vraiment permis de faire un vrai bon en terme d'homogénéité du support des normes entre les différents navigateurs a été la mise en place de jeu de tests exhaustifs, fiables et publics pour comparer les différents moteurs. Je pense surtout à l'initiative ACID2 et 3 par exemple…
    A ma connaissance, il n'existe pas encore de jeu de test potable pour le support de SVG. C'est probablement pour ça que ça coince encore pas mal à ce niveau.
    D'ailleurs, en cherchant un peu, je suis tombé sur des infos concernant ACID4 qui devrait mettre l'accent sur CSS3 et SVG justement. Le travail est en cours.

    • [^] # Re: jeux de tests

      Posté par . Évalué à 4.

      Les standards avancent uniquement avec des suites de testes exhaustif. L'auteur peux essayer d'en faire un :) (image attendu à coté du svg rendu par le navigateur)

      "La première sécurité est la liberté"

  • # Mon retour

    Posté par . Évalué à 8.

    Je suis sous Debian Stretch, Firefox 45.1.1, Gnome, driver Intel.

    Dans ta page d'exemple, je n'observe pas de soucis d'antialasing, c'est même plutôt joli. Par contre j'ai un petit bug : sur l'horloge de Montréal, j'ai le chiffre 10 qui se balade : à l'instant où la trotteuse bouge il se décale légèrement sur la gauche pendant la moitié de la seconde, et revient en position pendant l'autre moitié de la seconde. Ca le fait quelle que soit la position de la trotteuse.

    T'as une capture ici : https://framadrop.org/r/K3FXwl-QGC#eRcLKwh7lOoQtVg5zmbKsjczfEZLEMBbX5UNRJR9mno=

    • [^] # Re: Mon retour

      Posté par . Évalué à 3.

      Idem ici (Windows 7, Firefox 49.0.1), le chiffre 10 de l'horloge de Montréal mais aussi I, II, VI, VII, VIII et IX de l'horloge en chiffres romains.

    • [^] # Re: Mon retour

      Posté par . Évalué à 4. Dernière modification le 21/10/16 à 09:32.

      Idem sur Firefox 49 - Linux Mint 17.3.
      Mais uniquement le 10 de Montréal.

      • [^] # Re: Mon retour

        Posté par (page perso) . Évalué à 5.

        Merci, oui j'avais remarqué ça aussi une fois mais ça m'était sorti de l'esprit.

        Pour info, je viens de passer des transform="rotate()" à de vrais calculs pour placer les aiguilles sans rotation. Ça pourrait changer des trucs et aider pour l'affichage, peut-être.

        • [^] # Re: Mon retour

          Posté par . Évalué à 3.

          Effectivement, plus de bug chez moi !

        • [^] # Re: Mon retour

          Posté par (page perso) . Évalué à 5.

          Pour info, je viens de passer des transform="rotate()" à de vrais calculs pour placer les aiguilles sans rotation

          Ca expliquerait pourquoi maintenant l'aiguille des secondes est parfaitement positionnée sur les traits ? (après animation bien sûr). Ce matin, y'avait un léger décalage, pas gênant, mais tout de même notable.

          • [^] # Re: Mon retour

            Posté par (page perso) . Évalué à 3.

            Non, c'était un autre problème mais je l'ai réglé par la même occasion :) (une vérification mal faite pour le déplacement en douceur des aiguilles).

  • # De la difficulté à obtenir un rendu [...] HTML, cohérent entre les différentes plateformes

    Posté par . Évalué à -10.

    ok c'est bon pour moi : rien de nouveau sous le soleil depuis qu'internet et les arpenteurs existent…

    Cette industrie ne parvient toujours pas à produire…de l'industriel…

    • [^] # Re: De la difficulté à obtenir un rendu [...] HTML, cohérent entre les différentes plateformes

      Posté par . Évalué à 10.

      Parce que c'est bien connu, les autres industries sont tout à fait capables de se mettre d'accord sur des standards, de les implémenter, et de les respecter.

      Quand tu changes des essuie-glaces, par exemple, tu choisis la taille… et tu te démerdes parce que les petits bitonios en plastique pour la fixation sont tous différents.

      Quand tu achètes une cafetière à dosettes, bien entendu, elles utilisent toutes les mêmes dosettes et donnent toutes le même café.

      Quand ton pot de peinture est terminé, bien entendu, tu peux acheter un pot d'une autre marque qui porte le même nom de couleur et tu auras exactement la même nuance.

      La plupart du temps, il faut juste apprendre à vivre dans un monde imparfait. Il existe des normes, parfois les fabricants s'en foutent, parfois ils essayent de les implémenter, mais à moins d'avoir une très bonne raison pour le faire, il y a toujours des choses qui déconnent. Même quand le standard existe est est appliqué (par exemple les ampoules électriques), tu as la certitude que ton ampoule va rentrer dans le culot, mais parfois ça coince parce que le bulbe est trop gros, trop effilé, trop long ; et qu'à puissance égale tu peux avoir de grosses différences de température de couleur, ce qui fait que si tu veux un truc cohérent, il faut changer toutes tes ampoules en même temps.

      S'il existait un organisme de vérification de conformité des navigateurs internet qui t'empêchait physiquement d'éditer un navigateur internet dans le monde entier tant qu'il ne passe pas un certain nombre de tests très stricts sur le respect des standards, alors peut-être qu'on aurait un peu plus de cohérence. Mais personne ne voudrait d'un truc aussi lourd et contraignant, c'est comme ça.

      • [^] # Re: De la difficulté à obtenir un rendu [...] HTML, cohérent entre les différentes plateformes

        Posté par (page perso) . Évalué à 10.

        D'autant qu'il y a un soucis de taille.
        Pour avoir lu des normes industrielles, très souvent tu as des points volontairement non définis pour simplifier la mise en œuvre. Tu retrouves cela dans plein de langage comme le C ou C++ par exemple pour simplifier la réalisation des compilateurs. Et parfois des codeurs vont s'appuyer sur des comportements indéfinis qui marchent chez X mais pas chez Y qui gère la même situation autrement.

        Sans compter que quand tu as des normes qui font des milliers de pages (ce que doit représenter le porte feuille du W3C), tu as des erreurs de formulations qui introduisent des interprétations différentes de la même fonction. Et à part en comparant le résultat entre différentes implémentations, tu ne le sais pas que cela était un soucis car ça paraissait souvent évident à tous comment ça doit être fait (mais chaque évidence est différente de l'autre).
        Et je passe sur les erreurs possibles des normes en eux mêmes, ou des erreurs d'implémentations qui peuvent arriver.

        Et cela est valable quelque soit l'industrie, pour peu que le sujet ne soit pas trivial. En tout cas je n'ai pas trouvé le monde parfait où ces éléments ne sont jamais intervenus.

  • # Côté MS...

    Posté par . Évalué à 6.

    Sous Windows 10, aucun problème avec Firefox, Chrome et Edge. C'est anti-aliasé et tout semble bien affiché. L'anti-aliasing fait un effet bizarre sur la "smooth seconds hand" quand elle passe la verticale et l'horizontale, mais c'est pareil sur tous les navigateurs.

    Avec IE 11, aucune horloge ne s'affiche. La console affiche des warnings pour des balises qui ne peuvent pas se fermer automatiquement (ligne 114, 115, 116, 117 et 119), et une erreur ligne 178 de borda.js : Impossible d’obtenir la propriété « add » d’une référence null ou non définie.

    • [^] # Re: Côté MS...

      Posté par (page perso) . Évalué à 3.

      OK, IE11 est tout pourri et il y a pas mal de trucs qu'il gère mal, mais en bidouillant un peu, ça a l'air de passer maintenant !

      Merci pour le débuggage :)

      • [^] # Re: Côté MS...

        Posté par (page perso) . Évalué à 4.

        Je suis curieux de savoir ce que tu as bidouillé.

        Est ce que tu as été obligé de modifier le code lu utilisé par les autres navigateurs?

        Avec les CSS, on pouvait utiliser les css conditionnelles, mais avec le SVG?

        • [^] # Re: Côté MS...

          Posté par (page perso) . Évalué à 5.

          Le problème était lié au non support de classList par IE11 pour les éléments SVG (une interface qui permet d'ajouter ou enlever facilement des classes aux éléments) et au non-support en même temps de la modification l'attribut className pour ces éléments. Dans les faits, il n'y a pas de moyen de modifier leurs classes et que ce soit pris en compte, en JavaScript.

          Ma solution (suggérée sur Internet) a été d'utiliser la fonction classList des éléments DOM pour les éléments SVG, uniquement si elle n'est pas déjà définie pour les éléments SVG. C'est du bidouillage, mais visiblement ça marche, donc ça me suffit. Le code n'est pas conditionnel au navigateur, seulement à l'existence de la fonction dont j'ai besoin, et le SVG lui-même n'a pas eu à être modifié.

  • # Aa?

    Posté par (page perso) . Évalué à -2. Dernière modification le 21/10/16 à 12:18.

    Nan mais tu comprends pas, l'aliasing, c'est bien :p Tous ces pauvres alias pixellisés sans pitié ; rejoignez l'ALCAA, l'association de lutte contre l'antialiasing!

    • [^] # Re: Aa?

      Posté par (page perso) . Évalué à -2.

      Wow, pour un vendredi, vous êtes nerveuses, les moules. Vous devriez écouter un peu de musique :)

  • # ah ça me rappel un truc

    Posté par . Évalué à 8.

    J'avais trouvé(1) une belle horloge en CSS, ensuite je voulais l'animer en JS (en un chouille de PHP) puis synchroniser les secondes sur les 4 horloges.

    Défilement fluide :
    http://bunam.perso.neuf.fr/clocks/demo.html

    Défilement pas à pas :
    http://bunam.perso.neuf.fr/clocks/index.html

    J'avais remarqué un problème d'antialiasing sur Firefox (et pas sur Safari ni Chrome)

    (1) Copyright 2013 Nikolai Rassadin rassadin@gmail.com Content is licensed under CC BY-NC-SA 3.0

  • # Juste un détail...

    Posté par . Évalué à 3.

    Sur les montres, le 4 est écrit en chiffres romains avec 4 batons : IIII

    Voir :
    https://www.google.fr/search?q=montre+chiffre+romain&espv=2&biw=1680&bih=935&source=lnms&tbm=isch&sa=X&ved=0ahUKEwi_oLusqJbQAhWMExoKHaGTA6MQ_AUIBigB

    C'est une "exception" spécifique aux cadrans pour éviter les confusions entre IV et VI

    Axel

    • [^] # Re: Juste un détail...

      Posté par (page perso) . Évalué à 3. Dernière modification le 07/11/16 à 13:38.

      "IV vs VI" est donc considéré comme plus problématique à différencier que "IX vs XI" ? (pourtant la page Chiffres romains de Wikipédia évoque la graphie VIIII parfois utilisée par les Romains eux-mêmes)

      En fait la raison semble donner sur la même page : « Pour une considération esthétique : dans ce cas, les quatre premiers chiffres ne sont composés que de I (I, II, III et IIII), les quatre suivants sont composés de V (V, VI, VII, VIII) et les quatre derniers de X (IX, X, XI, XII). »

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.