HTML 5 Canvas - Painting
Making a web application that allows users to draw on a canvas requires several important steps: setting up your HTML document with a canvas context (a
canvas element with an id), setting up your script to target that canvas context and draw inside it and adding the required mouse event handlers for user interaction and associated logic. Once the event handlers are in place, it's then fairly simple to add any desired functionality. My goal of this article is to import image into canvas then to edit it with several painting tools and to end up saving as another format.We shall begin with a minimal HTML document:
<html lang="en">
<head meta charset="utf-8">
<title> Paint </title>
<style type="text/css">
<!-- #container { position: relative; }#imageView { border: 1px solid #000; } -- >
</style>
</head >
<body >
<div id="container" >
<canvas id="imageView" width="400" height="300">
<p> Unfortunately, your browser is currently unsupported by our web application. We are sorry for the inconvenience. Please use one of the supported browsers listed below, or draw the image you want using an offline tool. </p>
<p> Supported browsers: <a href="http://www.opera.com"> Opera </a >, <ahref="http://www.mozilla.com"> Firefox </a>, <a href="http://www.apple.com/safari"> Safari </a>,and <a href="http://www.konqueror.org"> Konqueror </a>. </p>
</canvas>
</div>
<script type="text/javascript"src="example1.js"> </script>
</body>
</html>
As you can see, we only have the bare bones of an HTML document here, with a canvas element contained inside.
If the browser does not support Canvas, then the fallback content will show. We will add more markup later on, but this is all we need for now.
The fallback content you provide should be as helpful as possible. You should not just say something like "this web application is unsupported by your browser" - that would be basically useless. Tell the user what he/she can do to get your application to work (eg use a different web browser), or provide alternative solutions, like a file upload input which allows the user to upload a painting created offline. Even better would be to detect Canvas support and then serve the application as is to browsers that support it, and the upload solution to browsers that don't, automatically. Naturally, the fallback content depends on the context in which the painting application appears.
I would like to open this window as pop up and load image into canvas from address in querystring.
Of course, way of loading image is gonna depends on what you preferred. Before getting into our work, I should make
simple function to retrieve value with key from query string.
location.querystring = (function() {
// The return is a collection of key/value pairs
var queryStringDictionary = {};
var querystring = unescape(location.search);
if (!querystring) {
return {};
}
// Remove the '?' via substring(1)
querystring = querystring.substring(1);
// '&' seperates key/value pairs
var pairs = querystring.split("&");
for (var i = 0; i < pairs.length; i++) {
var keyValuePair = pairs[i].split("=");
queryStringDictionary[keyValuePair[0]] = keyValuePair[1];
}
// Return the key/value pairs concatenated
queryStringDictionary.toString = function() {
if (queryStringDictionary.length == 0) {
return "";
}
var toString = "?";
for (var key in queryStringDictionary) {
toString += key + "=" + queryStringDictionary[key];
}
return toString;
};
return queryStringDictionary;
})();
For simple drawing work on canvas, we will try to paint something under the mouse by adding mouseevent handler to the canvas element. One thing we take care is each browser platform recognizes differently positon of mouse event.
function init () {
// ...
// Attach the mousemove event handler.
canvas.addEventListener('mousemove', ev_mousemove, false);
}
// The mousemove event handler.
var started = false;
function ev_mousemove (ev) {
var x, y;
// Get the mouse position relative to the canvas element.
if (ev.layerX || ev.layerX == 0) { // Firefox
x = ev.layerX;
y = ev.layerY;
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
x = ev.offsetX;
y = ev.offsetY;
}
// The event handler works like a drawing pencil which tracks the mouse
// movements. We start drawing a path made up of lines.
if (!started) {
context.beginPath();
context.moveTo(x, y);
started = true;
} else {
context.lineTo(x, y);
context.stroke();
}
}
we are just starting to see how dynamic and cool canvas can be. We use the event.layer / offset properties to determine the mouse position relative to the canvas element. That's all we need to start drawing.
Now we gotta take a step further close to painter. It's best to have a single event handler that only determines the coordinates relative to the canvas element. The implementation of each drawing tool should be split into independent functions. Lastly, drawing tools need to interact with the user for events like mousedown and mouseup as well, not just when moving the mouse (mousemove). Therefore, multiple event listeners will be added to the script.
function init () {
// The pencil tool instance.
tool = new tool_pencil();
// Attach the mousedown, mousemove and mouseup event listeners.
canvas.addEventListener('mousedown', ev_canvas, false);
canvas.addEventListener('mousemove', ev_canvas, false);
canvas.addEventListener('mouseup', ev_canvas, false);
}
function tool_pencil () {
tool = new tool_pencil();
var tool = this;
this.started = false;
this.mousedown = function (ev) {
context.beginPath();
context.moveTo(ev._x, ev._y);
tool.started = true;
};
this.mousemove = function (ev) {
if (tool.started) {
context.lineTo(ev._x, ev._y);
context.stroke();
}
}
}
function ev_canvas (ev) {
if (ev.layerX || ev.layerX == 0) { // Firefox
ev._x = ev.layerX;
ev._y = ev.layerY;
} else if (ev.offsetX || ev.offsetX == 0) { // Opera
ev._y = ev.offsetY;
ev._x = ev.offsetX;
}
var func = tool[ev.type];
if (func) {
func(ev);
}
}
Now handling events for canvas goes detailed to three them (
mousedown, mousemove and mouseup). The ev_canvas() function adds two new properties to the DOM event object, _x and _y, which simply hold the mouse coordinates relative to the canvas. This event handler acts like a "proxy" by calling other functions, depending on the event type. If the event is mousemove, then tool.mousemove() is called, and so on. The event handlers associated with the active tool can use the properties added to the DOM event object.All we have done is just simple drawing painter on HTML5 canvas. I hope you could reach to the point where all sides of applicatoin look professional and work technically smooth. At last I added a few tools enabling several works.
<ul>
<li>
<input id="btnLine" type="button" value="_width" onclick="tools_click(this)" />
</li>
<li>
<input id="btnColor" type="button" value="_color" onclick="tools_click(this)"/>
</li>
<li>
<input id="btnColor" type="button" value="_save" onclick="tools_click(this)" />
</li>
</ul>
function tool_pencil () {
tool = new tool_pencil();
var tool = this;
this.started = false;
this.mousedown = function (ev) {
context.beginPath();
context.moveTo(ev._x, ev._y);
tool.started = true;
};
this.mousemove = function (ev) {
if (tool.started) {
context.lineTo(ev._x, ev._y);
context.stroke();
}
}
this.mouseup = function (ev) {
if (tool.started) {
tool.mousemove(ev);
tool.started = false;
}
};
this._color = function (color) {
this.color = color;
ctx.strokeStyle = color;
};
this._width = function (width) {
this.width = width;
ctx.lineWidth = width;
};
this._save = function () {
var strData = ctx.canvas.toDataURL("image/jpg");
makeImageObject(strData);
};
};
Comments
Post a Comment