All Erase button (painting app with canvas) - javascript

I followed this tutorial to make a very basic paint app : http://www.williammalone.com/articles/create-html5-canvas-javascript-drawing-app/
I stopped at the first step (because it's all I wanted), except that I cannot erase like in the first example shown on the tutorial website. I suppose I made a mistake at linking the javascript function called "redraw" to the Erase button.
Here is my code :
<head>
<title>TEST PAINTING</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script>
$( document ).ready(function() {
var canvasDiv = document.getElementById('canvasDiv');
var canvas = document.createElement('canvas');
canvas.setAttribute('width', "500");
canvas.setAttribute('height', "200");
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if(typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
//
$('#canvas').mousedown(function(e){
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
$('#canvas').mousemove(function(e){
if(paint){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
$('#canvas').mouseup(function(e){
paint = false;
});
$('#canvas').mouseleave(function(e){
paint = false;
});
$('#clearCanvasSimple').click(function(e){
clearCanvs();
});
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
function addClick(x, y, dragging)
{
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function redraw()
{
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
context.strokeStyle = "#333";
context.lineJoin = "round";
context.lineWidth = 8;
for(var i=0; i < clickX.length; i++) {
context.beginPath();
if(clickDrag[i] && i){
context.moveTo(clickX[i-1], clickY[i-1]);
}else{
context.moveTo(clickX[i]-1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
function clearCanvas()
{
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
}
});
</script>
</head>
<body>
<div><button id="clearCanvasSimple" href="javascript:void(0)" onClick="clearCanvas()" type="button">Erase</button></div>
<div class="cadre" id="canvasDiv"></div>
</body>
Does anyone know how I could make this "Erase" button work?
Thank you !

You've set the redraw button to just repaint the code again.
It should be doing something like this:
function clearCanvas()
{
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
});
We clear the current points, then clear the canvas.
Place the clearCanvas function after the redraw function and add the following jquery to register the click on the button (all in side the ready function).
$('#clearCanvasSimple').click(function(e){
clearCanvas();
});

Related

Making a drawing app inside a bootstrap modal

I am trying to make a drawing app inside a bootstrap modal.
So far I have achieved this jsfiddle
Here's my code
var canvasDiv = document.getElementById('canvasDiv');
canvas = document.createElement('canvas');
canvas.setAttribute('width', 570);
canvas.setAttribute('height', 300);
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if(typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
$('#canvas').mousedown(function(e){
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
$('#canvas').mousemove(function(e){
if(paint){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
$('#canvas').mouseup(function(e){
paint = false;
});
$('#canvas').mouseleave(function(e){
paint = false;
});
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
function addClick(x, y, dragging)
{
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function redraw(){
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for(var i=0; i < clickX.length; i++) {
context.beginPath();
if(clickDrag[i] && i){
context.moveTo(clickX[i-1], clickY[i-1]);
}else{
context.moveTo(clickX[i]-1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
But when the mouse is clicked, the drawing is being made way off from where the mouse pointer is. Check the fiddle to get an understanding of what I mean.
Also I would like to know how to make the canvas take the height and width of the modal and not pass in static width and height like this canvas.setAttribute('width', 570);
1.offsetleft is relative to parent element https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetLeft , so you need $.offset
2.height and width is according to parent after it shows
result see https://jsfiddle.net/hj898aqb/1/

Issue on Drawing Straight Line with Mouse Down and Move Event

Can you please take a look at following demo and let me know how I can enable the code to draw 100% straight Line on the canvas?
$(function() {
var drawLine = false;
var theCanvas = document.getElementById('map');
var ctx = theCanvas.getContext('2d');
theCanvas.width = 420;
theCanvas.height = 300;
var canvasOffset = $('#map').offset();
$('#map').mousemove(function(e) {
if (drawLine === true) {
ctx.lineTo(e.pageX - canvasOffset.left, e.pageY - canvasOffset.top);
ctx.stroke();
}
});
$('#map').mousedown(function() {
drawLine = true;
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(e.pageX - canvasOffset.left, e.pageY - canvasOffset.top);
});
$(window).mouseup(function() {
drawLine = false;
});
});
#map{border:solid; margin-top: 50px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<canvas id="map"></canvas>
As you can see the code is working fine but what I want is drawing a straight line on drawing
Thanks
You would need to have 2 canvases:
temporary for animation
permanent to store drawing.
Algorithm:
ondown write start coordinates.
onmove record endpoint, clear canvas 1, draw a line on canvas 1 from start point to end point.
onup draw final line on 2nd canvas clear 1st canvas.
Too lazy create second canvas (it'll clear it every try now);
Put a comment where pass different canvas for permanent draw
$(function() {
var drawLine = false;
var theCanvas = document.getElementById('map');
var finalPos = {x:0, y:0};
var startPos = {x:0, y:0};
var ctx = theCanvas.getContext('2d');
theCanvas.width = 420;
theCanvas.height = 300;
var canvasOffset = $('#map').offset();
function line(cnvs) {
cnvs.beginPath();
cnvs.moveTo(startPos.x, startPos.y);
cnvs.lineTo(finalPos.x, finalPos.y);
cnvs.stroke();
}
function clearCanvas()
{
ctx.clearRect(0, 0, theCanvas.width, theCanvas.height);
}
$('#map').mousemove(function(e) {
if (drawLine === true) {
finalPos = {x: e.pageX - canvasOffset.left, y:e.pageY - canvasOffset.top};
clearCanvas();
line(ctx);
}
});
$('#map').mousedown(function(e) {
drawLine = true;
ctx.strokeStyle = 'blue';
ctx.lineWidth = 5;
ctx.lineCap = 'round';
ctx.beginPath();
startPos = { x: e.pageX - canvasOffset.left, y: e.pageY - canvasOffset.top};
});
$(window).mouseup(function() {
clearCanvas();
// Replace with var that is second canvas
line(ctx);
finalPos = {x:0, y:0};
startPos = {x:0, y:0};
drawLine = false;
});
});
#map{border:solid; margin-top: 50px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<canvas id="map"></canvas>

Showing two canvas (separatedly with the same functions) in one page

I'm trying to get two canvas drawing boards in one page (separatedly with all the functions draw and erase) and I couldn't find the trick.
Here is the code that allows me to show only one canvas drawing board :
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<title>TEST PAINTING</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script>
<script>
$( document ).ready(function() {
var canvasDiv = document.getElementById('canvasDiv');
var canvas = document.createElement('canvas');
canvas.setAttribute('width', "500");
canvas.setAttribute('height', "200");
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if(typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
//
$('#canvas').mousedown(function(e){
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
$('#canvas').mousemove(function(e){
if(paint){
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
$('#canvas').mouseup(function(e){
paint = false;
});
$('#canvas').mouseleave(function(e){
paint = false;
});
$('#clearCanvasSimple').click(function(e){
clearCanvas();
});
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
function addClick(x, y, dragging)
{
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function redraw()
{
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
context.strokeStyle = "#333";
context.lineJoin = "round";
context.lineWidth = 8;
for(var i=0; i < clickX.length; i++) {
context.beginPath();
if(clickDrag[i] && i){
context.moveTo(clickX[i-1], clickY[i-1]);
}else{
context.moveTo(clickX[i]-1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
function clearCanvas()
{
clickX = new Array();
clickY = new Array();
clickDrag = new Array();
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
}
});
</script>
</head>
<body>
<div><button id="clearCanvasSimple" href="javascript:void(0)" onClick="clearCanvas()" type="button">Erase</button></div>
<div class="cadre" id="canvasDiv"></div>
</body>
</html>
Dos anyone know how I could work it out ? Thank you very much !

Cannot clear the canvas

I am trying to clear the canvas for redrawing, it gets clear and when we try to redraw, the previous thing comes back.
Here is my code:
var drawingApp = (function () {
//declaring Variables
var canvas,
canvasDiv,
context,
canvasWidth = 200,
canvasHeight = 200,
clickX = [],
clickY = [],
clickDrag = [],
paint = false;
//Initalisation Function
function init() {
canvasDiv = document.getElementById('canvasDiv');
canvas = document.createElement('canvas');
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
canvas.setAttribute('id', 'canvas');
canvasDiv.appendChild(canvas);
if (typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
context = canvas.getContext("2d");
loadEvents(); //Load events
}
function loadEvents() {
//Mouse down Event
$('#canvas').mousedown(function (e) {
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
paint = true;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
//Mouse Move Event
$('#canvas').mousemove(function (e) {
if (paint) {
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop, true);
redraw();
}
});
//Mouse Up Event
$('#canvas').mouseup(function (e) {
paint = false;
});
//Mouse Leave Event
$('#canvas').mouseleave(function (e) {
paint = false;
});
}
//Add Click Function
function addClick(x, y, dragging) {
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
//Redraw Function
function redraw() {
context.clearRect(0, 0, context.canvas.width, context.canvas.height); // Clears the canvas
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for (var i = 0; i < clickX.length; i++) {
context.beginPath();
if (clickDrag[i] && i) {
context.moveTo(clickX[i - 1], clickY[i - 1]);
} else {
context.moveTo(clickX[i] - 1, clickY[i]);
}
context.lineTo(clickX[i], clickY[i]);
context.closePath();
context.stroke();
}
}
// Clears the canvas.
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
return {
init: init,
erase: clearCanvas
};
})();
$(function () {
drawingApp.init();
});
Here is my fiddle
Please see where m getting wrong
When you clear your canvas using the erase function, you fail to clear the clickX, clickY and clickDrag variables. So the next time it draws it still draws the old data.
Updated JSFiddle - http://jsfiddle.net/P8acZ/6/
The code that changed
function clearCanvas() {
clickDrag = [];
clickX = [];
clickY = [];
context.clearRect(0, 0, canvas.width, canvas.height);
}

How to select a polygonal area of an image using JavaScript / jQuery?

I'd like to be able to let my users select a specific polygonal (6-8 vertices with curved lines between points) area of an image they upload - how do I go about doing this using HTML5 & JS? The only library I found allows purely rectangular selection: http://odyniec.net/projects/imgareaselect/
There's already a library that does part of what you need: polyclip.js, by Zoltan Dulac You can build a UI that allows the user to select points, then feed the data to the library and you're done.
EDIT: Here is a jsFiddle demonstration. Click to select points on the original image and press the Generate button to generate a cropped version.
HTML:
<div id="mainContent">
<div id="canvasDiv">
<br/>
<button id="generate" type="button">Generate
</button>
</div>
<h1>Result:</h1>
<div class="clipParent" style="float:left;">
</div>
</div>
JS:
var canvasDiv = document.getElementById('canvasDiv');
canvas = document.createElement('canvas');
canvas.setAttribute('width', 500);
canvas.setAttribute('height', 500);
canvas.setAttribute('id', 'canvas');
$(canvasDiv).prepend(canvas);
if(typeof G_vmlCanvasManager != 'undefined') {
canvas = G_vmlCanvasManager.initElement(canvas);
}
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
$(canvas).attr({width : this.width, height: this.height});
context.drawImage(imageObj,0,0);
};
imageObj.src = 'http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
var clickX = new Array();
var clickY = new Array();
var clickDrag = new Array();
var paint;
function addClick(x, y, dragging)
{
clickX.push(x);
clickY.push(y);
clickDrag.push(dragging);
}
function redraw(){
canvas.width = canvas.width; // Clears the canvas
context.drawImage(imageObj,0,0);
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for(var i=0; i < clickX.length; i++)
{
context.beginPath();
context.arc(clickX[i], clickY[i], 3, 0, 2 * Math.PI, false);
context.fillStyle = '#ffffff';
context.fill();
context.lineWidth = 5;
context.stroke();
}
}
$('#canvas').click(function(e){
var mouseX = e.pageX - this.offsetLeft;
var mouseY = e.pageY - this.offsetTop;
addClick(e.pageX - this.offsetLeft, e.pageY - this.offsetTop);
redraw();
});
$('#generate').click(function(){
$(".clipParent").empty();
$(".clipParent").prepend('<img src="http://www.html5canvastutorials.com/demos/assets/darth-vader.jpg" id="genimg" />');
var arr = [];
for(var i=0; i < clickX.length; i++){
arr.push(clickX[i]);
arr.push(clickY[i]);
}
$("#genimg")[0].setAttribute("data-polyclip",arr.join(", "));
clickX=[];
clickY=[];
redraw();
polyClip.init();
});
You could load the image on to a canvas tag and then you can do all the drawing you like on that canvas.

Categories