HTML5 canvas – Custom brush (BezierCurveBrush)

Tutorials

I hope that you still remember when we did our first Paint program with HTML5. Today I have decided to enhance it with adding new additional brush to it. This brush will use ‘bezierCurveTo’ function. In result we will have interesting effect, just check out it!

Here are our demo and downloadable package:

Live Demo
download in package

Ok, download the source files and lets start coding !


Step 1. HTML

Here are html code of our enhanced Paint:

index.html

01 <!DOCTYPE html>
02 <html lang="en" >
03     <head>
04         <meta charset="utf-8" />
05         <title>HTML5 canvas - Custom brush (BezierCurveBrush) for your paing program | Script Tutorials</title>
06         <link href="css/main.css" rel="stylesheet" type="text/css" />
07         <script src="js/jquery-1.5.2.min.js"></script>
08         <script src="js/script.js"></script>
09     </head>
10     <body>
11         <header>
12             <h2>HTML5 canvas - Custom brush (BezierCurveBrush) for your paing program</h2>
13             <a href="https://www.script-tutorials.com/html5-canvas-custom-brush1/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a>
14         </header>
15         <div class="container">
16             <div class="column1">
17                 <canvas id="color" width="500" height="128"></canvas>
18             </div>
19             <div class="column2">
20                 <div>Preview:</div>
21                 <div id="preview"></div>
22                 <div id="pick"></div>
23             </div>
24             <div style="clear:both;"></div>
25         </div>
26         <canvas id="panel" width="1000" height="600"></canvas>
27     </body>
28 </html>

Step 2. CSS

Here are used CSS styles

css/main.css

01 /* page layout styles */
02 *{
03     margin:0;
04     padding:0;
05 }
06 body {
07     background-color:#eee;
08     color:#fff;
09     font:14px/1.3 Arial,sans-serif;
10 }
11 header {
12     background-color:#212121;
13     box-shadow: 0 -1px 2px #111111;
14     display:block;
15     height:70px;
16     position:relative;
17     width:100%;
18     z-index:100;
19 }
20 header h2{
21     font-size:22px;
22     font-weight:normal;
23     left:50%;
24     margin-left:-400px;
25     padding:22px 0;
26     position:absolute;
27     width:540px;
28 }
29 header a.stuts,a.stuts:visited{
30     border:none;
31     text-decoration:none;
32     color:#fcfcfc;
33     font-size:14px;
34     left:50%;
35     line-height:31px;
36     margin:23px 0 0 110px;
37     position:absolute;
38     top:0;
39 }
40 header .stuts span {
41     font-size:22px;
42     font-weight:bold;
43     margin-left:5px;
44 }
45 .container {
46     color#000;
47     margin20px auto;
48     overflowhidden;
49     positionrelative;
50     width800px;
51 }
52 /* custom styles */
53 .column1 {
54     float:left;
55     width:500px;
56 }
57 .column2 {
58     float:left;
59     padding-left:20px;
60     width:170px;
61 }
62 #panel {
63     border:1px #000 solid;
64     box-shadow:4px 6px 6px #444444;
65     cursor:crosshair;
66     display:block;
67     margin:0 auto;
68     height:600px;
69     width:1000px;
70 }
71 #color {
72     border:1px #000 solid;
73     box-shadow:0px 4px 6px #444444;
74     cursor:crosshair;
75 }
76 .column2 > div {
77     margin-bottom:10px;
78 }
79 #preview, #pick {
80     border:1px #000 solid;
81     box-shadow:2px 3px 3px #444444;
82     height:40px;
83     width:80px;
84     border-radius:3px;
85     -moz-border-radius:3px;
86     -webkit-border-radius:3px;
87 }

Step 3. JS

js/script.js

001 var canvas;
002 var canvasColor;
003 var ctx;
004 var ctxColor;
005 var bMouseDown = false;
006 var selColorR = 0;
007 var selColorG = 0;
008 var selColorB = 0;
009 var BezierCurveBrush = {
010     // inner variables
011     iPrevX : 0,
012     iPrevY : 0,
013     points : null,
014     // initialization function
015     init: function () { },
016     startCurve: function (x, y) {
017         this.iPrevX = x;
018         this.iPrevY = y;
019         this.points = new Array();
020     },
021     getPoint: function (iLength, a) {
022         var index = a.length - iLength, i;
023         for (i=index; i< a.length; i++) {
024             if (a[i]) {
025                 return a[i];
026             }
027         }
028     },
029     draw: function (x, y) {
030         if (Math.abs(this.iPrevX - x) > 5 || Math.abs(this.iPrevY - y) > 5) {
031             this.points.push([x, y]);
032             // draw main path stroke
033             ctx.beginPath();
034             ctx.moveTo(this.iPrevX, this.iPrevY);
035             ctx.lineTo(x, y);
036             ctx.lineWidth = 1;
037             ctx.strokeStyle = 'rgba(' + selColorR + ', ' + selColorG + ', ' + selColorB + ', 0.9)';
038             ctx.stroke();
039             ctx.closePath();
040             // draw extra strokes
041             ctx.strokeStyle = 'rgba(' + selColorR + ', ' + selColorG + ', ' + selColorB + ', 0.2)';
042             ctx.beginPath();
043             var iStartPoint = this.getPoint(25, this.points);
044             var iFirstPoint = this.getPoint(1, this.points);
045             var iSecondPoint = this.getPoint(5, this.points);
046             ctx.moveTo(iStartPoint[0],iStartPoint[1]);
047             ctx.bezierCurveTo(iFirstPoint[0], iFirstPoint[1], iSecondPoint[0], iSecondPoint[1], x, y);
048             ctx.stroke();
049             ctx.closePath();
050             this.iPrevX = x;
051             this.iPrevY = y;
052         }
053     }
054 };
055 $(function(){
056     // creating canvas objects
057     canvas = document.getElementById('panel');
058     ctx = canvas.getContext('2d');
059     canvasColor = document.getElementById('color');
060     ctxColor = canvasColor.getContext('2d');
061     drawGradients(ctxColor);
062     BezierCurveBrush.init();
063     $('#color').mousemove(function(e) { // mouse move handler
064         var canvasOffset = $(canvasColor).offset();
065         var canvasX = Math.floor(e.pageX - canvasOffset.left);
066         var canvasY = Math.floor(e.pageY - canvasOffset.top);
067         var imageData = ctxColor.getImageData(canvasX, canvasY, 1, 1);
068         var pixel = imageData.data;
069         var pixelColor = 'rgba('+pixel[0]+', '+pixel[1]+', '+pixel[2]+', '+pixel[3]+')';
070         $('#preview').css('backgroundColor', pixelColor);
071     });
072     $('#color').click(function(e) { // mouse click handler
073         var canvasOffset = $(canvasColor).offset();
074         var canvasX = Math.floor(e.pageX - canvasOffset.left);
075         var canvasY = Math.floor(e.pageY - canvasOffset.top);
076         var imageData = ctxColor.getImageData(canvasX, canvasY, 1, 1);
077         var pixel = imageData.data;
078         var pixelColor = 'rgba('+pixel[0]+', '+pixel[1]+', '+pixel[2]+', '+pixel[3]+')';
079         $('#pick').css('backgroundColor', pixelColor);
080         selColorR = pixel[0];
081         selColorG = pixel[1];
082         selColorB = pixel[2];
083     });
084     $('#panel').mousedown(function(e) { // mouse down handler
085         bMouseDown = true;
086         var canvasOffset = $(canvas).offset();
087         var canvasX = Math.floor(e.pageX - canvasOffset.left);
088         var canvasY = Math.floor(e.pageY - canvasOffset.top);
089         BezierCurveBrush.startCurve(canvasX, canvasY, falsefalsefalsefalsefalsefalse, canvasX, canvasY, 0, 0);
090     });
091     $('#panel').mouseup(function(e) { // mouse up handler
092         bMouseDown = false;
093     });
094     $('#panel').mousemove(function(e) { // mouse move handler
095         if (bMouseDown) {
096             var canvasOffset = $(canvas).offset();
097             var canvasX = Math.floor(e.pageX - canvasOffset.left);
098             var canvasY = Math.floor(e.pageY - canvasOffset.top);
099             BezierCurveBrush.draw(canvasX, canvasY, falsefalsefalsefalsefalsefalse, canvasX, canvasY, 0, 0);
100         }
101     });
102 });
103 function drawGradients() {
104     var grad = ctxColor.createLinearGradient(20, 0, canvasColor.width - 20, 0);
105     grad.addColorStop(0, 'red');
106     grad.addColorStop(1 / 6, 'orange');
107     grad.addColorStop(2 / 6, 'yellow');
108     grad.addColorStop(3 / 6, 'green')
109     grad.addColorStop(4 / 6, 'aqua');
110     grad.addColorStop(5 / 6, 'blue');
111     grad.addColorStop(1, 'purple');
112     ctxColor.fillStyle=grad;
113     ctxColor.fillRect(0, 0, canvasColor.width, canvasColor.height);
114 }

What I have added – BezierCurveBrush object. This is pretty easy object with own Draw function where we use ‘bezierCurveTo’ function to draw curves between first point (in beginning of drawing) and all next stored points.


Live Demo
download in package

Conclusion

Hope that today’s lesson was interesting for you. We made another one nice html5 sample. I will be glad to see your thanks and comments. Good luck!

Rate article