드래그 가능한 오브젝트를 만들기 위해이 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
}