2017-10-26 8 views
0

キャンバスボタンをクリックするだけで

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

 
Shape.prototype.draw = function(ctx) { 
 
    ctx.fillStyle = this.fill; 
 
    ctx.fillRect(this.x, this.y, this.w, this.h); 
 
} 
 

 
Shape.prototype.contains = function(mx, my) { 
 
    return (this.x <= mx) && (this.x + this.w >= mx) && 
 
      (this.y <= my) && (this.y + this.h >= my); 
 
} 
 

 
function CanvasState(canvas) { 
 
    
 
    this.canvas = canvas; 
 
    this.width = canvas.width; 
 
    this.height = canvas.height; 
 
    this.ctx = canvas.getContext('2d'); 
 
    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; 
 
    } 
 
    var html = document.body.parentNode; 
 
    this.htmlTop = html.offsetTop; 
 
    this.htmlLeft = html.offsetLeft; 
 

 
    
 
    this.valid = false; 
 
    this.shapes = []; 
 
    this.dragging = false; 
 
    this.selection = null; 
 
    this.dragoffx = 0; 
 
    this.dragoffy = 0; 
 
    
 
    var myState = this; 
 
    
 
    canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false); 
 
    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]; 
 
     myState.dragoffx = mx - mySel.x; 
 
     myState.dragoffy = my - mySel.y; 
 
     myState.dragging = true; 
 
     myState.selection = mySel; 
 
     myState.valid = false; 
 
     return; 
 
     } 
 
    } 
 
    if (myState.selection) { 
 
     myState.selection = null; 
 
     myState.valid = false; 
 
    } 
 
    }, true); 
 
    canvas.addEventListener('mousemove', function(e) { 
 
    if (myState.dragging){ 
 
     var mouse = myState.getMouse(e); 
 
     myState.selection.x = mouse.x - myState.dragoffx; 
 
     myState.selection.y = mouse.y - myState.dragoffy; 
 
     myState.valid = false; 
 
    } 
 
    }, true); 
 
    canvas.addEventListener('mouseup', function(e) { 
 
    myState.dragging = false; 
 
    }, true); 
 
    canvas.addEventListener('dblclick', function(e) { 
 
    var mouse = myState.getMouse(e); 
 
    myState.addShape(new Shape(mouse.x - 10, mouse.y - 10, 20, 20, 'rgba(0,255,0,.6)')); 
 
    }, true); 
 
    
 
    
 
    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); 
 
} 
 

 
CanvasState.prototype.draw = function() { 
 
    if (!this.valid) { 
 
    var ctx = this.ctx; 
 
    var shapes = this.shapes; 
 
    this.clear(); 
 
    
 
    var l = shapes.length; 
 
    for (var i = 0; i < l; i++) { 
 
     var shape = shapes[i]; 
 
     if (shape.x > this.width || shape.y > this.height || 
 
      shape.x + shape.w < 0 || shape.y + shape.h < 0) continue; 
 
     shapes[i].draw(ctx); 
 
    } 
 
    
 
    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; 
 
    } 
 
} 
 

 

 
CanvasState.prototype.getMouse = function(e) { 
 
    var element = this.canvas, offsetX = 0, offsetY = 0, mx, my; 
 
    
 
    if (element.offsetParent !== undefined) { 
 
    do { 
 
     offsetX += element.offsetLeft; 
 
     offsetY += element.offsetTop; 
 
    } while ((element = element.offsetParent)); 
 
    } 
 

 
    offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft; 
 
    offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop; 
 

 
    mx = e.pageX - offsetX; 
 
    my = e.pageY - offsetY; 
 
    
 
    return {x: mx, y: my}; 
 
} 
 

 

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

 
}
<canvas id="canvas1" width="200" height="200" style="border:1px solid #000000;"> 
 
    This text is displayed if your browser does not support HTML5 Canvas. 
 
    </canvas> 
 
    
 
    <button onclick= "init()">click </button>

内のボタンクリックで動的に四角形を追加し、私はドラッグすることとcanvas要素制限区域内でドロップすることができ長方形の要素を作成しています。 しかし、ボタンをクリックするたびに新しい矩形要素を動的に作成することができます。このボタンは、キャンバスの境界内でさらにドラッグアンドドロップできます。 そして、前の矩形要素は失われません。

答えて

1

クリックするたびに、init()を呼び出していました。CanvasStateをリセットしました。

私はaddShapeという別の機能を作ったばかりです。ちょうどinitと呼ばれています。

私はまた、CanvasStateへの参照を保持しています。だから、s.addShapeを行うことができました。変更はごくわずかでした。

この情報がお役に立てば幸いです。..

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

 
Shape.prototype.draw = function(ctx) { 
 
    ctx.fillStyle = this.fill; 
 
    ctx.fillRect(this.x, this.y, this.w, this.h); 
 
} 
 

 
Shape.prototype.contains = function(mx, my) { 
 
    return (this.x <= mx) && (this.x + this.w >= mx) && 
 
      (this.y <= my) && (this.y + this.h >= my); 
 
} 
 

 
function CanvasState(canvas) { 
 
    
 
    this.canvas = canvas; 
 
    this.width = canvas.width; 
 
    this.height = canvas.height; 
 
    this.ctx = canvas.getContext('2d'); 
 
    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; 
 
    } 
 
    var html = document.body.parentNode; 
 
    this.htmlTop = html.offsetTop; 
 
    this.htmlLeft = html.offsetLeft; 
 

 
    
 
    this.valid = false; 
 
    this.shapes = []; 
 
    this.dragging = false; 
 
    this.selection = null; 
 
    this.dragoffx = 0; 
 
    this.dragoffy = 0; 
 
    
 
    var myState = this; 
 
    
 
    canvas.addEventListener('selectstart', function(e) { e.preventDefault(); return false; }, false); 
 
    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]; 
 
     myState.dragoffx = mx - mySel.x; 
 
     myState.dragoffy = my - mySel.y; 
 
     myState.dragging = true; 
 
     myState.selection = mySel; 
 
     myState.valid = false; 
 
     return; 
 
     } 
 
    } 
 
    if (myState.selection) { 
 
     myState.selection = null; 
 
     myState.valid = false; 
 
    } 
 
    }, true); 
 
    canvas.addEventListener('mousemove', function(e) { 
 
    if (myState.dragging){ 
 
     var mouse = myState.getMouse(e); 
 
     myState.selection.x = mouse.x - myState.dragoffx; 
 
     myState.selection.y = mouse.y - myState.dragoffy; 
 
     myState.valid = false; 
 
    } 
 
    }, true); 
 
    canvas.addEventListener('mouseup', function(e) { 
 
    myState.dragging = false; 
 
    }, true); 
 
    canvas.addEventListener('dblclick', function(e) { 
 
    var mouse = myState.getMouse(e); 
 
    myState.addShape(new Shape(mouse.x - 10, mouse.y - 10, 20, 20, 'rgba(0,255,0,.6)')); 
 
    }, true); 
 
    
 
    
 
    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); 
 
} 
 

 
CanvasState.prototype.draw = function() { 
 
    if (!this.valid) { 
 
    var ctx = this.ctx; 
 
    var shapes = this.shapes; 
 
    this.clear(); 
 
    
 
    var l = shapes.length; 
 
    for (var i = 0; i < l; i++) { 
 
     var shape = shapes[i]; 
 
     if (shape.x > this.width || shape.y > this.height || 
 
      shape.x + shape.w < 0 || shape.y + shape.h < 0) continue; 
 
     shapes[i].draw(ctx); 
 
    } 
 
    
 
    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; 
 
    } 
 
} 
 

 

 
CanvasState.prototype.getMouse = function(e) { 
 
    var element = this.canvas, offsetX = 0, offsetY = 0, mx, my; 
 
    
 
    if (element.offsetParent !== undefined) { 
 
    do { 
 
     offsetX += element.offsetLeft; 
 
     offsetY += element.offsetTop; 
 
    } while ((element = element.offsetParent)); 
 
    } 
 

 
    offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft; 
 
    offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop; 
 

 
    mx = e.pageX - offsetX; 
 
    my = e.pageY - offsetY; 
 
    
 
    return {x: mx, y: my}; 
 
} 
 

 
var s; 
 

 
function init() { 
 
    s = new CanvasState(document.getElementById('canvas1')); 
 
} 
 

 
function addShape() { 
 
    s.addShape(new Shape(40,40,50,50)); // The default is gray 
 
} 
 

 
init();
<canvas id="canvas1" width="400" height="300" style="border:1px solid #000000;"> 
 
    This text is displayed if your browser does not support HTML5 Canvas. 
 
    </canvas> 
 
    
 
    <button onclick= "addShape()">click </button>

1

最初からこうすることで多くの作業になります。 fabric.jsのような図書館を利用することをお勧めします。ここにはdemo pageがあります。

関連する問題