Pixi.js: Donner une option pour définir des limites fixes sur un conteneur

Créé le 23 sept. 2016  ·  15Commentaires  ·  Source: pixijs/pixi.js

Je rencontre un problème où je dessine quelque chose à l'intérieur d'un conteneur et les limites de ce conteneur sont immédiatement recalculées. Bien que cet exemple particulier soit bien sûr plutôt artificiel - en réalité, je ne dessinerais quelque chose comme ça qu'une seule fois, je peux voir beaucoup de problèmes potentiels provenant de ce comportement l'utilisateur peut glisser depuis le côté, ce qui détruirait complètement la logique de capture que j'ai là en ce moment).

💾 v4.x (Legacy) 🤔 Question

Commentaire le plus utile

Hey @megakoresh , je pense que je sais ce qui cause la confusion ici. Étant donné que l'objectif principal de pixi est de rendre des objets 2D, presque toute l'API est orientée vers cette fin. Les limites peuvent être particulièrement déroutantes.

Dans pixi, les limites d'un Sprite sont définies par la texture. Autrement dit, la taille du résultat final de l'objet rendu. De même, puisqu'un conteneur n'est _pas dessiné_, et donc ses limites sont définies par les enfants qu'il contient. En particulier, par les limites de ces enfants. Pour un objet Graphics, les limites sont définies par la géométrie que vous y dessinez. Si vous dessinez un autre rectangle dans un objet Graphics en dehors des limites actuelles, les limites se développent pour inclure la géométrie nouvellement dessinée.

J'espère que cela a du sens et vous donne un aperçu rapide de la structure des limites dans Pixi.

Maintenant, spécifiquement pour votre exemple, je pense que votre problème vient du malentendu sur le fonctionnement des limites pour un objet Graphics. Je pense qu'il vous manque le fait que dessiner votre grille change les limites de l'objet Graphics ( desktop1 ) qui contient le rect vert ( wonderfulRectangle ).

Vous pouvez voir qu'après le premier dessin, votre grille dépasse la taille de la fenêtre:

image

Cela étend les limites de l'objet Graphics parent ( desktop1 ) pour inclure la géométrie hors fenêtre. Cela rend votre largeur plus grande, ce qui annule votre prochain calcul de la grille, et le cycle se poursuit. N'oubliez pas que les lignes ont de l'épaisseur et donc de la largeur.

Il y a plusieurs façons de résoudre ce problème, celle qui me vient à l'esprit est que puisque votre grille remplit toute la taille de la fenêtre, utilisez simplement la taille de la fenêtre plutôt que la taille de votre parent. Cela signifie que si / lorsque vous dessinez plus de géométrie en dehors de la fenêtre, vos calculs de grille ne changent jamais. Parce que la fenêtre de rendu ne change pas de taille.

Si ce n'est pas une option, par exemple, votre zone de grille n'a pas la taille de la fenêtre. Vous pouvez simplement faire les calculs basés sur une «taille connue» de la zone de grille. Je pense que c'est ce qu'Ivan essayait de dire à propos de l'utilisation d'une instance statique Rectangle . Fondamentalement, décidez que votre grille est de 800x600 et effectuez des calculs basés sur cela plutôt que sur les limites réelles des objets de la scène.

J'ai mis à jour le codepen pour utiliser la méthode viewport que j'ai décrite. Dis moi si tu as d'autres questions!

http://codepen.io/anon/pen/yarVwm?editors=0010

Tous les 15 commentaires

Le conteneur n'a pas de zone et de limites fixes, c'est juste une collection d'enfants, et c'est le comportement par défaut de PIXI. Si vous souhaitez fixer les limites, étendez votre propre conteneur, remplacez la méthode "CalculateBounds".

S'il n'a pas de zone et de limites fixes et qu'il s'agit essentiellement d'une structure de données, cela ne devrait pas affecter le rendu (de la même manière que si vous mettez un objet trop grand dans une iframe, l'iframe ne va pas s'agrandir) . Dans l'exemple, c'est clairement le cas, et je trouve difficile de blâmer cela sur la logique erronée de l'exemple. Peut-être que ne pas avoir d'option de limites fixes ne regarde pas la racine du problème, mais le problème est définitivement là.

Comment suggéreriez-vous que je mette en œuvre des éléments «hors écran»?

Pourquoi avez-vous besoin de limites de toute façon?

Avez-vous regardé l'exemple? Le comportement étrange est causé par le fait que chaque fois que drawDebugLines est exécuté et dessine les lignes dans le conteneur "icon's", ce conteneur s'agrandit. Ce qui à son tour gâche les points d'accrochage, car ceux-ci dépendent des dimensions du conteneur (largeur / colonnes, hauteur / lignes).

Si je mappe l'accrochage à l'élément de rendu, cela pose 2 problèmes: le rendu dépend de la taille de l'écran, de l'orientation, de la densité de pixels et des dimensions spécifiées par l'utilisateur de l'élément de dessin. Il peut contenir des éléments qui sont à la fois plus gros (par exemple hors écran, qui peuvent glisser) et plus petits (par exemple, si je rends le bureau 1 et le bureau2 visibles en même temps. Dans tous ces cas, l'accrochage et les autres contraintes doivent être préservés .

lel.width = wonderfulRectangle.width * 0.8;
lel.height = wonderfulRectangle.height * 0.9;

pourquoi ne l'utilisez-vous pas comme constante? Pouvez-vous simplement configurer quelque chose de global, comme ça:

var globalRect = new PIXI.Rectangle(0, 0, renderr.width/renderer.resolution, renderer.height/renderer.resolution);

mettre à jour ce rect à chaque redimensionnement et travailler avec cela. Pourquoi avez-vous besoin de "lel.width" et "lel.height"?

LEL. Celui-là n'a rien à voir avec quoi que ce soit, c'est juste un Sprite qui peut être déplacé et je règle la largeur et la hauteur car l'image d'origine est trop grande et j'ai besoin de l'adapter dans un rectangle. Si vous regardez le code dans le, vous verrez que le conteneur principal de cette «icône» est desktop1 et c'est celui sur lequel j'essaye de mettre l'icône en place. Celui-ci appartient au desktopLayer et le desktopLayer est celui que j'ai mis sur scène.

Ce que j'essaie d'émuler, c'est le comportement d'un écran Android Launcher avec plusieurs vues balayables et une grille d'icônes sur un fond de bureau.

return new PIXI.Point(snapPosX.clamp(0, target.parent.width), snapPosY.clamp(0, target.parent.height));

Je ne comprends toujours pas ce que tu veux. Les limites des conteneurs PIXI fonctionnent exactement comme elles sont censées le faire. Vous n'êtes pas le premier à avoir commis cette erreur.

Oh le souffle du fabricant, je ne peux plus faire ça. Quelqu'un peut-il simplement regarder l'exemple, déplacer la rageface et me dire pourquoi cette merde avec les lignes se produit et si c'est un bug / une fonctionnalité manquante dans PIXI ou si j'ai une erreur dans le code?

Je pensais que c'était parce que vos lignes affectaient réellement la largeur et la hauteur du conteneur et que vous utilisiez ces propriétés pour dessiner des lignes en premier lieu.

Codepen ne fonctionne plus pour moi, d'une manière ou d'une autre. Des idées pourquoi?

Ouais, c'est cassé pour moi aussi parce que j'ai accidentellement commenté l'appel d'initialisation, mon mauvais, désolé, corrigé. Oui, vous avez raison - c'est ce que je fais et je ne vois pas d'autre moyen pour moi de tracer ces lignes pour refléter la grille visuellement. Alors, que me proposeriez-vous exactement pour tracer ces lignes? Configurer une sorte d'objet méta-seulement séparé Rectangle qui copie toujours les dimensions du conteneur rendu associé et l'utiliser pour dériver les points d'accrochage et d'autres positions? Cela semble être une sur-ingénierie autour du problème au lieu de le résoudre. Y a-t-il une raison pour laquelle un conteneur ne peut pas avoir de "débordement" comme un élément DOM normal?

J'ai posté cela comme un problème non pas parce qu'il n'y a pas de solution, mais parce que je ne vois pas la justification de ce comportement illogique. Surtout parce que les lignes ne sortent pas réellement des limites du conteneur, elles sont dessinées d'un bord à l'autre. Dans le produit que je construis, on s'attend à ce que l'utilisateur fasse beaucoup d'interaction avec le contenu, je crains que si je dois configurer des "rectangles de référence" pour chaque objet de la scène, le code sera extrêmement compliqué et difficile à maintenir .

Vous avez mentionné que j'avais une «erreur» dans mon code. Quelle est cette erreur? J'ai cherché très minutieusement mais je ne trouve aucune logique défectueuse.

Utilisez une variable globale au lieu de "largeur / hauteur" qui change. Mettez à jour cette variable si nécessaire.

var globalRect = new PIXI.Rectangle(0, 0, renderer.width/renderer.resolution, renderer.height/renderer.resolution);

Si vous voulez des limites "locales", créez-les, mais n'utilisez pas les mêmes variables que pixi:

container.myRect = new PIXI.Rectangle(0, 0, renderer.width/renderer.resolution, renderer.height/renderer.resolution);

L'erreur est qu'il n'y a pas du tout de disposition dans PIXI. «largeur» et «hauteur» ont une signification différente. Vous ne pouvez pas serrer les coordonnées enfants par la hauteur de largeur du parent, car l'enfant les affecte.

Il n'y a aucun moyen pour PIXI de savoir que vous voulez la largeur / hauteur d'un rectangle que vous avez dessiné à l'intérieur des graphiques, et non des limites graphiques entières (et s'il y a aussi des cercles?), Et pas des limites enfants. La seule logique raisonnable pour les limites est de prendre tout ce qui s'y trouve.

Imaginons que nous ayons un conteneur avec deux sprites, chacun a (w = 10, h = 10), l'un est en (0,0), l'autre est en (100000, 100000). Quelle largeur et quelle hauteur ce conteneur a-t-il? De plus, même si nous fixons d'une manière ou d'une autre les limites, qu'affecteront-elles?

Et si nous voulons changer la largeur et la hauteur d'une manière ou d'une autre, comment ce changement affectera-t-il les éléments à l'intérieur du conteneur?

Je ne plaisante pas, c'est vraiment difficile pour moi d'imaginer d'autres conceptions d'API. Si vous avez des idées, peut-être un composant supplémentaire pour la mise en page, veuillez l'écrire ici. N'oubliez pas que nous avons affaire à un rendu de scène et non à une interface graphique, les performances sont un vrai problème.

Hey @megakoresh , je pense que je sais ce qui cause la confusion ici. Étant donné que l'objectif principal de pixi est de rendre des objets 2D, presque toute l'API est orientée vers cette fin. Les limites peuvent être particulièrement déroutantes.

Dans pixi, les limites d'un Sprite sont définies par la texture. Autrement dit, la taille du résultat final de l'objet rendu. De même, puisqu'un conteneur n'est _pas dessiné_, et donc ses limites sont définies par les enfants qu'il contient. En particulier, par les limites de ces enfants. Pour un objet Graphics, les limites sont définies par la géométrie que vous y dessinez. Si vous dessinez un autre rectangle dans un objet Graphics en dehors des limites actuelles, les limites se développent pour inclure la géométrie nouvellement dessinée.

J'espère que cela a du sens et vous donne un aperçu rapide de la structure des limites dans Pixi.

Maintenant, spécifiquement pour votre exemple, je pense que votre problème vient du malentendu sur le fonctionnement des limites pour un objet Graphics. Je pense qu'il vous manque le fait que dessiner votre grille change les limites de l'objet Graphics ( desktop1 ) qui contient le rect vert ( wonderfulRectangle ).

Vous pouvez voir qu'après le premier dessin, votre grille dépasse la taille de la fenêtre:

image

Cela étend les limites de l'objet Graphics parent ( desktop1 ) pour inclure la géométrie hors fenêtre. Cela rend votre largeur plus grande, ce qui annule votre prochain calcul de la grille, et le cycle se poursuit. N'oubliez pas que les lignes ont de l'épaisseur et donc de la largeur.

Il y a plusieurs façons de résoudre ce problème, celle qui me vient à l'esprit est que puisque votre grille remplit toute la taille de la fenêtre, utilisez simplement la taille de la fenêtre plutôt que la taille de votre parent. Cela signifie que si / lorsque vous dessinez plus de géométrie en dehors de la fenêtre, vos calculs de grille ne changent jamais. Parce que la fenêtre de rendu ne change pas de taille.

Si ce n'est pas une option, par exemple, votre zone de grille n'a pas la taille de la fenêtre. Vous pouvez simplement faire les calculs basés sur une «taille connue» de la zone de grille. Je pense que c'est ce qu'Ivan essayait de dire à propos de l'utilisation d'une instance statique Rectangle . Fondamentalement, décidez que votre grille est de 800x600 et effectuez des calculs basés sur cela plutôt que sur les limites réelles des objets de la scène.

J'ai mis à jour le codepen pour utiliser la méthode viewport que j'ai décrite. Dis moi si tu as d'autres questions!

http://codepen.io/anon/pen/yarVwm?editors=0010

LOL k. Donc, avec vos efforts combinés, je pense que je comprends le cœur du problème: je pense que je pensais que si la bibliothèque est souvent assemblée avec des bibliothèques de canevas, je suppose que c'est la même chose, ce qui n'est clairement pas. Je suppose qu'alors, prendre en charge le regroupement d'objets visuels et des choses comme le débordement ne sont pas simples (peut-être que lorsque j'apprends davantage la bibliothèque, je peux créer un plugin pour cela) et que je dois m'occuper de ces choses moi-même, tandis que PIXI lui-même prend soin de lui de simplement afficher des choses à l'écran. Affaire classée, merci.

Ce thread a été automatiquement verrouillé car il n'y a eu aucune activité récente après sa fermeture. Veuillez ouvrir un nouveau numéro pour les bogues associés.

Cette page vous a été utile?
0 / 5 - 0 notes

Questions connexes

YuryKuvetski picture YuryKuvetski  ·  3Commentaires

softshape picture softshape  ·  3Commentaires

lucap86 picture lucap86  ·  3Commentaires

sntiagomoreno picture sntiagomoreno  ·  3Commentaires

distinctdan picture distinctdan  ·  3Commentaires