Created
August 6, 2013 10:20
-
-
Save shinaisan/6163379 to your computer and use it in GitHub Desktop.
A dead simple HTML5 canvas drawing example with a drawing tool selection based on Twitter Bootstrap.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<head> | |
<link rel="stylesheet" href="http://getbootstrap.com/2.3.2/assets/css/bootstrap.css"></link> | |
<!-- jquery.js must be loaded before bootstrap.js. --> | |
<script type="text/javascript" src="http://getbootstrap.com/2.3.2/assets/js/jquery.js"></script> | |
<script type="text/javascript" src="http://getbootstrap.com/2.3.2/assets/js/bootstrap.js"></script> | |
<script type="text/javascript" src="paint.js"></script> | |
<style type="text/css"> | |
body { | |
padding-top: 60px; | |
} | |
canvas { | |
position: absolute; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="navbar navbar-inverse navbar-fixed-top"> | |
<div class="navbar-inner"> | |
<div class="container"> | |
<div class="nav-collapse collapse"> | |
<ul class="nav"> | |
<li><a href="#">Home</a></li> | |
<li><a href="#">About</a></li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="container"> | |
<div class="span1"> | |
<div id="tools-area" class="btn-group btn-group-vertical" data-toggle="buttons-radio"> | |
<button title="move" data-placement="right" type="button" class="btn active" value="move"> | |
<i class="icon-move"></i> | |
</button> | |
<button title="pencil" data-placement="right" type="button" class="btn" value="pencil"> | |
<i class="icon-pencil"></i> | |
</button> | |
<button title="rectangle" data-placement="right" type="button" class="btn" value="rect"> | |
<i class="icon-stop"></i> | |
</button> | |
</div> | |
</div> | |
<div class="span10"> | |
<div id="canvas-area"> | |
<canvas id="background-canvas"><div>canvas is not supported.</div></canvas> | |
<canvas id="user-canvas"></canvas> | |
<canvas id="foreground-canvas"></canvas> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var configurations = { | |
canvasWidth: 500, | |
canvasHeight: 500, | |
color: "#48c" | |
}; | |
var tools = { | |
selection: function() { | |
var v = $("#tools-area .active").val(); | |
return tools[v]; | |
}, | |
move: (function() { | |
var imageData = null; | |
return { | |
onDrag: function(from, to) { | |
var w = canvases.user.canvas.width; | |
var h = canvases.user.canvas.height; | |
if (imageData == null) { | |
imageData = canvases.user.getImageData(0, 0, w, h); | |
} | |
var dx = to.x - from.x; | |
var dy = to.y - from.y; | |
canvases.user.clearRect(0, 0, w, h); | |
canvases.user.putImageData(imageData, dx, dy); | |
}, | |
onDragEnd: function(from, to) { | |
imageData = null; | |
} | |
}; | |
})(), | |
pencil: (function() { | |
var prevPos = null; | |
return { | |
onDrag: function(from, to) { | |
var c = canvases.user; | |
c.save(); | |
c.fillStyle = configurations.color; | |
c.strokeStyle = configurations.color; | |
c.lineWidth = 1; | |
if (prevPos != null) { | |
c.beginPath(); | |
c.moveTo(prevPos.x, prevPos.y); | |
c.lineTo(to.x, to.y); | |
c.stroke(); | |
} else { | |
c.fillRect(to.x, to.y, 1, 1); | |
} | |
c.restore(); | |
prevPos = to; | |
}, | |
onDragEnd: function(from, to) { | |
prevPos = null; | |
} | |
}; | |
})(), | |
rect: { | |
onDrag: function(from, to) { | |
var c = canvases.foreground; | |
c.clearRect(0, 0, c.canvas.width, c.canvas.height); | |
c.save(); | |
c.fillStyle = configurations.color; | |
c.fillRect(from.x, from.y, to.x - from.x, to.y - from.y); | |
c.restore(); | |
}, | |
onDragEnd: function(from, to) { | |
var c = canvases.foreground; | |
c.clearRect(0, 0, c.canvas.width, c.canvas.height); | |
var c = canvases.user; | |
c.save(); | |
c.fillStyle = configurations.color; | |
c.fillRect(from.x, from.y, to.x - from.x, to.y - from.y); | |
c.restore(); | |
} | |
} | |
}; | |
var control = (function() { | |
var dragFrom = null; | |
return { | |
onmousedown: function(e) { | |
dragFrom = canvases.getOffset(e); | |
}, | |
onmousemove: function(e) { | |
var pos = canvases.getOffset(e); | |
var from = dragFrom; | |
var tool = tools.selection(); | |
from && tool && tool.onDrag && tool.onDrag(from, pos); | |
}, | |
onmouseup: function(e) { | |
var pos = canvases.getOffset(e); | |
var from = dragFrom; | |
var tool = tools.selection(); | |
from && tool && tool.onDragEnd && tool.onDragEnd(from, pos); | |
dragFrom = null; | |
} | |
}; | |
})(); | |
var canvases = {}; | |
var refreshBackground = function(canvas) { | |
var gap = 10; | |
var fill = false; | |
var w = configurations.canvasWidth; | |
var h = configurations.canvasHeight; | |
for (var i = 0; i < w; i = i + gap) { | |
fill = (i % (gap * 2) == 0); | |
for (var j = 0; j < h; j = j + gap) { | |
if (fill) { | |
canvas.fillStyle = '#eeeeee'; | |
canvas.fillRect(i, j, gap, gap); | |
} | |
fill = !fill; | |
} | |
} | |
}; | |
$(document).ready(function() { | |
// Tooltips | |
$("#tools-area .btn").tooltip(); | |
// Canvases | |
canvases = { | |
background: $("#background-canvas")[0].getContext("2d"), | |
user: $("#user-canvas")[0].getContext("2d"), | |
foreground: $("#foreground-canvas")[0].getContext("2d"), | |
getOffset: function(event) { | |
return { | |
x: event.pageX - $("#foreground-canvas").offset().left, | |
y: event.pageY - $("#foreground-canvas").offset().top | |
}; | |
}, | |
resizeAll: function() { | |
for (var key in canvases) { | |
var c = canvases[key]; | |
if (c.canvas != undefined) { | |
c.canvas.width = configurations.canvasWidth; | |
c.canvas.height = configurations.canvasHeight; | |
} | |
} | |
} | |
}; | |
canvases.resizeAll(); | |
refreshBackground(canvases.background); | |
// Mouse events | |
$("#foreground-canvas").bind("mousedown", control.onmousedown) | |
.bind("mousemove", control.onmousemove) | |
.bind("mouseup", control.onmouseup); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment