HTML5 canvas – Creating own Paint program tutorial. New interesting article about canvases in HTML5 – I will show you how you can create nice and simple Paint program. Main idea – to draw a color picker area (rainbow gradient), and load some image to another canvas (here we will draw with a selected color).
Here are our demo and downloadable package:
Live Demo
[sociallocker]
download in package
[/sociallocker]
Ok, download the source files and lets start coding !
Step 1. HTML
Here are html code of our Paint:
index.html
01 | <!DOCTYPE html> |
02 | <html lang="en" > |
03 | <head> |
04 | <meta charset="utf-8" /> |
05 | <title>HTML5 canvas - Creating own Paint 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 | <div class="container"> |
12 | <div class="column1"> |
13 | <canvas id="color" width="500" height="128"></canvas> |
14 | <canvas id="panel" width="500" height="333"></canvas> |
15 | </div> |
16 | <div class="column2"> |
17 | <div><input type="button" value="Next image" id="swImage" /></div> |
18 | <div>Preview:</div> |
19 | <div id="preview"></div> |
20 | <div id="pick"></div> |
21 | <div>Color:</div> |
22 | <div>RGB: <input type="text" id="rgbVal" /></div> |
23 | <hr /> |
24 | </div> |
25 | <div style="clear:both;"></div> |
26 | </div> |
27 | <footer> |
28 | <h2>HTML5 canvas - Creating own Paint program</h2> |
29 | <a href="https://www.script-tutorials.com/html5-canvas-creating-own-paint-program/" class="stuts">Back to original tutorial on <span>Script Tutorials</span></a> |
30 | </footer> |
31 | </body> |
32 | </html> |
Step 2. CSS
Here are used CSS styles
css/main.css
001 | /* general styles */ |
002 | *{ |
003 | margin:0; |
004 | padding:0; |
005 | } |
006 | body { |
007 | background-color:#bababa; |
008 | color:#fff; |
009 | font:14px/1.3 Arial,sans-serif; |
010 | } |
011 | footer { |
012 | background-color:#212121; |
013 | bottom:0; |
014 | box-shadow: 0 -1px 2px #111111; |
015 | display:block; |
016 | height:70px; |
017 | left:0; |
018 | position:fixed; |
019 | width:100%; |
020 | z-index:100; |
021 | } |
022 | footer h2{ |
023 | font-size:22px; |
024 | font-weight:normal; |
025 | left:50%; |
026 | margin-left:-400px; |
027 | padding:22px 0; |
028 | position:absolute; |
029 | width:540px; |
030 | } |
031 | footer a.stuts,a.stuts:visited{ |
032 | border:none; |
033 | text-decoration:none; |
034 | color:#fcfcfc; |
035 | font-size:14px; |
036 | left:50%; |
037 | line-height:31px; |
038 | margin:23px 0 0 110px; |
039 | position:absolute; |
040 | top:0; |
041 | } |
042 | footer .stuts span { |
043 | font-size:22px; |
044 | font-weight:bold; |
045 | margin-left:5px; |
046 | } |
047 | .container { |
048 | color:#000; |
049 | margin:20px auto; |
050 | position:relative; |
051 | width:730px; |
052 | } |
053 | /* custom styles */ |
054 | .column1 { |
055 | float:left; |
056 | width:500px; |
057 | } |
058 | .column2 { |
059 | float:left; |
060 | padding-left:20px; |
061 | width:170px; |
062 | } |
063 | #panel { |
064 | border:1px #000 solid; |
065 | box-shadow:4px 6px 6px #444444; |
066 | cursor:crosshair; |
067 | } |
068 | #color { |
069 | border:1px #000 solid; |
070 | box-shadow:0px 4px 6px #444444; |
071 | cursor:crosshair; |
072 | } |
073 | .column2 > div { |
074 | margin-bottom:10px; |
075 | } |
076 | #swImage { |
077 | border:1px #000 solid; |
078 | box-shadow:2px 3px 3px #444444; |
079 | cursor:pointer; |
080 | height:25px; |
081 | line-height:25px; |
082 | border-radius:3px; |
083 | -moz-border-radius:3px; |
084 | -webkit-border-radius:3px; |
085 | } |
086 | #swImage:hover { |
087 | margin-left:2px; |
088 | } |
089 | #preview, #pick { |
090 | border:1px #000 solid; |
091 | box-shadow:2px 3px 3px #444444; |
092 | height:40px; |
093 | width:80px; |
094 | border-radius:3px; |
095 | -moz-border-radius:3px; |
096 | -webkit-border-radius:3px; |
097 | } |
098 | .column2 input[type=text] { |
099 | float:right; |
100 | width:110px; |
101 | } |
Step 3. JS
js/script.js
01 | var canvas; |
02 | var canvasColor; |
03 | var ctx; |
04 | var ctxColor; |
05 | var bMouseDown = false; |
06 | var selColorR = 0; |
07 | var selColorG = 0; |
08 | var selColorB = 0; |
09 | var images = [ // predefined array of used images |
10 | 'images/pic1.jpg', |
11 | 'images/pic2.jpg', |
12 | 'images/pic3.jpg', |
13 | 'images/pic4.jpg', |
14 | 'images/pic5.jpg' |
15 | ]; |
16 | var iActiveImage = 0; |
17 | $(function(){ |
18 | // drawing active image |
19 | var image = new Image(); |
20 | image.onload = function () { |
21 | ctx.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas |
22 | } |
23 | image.src = images[iActiveImage]; |
24 | // creating canvas objects |
25 | canvas = document.getElementById('panel'); |
26 | ctx = canvas.getContext('2d'); |
27 | canvasColor = document.getElementById('color'); |
28 | ctxColor = canvasColor.getContext('2d'); |
29 | drawGradients(ctxColor); |
30 | $('#color').mousemove(function(e) { // mouse move handler |
31 | var canvasOffset = $(canvasColor).offset(); |
32 | var canvasX = Math.floor(e.pageX - canvasOffset.left); |
33 | var canvasY = Math.floor(e.pageY - canvasOffset.top); |
34 | var imageData = ctxColor.getImageData(canvasX, canvasY, 1, 1); |
35 | var pixel = imageData.data; |
36 | var pixelColor = "rgba("+pixel[0]+", "+pixel[1]+", "+pixel[2]+", "+pixel[3]+")"; |
37 | $('#preview').css('backgroundColor', pixelColor); |
38 | }); |
39 | $('#color').click(function(e) { // mouse click handler |
40 | var canvasOffset = $(canvasColor).offset(); |
41 | var canvasX = Math.floor(e.pageX - canvasOffset.left); |
42 | var canvasY = Math.floor(e.pageY - canvasOffset.top); |
43 | var imageData = ctxColor.getImageData(canvasX, canvasY, 1, 1); |
44 | var pixel = imageData.data; |
45 | $('#rgbVal').val(pixel[0]+','+pixel[1]+','+pixel[2]); |
46 | var pixelColor = "rgba("+pixel[0]+", "+pixel[1]+", "+pixel[2]+", "+pixel[3]+")"; |
47 | $('#pick').css('backgroundColor', pixelColor); |
48 | selColorR = pixel[0]; |
49 | selColorG = pixel[1]; |
50 | selColorB = pixel[2]; |
51 | }); |
52 | $('#panel').mousedown(function(e) { // mouse down handler |
53 | bMouseDown = true; |
54 | }); |
55 | $('#panel').mouseup(function(e) { // mouse up handler |
56 | bMouseDown = false; |
57 | }); |
58 | $('#panel').mousemove(function(e) { // mouse move handler |
59 | if (bMouseDown) { |
60 | var canvasOffset = $(canvas).offset(); |
61 | var canvasX = Math.floor(e.pageX - canvasOffset.left); |
62 | var canvasY = Math.floor(e.pageY - canvasOffset.top); |
63 | var imageData = ctx.getImageData(canvasX, canvasY, 1, 1); |
64 | var pixel = imageData.data; |
65 | pixel[0] = selColorR; // Red |
66 | pixel[1] = selColorG; // Green |
67 | pixel[2] = selColorB; // Blue |
68 | pixel[3] = 255; // Alpha channel |
69 | ctx.putImageData(imageData, canvasX, canvasY); |
70 | } |
71 | }); |
72 | $('#swImage').click(function(e) { // switching images |
73 | iActiveImage++; |
74 | if (iActiveImage >= 10) iActiveImage = 0; |
75 | image.src = images[iActiveImage]; |
76 | }); |
77 | }); |
78 | function drawGradients() { |
79 | var grad = ctxColor.createLinearGradient(20, 0, canvasColor.width - 20, 0); |
80 | grad.addColorStop(0, 'red'); |
81 | grad.addColorStop(1 / 6, 'orange'); |
82 | grad.addColorStop(2 / 6, 'yellow'); |
83 | grad.addColorStop(3 / 6, 'green') |
84 | grad.addColorStop(4 / 6, 'aqua'); |
85 | grad.addColorStop(5 / 6, 'blue'); |
86 | grad.addColorStop(1, 'purple'); |
87 | ctxColor.fillStyle=grad; |
88 | ctxColor.fillRect(0, 0, canvasColor.width, canvasColor.height); |
89 | } |
Firstly, pay attention that now we have 2 canvases. First one canvas will for image, second one canvasColor – for color picker area. I created separated function to draw rainbow gradients: drawGradients. Then, added mouse event handlers. And, when we clicking at our second canvas (color picker) – we saving selected color. And, when we dragging at our image – we will ‘draw’ at first canvas. All easy. In result – our HTML5 Paint application ready!
Live Demo
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!







