web-dev-qa-db-fra.com

Travailler avec Canvas et AngularJS

Je prends la tâche de réécrire l'application flash suivante en HTML5:

http://www.docircuits.com/circuit-editor

Compte tenu de la complexité de l'application et de ma R&D jusqu'à présent, j'ai identifié AngularJS comme le framework MVC préféré pour la mise en œuvre. L'application comporte différentes parties telles que des panneaux, des menus, des propriétés, des graphiques, etc., qui, je crois, peuvent être facilement implémentés dans AngularJS.

Le problème clé, cependant, est que la conception et l'interaction des composants (des choses comme le glisser/déposer, le déplacement, la gestion des fils, etc.) doivent être basées sur Canvas, car j'ai pu exporter toutes les images vectorielles de Flash à l'aide de la boîte à outils CreateJS ( http://www.Adobe.com/in/products/flash/flash-to-html5.html ) dans une bibliothèque Canvas et non vers un SVG.

Le problème est qu'il n'y a aucun moyen clair de communiquer entre les "objets individuels à l'intérieur d'un canevas" et AngularJS. J'ai examiné les exemples suivants, mais presque tous fonctionnent sur l'objet Canvas, et non sur la gestion des composants individuels à l'intérieur de Canvas:

Liaison AngularJS à WebGL/Canvas

Existe-t-il déjà une directive de dessin sur toile pour AngularJS?

Je suis un peu coincé ici et je ne sais pas quoi faire. J'apprécierais vraiment quelques commentaires sur:

  • Si AngularJS est le bon choix?

  • Dois-je essayer d'implémenter la partie Canvas dans une autre bibliothèque (telle que Fabric.js, kinect.js, Easel.js) et l'intégrer avec Angular (qui semble encore une tâche trop lourde pour l'instant) ?

  • Si rien de ce qui précède, dans quel autre cadre dois-je basculer pour gérer facilement le canevas ainsi que d'autres fonctionnalités telles que les panneaux, les menus, les graphiques, etc.?

38
Kapil Kaushik

Nous avons finalement réussi à travailler ensemble avec AngularJS et HTML5 Canvas. Ci-dessous, je partagerai brièvement nos exigences et l'approche que nous avons suivie pour y parvenir.

L'exigence était un peu délicate car nous voulions:

  1. Gérer les poignées d'événements sur des éléments individuels à l'intérieur du canevas et pouvoir ajouter ces éléments dynamiquement en fonction des données dans AngularJS

  2. Conservez les données pour chaque élément individuel dans AngularJS tout en utilisant Canvas pour afficher uniquement les données.

  3. Utilisez l'héritage du contrôleur pour un traitement spécial des données dans certains cas (par exemple, toutes les instances doivent être mobiles et déplaçables, mais certaines instances peuvent avoir besoin de clignoter ou d'afficher des bandes de couleurs, etc.)

Pour gérer les opérations sur Canvas, nous l'avons divisé en deux parties:

  1. Service de toile

    Il fait le travail de

    • initialisation du canevas

    • ajouter ou supprimer un élément du canevas

    • rafraîchir la toile

  2. Directive d'instance et contrôleur

    • le contrôleur angular conserve la poignée de "l'élément canvas" correspondant, ainsi que toutes les données qui lui sont associées.

    • les écouteurs d'événements de chaque élément déclenchent des fonctions spécifiques dans le contrôleur angular qui manipule les données d'instance

    • la directive surveille les données d'instance dans le contrôleur et met à jour le canevas en conséquence à l'aide du service de canevas

Pour l'héritage du contrôleur, nous avons trouvé l'approche suivante assez utile: https://github.com/exratione/angularjs-controller-inheritance

Cela nous a aidés à créer des contrôleurs de manière dynamique et à l'aide de la directive d'instance, nous avons également pu gérer des mises à jour individuelles sur le canevas ainsi que la gestion générique des événements.

Je comprends que cette approche n'est peut-être pas complètement orientée AngularJS, mais elle a bien fonctionné pour nous, et nous avons pu gérer une quantité raisonnable d'interaction entre AngularJS et HTML5 Canvas.

42
Kapil Kaushik

Bien sûr, vous pouvez le faire avec Angular très bien. Cependant, selon la complexité de votre application et le type de synchronisation de données dont vous avez besoin, je recommanderais d'utiliser des prototypes JS pour gérer cela. La "méthode angulaire" "serait d'utiliser des directives à la place.

Créez un contexte de dessin global, puis divisez les différents composants en objets JS. Gérez la configuration, la logique, la mise à jour, etc. au sein de chaque objet (un peu comme une classe), puis dessinez dans le contexte global. Vous devriez avoir un _ draw loop qui est essentiellement une fonction setTimeOut qui met à jour les états des objets de jeu et redessine tout.

Une approche alternative consiste à combiner Angular et prototypes JS. Ceci est un excellent exemple: https://github.com/IgorMinar/Memory-Game

EDIT: un autre exemple de construction de jeux avec angular http://alicialiu.net/leveling-up-angular-talk/examples/directive.html

8
winkerVSbecks