2014-04-28 4 views
0

드래그 가능한 오브젝트를 만들기 위해이 site의 tuturial을 따라갔습니다. 그 자체가 code입니다. 내 목표는 드래그 가능한 항목 (결정을 내리는 데 사용 된 항목)과 3 개의 드래그 할 수없는 모양 (선택 항목)으로 게임을 만드는 것입니다.다른 캔버스를 드래그하면 html 캔버스의 정적 오브젝트가 사라집니다.

3 개의 드래그 할 수없는 객체를 만드는 방법을 모르겠습니다. 나는 드래그 할 수 없도록 개의 분리 된 기능 (예 : fillSquare)으로 세 개의 사각형을 만들려고 시도했지만, 내 게임의 목적을 무색하게하는 드래그 가능한 항목을 움직이면 사라집니다. 캔버스 상태를 사용하여 화면에 항목을 유지해야한다고 확신하지만 계속 진행하는 방법에 대해 혼란스러워합니다. 아래 코드는 위에 게시 된 링크의 내용을 간략하게 나타낸 것입니다. 어떤 도움을 주셔서 감사합니다. 당신이 addShape()을 사용 (당신이 인용 코드의 끝에서 init() 기능의 예 참조) 할 필요가 같은

function Shape(x, y, w, h, fill) { 
    this.x = x || 0; 
    this.y = y || 0; 
    this.w = w || 1; 
    this.h = h || 1; 
    this.fill = fill || '#AAAAAA'; 
} 

// Draws this shape to a given context 
Shape.prototype.draw = function (ctx) { 
    ctx.fillStyle = this.fill; 
    ctx.fillRect(this.x, this.y, this.w, this.h); 
} 

// Determine if a point is inside the shape's bounds 
Shape.prototype.contains = function (mx, my) { 
    // All we have to do is make sure the Mouse X,Y fall in the area between 
    // the shape's X and (X + Height) and its Y and (Y + Height) 
    return (this.x <= mx) && (this.x + this.w >= mx) && (this.y <= my) && (this.y + this.h >= my); 
} 

function CanvasState(canvas) { 
    // **** First some setup! **** 
    this.canvas = canvas; 
    this.width = canvas.width; 
    this.height = canvas.height; 
    this.ctx = canvas.getContext('2d'); 

    // fixes mouse co-ordinate problems when there's a border or padding. 
    var stylePaddingLeft, stylePaddingTop, styleBorderLeft, styleBorderTop; 
    if (document.defaultView && document.defaultView.getComputedStyle) { 
     this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0; 
     this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0; 
     this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0; 
     this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0; 
    } 

    //helps protect mouse coordinates for pages with fixed-position bars 
    var html = document.body.parentNode; 
    this.htmlTop = html.offsetTop; 
    this.htmlLeft = html.offsetLeft; 

    // **** Keep track of state! **** 
    this.valid = false; // when set to false, the canvas will redraw everything 
    this.shapes = []; // the collection of things to be drawn 
    this.dragging = false; // Keep track of when we are dragging 

    // the current selected object. In the future we could turn this into an array for multiple selection 
    this.selection = null; 
    this.dragoffx = 0; // See mousedown and mousemove events for explanation 
    this.dragoffy = 0; 

    // **** Then events! **** 
    //saves a reference to CanvasState so we can use it in events 
    var myState = this; 

    // Up, down, and move are for dragging 
    canvas.addEventListener('mousedown', function (e) { 
     var mouse = myState.getMouse(e); 
     var mx = mouse.x; 
     var my = mouse.y; 
     var shapes = myState.shapes; 
     var l = shapes.length; 
     for (var i = l - 1; i >= 0; i--) { 
      if (shapes[i].contains(mx, my)) { 
       var mySel = shapes[i]; 
       // Keep track of where in the object we clicked 
       // so we can move it smoothly (see mousemove) 
       myState.dragoffx = mx - mySel.x; 
       myState.dragoffy = my - mySel.y; 
       myState.dragging = true; 
       myState.selection = mySel; 
       myState.valid = false; 
       return; 
      } 
     } 
     // If there was an object selected, we deselect it 
     if (myState.selection) { 
      myState.selection = null; 
      myState.valid = false; // Need to clear the old selection border 
     } 
    }, true); 
    canvas.addEventListener('mousemove', function (e) { 
     if (myState.dragging) { 
      var mouse = myState.getMouse(e); 
      // We don't want to drag the object by its top-left corner, we want to drag it 
      // from where we clicked. Thats why we saved the offset and use it here 
      myState.selection.x = mouse.x - myState.dragoffx; 
      myState.selection.y = mouse.y - myState.dragoffy; 
      myState.valid = false; // Something's dragging so we must redraw 
     } 
    }, true); 
    canvas.addEventListener('mouseup', function (e) { 
     myState.dragging = false; 
    }, true); 

    // **** Options! **** 
    this.selectionColor = '#CC0000'; 
    this.selectionWidth = 2; 
    this.interval = 30; 
    setInterval(function() { 
     myState.draw(); 
    }, myState.interval); 
} 

CanvasState.prototype.addShape = function (shape) { 
    this.shapes.push(shape); 
    this.valid = false; 
} 

CanvasState.prototype.clear = function() { 
    this.ctx.clearRect(0, 0, this.width, this.height); 
} 

// While draw is called as often as the INTERVAL variable demands, 
// It only ever does something if the canvas gets invalidated by our code 
CanvasState.prototype.draw = function() { 
    // if our state is invalid, redraw and validate! 
    if (!this.valid) { 
     var ctx = this.ctx; 
     var shapes = this.shapes; 
     this.clear(); 

     // draw all shapes 
     var l = shapes.length; 
     for (var i = 0; i < l; i++) { 
      var shape = shapes[i]; 
      // We can skip the drawing of elements that have moved off the screen: 
      if (shape.x > this.width || shape.y > this.height || shape.x + shape.w < 0 || shape.y + shape.h < 0) continue; 
      shapes[i].draw(ctx); 
     } 

     // draw selection 
     if (this.selection != null) { 
      ctx.strokeStyle = this.selectionColor; 
      ctx.lineWidth = this.selectionWidth; 
      var mySel = this.selection; 
      ctx.strokeRect(mySel.x, mySel.y, mySel.w, mySel.h); 
     } 

     this.valid = true; 
    } 
} 


// Creates an object with x and y defined, set to the mouse position relative to the state's canvas 
CanvasState.prototype.getMouse = function (e) { 
    var element = this.canvas, 
     offsetX = 0, 
     offsetY = 0, 
     mx, my; 

    // Compute the total offset 
    if (element.offsetParent !== undefined) { 
     do { 
      offsetX += element.offsetLeft; 
      offsetY += element.offsetTop; 
     } while ((element = element.offsetParent)); 
    } 

    // Add padding and border style widths to offset 
    // Also add the <html> offsets in case there's a position:fixed bar 
    offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft; 
    offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop; 

    mx = e.pageX - offsetX; 
    my = e.pageY - offsetY; 

    // We return a simple javascript object (a hash) with x and y defined 
    return { 
     x: mx, 
     y: my 
    }; 
} 

function init() { 
    var s = new CanvasState(document.getElementById('canvas')); 
    s.addShape(new Shape(40, 40, 50, 50)); // The default is gray 
} 

답변

0

보인다.

왜 아닙니다 fillRect()? draw()가 호출 될 때마다 clear()을 호출 한 다음 addShape()을 통해 추가 된 모양을 그립니다. 환언

은 캔버스 각 프레임이 그려져 전에 * 지워지고를 되하고 addShape() ... 경유 첨가 형상은 그려야이다. 다시 강조하자면,이 그림은 모두 모든 프레임이 발생합니다. 이전 프레임의 내용은 남아 있지 않습니다!

각 모양에 isDraggable 속성을 추가하는 것이 좋습니다.이 모양은 마우스 이벤트 핸들러에서 테스트하고 조기에 종료 할 수 있습니다. 먼저 addShape() 함수에 매개 변수로 추가 한 다음 생성 된 모양의 속성에 저장합니다.