Canvas drawing app
How do I make an canvas drawing app?
I'm working on a drawing web app. This is the first stage, as it were, where I'm setting up the main UI. It has rulers, can resize the canvas and tracks mouse position and drag distance. The tool buttons are just visual right now.. What is a canvas drawing app? How do you make a canvas drawing app? This script and codes were developed by Ilia on 04 August 2022, Thursday.
Canvas drawing app - Script Codes HTML Codes
<!DOCTYPE html>
<html >
<head> <meta charset="UTF-8"> <title>Canvas drawing app</title> <script src="http://s.codepen.io/assets/libs/modernizr.js" type="text/javascript"></script> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"> <style> /* NOTE: The styles were added inline because Prefixfree needs access to your styles and they must be inlined if they are on local disk! */ * { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box }
body { font-size:62.5%; background:#232425; padding:10px; height:100%; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none;
}
#workspace { position:relative }
canvas { margin:21px 0 0 21px; background-color:#fff }
canvas.grid { background-size:100px 100px, 100px 100px, 20px 20px, 20px 20px; background-position:-1px -1px, -1px -1px, -1px -1px, -1px -1px; background-image: linear-gradient(rgba(0,0,0,.3) 1px, transparent 1px), linear-gradient(90deg, rgba(0,0,0,.3) 1px, transparent 1px), linear-gradient(rgba(0,0,0,.1) 1px, transparent 1px), linear-gradient(90deg, rgba(0,0,0,.1) 1px, transparent 1px);
}
/* ruler styles */
.ruler { position:absolute; background:#333435; background-size:100px 100px; background-position:-1px -1px;
}
.ruler:after { content:''; display:block; position:absolute; background-size:10px 10px; background-position:-1px -1px;
}
#horizontalRuler { height:20px; width:300px; top:0; left:21px; background-image:linear-gradient(90deg, rgba(255,255,255,.4) 1px, transparent 1px);
}
#horizontalRuler:after { top:50%; left:0; width:100%; height:50%; background-image:linear-gradient(90deg, rgba(255,255,255,.2) 1px, transparent 1px);
}
#verticalRuler { height:200px; width:20px; top:21px; left:0; background-image:linear-gradient(rgba(255,255,255,.4) 1px, transparent 1px);
}
#verticalRuler:after { top:0; left:50%; width:50%; height:100%; background-image:linear-gradient(rgba(255,255,255,.2) 1px, transparent 1px);
}
#workspace ul { list-style:none; padding:0; margin:0; color:#999 }
.ruler li { position:absolute }
#horizontalRuler li { top:-1px }
#horizontalRuler li:first-child { display:none }
#verticalRuler li { right:0; margin-top:-12px }
.ruler .marker { position:absolute; top:0; left:0; display:block; background:rgba(0,255,255,.8);
}
#hMarker { width:1px; height:100% }
#vMarker { width:100%; height:1px }
/* tools styles */
.tool-box { color:#ccc; display:inline-block; background:#434445; border-radius:2px; border:1px solid #535655;
}
.tool-box label { padding:0 .5em }
#set_cSize { width:300px; margin-left:21px; padding:3px 8px; margin-bottom:5px; font-size:1.3em;
}
#set_cSize input[type='number'] { background:transparent; color:#ddd; width:60px; border:1px solid #666; text-align:center; border-radius:4px; -webkit-transition:all .2s linear; transition:all .2s linear;
}
#set_cSize input:hover { background:#222 }
#set_cSize input:focus { color:#fff }
#set_cSize input[type='checkbox'] { position:relative; top:1px;
}
#set_cSize label { padding-left:1em }
#statusBar { display:block; width:480px; height:16px; border-radius:0 0 2px 2px; border-top:none; margin:-4px 0 0 21px; line-height:16px;
}
#toolBox { display:block; width:60px; height:430px; position:absolute; top:10px; left:515px;
}
.tool-group { margin-bottom:8px }
.tools { padding-left:1px }
.shape-tool { float:left; width:26px; height:26px; border:1px solid transparent; border-radius:3px; margin:1px; padding:0; color:#ccc; text-indent:-9999em; background-color:transparent; background-image:url(http://iliadraznin.com/uploads/tool-icons.png); background-repeat:no-repeat; -webkit-transition:background-color .2s linear, border-color .2s linear; transition:background-color .2s linear, border-color .2s linear;
}
.shape-tool:hover { border-color:#777; background-color:#3c3c3c }
.shape-tool.active { border-color:#555; background-color:#222 }
#toolEllipse { background-position:0 0 }
#toolEllipse:hover, #toolEllipse.active { background-position:0 -24px }
#toolRect { background-position:-24px 0 }
#toolRect:hover, #toolRect.active { background-position:-24px -24px }
#toolLine { background-position:-48px 0 }
#toolLine:hover, #toolLine.active { background-position:-48px -24px }
#toolFreeform { background-position:-72px 0 }
#toolFreeform:hover, #toolFreeform.active { background-position:-72px -24px } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/prefixfree/1.0.7/prefixfree.min.js"></script>
</head>
<body> <div class="tool-box" id="set_cSize"> <span>Canvas size</span> <input type="number" id="set_cWidth"> <span>x</span> <input type="number" id="set_cHeight"> <label>Grid <input type="checkbox" id="gridOn" checked></label> </div> <div id="workspace" role="main"> <div id="horizontalRuler" class="ruler"><b id="hMarker" class="marker"></b></div> <div id="verticalRuler" class="ruler"><b id="vMarker" class="marker"></b></div> <canvas id="canvas" class="grid" width="480" height="360"></canvas> <div class="tool-box" id="statusBar"></div> </div><!-- #workspace --> <div class="tool-box" id="toolBox"> <div class="tool-group clr" id="toolShapes"> <label>Shapes</label> <div class="tools"> <button type="button" class="shape-tool" id="toolEllipse" title="Create Ellipse">Ellipse</button> <button type="button" class="shape-tool" id="toolRect" title="Create Rectangle">Rectangle</button> <button type="button" class="shape-tool" id="toolLine" title="Create Line">Line</button> <button type="button" class="shape-tool" id="toolFreeform" title="Create Freeform Line">Freeform</button> </div> </div> <div class="tool-group clr" id="toolColors"> <label>Colors</label> <div class="tools"> </div> </div> </div> <script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script> <script src="js/index.js"></script>
</body>
</html>
Canvas drawing app - Script Codes CSS Codes
* { -moz-box-sizing:border-box; -webkit-box-sizing:border-box; box-sizing:border-box }
body { font-size:62.5%; background:#232425; padding:10px; height:100%; -webkit-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none;
}
#workspace { position:relative }
canvas { margin:21px 0 0 21px; background-color:#fff }
canvas.grid { background-size:100px 100px, 100px 100px, 20px 20px, 20px 20px; background-position:-1px -1px, -1px -1px, -1px -1px, -1px -1px; background-image: linear-gradient(rgba(0,0,0,.3) 1px, transparent 1px), linear-gradient(90deg, rgba(0,0,0,.3) 1px, transparent 1px), linear-gradient(rgba(0,0,0,.1) 1px, transparent 1px), linear-gradient(90deg, rgba(0,0,0,.1) 1px, transparent 1px);
}
/* ruler styles */
.ruler { position:absolute; background:#333435; background-size:100px 100px; background-position:-1px -1px;
}
.ruler:after { content:''; display:block; position:absolute; background-size:10px 10px; background-position:-1px -1px;
}
#horizontalRuler { height:20px; width:300px; top:0; left:21px; background-image:linear-gradient(90deg, rgba(255,255,255,.4) 1px, transparent 1px);
}
#horizontalRuler:after { top:50%; left:0; width:100%; height:50%; background-image:linear-gradient(90deg, rgba(255,255,255,.2) 1px, transparent 1px);
}
#verticalRuler { height:200px; width:20px; top:21px; left:0; background-image:linear-gradient(rgba(255,255,255,.4) 1px, transparent 1px);
}
#verticalRuler:after { top:0; left:50%; width:50%; height:100%; background-image:linear-gradient(rgba(255,255,255,.2) 1px, transparent 1px);
}
#workspace ul { list-style:none; padding:0; margin:0; color:#999 }
.ruler li { position:absolute }
#horizontalRuler li { top:-1px }
#horizontalRuler li:first-child { display:none }
#verticalRuler li { right:0; margin-top:-12px }
.ruler .marker { position:absolute; top:0; left:0; display:block; background:rgba(0,255,255,.8);
}
#hMarker { width:1px; height:100% }
#vMarker { width:100%; height:1px }
/* tools styles */
.tool-box { color:#ccc; display:inline-block; background:#434445; border-radius:2px; border:1px solid #535655;
}
.tool-box label { padding:0 .5em }
#set_cSize { width:300px; margin-left:21px; padding:3px 8px; margin-bottom:5px; font-size:1.3em;
}
#set_cSize input[type='number'] { background:transparent; color:#ddd; width:60px; border:1px solid #666; text-align:center; border-radius:4px; -webkit-transition:all .2s linear; transition:all .2s linear;
}
#set_cSize input:hover { background:#222 }
#set_cSize input:focus { color:#fff }
#set_cSize input[type='checkbox'] { position:relative; top:1px;
}
#set_cSize label { padding-left:1em }
#statusBar { display:block; width:480px; height:16px; border-radius:0 0 2px 2px; border-top:none; margin:-4px 0 0 21px; line-height:16px;
}
#toolBox { display:block; width:60px; height:430px; position:absolute; top:10px; left:515px;
}
.tool-group { margin-bottom:8px }
.tools { padding-left:1px }
.shape-tool { float:left; width:26px; height:26px; border:1px solid transparent; border-radius:3px; margin:1px; padding:0; color:#ccc; text-indent:-9999em; background-color:transparent; background-image:url(http://iliadraznin.com/uploads/tool-icons.png); background-repeat:no-repeat; -webkit-transition:background-color .2s linear, border-color .2s linear; transition:background-color .2s linear, border-color .2s linear;
}
.shape-tool:hover { border-color:#777; background-color:#3c3c3c }
.shape-tool.active { border-color:#555; background-color:#222 }
#toolEllipse { background-position:0 0 }
#toolEllipse:hover, #toolEllipse.active { background-position:0 -24px }
#toolRect { background-position:-24px 0 }
#toolRect:hover, #toolRect.active { background-position:-24px -24px }
#toolLine { background-position:-48px 0 }
#toolLine:hover, #toolLine.active { background-position:-48px -24px }
#toolFreeform { background-position:-72px 0 }
#toolFreeform:hover, #toolFreeform.active { background-position:-72px -24px }
Canvas drawing app - Script Codes JS Codes
$(function() { var _win = $(window), _canvas = $('#canvas'), _ctx = _canvas[0].getContext('2d'), _color = '#000', _fill = '#000', _stroke = 1, _cWidth = +_canvas.attr('width'), _cHeight = +_canvas.attr('Height'), _cPos = { x: _canvas.offset().left, y: _canvas.offset().top }, _mPos = { x:0, y:0 }, _mOldPos = { x:0, y:0 }, _mStartPos = { x:0, y:0 }, isDrag = false; // setup the rulers with counters and markers var hRuler = $('#horizontalRuler'), vRuler = $('#verticalRuler'), status = $('#statusBar'), hMarker = $('#hMarker'), vMarker = $('#vMarker'); function setupRulers() { var hCount = (_cWidth + 1) / 100, vCount = (_cHeight + 1) / 100, hList = $('<ul/>'), vList = $('<ul/>'), i = 0, k; // clear out the counter first hRuler.find('ul').remove(); vRuler.find('ul').remove(); // add the coordinates list for ( ; i < hCount; i++) { k = i * 100; hList.append( $('<li>' + k + '</li>').css('left', k) ); } hRuler.css('width', _cWidth).append(hList); for (i = 0; i < vCount; i++) { k = i * 100; vList.append( $('<li>' + k + '</li>').css('top', k) ); } vRuler.css('height', _cHeight).append(vList); } setupRulers(); // the main move event _canvas.on('mousemove', function(e) { var delta, dx, dy; _mPos.x = e.pageX - _cPos.x; _mPos.y = e.pageY - _cPos.y; // move the markers hMarker.css('left', _mPos.x); vMarker.css('top', _mPos.y); // update status status.empty().append( '<label title="cursor position">X ' + _mPos.x + ' Y ' + _mPos.y + '</label>' ); if (isDrag) { delta = dist(_mPos, _mStartPos).delta; status.append( '<label>X<sub>1</sub> ' + _mStartPos.x + ' Y<sub>1</sub> ' + _mStartPos.y + '</label>' + '<label>Δ ' + delta + '</label>' ); } // record the position for next frame _mOldPos = _mPos; }); _canvas.on('mousedown', function(e) { if (!isDrag) { isDrag = true; _mStartPos.x = e.pageX - _cPos.x; _mStartPos.y = e.pageY - _cPos.y; } }); _canvas.on('mouseup', function(e) { if (isDrag) { isDrag = false; } }); // modify canvas size var setSizePanel = $('#set_cSize'), toolBox = $('#toolBox'); $('#set_cWidth').val(_cWidth); $('#set_cHeight').val(_cHeight); setSizePanel.on('change', 'input', function() { var that = $(this), val = that.val(); if (val <= 100 || val > 1200) { val = val <= 100 ? 100 : 1200; that.val(val); } if (that.attr('id') == 'set_cWidth') { _cWidth = +val; _canvas.attr('width', _cWidth); status.css('width', _cWidth); setSizePanel.css('width', _cWidth >= 300 ? _cWidth : 300); toolBox.css('left', _cWidth >= 300 ? _cWidth + 35 : 335); } else if (that.attr('id') == 'set_cHeight') { _cHeight = +val; _canvas.attr('height', _cHeight); toolBox.css('height', _cHeight + 70); } // update rulers setupRulers(); // reset the markers hMarker.css('left', 0); vMarker.css('top', 0); }).css('width', _cWidth); // toggle grid $('#gridOn').on('click', function(e) { if ($(this).prop('checked')) { _canvas.addClass('grid'); } else { _canvas.removeClass('grid'); } }); toolBox.on('click', '.shape-tool', function(e) { toolBox.find('.active').removeClass('active'); $(this).addClass('active'); })
});
function dist(p1, p2) { var dx = p2.x - p1.x, dy = p2.y - p1.y; return { delta: Math.sqrt( dx*dx + dy*dy ) | 0, x: dx, y: dy };
}
Developer | Ilia |
Username | iliadraznin |
Uploaded | August 04, 2022 |
Rating | 3.5 |
Size | 5,828 Kb |
Views | 40,480 |
Find the perfect freelance services for your business! Fiverr's mission is to change how the world works together. Fiverr connects businesses with freelancers offering digital services in 500+ categories. Find Developer!
Name | Size |
Reproducing content box from RSI | 2,998 Kb |
CSS3 Working Clock | 5,889 Kb |
A Pen by Ilia | 2,567 Kb |
Map Controls | 3,721 Kb |
Dynamic SVG creation | 5,075 Kb |
Jasper is the AI Content Generator that helps you and your team break through creative blocks to create amazing, original content 10X faster. Discover all the ways the Jasper AI Content Platform can help streamline your creative workflows. Start For Free!
Name | Username | Size |
HTM5 picture dropzone | Jaysalvat | 2,576 Kb |
Drag in vanilla js using dotval math instead of translate | Paulq | 2,662 Kb |
Weather App | OmranAbazid | 2,596 Kb |
Canvas stripes | Adrianparr | 1,948 Kb |
A vuejs widget | Chrgl86 | 2,869 Kb |
Pure CSS candle light animation by One element | Ksksoft | 2,193 Kb |
Angular Route | Arun_v606 | 1,837 Kb |
Monochrome Form | AlienPiglet | 3,096 Kb |
Portfolio Page | HuffmanJ25 | 5,240 Kb |
Layout 11 | Altynai | 1,690 Kb |
Surf anonymously, prevent hackers from acquiring your IP address, send anonymous email, and encrypt your Internet connection. High speed, ultra secure, and easy to use. Instant setup. Hide Your IP Now!