Introduction
HTML5 provides powerful canvas elements, using canvas and combining JavaScript to achieve some of the most powerful features. This paper introduces the implementation of drawing tools based on HTML5 Canvas. Talk less, first look at the finished product:
The app is designed to follow WYSIWYG, what's The What do you see are principles, and it has the following features:
1. Free curve, straight line, rectangle frame and text can be drawn;
2. You can define the color and width of line segments and rectangles as needed;
3. You can need the font size, color, font;
4. Support undo, redo operation;
5. Support Eraser function;
6. Support local image saving function.
Source Download readers can go to my
GitHub jpainter project to download, or use the Git tool directly:
https://github.com/LuanLouis/jPainter.git
Development experience Sharing
The realization of the above functions, the difficulty is not many, it is worth mentioning the following points:
1. How the mouse press and move event should be implemented
2. How to achieve WYSIWYG design
3. The implementation principle of the undo redo
4. Save artboard information as a picture
how the mouse presses and moves events should be implemented
If we want to draw a free curve in the artboard, we need to capture the path that was dragged while the mouse was pressed and dragged. So how do we capture such an event? Readers familiar with JavaScript events should know that the handle to the mouse move event is onmousemove, and some readers may think that you can bind the event handler directly for OnMouseMove. Judging by the button property of the event object, which key of the mouse is clicked, is it OK? The code is as follows:
$ (function () { $ (document). MouseMove (function (e) {console.log (e.button+ " " +e.which);})});
In fact, when the above code runs, when we click on the page, either the mouse button is the output of the following information:
As you can see from the output, the results are not the same as we expected. What is this for?
The reason: The JavaScript event mechanism is this, when the user triggers an event, the JavaScript host-browser encapsulates the event into an events object, and then assigns a value to the event property based on the type of events. The corresponding event handler is then invoked according to the type of event, based on what type of events. For example, if we press the right mouse button on the interface, then the browser will first create an event object, then assign a value to the event property, and the corresponding button will be set to 2, which to 3 for right-click, and then JavaScript This event object is passed as an argument to the appropriate event handler, which executes the event handler function. That is, the button property of the event (and the which attribute after jquery encapsulation) is only meaningful if the click, mousedown,mousup corresponding event handler function.
So how can we tell if the mouse button is pressed while the mouse is moving?
Workaround: The mouse press and release is a process, we can set a flag, when the mouse is pressed to true, the mouse is released to false, and then in the mouse movement of the event processing function to determine the flag, and then can distinguish whether the mouse is pressed.
Suppose we need to capture the corresponding mouse event on the <body> element, the following is the binding of the event handler function using jquery:
OnMouseMove Event $ ("body"). MouseMove (function (e) { if (flag) { //mouse pressed }})//onmousedown event $ (" Body "). OnMouseDown (function (e) { flag = true; Event handling})//onmouseup event $ ("Body"). MouseUp (function (e) { flag = false; Event handling})
Of course, if the reader has other implementations, please do not hesitate to enlighten, learn together!
How to achieve the WYSIWYG design
When using canvas drawing, its drawing is controlled by JavaScript, for example, I want to draw a rectangle and should use code similar to the following:
var C=document.getelementbyid ("MyCanvas"), Var cxt=c.getcontext ("2d"), cxt.fillstyle= "#FF0000"; Cxt.fillrect ( 0,0,150,75);
but for an interactive user interface, if you want to create a rectangle, you should drag it over the artboard with your mouse, and then you can see the size, borders, colors, and so on, of the rectangle I'm going to draw at any time. How to let the user see the dynamic effect? Of course, using canvas is definitely not possible, here I think of a method, is to
use the <DIV> element to simulate the rectangle we need to draw, when the user in the process of dragging the mouse, using the div display rectangle information, once the user releases the mouse, then, the Div hidden , use JavaScript to draw in the corresponding shape, depending on the trajectory of the mouse and the rectangle configuration.
Similarly, drawing straight lines and adding text is also a logic disguised through HTML:
When drawing a straight line, when the user drags on the artboard and presses the mouse, it dynamically shows a line using HTML camouflage, which can change with the user's mouse movement, and when the user releases the mouse, the HTML element corresponding to the simulated line is hidden, and the javavscript is called to draw the real straight line;
When adding text, the <textarea> element used here is simulated text input box, when the user adds text on the artboard, you can drag the mouse to set the size of the input box, and then enter the text, once the input box loses focus, hide this <textarea> element, Then use JavaScript to draw the appropriate text
the implementation principle of undo redo
before you introduce the implementation of undo redo, you should first talk about the canvas's Todataurl () method. The Todataurl () method converts the content drawn on the canvas into a formatted PNG image and encodes the picture through Base64, converting it into a form such as:data:image/png;base64,ivborw0kgg ....... String that is used to represent the picture data. (PS: The confused reader can find out about the BASE64 storage of HTML image , this knowledge point is still very important)
The principle of undo redo is actually very simple, that is, when every painting is performed, the contents of the artboard are converted into base64 encoded strings, stored in the cache array, and then emptied when the undo is needed, and the last edited picture in the cache array is drawn onto the artboard. The relevant implementation details are shown in the following code:
Undo Redo Var history =new Array (); var cstep =-1; /** * Put current canvas to cache * /function Historypush () { cstep++; if (Cstep < history.length) { history.length = cstep; } History.push ($ ("#myCanvas"). Get (0). Todataurl ()); /** * Function:undo * * * function undo () { if (cstep >= 0) { cstep--; var tempimage = new Image (); TEMPIMAGE.SRC = History[cstep]; Tempimage.onload = function () {ctx.drawimage (tempimage, 0, 0);}; } } /** * Function: redo */ function Redo () { if (cstep
to save artboard information as a picture
The code is as follows:
/** * Save canvas content as Image */ function saveitasimage () { var image = $ ("#myCanvas"). Get (0). Todataurl ("Image/png"). Replace ("Image/png", "Image/octet-stream"); Locally save window.location.href=image; }
Source Download readers can go to my
GitHub jpainter project to download, or use the Git tool directly:
https://github.com/LuanLouis/jPainter.git
--------------------------------------------------------------------------------------------------------------- --------------------------
This article originates from http://blog.csdn.net/luanlouis/, if need reprint, please indicate source, thank you!