Skip to content

Instantly share code, notes, and snippets.

@shinaisan
Created August 6, 2013 10:20
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save shinaisan/6163379 to your computer and use it in GitHub Desktop.
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.
<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>
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