This might be a somewhat stupid question, but...is it possible to fill an HTML canvas element, pixel by pixel, depending on where a user clicks?
I want to have a blank canvas, that users will click one pixel at a time, which will fill a color, and enter that user/pixel into a database.
How would this be done? How can I know what pixel, what user clicked?
Thanks
Yes, you can set each canvas pixel individually based on mouse-clicks.
Here's how you set an individual pixel using context.getImageData and context.putImageData:
function setPixel(x, y, red, green, blue) {
pixPos=( (~~x) + (~~y)) * 4;
var pxData = ctx.getImageData(x,y,1,1);
pxData.data[0]=red;
pxData.data[1]=green;
pxData.data[2]=blue;
pxData.data[3]=255;
ctx.putImageData(pxData,x,y);
}
And you get the X/Y position of the mouse click by adding an event listener like this:
// get the position of the canvas relative to the web page
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
// tell the browser to send you mouse down events
// Here I use jquery -- be sure to add jquery or just do addEventListener instead
$("#canvas").mousedown(function(e){handleMouseDown(e);});
// handle the mousedown events that the browser sends you
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
setPixel(mouseX,mouseY,red,green,blue);
}
Here's code and a fiddle: http://jsfiddle.net/m1erickson/wtStf/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; }
canvas{border:1px solid red;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var canvasOffset=$("#canvas").offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var red=255;
var green=0;
var blue=0;
function setPixel(x, y, red, green, blue) {
pixPos=( (~~x) + (~~y)) * 4;
var pxData = ctx.getImageData(x,y,1,1);
pxData.data[0]=red;
pxData.data[1]=green;
pxData.data[2]=blue;
pxData.data[3]=255;
ctx.putImageData(pxData,x,y);
}
function handleMouseDown(e){
mouseX=parseInt(e.clientX-offsetX);
mouseY=parseInt(e.clientY-offsetY);
// Put your mousedown stuff here
setPixel(mouseX,mouseY,red,green,blue);
}
$("#canvas").mousedown(function(e){handleMouseDown(e);});
}); // end $(function(){});
</script>
</head>
<body>
<canvas id="canvas" width=300 height=300></canvas>
</body>
</html>
[Edited for additional question]
You can easily modify the code to set blocks of pixels like this:
var blockWidth=25;
var blockHeight=25;
function setPixel(x, y, red, green, blue) {
pixPos=( (~~x) + (~~y)) * 4;
var pxData = ctx.getImageData(x,y,blockWidth,blockHeight);
for(var n=0;n<blockWidth*blockHeight;n++){
pxData.data[n*4+0]=red;
pxData.data[n*4+1]=green;
pxData.data[n*4+2]=blue;
pxData.data[n*4+3]=255;
}
ctx.putImageData(pxData,x,y);
}