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 !
Related
I'm trying to get the area of a polygone draw onclick in a canvas element
In the image above I try to get the area inside the red point which has a some opacity.
Is there anyway to do that "on the fly" which mean for each polygon draw.
I've already seen earcut.js which allow triangulation but I don't really understand how to get area whith this
var canvas = $('canvas');
var context = canvas[0].getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
$(canvas).attr({
width : this.width,
height: this.height
});
context.drawImage(imageObj,0,0);
};
imageObj.src = 'https://www.html5canvastutorials.com/demos/assets/darth-vader.jpg';
var clicks = [];
function drawPolygon(){
context.fillStyle = 'rgba(100,100,100,0.5)';
context.strokeStyle = "#df4b26";
context.lineWidth = 1;
context.beginPath();
context.moveTo(clicks[0].x, clicks[0].y);
for(var i=1; i < clicks.length; i++) {
context.lineTo(clicks[i].x,clicks[i].y);
}
context.closePath();
context.fill();
context.stroke();
};
function drawPoints(){
context.strokeStyle = "#df4b26";
context.lineJoin = "round";
context.lineWidth = 5;
for(var i=0; i < clicks.length; i++){
context.beginPath();
context.arc(clicks[i].x, clicks[i].y, 3, 0, 2 * Math.PI, false);
context.fillStyle = '#ffffff';
context.fill();
context.lineWidth = 5;
context.stroke();
}
};
function redraw(){
canvas.width = canvas.width; // Clears the canvas
context.drawImage(imageObj,0,0);
drawPolygon();
drawPoints();
};
canvas
.mouseup(function (e) {
clicks.push({
x: e.offsetX,
y: e.offsetY
});
redraw();
});
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>draw polygon with canvas</title>
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<canvas width="600" height="400"></canvas>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="js/index.js"></script>
</body>
</html>
There is very simple algorithm to calculate area of polygon with given vertex coordinates: Shoelace formula
A = 1/2* Sum((x[i+1] + x[i]) * ([y[i+1] - y[i]))
(note indexes wrap in circular manner, so x[n]=x[0])
that might be implemented in a single loop.
I have a canvas code to draw a signature. The code works perfectly fine with chrome and Firefox but does not draw at all on IE 11.
My canvas is:
<canvas id="signitureCanvas" style="border: 3px solid #000; cursor:crosshair; background-color:white;"></canvas>
My code is as below:
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
var canvasWidth = 200;
var canvasLength = 120;
canvas.width = canvasWidth;
canvas.height = canvasLength;
var canvasx = $(canvas).offset().left;
var canvasy = $(canvas).offset().top;
var last_mousex = last_mousey = 0;
var mousex = mousey = 0;
var mousedown = false;
var tooltype = 'draw';
//Mousedown
$(canvas).on('mousedown', function (e) {
last_mousex = mousex = parseInt(e.clientX - canvasx);
last_mousey = mousey = parseInt(e.clientY - canvasy);
mousedown = true;
});
//Mouseup
$(canvas).on('mouseup', function (e) {
mousedown = false;
});
//Mousemove
$(canvas).on('mousemove', function (e) {
mousex = parseInt(e.clientX - canvasx);
mousey = parseInt(e.clientY - canvasy);
if (mousedown) {
ctx.beginPath();
if (tooltype == 'draw') {
ctx.globalCompositeOperation = 'source-over';
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
} else {
ctx.globalCompositeOperation = 'destination-out';
ctx.lineWidth = 10;
}
ctx.moveTo(last_mousex, last_mousey);
ctx.lineTo(mousex, mousey);
ctx.lineJoin = ctx.lineCap = 'round';
ctx.stroke();
}
last_mousex = mousex;
last_mousey = mousey;
});
function ClearCanvas() {
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
Is IE 11 in particular having problems?
Edit:
I figured out the problem is with my Iframe:
When height and width are set to 300 everything works fine:
<embed id="fred" type="application/pdf" style="border:1px solid #666CCC" title="PDF in an i-Frame" src="#Model.FilePath" frameborder="1" scrolling="yes" height="300" width="300" />
When I set it to 1000, it won't work:
<embed id="fred" type="application/pdf" style="border:1px solid #666CCC" title="PDF in an i-Frame" src="#Model.FilePath" frameborder="1" scrolling="yes" height="1000" width="1000" />
I believe it's something with the offset but I can't figure how to fix it.
any help?
For further knowledge to whom might ask:
I have found this piece of code that works on all browsers, layerX and layerY are different for firefox browsers:
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
var canvasWidth = 200;
var canvasLength = 120;
canvas.width = canvasWidth;
canvas.height = canvasLength;
var x = 0;
var y = 0;
function tool_pencil() {
var tool = this;
this.started = false;
// This is called when you start holding down the mouse button
// This starts the pencil drawing
this.mousedown = function (ev) {
ctx.beginPath();
ctx.strokeStyle = 'black';
ctx.lineWidth = 3;
ctx.lineJoin = ctx.lineCap = 'round';
ctx.moveTo(x, y);
tool.started = true;
};
// This function is called every time you move the mouse. Obviously, it only
// draws if the tool.started state is set to true (when you are holding down
// the mouse button)
this.mousemove = function (ev) {
if (tool.started) {
ctx.lineTo(x, y);
ctx.stroke();
}
};
// This is called when you release the mouse button
this.mouseup = function (ev) {
if (tool.started) {
tool.mousemove(ev);
tool.started = false;
}
};
}
// The general-purpose event handler. This function just determines
// the mouse position relative to the <canvas> element
function ev_canvas(ev) {
// Firefox
if (ev.offsetX || ev.offsetX == 0) {
x = ev.offsetX;
y = ev.offsetY;
// Opera
} else if (ev.layerX || ev.layerX == 0) {
x = ev.layerX;
y = ev.layerX;
}
// Call the event handler of the tool
var func = tool[ev.type];
if (func) {
func(ev);
}
}
function ClearCanvas() {
var canvas = document.getElementById('signitureCanvas');
var ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
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/
I want to resize the canvas field like paint app in javascript how can I do ?
My html file is :
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="paint.css">
<title>Paint</title>
</head>
<body>
<canvas id="canvas" style="border: solid 1px black">Your Browser does not support Canvas, please upgrade</canvas>
<script src="paint.js"></script>
</body>
</html>
Thanks !
It turned out to be a bit more complex.
Resizing the canvas clears it, therefore you need to do it this way:
create a new canvas
assign the dimensions
draw the old canvas over the new canvas
replace the old canvas with the new canvas
//Base canvas and dimensions
var canvas = document.body.appendChild(document.createElement("canvas"));
var width = canvas.height = canvas.width = 400;
var height = width;
var ctx = canvas.getContext("2d");
//Drawing variables
var lastPosition = null;
var drawing = false;
//Drawing functionality
function startDraw() {
drawing = true;
}
canvas.onmousedown = startDraw;
function stopDraw() {
drawing = false;
}
canvas.onmouseup = stopDraw;
canvas.onmouseleave = stopDraw;
function mouseMove(evt) {
var pos = {
x: evt.offsetX,
y: evt.offsetY
};
if (lastPosition !== null && drawing === true) {
ctx.beginPath();
ctx.moveTo(lastPosition.x, lastPosition.y);
ctx.lineTo(pos.x, pos.y);
ctx.closePath();
ctx.stroke();
}
lastPosition = pos;
}
canvas.onmousemove = mouseMove;
//Resizer functions
var resizerX = document.body.appendChild(document.createElement("button"));
resizerX.innerHTML = "Resize X";
resizerX.onclick = function() {
var newValue = null;
while (isNaN(newValue) || newValue < 10) {
newValue = parseInt(prompt("Insert new width", width.toString()));
}
var c = document.createElement("canvas");
width = newValue;
c.width = width;
c.height = height;
ctx = c.getContext("2d");
ctx.drawImage(canvas, 0, 0);
canvas.parentNode.replaceChild(c, canvas);
canvas = c;
canvas.onmousedown = startDraw;
canvas.onmouseup = stopDraw;
canvas.onmouseleave = stopDraw;
canvas.onmousemove = mouseMove;
};
var resizerY = document.body.appendChild(document.createElement("button"));
resizerY.innerHTML = "Resize Y";
resizerY.onclick = function() {
var newValue = null;
while (isNaN(newValue) || newValue < 10) {
newValue = parseInt(prompt("Insert new height", height.toString()));
}
var c = document.createElement("canvas");
height = newValue;
c.width = width;
c.height = height;
ctx = c.getContext("2d");
ctx.drawImage(canvas, 0, 0);
canvas.parentNode.replaceChild(c, canvas);
canvas = c;
canvas.onmousedown = startDraw;
canvas.onmouseup = stopDraw;
canvas.onmouseleave = stopDraw;
canvas.onmousemove = mouseMove;
};
canvas {
background-color: #eee
}
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();
});