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);
}
Related
const canvas = document.getElementById("canvas");
canvas.width = window.innerWidth = 750;
canvas.height = 600;
var context = canvas.getContext("2d");
context.fillStyle = "white";
context.fillReact(0, 0, canvas.width, canvas.height);
let draw_color = "black";
let draw_width = "2";
let is_drawing = false;
canvas.addEventListener("touchstart", start, false);
canvas.addEventListener("touchmove", draw, false);
canvas.addEventListener("mousedown", start, false);
canvas.addEventListener("mousemove", draw, false);
function start(event) {
is_drawing = true;
context.beginPath();
context.moveTo(event.clientX = canvas.offsetLeft, event.clientY = canvas.offsetTop);
event.preventDefault();
}
function draw(event) {
if (is_drawing) {
context.beginPath();
context.moveTo(event.clientX = canvas.offsetLeft, event.clientY = canvas.offsetTop);
context.strokeStyle = draw_color;
context.lineWidth = draw_width;
context.lineCap = "round";
context.lineJoin = "round";
context.stroke();
}
}
I did everything right yet it is showing context.fillReact is not a function, it should have draw a line on moving the cursor but it is not doing anything just showing the error.
As far as I know, canvas element's context object does not have any fillReact method in it. Maybe you mean fillRect?
I have a canvas where on "mousemove" i want draw on it:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var isDown = false;
var lastPoint = {x: 0, y: 0};
function onMouseDown(event) {
isDown = true;
var point = getCanvasPointOfMouseEvent(event);
ctx.beginPath();
ctx.moveTo(point.x, point.y);
lastPoint = point;
}
function onMouseMove(event) {
if ( isDown !== false) {
var point = getCanvasPointOfMouseEvent(event);
ctx.beginPath();
ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.lineWidth = '10';
ctx.lineJoin = 'round';
ctx.moveTo(lastPoint.x, lastPoint.y);
ctx.lineTo(point.x, point.y);
ctx.closePath();
ctx.stroke();
lastPoint = point;
}
}
function onMouseUp(event) {
isDown = false;
ctx.closePath();
}
function getCanvasPointOfMouseEvent(event) {
var canvasX = (event.pageX - canvas.offsetLeft);
var canvasY = (event.pageY - canvas.offsetTop);
return {x: canvasX, y: canvasY};
}
#canvas {
border: 1px solid red;
cursor: crosshair;
}
<canvas width="250px" height="250px" onmousedown="onMouseDown(event)" onmousemove="onMouseMove(event)" onmouseup="onMouseUp(event)" id="canvas">
Your browser doesn't support canvas!
</canvas>
The output is lines with dots:
but i want only lines, like this:
how fix it?
Basics is clear all and redraw all.
To achieve this, you'll have to store all the coordinates in an array, and each time you want to draw, to create a new sub-path with all the stored coordinates.
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var isDown = false;
var points = [];
function onMouseDown(event) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point); // store
redrawAll(); // clearAll and redraw
isDown = true; // make it last so we can grab the isStart below
}
function onMouseMove(event) {
if ( isDown !== false) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point); // store
redrawAll(); // clear all and redraw
}
}
function redrawAll() {
// clear all
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.lineWidth = '10';
ctx.lineJoin = 'round';
// redraw as a single sub-path
ctx.beginPath();
points.forEach(function(pt) {
if(pt.isStart) ctx.moveTo(pt.x, pt.y);
else ctx.lineTo(pt.x, pt.y);
});
ctx.stroke();
}
function onMouseUp(event) {
isDown = false;
}
function getCanvasPointOfMouseEvent(event) {
var canvasX = (event.pageX - canvas.offsetLeft);
var canvasY = (event.pageY - canvas.offsetTop);
return {x: canvasX, y: canvasY, isStart: !isDown};
}
#canvas {
border: 1px solid red;
cursor: crosshair;
}
<canvas width="250px" height="250px" onmousedown="onMouseDown(event)" onmousemove="onMouseMove(event)" onmouseup="onMouseUp(event)" id="canvas">
Your browser doesn't support canvas!
</canvas>
If you want each mouseup to create a new sub-path (and hence have these mix up when passing twice at the same coords), you just have to slightly modify the redrawAll function:
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext('2d');
var isDown = false;
var points = [];
function onMouseDown(event) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point);
redrawAll();
isDown = true;
}
function onMouseMove(event) {
if ( isDown !== false) {
var point = getCanvasPointOfMouseEvent(event);
points.push(point);
redrawAll();
}
}
function redrawAll() {
ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height);
ctx.strokeStyle = 'rgba(255, 0, 0, 0.5)';
ctx.lineWidth = '10';
ctx.lineJoin = 'round';
ctx.beginPath();
points.forEach(function(pt) {
if(pt.isStart){
ctx.stroke(); // draw previous
ctx.beginPath(); // begin a new sub-path
}
ctx.lineTo(pt.x, pt.y); // will moveTo automatically if needed
});
ctx.stroke();
}
function onMouseUp(event) {
isDown = false;
}
function getCanvasPointOfMouseEvent(event) {
var canvasX = (event.pageX - canvas.offsetLeft);
var canvasY = (event.pageY - canvas.offsetTop);
return {x: canvasX, y: canvasY, isStart: !isDown};
}
#canvas {
border: 1px solid red;
cursor: crosshair;
}
<canvas width="250px" height="250px" onmousedown="onMouseDown(event)" onmousemove="onMouseMove(event)" onmouseup="onMouseUp(event)" id="canvas">
Your browser doesn't support canvas!
</canvas>
I have a drawing interface which the drawings need to be saved at 1280x720px. However, I want the canvas to be able to be scalable in relation to that aspect ratio. A problem is that when I draw, the start of the path is not on the cursor.
I've looked everywhere and cannot find a solution. Here is the javascript:
var clearButton = document.getElementById('doodle-bin');
var canvascontainer = document.getElementById('doodle-canvas-container');
var canvas = document.getElementById('doodle-canvas');
var context = canvas.getContext('2d');
var radius = (document.getElementById('doodle-canvas-container').clientWidth + document.getElementById('doodle-canvas-container').clientHeight)/150;
var dragging = false;
context.mozImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
canvas.width = 1280;
canvas.height = 720;
canvas.style.width = '100%';
canvas.style.height = '100%';
/* CLEAR CANVAS */
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
clearButton.addEventListener('click', clearCanvas);
var putPoint = function (e) {
if (dragging) {
context.lineTo(e.offsetX, e.offsetY);
context.lineWidth = radius * 2;
context.stroke();
context.beginPath();
context.arc(e.offsetX, e.offsetY, radius, 0, Math.PI * 2);
context.fill();
context.beginPath();
context.moveTo(e.offsetX, e.offsetY);
}
};
var engage = function (e) {
dragging = true;
putPoint(e);
};
var disengage = function () {
dragging = false;
context.beginPath();
};
canvas.addEventListener('mousedown', engage);
canvas.addEventListener('mousemove', putPoint);
canvas.addEventListener('mouseup', disengage);
document.addEventListener('mouseup', disengage);
canvas.addEventListener('contextmenu', disengage);
Use the following function to get the proper mouse position even if the canvas is re-scaled. This will resolve the path start issue.
function getMouesPosition(e) {
var mouseX = e.offsetX * canvas.width / canvas.clientWidth | 0;
var mouseY = e.offsetY * canvas.height / canvas.clientHeight | 0;
return {x: mouseX, y: mouseY};
}
var clearButton = document.getElementById('doodle-bin');
var canvascontainer = document.getElementById('doodle-canvas-container');
var canvas = document.getElementById('doodle-canvas');
var context = canvas.getContext('2d');
var radius = (document.getElementById('doodle-canvas-container').clientWidth + document.getElementById('doodle-canvas-container').clientHeight) / 150;
var dragging = false;
context.mozImageSmoothingEnabled = false;
context.imageSmoothingEnabled = false;
canvas.width = 1280;
canvas.height = 720;
canvas.style.width = '100%';
canvas.style.height = '100%';
/* CLEAR CANVAS */
function clearCanvas() {
context.clearRect(0, 0, canvas.width, canvas.height);
}
clearButton.addEventListener('click', clearCanvas);
function getMouesPosition(e) {
var mouseX = e.offsetX * canvas.width / canvas.clientWidth | 0;
var mouseY = e.offsetY * canvas.height / canvas.clientHeight | 0;
return {x: mouseX, y: mouseY};
}
var putPoint = function (e) {
if (dragging) {
context.lineTo(getMouesPosition(e).x, getMouesPosition(e).y);
context.lineWidth = radius * 2;
context.stroke();
context.beginPath();
context.arc(getMouesPosition(e).x, getMouesPosition(e).y, radius, 0, Math.PI * 2);
context.fill();
context.beginPath();
context.moveTo(getMouesPosition(e).x, getMouesPosition(e).y);
}
};
var engage = function (e) {
dragging = true;
putPoint(e);
};
var disengage = function () {
dragging = false;
context.beginPath();
};
canvas.addEventListener('mousedown', engage);
canvas.addEventListener('mousemove', putPoint);
canvas.addEventListener('mouseup', disengage);
document.addEventListener('mouseup', disengage);
canvas.addEventListener('contextmenu', disengage);
body{margin:0;overflow:hidden}canvas{border:1px solid #ccc}
<button id="doodle-bin">Clear</button>
<div id="doodle-canvas-container">
<canvas id="doodle-canvas"></canvas>
</div>
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>
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);
}