2016-08-23 2 views
0

Ich benutze KineticJS und versuche etwas zu erledigen, das einfach genug aussieht: Ich versuche eine Form zu bekommen, um die Position mit der gerade gezogenen Form zu ändern. Die Idee ist folgende:
• Sie nehmen eine Form auf der Leinwand auf. Dies löst einen mousedown Ereignis-Listener aus, der die aktuelle Position der von Ihnen aufgenommenen Form speichert.
• Wenn Sie die Form beibehalten und das mouseover auf einer anderen Form auslösen, wird das Ereignis dieser Form ausgelöst und tauscht ihre Position basierend auf der gespeicherten Position der aktuellen Form aus.KineticJS - Austauschen von Formpositionen bei Kontakt/Mausauslöser

Hier ist der relevante Code, den ich geschrieben habe, um zu versuchen, dass die Arbeit zu bekommen:

Brettaufbau: einfach nur das Board einrichten und die benötigten Funktionen hier aufrufen. Ich mache noch nichts mit der Bühne, dem gameBoard oder dem ctx (ein Teil davon war, als ich versuchte, drawImage auf mehreren Leinwänden zu verwenden, aber ich habe das vorerst aufgegeben).

class BoardView { 
    constructor(stage, gameBoard, ctx) { 
    this.stage = stage; 
    this.gameBoard = gameBoard; 
    this.ctx = ctx; 
    this.orbs = [[], [], [], [], []]; 
    this.setupBoard(); 
    } 

Vorstand Setup-Funktionen: Dies ist, wo ich mich über das Brett und geben Sie jedem Kinetic Kreis Einrichten der Attribute auf der Ebene zu machen braucht. Vielleicht vermisse ich hier etwas Offensichtliches?

setupBoard() { 
    for (let colIdx = 0; colIdx < 5; colIdx++) { 
     this.addRow(colIdx); 
    } 

    this.renderBoard(); 
    } 

    addRow (colIdx) { 
    for (let rowIdx = 0; rowIdx < 6; rowIdx++) { 
     let orbType = Math.round(Math.random() * 5); 
     let orbColor; 

     if (orbType === 0) { 
      orbColor = "#990000"; 
     } else if (orbType === 1) { 
      orbColor = "#112288"; 
     } else if (orbType === 2) { 
      orbColor = "#005544"; 
     } else if (orbType === 3) { 
      orbColor = "#776611"; 
     } else if (orbType === 4) { 
      orbColor = "#772299"; 
     } else { 
      orbColor = "#dd2277"; 
     } 
     let orbject = new Kinetic.Circle({ 
     x: (rowIdx + 0.5) * 100, 
     y: (colIdx + 0.5) * 100, 
     width: 100, 
     height: 100, 
     fill: orbColor, 
     draggable: true 
     }); 
     this.orbs[colIdx].push(orbject); 
    } 
    } 

Brettfunktion machen: Dies ist, wo ich alle in die Kinetic-Kreis in neue Schichten Objekte, und geben diese Schichten alle ihre eigenen Attribute, mit zu arbeiten, wenn ich die Event-Handler aufrufen. Ich habe auch hier die Event-Handler eingerichtet, nachdem ich die Layer zur Bühne hinzugefügt habe. Verwechsle ich das vielleicht, indem ich zu viele Schichten hinzufüge?

renderBoard() { 

    for (let row = 0; row < this.orbs.length; row++) { 
     for (let orb = 0; orb < this.orbs[row].length; orb++) { 
     let layer = new Kinetic.Layer(); 

     layer.add(this.orbs[row][orb]); 
     layer.moving = false; 
     layer.orbId = `orb${row}${orb}`; 
     layer.pos = [this.orbs[row][orb].attrs.x, this.orbs[row][orb].attrs.y]; 

     this.stage.add(layer); 

     layer.on("mousedown", this.handleMouseDown); 
     layer.on("mouseup", this.handleMouseUp); 
     layer.on("mouseout", this.handleMouseOut); 
     layer.on("mousemove", this.handleMouseMove); 
     } 
    } 
    } 

Mausereignishandler: Dies ist, wo ich glaube, ich bin mein Hauptproblem ist. Wie handhabe ich das Bewegen der Maus, um die Kugeln zu wechseln? Vielleicht mache ich etwas furchtbar falsch?

handleMouseDown (e) { 
    window.currentOrb = this; 
    console.log(window.currentOrb.orbId); 

    this.moving = true; 
    } 

    //handleMouseUp (e) { 
    // window.currentOrb = undefined; 
    // this.moving = false; 
    //} 

    //handleMouseOut (e) { 
    //} 

    handleMouseMove (e) { 
    if (window.currentOrb !== undefined && window.currentOrb.orbId != this.orbId) { 
     this.children[0].attrs.x = window.currentOrb.pos[0]; 
     this.children[0].attrs.y = window.currentOrb.pos[1]; 
     this.children[0].draw(); 
    } else { 
    } 
    } 
} 


module.exports = BoardView; 

Ich habe versucht, an den KineticJS docs suchen und viele Antworten, wie Stackoverflow konnte ich in der Hoffnung, eine Lösung zu finden, die für mich arbeiten würde, aber nichts habe ich gesehen und versucht, so weit (einschließlich der Vorschläge das kam, als ich diese Frage schrieb) schien mir behilflich zu sein, und ich bin mir bewusst, dass die Art und Weise, wie ich das bisher gemacht habe, wahrscheinlich nicht der beste Weg ist, um das zu erreichen, was ich will Vorschläge, Hinweise, beantwortete Fragen oder was auch immer, kann mich in die richtige Richtung weisen, was ich verpasse, um dies zur Arbeit zu bringen.

Falls dies hilfreich ist, hier ist auch eine Visualisierung, wie die Dinge aussehen, wenn das Board gerendert wird.

enter image description here

Die Kreise sind alle Kinetic Kreise (Orbs zum Zwecke der, was ich werde), und Klicken und einem zum anderen ziehen, die eine, die nicht gezogen wird, sondern schwebte über sollte bewegen an die ursprüngliche Position der gezogenen Kreise.

Danke!

EDIT:

machte ich ein paar Änderungen an dem Code seitdem. Zunächst einmal, änderte es viele Schichten auf die Bühne hinzufügen, um nur eine:

renderBoard() { 
    let layer = new Kinetic.Layer(); 

    for (let row = 0; row < this.orbs.length; row++) { 
    for (let orb = 0; orb < this.orbs[row].length; orb++) { 

     layer.add(this.orbs[row][orb]); 

     this.orbCanvases.push(orbCanvas.id); 
    } 
    } 
    this.stage.add(layer); 
} 

ich stattdessen Zuhörer auf die Kugel Objekte hinzugefügt statt:

addRow (colIdx) { 
    for (let rowIdx = 0; rowIdx < 6; rowIdx++) { 

    //same code as before 

    let orbject = new Kinetic.Circle({ 
     x: (rowIdx + 0.5) * 100, y: (colIdx + 0.5) * 100, 
     width: 100, height: 100, 
     fill: orbColor, draggable: true, pos: [rowIdx, colIdx] 
    }); 
    orbject.on("mousedown", this.handleMouseDown); 
    orbject.on("mouseup", this.handleMouseUp); 
    orbject.on("mouseout", this.handleMouseOut); 
    orbject.on("mousemove", this.handleMouseMove); 

    this.orbs[colIdx].push(orbject); 
    } 
} 

Dies den Vorteil, dass Drag hatte und Drop viel viel schneller, wo vorher, es ging sehr langsam, aber ich kann immer noch nicht meine Objekte Position tauschen.

Um klar zu sein, mein Hauptproblem ist zu wissen, welche x, y Werte ich ändern sollte. Im Moment in handleMouseMove, ich habe zu ändern versucht:

e.target.attrs.x = newX; 
e.target.attrs.y = newY; 
// newX and newY can be any number 

Doch egal, was ich es ändern, hat dies keine Auswirkungen. So würde es mir helfen, zu wissen, ob ich das falsche Ding/den falschen Ort ändere, zum Beispiel, vielleicht sollte ich den Kinetischen Kreis von dem Array ändern, den ich gespeichert habe? Danke noch einmal.

EDIT 2:

Ich glaube, ich habe es! Allerdings hatte ich this.orbs zu nehmen und es in dem Fenster auf window.orbs gesetzt, und es zu testen ich getan habe:

window.orbs[0][0].x(450); 
window.orbs[0][0].draw(); 

Und dies verursachte die x-Position zu ändern. Aber es in ein Fenster zu stecken scheint nicht gut zu sein?

EDIT 3:

bekam ich die Kugeln tauschen nun kontinuierlich, außer wenn es die gleiche Kugel wieder ausgelagert werden, während mouseover Feuer fort. Bei mouseup kann es jedoch erneut getauscht werden. Ich musste auch mehrere Ebenen neu aufbauen, um die mouseover Events zum Funktionieren zu bringen, während ich eine andere Kugel hielt, aber die Leistung scheint sich ein wenig verbessert zu haben.

Ich werde versuchen, herauszufinden, wie man sich die Lage sein, kontinuierlich auf der gleichen Maus halten zu tauschen, aber in der Zwischenzeit, hier ist der Code, den ich schrieb, dies zu erreichen:

addRow (colIdx) { 
    for (let rowIdx = 0; rowIdx < 6; rowIdx++) { 

    // same code as before, changed attr given to Kinetic.Circle 

    let orbject = new Kinetic.Circle({ 
     x: (rowIdx + 0.5) * 100, y: (colIdx + 0.5) * 100, 
     width: 100, height: 100, 
     fill: orbColor, draggable: true, orbId: `orb${colIdx}${rowIdx}` 
    }); 
    } 
} 

handleMouseDown (e) { 
    window.currentOrb = window.orbs[e.target.attrs.orbId]; 
    window.newX = e.target.attrs.x; 
    window.newY = e.target.attrs.y; 
} 

Maus nach unten Speichern currentOrb von ID und seiner X- und Y-

handleMouseUp (e) { 
    window.currentOrb.x(window.newX); 
    window.currentOrb.y(window.newY); 
    window.currentOrb.parent.clear(); 
    window.currentOrb.parent.draw(); 
    window.currentOrb.draw(); 
    window.currentOrb = undefined; 
    for (let i = 0; i < 5; i++) { 
    for (let j = 0; j < 6; j++) { 
     window.orbs[`orb${i}${j}`].draw(); 
    } 
    } 
} 

Wenn Maustaste losgelassen wird, zur Zeit, alle Kugeln neu gezeichnet werden, so dass sie alle verwendet werden können. Ich plane, dies neu zu gestalten, so dass nur die Orbs, die sich über diese Änderung befinden, diese Änderung haben.

handleMouseMove (e) { 

    if (window.currentOrb !== undefined && (window.currentOrb.attrs.orbId !== e.target.attrs.orbId)) { 
    window.orbMove.pause(); 
    window.currentTime = 0; 
    window.orbMove.play(); 
    let targOrbX = e.target.attrs.x; 
    let targOrbY = e.target.attrs.y; 
    // This is the target orb that's being changed's value 
    // We're storing this in targOrb 

    e.target.x(window.newX); 
    e.target.y(window.newY); 
    e.target.parent.clear(); 
    e.target.parent.draw(); 
    e.target.draw(); 

    // Here we have the previously set current orb's position becoming 
    // the target orb's position 

    window.newX = targOrbX; 
    window.newY = targOrbY; 

    // Now that the move is made, we can set the newX and Y to be the 
    // target orb's position once mouseup 
    } 
} 

Orb Auslagerungslogik, die einst für die Weitergabe über Kugeln funktioniert, aber nicht, wenn sie wieder in der gleichen Runde übergegangen.

Antwort

0

Wann findet der "Hover" offiziell statt?

  • Wenn die Position des Mausereignisses in die zweite Kugel eintritt? Wenn ja, drücken Sie die Maus gegen jede nicht-Schleppen orb testen:

    // pseudo-code -- make this test for every non-dragging orb 
    var dx=mouseX-orb[n].x; 
    var dy=mouseY-orb[n].y; 
    if(dx*dx+dy*dy<orb[n].radius){ 
        // change orb[n]'s x,y to the dragging orb's x,y (and optionally re-render) 
    } 
    
  • Wenn das Ziehen Kugel die zweite Kugel schneidet? Wenn ja, testen Kollision das Ziehen Kugel vs jeder Nicht-Schleppen Kugel:

    // pseudo-code -- make this test for every non-dragging orb 
    var dx=orb[draggingIndex].x-orb[n].x; 
    var dy=orb[draggingIndex].y-orb[n].y; 
    var rSum=orb[draggingIndex].radius+orb[n].radius; 
    if(dx*dx+dy*dy<=rSum*rSum){ 
        // change orb[n]'s x,y to the dragging orb's x,y (and optionally re-render) 
    } 
    

BTW, wenn Sie eine Kugel über alle anderen Kugeln ziehen, die anderen Kugeln werden alle Stapel auf den Schlepp Kugeln ursprüngliche Position - - ist es das was du willst?

+0

Was ich will (vorerst - ich möchte zumindest den Austausch von Orbs zur Arbeit bringen) ist das Erste. Ich habe ein paar Änderungen am Code vorgenommen und ein Bonus ist, dass Drag und Drop viel schneller, aber Swapping funktioniert immer noch nicht. Mein Hauptproblem besteht darin, die Kugeln überhaupt zu tauschen, und welche x, y ich dafür ändere. Ich werde Änderungen an meinem OP vornehmen und detaillierter darauf eingehen, was ich oben gerne hätte. Vielen Dank. – karivool

+0

Es ist eine Weile her, seit ich K-JS benutzt habe, es sollte etwas wie ein 'onDragMove'-Ereignis auf der ziehenden Kugel sein. Das gibt dir die schleppende Position. Mach dir keine Mühe mit der eingebauten 'schneidenden' Methode - es ist langsam. Verwenden Sie stattdessen eine der beiden Methoden, die ich in meiner Antwort beschrieben habe. Denken Sie daran, dass Sie mit K-JS die Ebene neu zeichnen müssen, damit Ihre schwebenden Kugeln sich visuell zu den gespeicherten x, y bewegen. Wenn deine Kugeln sich nicht bewegen, achte darauf, dass du etwas wie "layer.redraw" machst, nachdem du jede Kugel bewegt hast. – markE

+1

Danke, ich habe es geschafft, dass meine Orbs jetzt Plätze tauschen, wenn die Maus einen berührt (und sie kontinuierlich austauschen kann). Es tut dies nicht, wenn du versuchst zurück zu tauschen, während der 'Mauszeiger' noch feuert, also werde ich das herausfinden. '.draw' scheint dafür nicht zu funktionieren, aber für' mouseup', aber ich werde versuchen, das herauszufinden. Danke noch einmal! – karivool