2016-08-23 5 views
0

나는 KineticJS를 사용하고 있으며, 이제는 아주 간단하게 보이려고 노력하고 있습니다 : 현재 드래그되고있는 모양으로 위치를 변경하려고 시도하고 있습니다.KineticJS - 접촉시 모양 위치를 바꿀 수 있습니다.

아이디어는 다음과 같습니다.
• 캔버스에서 모양을 선택합니다. 그러면 mousedown 이벤트 리스너가 트리거되어 사용자가 선택한 모양의 현재 위치가 저장됩니다.
• 도형을 유지하는 동안 mouseover을 다른 도형으로 트리거하면 해당 도형의 이벤트가 트리거되어 현재 모양의 저장된 위치를 기반으로 해당 위치가 바뀝니다.

보드 설정 :

여기에 내가 그 작업을 가려고 작성한 관련 코드 단순히 보드를 설정하고 여기에 필요한 함수를 호출. 무대, gameBoard 또는 ctx로는 아무 것도하지 않습니다. (일부는 drawImage를 여러 캔버스에서 작동 시키려고했지만 지금은 버렸습니다).

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

보드 설정 기능 : 내가 보드를 설정하고 각각의 운동 원에게이 레이어 렌더링하는 데 필요한 특성을 제공에 대해 갈 곳 이다. 어쩌면 나는 여기에 명백한 것을 놓치고 있을까? 나는 모든 운동 원이 새 레이어에 객체를 추가하고, 그 층에게 내가 이벤트 핸들러를 호출 할 때 작업 할 모든 자신의 특성을주는 곳 이것은 :

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); 
    } 
    } 

보드 기능을 렌더링합니다. 스테이지에 레이어를 추가 한 후 여기에 이벤트 핸들러를 설정합니다. 너무 많은 레이어를 추가하여 어쩌면 이렇게 엉망이 되었습니까?

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); 
     } 
    } 
    } 

마우스 이벤트 핸들러 : 나는 내 주요 문제가 있다고 생각 어디 이입니다. orbs를 변경하기 위해 마우스를 움직이는 이벤트를 처리하는 방법, 아마도 내가 끔찍한 일을하고있는 것입니까?

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; 

내가 나를 위해 일을 할 수있는 솔루션을 찾는 희망에 내가 할 수있는대로 KineticJS 워드 프로세서 많은 StackOverflow의 답변을보고 시도했지만, 아무것도 지금까지 (제안을 포함하여 본 적이과 시도했습니다 나는이 질문을 썼을 때 올라왔다.) 도움이되는 것처럼 보였고, 내가 지금까지 해왔 던 방식이 아마 내가 원하는 것을 성취하는 최선의 방법과는 거리가 멀다는 것을 알고있다. 제안, 포인터, 답변 된 질문 또는 무엇이든지 올바른 방향으로 나를 가리켜 서 내가 이것을 잃어 버려서 제대로 작동하게 할 수는 없습니다.

이 정보가 도움이 될 경우, 보드 렌더링시의 모습을 시각적으로 보여줍니다.

enter image description here

동그라미는 모든 운동 원, 드래그되지 않는 한, 그리고 클릭하고 다른 하나를 드래그 (내가 갈거야 무엇을 목적으로 천체)하지만 이동해야 마우스가 가리키는 드래그 된 원의 원래 위치로 이동합니다.

감사합니다.

는 편집 :

나는 그 이후로 코드에 몇 가지 변경을했다. 첫째로, 나는 무대에 많은 레이어를 추가로 변경 한이 만드는 드래그 앤 드롭의 혜택을했다

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); 
    } 
} 

: 내가 대신 대신 구 객체에 리스너를 추가

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); 
} 

이전보다 훨씬 느린 속도로 진행되었지만 여전히 개체를 스왑 위치로 가져올 수는 없습니다.

필자의 주요 문제는 x, y 값을 변경해야한다는 것입니다. handleMouseMove의 순간, 나는 변경하려고했습니다 :

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

그러나, 아무리 내가로 변경 무엇, 그것은 아무런 영향을 미치지 않습니다. 그래서 제가 잘못된 물건/장소를 바꾸는 지 알면 도움이 될 것입니다. 예를 들어, 키네틱 서클을 내가 저장 한 배열에서 바꿔야한다고 생각할 수도 있습니다. 다시 한번 감사드립니다.

편집 2 :

이 나는 ​​거 같아요! 그러나, 나는 this.orbs을 가지고 window.orbs의 창에 설정하고, 내가 한을 테스트했다 :

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

을 그리고 이것은 x 위치 변경 원인이되었다. 그러나 그것을 창문에 넣는 것은 좋은 습관처럼 보이지 않습니까?

편집 3 :

가 나는 천체가 지금은 mouseover 화재를 계속하는 동안 다시 교환하고 같은 구를 때를 제외하고 지속적으로 교체되었다. 그러나 mouseup에 다시 바꿀 수 있습니다. 또한 다른 구체를 잡고있는 동안 mouseover 이벤트가 작동하도록 다중 레이어를 다시 설정해야했지만 성능이 약간 향상 된 것으로 보입니다.

내가 시도하고이 같은 마우스 보류 지속적으로 교환 할 수 있도록하는 방법을 알아내는 것, 이에 앞서 다음 나는이 달성하기 위해 쓴 코드입니다있어 :

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

마우스를 아래로 ID와 X와

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(); } } } 

마우스를 놓으면 그들은 모두 사용할 수 있도록, 현재, 모든 ORB가 다시 그려야하는 Y

에 의해 currentOrb 절약. 나는 이것을 수정하려고 계획하고 있기 때문에 orbs 만이 변화를 경험했습니다.

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

오브 교환 회 천체 통해 전달 작동 논리,하지만 그들은 같은 차례로 반복해서 전달합니다.

답변

0

"호버"는 언제 공식적으로 개최됩니까?

  • 마우스 이벤트의 위치가 두 번째 orb?

    // 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) 
    } 
    
  • 을 드래그 오브 번째 구를 교차 할 때 : 그렇다면, 모든 비 드래그 구 대 마우스를 테스트 명중? 예, 충돌이 아닌 모든 드래그 구 대 드래그 구를 테스트하는 경우 :

    // 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, 당신은 다른 모든 천체에 비해 구를 드래그하면, 다른 천체 것이다 드래그 천체의 모든 스택을 원래 위치 - - 너가 원하는게 그거야?

+0

내가 원했던 것은 (당분간은 적어도 구술 교체 작업을하고 싶습니다.) 이전이었습니다. 코드를 약간 변경했는데 드래그 앤 드롭이 훨씬 빨라졌지만 스와핑은 여전히 ​​작동하지 않습니다. 내 주요 문제는 orbs가 전혀 교체되지 않게하는 것이고, 어떤 x, y 내가 이것을 바꾸기 위해 바뀐다. 나는 내가 상기 한 것을 더 상세하게 OP와 주소를 변경할 것이다. 감사. – karivool

+0

K-JS를 사용한 이후로 꽤 오래되었습니다. 드래그하는 오브에서 onDragMove 이벤트가 있어야합니다. 그것은 당신에게 끌기 자세를줍니다. 내장 된'intersecting' 메서드를 사용하여 신경 쓰지 마라. 느리다. 대신, 내 대답에 설명 된 두 가지 방법 중 하나를 사용하십시오. K-JS를 사용하면 맴돌 았던 orbs가 저장된 x, y로 시각적으로 이동할 수 있도록 레이어를 다시 그려야합니다. orbs가 움직이지 않는다면 각 orb를 움직여서 layer.redraw와 같은 것을하고 있는지 확인하십시오. – markE

+1

고마워요. 마우스를 만지면 이제 orbs를 바꿔 놓을 수 있습니다. 'mousemove'가 여전히 발사되는 동안 당신이 되돌아 가려고 할 때 그렇게하지 않습니다. 그래서 나는 그것을 알아낼 것입니다. '.draw'는'mousemove'에 대해서는이 기능이 작동하지 않는 것처럼 보이지만,'mouseup'에 대해서는 작동합니다, 그러나 나는 그것을 알아 내려고 노력할 것입니다. 다시 한 번 감사드립니다! – karivool

관련 문제