Forum Programmation.web HTML5 Canvas : défilement/zoom dans une zone de saisie.

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
1
9
juil.
2014

EDIT : une demo de ce que j'ai fait (voir commentaires plus bas pour explications)

Bonjour.

Toujours sur un de mes projets, j'ai pas mal avancé sur une partie de l'IHM, mais je bloque sur un point de "détail".

Petite explication : je suis en train de développer une interface permettant de créer un TCO pour modélisme ferroviaire à l'aide de canvas HTML5. J'ai organisé la "surface" de saisie en "tuiles" carrées, dans lesquelles je trace les divers éléments de voie (aiguillages, courbes, etc) …. Ma zone de saisie est composé de 3 canvas superposés :

  • sur le premier canvas (au fond), j'ai tracé ma grille de "tuiles". Pour tracer ma grille je trace mes rectangles 1 à 1 à l'aide de la fonction drawrect.

  • sur le second canvas, je dessine les éléments de voie (aiguillages, rails, etc …) qui sont "posés" sur le plan. Ces éléments son dessinés à l'aide de la fonction line (et/ou path, je ne me rappelle plus exacteent, mais peu importe).

  • sur le canvas du dessus, je dessine les éléments de voie qui ne sont pas "posés", et qui suivent le pointeur de souris pendant le positionnement de l'élément de voie. J'utilise les mêmes fonctions de traçage que sur le second canvas, et j'efface/retrace en fonction de la position de la souris. La superposition des canvas me permet de mieux gérer le déplacement au suivi de la souris, ou la suppression d'un élément de voie qui serait déjà posé sans avoir à redessiner tout ce qui existe en dessous.

A chaque fois que je "pose" un élément sur la voie, je remplis un tableau (pas encore sauvegardé de manière persistente), contenant le type d'élément et les coordonnées de la "tuile" sur laquelle il est positionné. Ceci dans le but de pouvoir retracer mes elements lors de zoom ou défilement de la zone de saisie.

Pour l'instant, j'ai tracé une zone de saisie qui tient complètement sur le canvas. Je peux agrandir ou réduire la taille des tuiles (et donc la densité de celles-ci sur ma zone de saisie) assez facilement en modifiant une constante (par contre il me faut relire ma page donc perdre mes modifs pour le moment).
Je suis capable d'effacer et de retracer à la demande la grille ainsi que les éléments déjà positionnés.

Par contre je souhaiterais pouvoir scroller et zoomer pendant la saisie dans le cas ou le schema de mon TCO viendrait à dépasser la taille de mon canvas, un peu comme le font les outils de saisie de schéma tel que Dia ou Inkscape : mais je ne sais pas par quel bout prendre le problème. L'idée serait de :

  • pouvoir déplacer la zone de saisie sur la droite ou vers le bas lorsque j'arrive vers les extrémités du canvas
  • pouvoir zoomer/dézoomer (et scroller si besoin). Je voudrais pouvoir gérer le déplacement de la zone de saisie à l'aide de barres de défilementà droite et en bas du canvas.

J'hésite entre deux méthodes pour réaliser ça :

  • utiliser les outils de l'API canvas pour zoomer. Ca me demanderait d'effacer le contenu des canvas (je sais faire), modifier les coordonnées de mon repère (avoir une origine aux coordonnées (-20,-20) par exemple, et éventuellement jouer sur le zoom) puis retracer la grille de tuile ainsi queles elements de voie. Ceci nécessiterait bien sur de prendre en compte ce zoom et le décalage de l'origine du repère pour la détection de la position des éléments de voie que je tracerai.

  • ne pas utiliser les API du canvas, effacer le contenu de mes canvas, et redessiner en appliquant un décalage et/ou un coefficient d'agrandissement ou de réduction sur les dimensions de mes tuiles. Il me faudra également gérer un décalage de repère et prendre en compte un facteur multiplicateur pour le zoom.
    Quelle est à votre avis la méthode la plus judicieuse à utiliser, vous qui connaissez un peu mieux que moi le développement HTML ? Personnellement je suis plutôt porté vers la 2eme méthode. Il y a plus de choses à faire à la main, mais je pense qu'on garde un meilleur contrôle. En effet, j'ai l'impression que les effets de changement d'échelle/zoom/translation en html5 ne sont pas fait pour ce que je veux faire, mais plutôt pour permettre de dessiner plus facilement certains motifs en déplaçant l'origine et l'orientation du repère. Si je dois faire ainsi, je sais comment faire pour gérer le zoom mais je sèche pour le défilement.

Auriez-vous une idée ?

Note : je comptais mettre en place un petit serveur www pour que vous puissiez voir une démo et mieux comprendre ce que je décris mais je n'ai pas de serveur www sous la main. Peut-être demain ?

  • # Infos sur la démo

    Posté par  . Évalué à 2. Dernière modification le 10 juillet 2014 à 01:33.

    Bonsoir.

    J'ai mis en ligne une petite démo.

    Le code n'est pas forcément des plus propres, et l'organisation de celui-ci est un peu fouillis, mais il ne s'agit pour le moment que d'un POC pour moi pouvoir explorer les diverses solutions qui s'offrent à moi.

    Pour le moment, les controles (zoom, rotation des elements de voie) se font au clavier.

    Pour ajouter un elt de voie, il suffit de cliquer dessus et de positionner la souris sur le canvas.

    Vous pouvez le déplacer, et le faire tourner via les touches r et e. Vous le positionnez à l'endroit voulu en cliquant sur le canvas.

    Pour supprimer un element : bouton delete de la page puis se positionner à l'endroit ou vous voulez supprimer + clic

    J'ai avancé un peu sur le zoom : z pour zoomer, a pour dézoomer.

    A noter qu'il ya encore un petit bug avec le zoom : il semble que tous les elements tracés ne soient pas redessinés. JE ne sais pas encore pourquoi.

    J'ai utilisé la méthode qui ne fait pas appel aux fonctions de zoom du canvas. Je la ferai plus tard pour comparer.

    Je cherche maintenant à traiter la translation. Une fois que ce sera fait, je la combinerai avec le zoom/dezoom. pour positionner le centre de zoom au niveau du curseur de la souris.

    Il n'y a toujours pas de persistence de données. Ca viendra plus tard (et je vous demanderai peut-être de tester).

    Il y a encore beaucoup de travail, mais j'avance petit à petit.

    Testé avec Chromium et avec Firefox sous Xubuntu.*

    Si vous avez des remarques, je suis preneur.

    • [^] # Re: Infos sur la démo

      Posté par  . Évalué à 2.

      Bon, finalement j'ai réussi à gérer un zoom et un défilement sans trop de problème, sans utiliser les fonctions de zoom de l'API Canvas.

      J'ai mis la démo en ligne à jour. Il me faut maintenant tenter d'associer une barre de défilement à tout ça, et essayer de zoomer à l'aide de la molette de souris.Ce n'est pas vraiment le plus difficile à mon avis. Après ça je continuerai de m'occuper de la persistence en BDD.

      Ensuite je recommencerai … je ferai un truc plus joli, mieux étudié, avec une GUI un peu mieux pensée.

      • [^] # Re: Infos sur la démo

        Posté par  . Évalué à 3.

        sans utiliser les fonctions de zoom de l'API Canvas.

        c'est quand meme dommage de reinventer la roue quand les outils existent deja, non ?

        sinon, beau travail avec cependant 2 soucis (sous safari, j'ai que ca sous la main pour l'instant)
        - le texte à gauche est coupé par la grille "Effacement con" "Redessiner apre"
        - quand je zoome/dezoome ca efface tout et ne garde d'un seul rail

        • [^] # Re: Infos sur la démo

          Posté par  . Évalué à 2.

          c'est quand meme dommage de reinventer la roue quand les outils existent deja, non ?

          Pas forcément, je vais implémenter la seconde solution dans mon POC et voir quel est le plus intéressant. C'est aussi une façon pour moi d'apprendre ;).

          sinon, beau travail

          Merci c'est encourageant. J'ai appris beaucoup de choses :).

          le texte à gauche est coupé par la grille "Effacement con" "Redessiner apre"

          Un peu normal, j'ai ajouté ça à la rache sans modifier la taille de caractère. Je corrigerai à l'occasion.

          quand je zoome/dezoome ca efface tout et ne garde d'un seul rail

          En tout cas chez moi avec Chromium et Firefox ça passe bien. Mais je revérifierai quand même.

Suivre le flux des commentaires

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