Pixi.js: Sprite rastet bei Mausbewegung an der Sprite-Ankerposition an der Maus ein

Erstellt am 23. Juni 2013  ·  5Kommentare  ·  Quelle: pixijs/pixi.js

  1. Beim Ziehen (Mousemove), unabhängig davon, wo auf dem Sprite die Maus platziert ist, positioniert sich das Sprite selbst neu, sodass sich der Mauszeiger jetzt an der Ankerposition des Sprites befindet.
  2. Für größere Sprites ist diese Verschiebung ziemlich erschütternd.
  3. Es wäre schön, wenn sich der Mauszeiger nicht an der Ankerposition befinden müsste. Intern muss die Ankerposition für Berechnungen etc. unabhängig von der Mausposition auf dem Sprite beibehalten werden.
  4. Beispielcode und Bild angehängt. Hinweise zur Reproduktion:

    • Code angepasst und vereinfacht aus dem Drag-Beispiel in pixi.js (Beispiel 8).

    • Laden Sie das Bild herunter und benennen Sie es in "aboriginal-bunny.png" um, wie im Code angegeben.

    • Der Hasenankerpunkt ist auf 0,1, 0,1 . eingestellt

    • Platzieren Sie den Mauszeiger irgendwo nahe am unteren Rand des Sprites, im Wesentlichen irgendwo weit vom Ankerpunkt entfernt

    • Beim Mousedown ändert sich das Alpha des Sprites, aber alles andere ist gleich, also scheint das Problem nicht beim Mousedown zu liegen.

    • Ziehen Sie als Nächstes – beginnen Sie mit der Bewegung mit gedrückter Maustaste – nur leicht

    • Beachten Sie die plötzliche Verschiebung des Sprites, sodass sich die Maus an ihrem Ankerpunkt befindet.

    • Von nun an wird das Ziehen mit der Maus an diesem Anker beibehalten.

<!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

Hilfreichster Kommentar

Erstmal vielen Dank für den ausführlichen Fehlerbericht und den Beispielcode, es hilft sehr, wenn wir so viele Informationen bekommen!

Leider ist dies kein Fehler. Dieses Problem wird dadurch verursacht, dass Sie die Position des Sprites bei jeder Mausbewegung auf die Position der Maus einstellen (wahrscheinlich, weil dies im Beispiel der Fall ist). Was wirklich passieren sollte, ist, dass Sie Ihr Sprite um das Delta der Mausbewegung aktualisieren sollten. Versuchen Sie so etwas:

        /*
         * 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;
            }
        }

Die wichtigen Bits sind auf mousedown Ich speichere die Position der Maus, dann auf mousemove aktualisiere ich meine Sprite-Position um wie viel sich die Maus _bewegt_ hat (nicht auf die neue Position setzen), dann Ich aktualisiere die gespeicherte Mausposition für das nächste Mal. Ich hoffe das hilft!

Alle 5 Kommentare

Erstmal vielen Dank für den ausführlichen Fehlerbericht und den Beispielcode, es hilft sehr, wenn wir so viele Informationen bekommen!

Leider ist dies kein Fehler. Dieses Problem wird dadurch verursacht, dass Sie die Position des Sprites bei jeder Mausbewegung auf die Position der Maus einstellen (wahrscheinlich, weil dies im Beispiel der Fall ist). Was wirklich passieren sollte, ist, dass Sie Ihr Sprite um das Delta der Mausbewegung aktualisieren sollten. Versuchen Sie so etwas:

        /*
         * 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;
            }
        }

Die wichtigen Bits sind auf mousedown Ich speichere die Position der Maus, dann auf mousemove aktualisiere ich meine Sprite-Position um wie viel sich die Maus _bewegt_ hat (nicht auf die neue Position setzen), dann Ich aktualisiere die gespeicherte Mausposition für das nächste Mal. Ich hoffe das hilft!

Hallo,

Dies behebt mein Problem und ist viel klarer zu verstehen, danke. Und ja, mein Code basiert auf der Funktionsweise des Beispiels, daher wäre es gut, wenn das Beispiel aktualisiert werden könnte - ich erinnere mich, dass ich Probleme hatte, zu verstehen, wie es funktioniert, ich denke, es hat nicht vollständig funktioniert. :P

Eine verwandte Frage: Ist es unbedingt erforderlich, Interaktionsdaten beim Mouseup auf null zu setzen?

Mir ist auch noch unklar, wann getLocalPosition erforderlich ist, im Vergleich zu nur der aktuellen Position.

PS. keine sorge bezüglich: detail des fehlerberichts, das mindeste, was ich tun konnte. Vielen Dank für die Bereitstellung der Bibliothek. :)

Der Grund für getLocalPosition besteht darin, die absoluten Koordinaten des Mausereignisses in lokale relative Koordinaten umzuwandeln, die von DisplayObjects verwendet werden. Die Position jedes DisplayObject ist relativ zu seinem Elternteil, also nehmen wir die absoluten Mauskoordinaten und transformieren sie mit this.data.getLocalPosition(this.parent) relativ zum Elternteil.

Es ist nicht unbedingt notwendig, this.data = null bei Mouseup zu setzen. Eigentlich sollten Sie in der Lage sein, nur den Parameter data für jede Funktion zu verwenden und this.data überhaupt nicht zu verwenden.

Danke nochmal für deine Hilfe; ziemlich neu in Bezug auf Grafikbibliotheken, also müssen Sie sich mit verschiedenen Implementierungsoptionen auseinandersetzen. Ich schätze die pixi-Entwickler, die sich die Zeit nehmen, meine Fragen zeitnah zu beantworten.

Dieser Thread wurde automatisch gesperrt, da nach dem Schließen in letzter Zeit keine Aktivität stattgefunden hat. Bitte öffnen Sie eine neue Ausgabe für verwandte Fehler.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen