Pixi.js: Le sprite s'accroche à la souris à la position d'ancrage du sprite lors du déplacement de la souris

Créé le 23 juin 2013  ·  5Commentaires  ·  Source: pixijs/pixi.js

  1. Lorsque vous faites glisser (mousemove), quel que soit l'endroit où la souris est placée sur le sprite, le sprite se repositionne de telle sorte que le pointeur de la souris se trouve maintenant à la position d'ancrage du sprite.
  2. Pour les sprites plus grands, ce changement est assez choquant.
  3. Ce serait bien de ne pas exiger que le pointeur de la souris soit à la position d'ancrage. En interne, la position de l'ancre doit être maintenue pour les calculs, etc. quelle que soit la position de la souris sur le sprite.
  4. Exemple de code et image jointe. Remarques sur la reproduction :

    • Code adapté et simplifié à partir de l'exemple de glisser dans pixi.js (Exemple 8).

    • Téléchargez l'image et renommez-la en "aboriginal-bunny.png" comme indiqué dans le code.

    • Le point d'ancrage du lapin est réglé sur 0,1, 0,1

    • Placez le curseur de la souris quelque part près du bas du sprite, essentiellement n'importe où loin du point d'ancrage

    • Au mousedown, l'alpha du sprite change, mais tout le reste est le même, donc le problème ne semble pas être sur mousedown.

    • Ensuite, faites glisser -- commencez à vous déplacer avec le bouton de la souris enfoncé -- juste légèrement

    • Notez le décalage soudain du sprite pour que la souris soit sur son point d'ancrage.

    • Désormais, le glissement est maintenu avec la souris à cette ancre.

<!DOCTYPE HTML>
<html>
<head>
    <!-- Shamelessly adapted from pixi.js Example 8 - Dragging -->
    <title>Sprite to Mouse Snapping issue</title>
    <script src="pixi.js"></script>
</head>
<body>
    <script>

    var stage = new PIXI.Stage(0x97c56e, true);
    var renderer = PIXI.autoDetectRenderer(window.innerWidth, window.innerHeight, null);

    // add the renderer view element to the DOM
    document.body.appendChild(renderer.view);
    renderer.view.style.position = "absolute";
    renderer.view.style.top = "0px";
    renderer.view.style.left = "0px";
    requestAnimFrame( animate );

    // create a texture from an image path
    var texture = PIXI.Texture.fromImage("aboriginal-bunny.png");

    createAboriginalBunny(100, 100);

    function createAboriginalBunny(x, y)
    {
        var bunny = new PIXI.Sprite(texture);
        bunny.setInteractive(true);

        // leaving anchor point at 10% to illustrate the problem clearer
        bunny.anchor.x = 0.1;
        bunny.anchor.y = 0.1;

        /*
         * Set-up dragging
         */     
        bunny.mousedown = bunny.touchstart = function(data)
        {
            this.data = data;
            this.alpha = 0.5;
            this.dragging = true;
        };

        bunny.mouseup = bunny.mouseupoutside = bunny.touchend = bunny.touchendoutside = function(data)
        {
            this.alpha = 1
            this.dragging = false;
            // set the interaction data to null
            this.data = null;
        };

        bunny.mousemove = bunny.touchmove = function(data)
        {
            if(this.dragging)
            {
                // need to get parent coords..
                var newPosition = this.data.getLocalPosition(this.parent);
                this.position.x = newPosition.x;
                this.position.y = newPosition.y;
            }
        }

        // move the sprite to initial pos
        bunny.position.x = x;
        bunny.position.y = y;

        stage.addChild(bunny);
    }

    function animate() {
        requestAnimFrame( animate );
        renderer.render(stage);
    }

    </script>

    </body>
</html>

aboriginal-bunny

Commentaire le plus utile

Tout d'abord, merci pour le rapport de bogue détaillé et l'exemple de code, ça aide beaucoup quand on nous donne autant d'informations !

Malheureusement, ce n'est pas un bug. Ce problème est dû au fait que vous définissez la position du sprite sur la position de la souris à chaque mouvement de souris (probablement parce que c'est ce que fait l'exemple). Vraiment, ce qui devrait arriver, c'est que vous devriez mettre à jour votre sprite par le delta du mouvement de la souris. Essayez quelque chose comme ceci :

        /*
         * Set-up dragging
         */     
        bunny.mousedown = bunny.touchstart = function(data)
        {
            this.data = data;
            this.alpha = 0.5;
            this.dragging = this.data.getLocalPosition(this.parent);;
        };

        bunny.mouseup = bunny.mouseupoutside = bunny.touchend = bunny.touchendoutside = function(data)
        {
            this.alpha = 1
            this.dragging = false;
            // set the interaction data to null
            this.data = null;
        };

        bunny.mousemove = bunny.touchmove = function(data)
        {
            if(this.dragging)
            {
                // need to get parent coords..
                var newPosition = this.data.getLocalPosition(this.parent);
                this.position.x += (newPosition.x - this.dragging.x);
                this.position.y += (newPosition.y - this.dragging.y);
                this.dragging = newPosition;
            }
        }

Les bits importants sont sur mousedown Je stocke l'emplacement de la souris, puis sur mousemove Je mets à jour la position de mon sprite de combien la souris s'est déplacée (ne la met pas à la nouvelle position), puis Je mets à jour la position de la souris stockée pour la prochaine fois. J'espère que ça aide!

Tous les 5 commentaires

Tout d'abord, merci pour le rapport de bogue détaillé et l'exemple de code, ça aide beaucoup quand on nous donne autant d'informations !

Malheureusement, ce n'est pas un bug. Ce problème est dû au fait que vous définissez la position du sprite sur la position de la souris à chaque mouvement de souris (probablement parce que c'est ce que fait l'exemple). Vraiment, ce qui devrait arriver, c'est que vous devriez mettre à jour votre sprite par le delta du mouvement de la souris. Essayez quelque chose comme ceci :

        /*
         * Set-up dragging
         */     
        bunny.mousedown = bunny.touchstart = function(data)
        {
            this.data = data;
            this.alpha = 0.5;
            this.dragging = this.data.getLocalPosition(this.parent);;
        };

        bunny.mouseup = bunny.mouseupoutside = bunny.touchend = bunny.touchendoutside = function(data)
        {
            this.alpha = 1
            this.dragging = false;
            // set the interaction data to null
            this.data = null;
        };

        bunny.mousemove = bunny.touchmove = function(data)
        {
            if(this.dragging)
            {
                // need to get parent coords..
                var newPosition = this.data.getLocalPosition(this.parent);
                this.position.x += (newPosition.x - this.dragging.x);
                this.position.y += (newPosition.y - this.dragging.y);
                this.dragging = newPosition;
            }
        }

Les bits importants sont sur mousedown Je stocke l'emplacement de la souris, puis sur mousemove Je mets à jour la position de mon sprite de combien la souris s'est déplacée (ne la met pas à la nouvelle position), puis Je mets à jour la position de la souris stockée pour la prochaine fois. J'espère que ça aide!

Bonjour,

Cela résout mon problème et est beaucoup plus clair à comprendre, merci. Et oui, mon code est basé sur le fonctionnement de l'exemple, donc ce serait bien si l'exemple pouvait être mis à jour - je me souviens avoir eu du mal à comprendre comment cela fonctionnait, je suppose que cela n'a pas complètement fonctionné. :P

Une question connexe, est-il strictement nécessaire de définir les données d'interaction sur null au lever de la souris ?

Je ne sais toujours pas quand getLocalPosition est requis, par rapport à la position actuelle.

PS. pas de soucis concernant les détails du rapport de bogue, du moins que je puisse faire. Merci d'avoir fourni la bibliothèque. :)

La raison de getLocalPosition est de transformer les coordonnées absolues de l'événement de la souris en coordonnées relatives locales utilisées par DisplayObjects. La position de chaque DisplayObject est relative à son parent, nous prenons donc les coordonnées absolues de la souris et les transformons pour qu'elles soient relatives au parent avec this.data.getLocalPosition(this.parent) .

Il n'est pas particulièrement nécessaire de définir this.data = null sur mouseup. Vraiment, vous devriez pouvoir utiliser simplement le paramètre data pour chaque fonction, et ne pas utiliser du tout this.data .

Merci encore pour votre aide; assez nouveau pour les bibliothèques graphiques, donc se réconcilier avec divers choix d'implémentation. J'apprécie que les développeurs pixi prennent le temps de répondre à mes questions en temps opportun.

Ce fil a été automatiquement verrouillé car il n'y a eu aucune activité récente après sa fermeture. Veuillez ouvrir un nouveau problème pour les bogues liés.

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

Questions connexes

Darker picture Darker  ·  3Commentaires

MRVDH picture MRVDH  ·  3Commentaires

SebastienFPRousseau picture SebastienFPRousseau  ·  3Commentaires

sntiagomoreno picture sntiagomoreno  ·  3Commentaires

courtneyvigo picture courtneyvigo  ·  3Commentaires