How's it going guys?
Recently, with the help given from this site, I've learned how to draw a rectangle on an HTML5 canvas at the click of the button... that's not the problem:) The is problem this... unfortunately, it didn't work at all when I tried to use it on my iPhone... why:(?
Here's my code:
JAVASCRIPT:
// "Rectangle" Button
function rect()
{
var canvas = document.getElementById('canvasSignature'),
ctx = canvas.getContext('2d'),
rect = {},
drag = false;
function init() {
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
}
function mouseDown(e) {
rect.startX = e.pageX - this.offsetLeft;
rect.startY = e.pageY - this.offsetTop;
drag = true;
}
function mouseUp() {
drag = false;
}
function mouseMove(e) {
if (drag) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY ;
draw();
}
}
function draw() {
ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
}
init();
}
HTML5:
<div id="canvasDiv">
<canvas id="canvasSignature" width="580px" height="788px" style="border:2px solid #000; background: #FFF;"></canvas>
</div>
<div id="rect">
<p><button onclick="rect();">Rectangle</button></p>
</div>
Any help at all would be greatly appreciated:)
for first you got a mistake in you code
you star with this
rect() {
and close it only at the end of script
and on touch devices you need to use touch* events i think
something like this
var canvas = document.getElementById('canvasSignature'), ctx = canvas.getContext('2d'), rect = {}, drag = false;
function init() {
canvas.addEventListener("touchstart", touchHandler, false);
canvas.addEventListener("touchmove", touchHandler, false);
canvas.addEventListener("touchend", touchHandler, false);
}
function touchHandler(event) {
if (event.targetTouches.length == 1) { //one finger touche
var touch = event.targetTouches[0];
if (event.type == "touchstart") {
rect.startX = touch.pageX;
rect.startY = touch.pageY;
drag = true;
} else if (event.type == "touchmove") {
if (drag) {
rect.w = touch.pageX - rect.startX;
rect.h = touch.pageY - rect.startY ;
draw();
}
} else if (event.type == "touchend" || event.type == "touchcancel") {
drag = false;
}
}
}
function draw() {
ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
}
init();
Related
Edit: I noticed that if I quickly touch the screen, a dot formed. When you touch the screen and then move it on the canvas, the page itself moving, I wonder if this has something to do with scrolling?
I have drawing page , everything working correctly on desktop but not mobile. This is simple summary of my page:
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "black",
y = 2;
function candraw() {
canvas = document.getElementById('can');
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
canvas.addEventListener("mousemove", function (e) {
findxy('move', e)
}, false);
canvas.addEventListener("touchmove", function (e) {
findxy('move', e)
}, false);
canvas.addEventListener("mousedown", function (e) {
findxy('down', e)
}, false);
canvas.addEventListener("touchstart", function (e) {
findxy('down', e)
}, false);
canvas.addEventListener("mouseup", function (e) {
findxy('up', e)
}, false);
canvas.addEventListener("touchend", function (e) {
findxy('up', e)
}, false);
canvas.addEventListener("mouseout", function (e) {
findxy('out', e)
}, false);
canvas.addEventListener("touchcancel", function (e) {
findxy('out', e)
}, false);
}
function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function findxy(res, e) {
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
draw();
}
}
}
candraw();
<html>
<body>
<canvas id="can" width="400" height="400" style="border:2px solid;"> </canvas>
</body>
</html>
I expect touchmove, touchstart, touchend work like mousemove, mousedown, mouseup but these are not working or working different way.
As a result I cant draw on mobile. How can I solve this problem?
I solved my problem , javascript using e.clientX and e.clientY for only desktop.
So for mobile we must use touches like this: e.touches[0].clientX , e.touches[0].clientY.
function findxy must be like this(dont use only touches if you want use mobile and desktop you need use devices detector i already used below):
function findxy(res, e) {
if (res == 'down') {
prevX = currX;
prevY = currY;
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){
currX = e.touches[0].clientX - canvas.offsetLeft;
currY = e.touches[0].clientY - canvas.offsetTop;
}else{
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
}
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
if(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)){
currX = e.touches[0].clientX - canvas.offsetLeft;
currY = e.touches[0].clientY - canvas.offsetTop;
}else{
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
}
draw();
}
}
}
I want to draw a simple circle on a canvas using mouse events, but what I am getting is partial circles, half circles, and sometimes a full one. The rectangle is working fine.Picture of resulting partial circles is attached.enter image description here
Code is
function draw() {
if (circ == 1)
{
context.beginPath();
context.arc(rect.startX, rect.startY, rect.w, rect.h, Math.PI * 2, false);
context.stroke();
}
}
function mouseDownrect(e) {
rect.startX = (e.layerX - this.offsetLeft);
rect.startY = e.layerY - this.offsetTop;
drag = true;
}
function mouseUprect() {
draw();
rect.w = 0;
rect.h = 0;
drag = false;
}
function mouseMoverect(e) {
if (drag == true) {
rect.w = (e.layerX - this.offsetLeft) - rect.startX;
rect.h = (e.layerY - this.offsetTop) - rect.startY;
}
}
function rectangle() {
color = 'black';
rectan = 1;
circ = 0;
pen = 0;
canvas.addEventListener('mousedown', mouseDownrect, false);
canvas.addEventListener('mouseup', mouseUprect, false);
canvas.addEventListener('mousemove', mouseMoverect, false);
}
function Circle()
{
color = 'black';
circ = 1;
rectan = 0;
pen = 0;
canvas.addEventListener('mousedown', mouseDownrect, false);
canvas.addEventListener('mouseup', mouseUprect, false);
canvas.addEventListener('mousemove', mouseMoverect, false);
}
The fourth argument in arc() is the starting ANGLE. So you want 0 to Math.PI * 2 for a full circle.
context.arc(rect.startX, rect.startY, rect.w, 0, Math.PI * 2, false);
Also, the 3rd argument is the RADIUS, and i don't know what you want that to be.
I've got a page where I added a canvas which will be used by a technician or client for their signatures. I've managed to get it working and able to draw inside the canvas. However, when the page is scrolled a bit downwards the positioning of where the drawing starts is higher than the mouse point. When I scroll the page back to the top again, the position of the where the drawing starts is directly on the mouse point again.
How do I get the correct position of X and Y irrespective of whether the page is scrolled or not?
This is what I've done:
HTML:
<body onload="init();">
<div id="dialogSignature" runat="server" style="padding-top:10px; display:none; ">
<canvas id="myCanvas" width="400" height="200" style="border:2px solid;"></canvas>
<img id="canvasimg" style="position:absolute;top:10%;left:52%;" style="display:none;">
</body>
<table>
<tr>
<td>
<input type="button" value="Clear" id="clr" size="23" onclick="erase()" class="myButton" >
</td>
<td>
<button class="myButton" onclick="javascript:UploadPic();return false;">Sumbit</button>
</td>
</tr>
</table>
<asp:Label ID="lblText" runat="server" Text="Label" Visible="false"></asp:Label>
<asp:Label ID="lblScopeIdentity" runat="server" Text="sss" Visible="false"></asp:Label>
</div>
Javascript:
<script type="text/javascript">
var canvas, ctx, flag = false,
prevX = 0,
currX = 0,
prevY = 0,
currY = 0,
dot_flag = false;
var x = "black",
y = 2;
function init() {
canvas = document.getElementById('myCanvas');
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
canvas.addEventListener("mousemove", function (e) {
findxy('move', e)
}, false);
canvas.addEventListener("mousedown", function (e) {
findxy('down', e)
}, false);
canvas.addEventListener("mouseup", function (e) {
findxy('up', e)
}, false);
canvas.addEventListener("mouseout", function (e) {
findxy('out', e)
}, false);
canvas.addEventListener("touchstart", function (e) {
mousePos = getTouchPos(canvas, e);
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousedown", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchend", function (e) {
var mouseEvent = new MouseEvent("mouseup", {});
canvas.dispatchEvent(mouseEvent);
}, false);
canvas.addEventListener("touchmove", function (e) {
var touch = e.touches[0];
var mouseEvent = new MouseEvent("mousemove", {
clientX: touch.clientX,
clientY: touch.clientY
});
canvas.dispatchEvent(mouseEvent);
}, false);
// Prevent scrolling when touching the canvas
document.body.addEventListener("touchstart", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, false);
document.body.addEventListener("touchend", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, false);
document.body.addEventListener("touchmove", function (e) {
if (e.target == canvas) {
e.preventDefault();
}
}, false);
}
function getTouchPos(canvasDom, touchEvent) {
var rect = canvasDom.getBoundingClientRect();
return {
x: touchEvent.touches[0].clientX - rect.left,
y: touchEvent.touches[0].clientY - rect.top
};
}
function color(obj) {
switch (obj.id) {
case "green":
x = "green";
break;
case "blue":
x = "blue";
break;
case "red":
x = "red";
break;
case "yellow":
x = "yellow";
break;
case "orange":
x = "orange";
break;
case "black":
x = "black";
break;
case "white":
x = "white";
break;
}
if (x == "white") y = 14;
else y = 2;
}
function draw() {
ctx.beginPath();
ctx.moveTo(prevX, prevY);
ctx.lineTo(currX, currY);
ctx.strokeStyle = x;
ctx.lineWidth = y;
ctx.stroke();
ctx.closePath();
}
function erase() {
var m = confirm("Want to clear");
if (m) {
ctx.clearRect(0, 0, w, h);
document.getElementById("canvasimg").style.display = "none";
}
}
function save() {
document.getElementById("canvasimg").style.border = "2px solid";
var dataURL = canvas.toDataURL();
document.getElementById("canvasimg").src = dataURL;
document.getElementById("canvasimg").style.display = "inline";
}
function findxy(res, e) {
if (res == 'down') {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(currX, currY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
prevX = currX;
prevY = currY;
currX = e.clientX - canvas.offsetLeft;
currY = e.clientY - canvas.offsetTop;
draw();
}
}
}
var scopeIdentityUse = "<%=scopeIdentityJS1%>";
var Pic = document.getElementById("myCanvas").toDataURL("image/png");
Pic = Pic.replace(/^data:image\/(png|jpg);base64,/, "")
$.ajax({
type: 'POST',
url: 'Save_Picture.aspx/UploadPic',
data: '{ "imageData" : "' + Pic + '", "param" : "' + scopeIdentityUse + '" }',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (msg) {
document.location.href = 'CreatePDFReport.aspx'
//alert("Done, Picture Uploaded.");
}
});
</script>
Below is a better version of the correct position of mouse pointer. (styling needs to be redone though in stylesheet)....
Javascript:
<script type="text/javascript">
var canvas, ctx;
var mouseX, mouseY, mouseDown = 0;
var touchX, touchY;
var lastX, lastY = -1;
function init() {
canvas = document.getElementById('can');
ctx = canvas.getContext('2d');
w = canvas.width;
h = canvas.height;
canvas.addEventListener('mousedown', sketchpad_mouseDown, false);
canvas.addEventListener('mousemove', sketchpad_mouseMove, false);
canvas.addEventListener('mouseup', sketchpad_mouseUp, false);
canvas.addEventListener('touchstart', sketchpad_touchStart, false);
canvas.addEventListener('touchend', sketchpad_touchEnd, false);
canvas.addEventListener('touchmove', sketchpad_touchMove, false);
function drawLine(ctx, x, y, size) {
if (lastX == -1) {
lastX = x;
lastY = y;
}
r = 0; g = 0; b = 0; a = 255;
ctx.strokeStyle = "rgba(" + r + "," + g + "," + b + "," + (a / 255) + ")";
ctx.lineCap = "round";
ctx.beginPath();
ctx.moveTo(lastX, lastY);
ctx.lineTo(x, y);
ctx.lineWidth = size;
ctx.stroke();
ctx.closePath();
lastX = x;
lastY = y;
}
function sketchpad_mouseDown() {
mouseDown = 1;
drawLine(ctx, mouseX, mouseY, 6);
}
function sketchpad_mouseUp() {
mouseDown = 0;
lastX = -1
lastY = -1
}
function sketchpad_mouseMove(e) {
getMousePos(e);
if (mouseDown == 1) {
drawLine(ctx, mouseX, mouseY, 6);
}
}
function getMousePos(e) {
if (!e)
var e = event;
if (e.offsetX) {
mouseX = e.offsetX;
mouseY = e.offsetY;
}
else if (e.layerX) {
mouseX = e.layerX;
mouseY = e.layerY;
}
}
function sketchpad_touchStart() {
getTouchPos();
drawLine(ctx, touchX, touchY, 6);
event.preventDefault();
}
function sketchpad_touchEnd() {
lastX = -1;
lastY = -1;
}
function sketchpad_touchMove(e) {
getTouchPos(e);
drawLine(ctx, touchX, touchY, 6);
event.preventDefault();
}
function getTouchPos(e) {
if (!e)
var e = event;
if (e.touches) {
if (e.touches.length == 1) {
var touch = e.touches[0];
touchX = touch.pageX - touch.target.offsetLeft;
touchY = touch.pageY - touch.target.offsetTop;
}
}
}
function fd_erase(elem1) {
ctx.clearRect(0, 0, w, h);
if (typeof elem1 != 'undefined') {
document.getElementById(elem1).style.display = "none";
document.getElementById(elem1).value = '';
}
}
function fd_save() {
canvas = document.getElementById('can');
ctx = canvas.getContext('2d');
var dataURL = canvas.toDataURL();
document.getElementById('Signature1_img').src = dataURL;
document.getElementById('Signature1').value = dataURL;
document.getElementById('Hidden1').value = dataURL;
document.getElementById('Signature1_img').style.display = "inline";
}
And on html:
<div style="position: absolute; width:794px; height:1122px; background-color:#FFFFFF;">
<form runat="server" id="form1">
<canvas id="can" Width="300px" Height="300px" style="top:108px;left:96px;color:#000000;background-color:#FFFFFF;border:1px solid #000;"></canvas>
<input type="hidden" id="Signature1" name="Signature1" value="" >
<input type="text" id="Hidden1" name="hndText" runat="server" value="" >
<img id="Signature1_img" name="Signature1_img" Width="300px" Height="300px" style="color:#000000;background-color:#FFFFFF;border-style:solid;border-width:1px;border-color:#000000;display:none;">
</form>
</div>
$(document).ready(function () {
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
rect = {},
drag = false;
function init() {
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
}
function mouseDown(e) {
rect.startX = e.pageX - this.offsetLeft;
rect.startY = e.pageY - this.offsetTop;
drag = true;
}
function mouseUp() {
drag = false;
}
function mouseMove(e) {
if (drag) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY;
ctx.clearRect(0, 0, canvas.width, canvas.height);
draw();
}
}
function draw() {
ctx.fillRect(rect.startX, rect.startY, rect.w, rect.h);
}
init();
});
This is what i have so far but when i create another rectangle the last one is automatically erased.
I need to crate multiple rectangles and make them drag able inside canvas.
Using drawOldShapes() method, you can persist the old rectangles.
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
// ctx.globalAlpha = 0.5;
rect = {},
drag = false;
var rectStartXArray = new Array() ;
var rectStartYArray = new Array() ;
var rectWArray = new Array() ;
var rectHArray = new Array() ;
function init() {
canvas.addEventListener('mousedown', mouseDown, false);
canvas.addEventListener('mouseup', mouseUp, false);
canvas.addEventListener('mousemove', mouseMove, false);
}
function mouseDown(e) {
rect.startX = e.pageX - this.offsetLeft;
rect.startY = e.pageY - this.offsetTop;
drag = true;
}
function mouseUp() {
rectStartXArray[rectStartXArray.length] = rect.startX;
rectStartYArray[rectStartYArray.length] = rect.startY;
rectWArray[rectWArray.length] = rect.w;
rectHArray[rectHArray.length] = rect.h;
drag = false;
}
function mouseMove(e) {
if (drag) {
rect.w = (e.pageX - this.offsetLeft) - rect.startX;
rect.h = (e.pageY - this.offsetTop) - rect.startY;
ctx.clearRect(0, 0, canvas.width, canvas.height);
draw();
}
drawOldShapes();
}
function draw() {
ctx.beginPath();
ctx.rect(rect.startX, rect.startY, rect.w, rect.h);
ctx.stroke();
}
function drawOldShapes(){
for(var i=0;i<rectStartXArray.length;i++)
{
if(rectStartXArray[i]!= rect.startX && rectStartYArray[i] != rect.startY && rectWArray[i] != rect.w && rectHArray[i] != rect.h)
{
ctx.beginPath();
ctx.rect(rectStartXArray[i], rectStartYArray[i], rectWArray[i], rectHArray[i]);
ctx.stroke();
}
}
}
init();
I guess you need to store each rectangle in an array and each time draw() is called you need to draw all of them.
something like:
rects = [];
rect = null;
//onmouse down:
rect = { x1 : <value from Mouse>,y1: <value from Mouse>,x2 : 0 ,y2 : 0 };
//onmouse up
rect.x2 = <value from Mouse>;
rect.y2 = <value from Mouse>;
rects.push( rect );
rect = null;
//draw
for( var i = 0; i < rects.length; i++ ) {
//drawing each rectangle
}
That is just kind of suggestion to approach. Next to the coordinates you can also store information about fill-color, stroke-width and -style and so on.
Good luck!
The following code is working properly in other browsers except IE. My code is:
<script lang="javascript" type="text/javascript">
alert("fdgdfgdfg");
var canvas;
var ctx;
var canX;
var canY;
var rltvX;
var rltvY;
var x = "black";
var flag = false;
var w, h;
function init() {
alert("aaaaaaaaaaa");
alert("bbbbbbbbbbb");
canvas = document.getElementById("canvas");
ctx = canvas.getContext("2d");
w = canvas.width;
h = canvas.height;
canvas.addEventListener("mousemove", function(e) {findxy('move', e);}, false);
canvas.addEventListener("mousedown", function(e) {findxy('down', e);}, false);
canvas.addEventListener("mouseup", function(e) {findxy('up', e);}, false);
canvas.addEventListener("mouseout", function(e) {findxy('out', e);}, false);
canvas.addEventListener("touchstart", touchDown, false);
canvas.addEventListener("touchmove", move, true);
canvas.addEventListener("touchend", touchUp, false);
document.body.addEventListener("mouseup", mouseUp, false);
document.body.addEventListener("touchcancel", touchUp, false);
}
function findxy(res, e) {
if (res == 'down') {
canX = e.clientX - canvas.offsetLeft-5;
canY = e.clientY - canvas.offsetTop-25;
flag = true;
dot_flag = true;
if (dot_flag) {
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(canX, canY, 2, 2);
ctx.closePath();
dot_flag = false;
}
}
if (res == 'up' || res == "out") {
flag = false;
}
if (res == 'move') {
if (flag) {
rltvX = canX;
rltvY = canY;
canX = e.clientX - canvas.offsetLeft-5;
canY = e.clientY - canvas.offsetTop-25;
ctx.beginPath();
ctx.moveTo(rltvX, rltvY);
ctx.lineTo(canX, canY);
ctx.strokeStyle = x;
ctx.lineWidth = 2;
ctx.stroke();
ctx.closePath();
}
}
}
function touchDown(e) {
if (!e)
var e = event;
e.preventDefault();
canX = e.targetTouches[0].pageX - canvas.offsetLeft-5;
canY = e.targetTouches[0].pageY - canvas.offsetTop-25;
ctx.beginPath();
ctx.fillStyle = x;
ctx.fillRect(canX, canY, 2, 2);
ctx.closePath();
}
function move(e) {
if (!e)
var e = event;
e.preventDefault();
rltvX = canX;
rltvY = canY;
canX = e.targetTouches[0].pageX - canvas.offsetLeft-5;
canY = e.targetTouches[0].pageY - canvas.offsetTop-25;
ctx.beginPath();
ctx.strokeStyle = x;
ctx.lineWidth = 2;
ctx.moveTo(rltvX, rltvY);
ctx.lineTo(canX, canY);
ctx.stroke();
}
</script>
The error is, the object 'canvas' does not support the method addEventListener(). This is working properly in all browsers except IE. is there any alternative?
If you are using IE8 you should use the attachEvent() method instead of addEventListener(). This means you have to check first which browser the user has, then call the correct method on the element.
EDIT for how to check which method to use:
if (el.addEventListener){
el.addEventListener(...);
} else if (el.attachEvent){
el.attachEvent(...);
}
Where el is your DOM element.