canvas.toDataURL() value changing even if canvas didn't change - javascript

I've been studying and trying to write an application that takes whatever image is on an HTML5 canvas element and send it to clients. When trying to take the image using canvas.toDataURL(), compressing and sending it back to server, the client was sometimes displaying the image and sometimes not displaying what was sent. First I thought that it could be that the data was corrupted, but working on a local server and having 29/30 corrupted data didn't make sense to me, so I've tried to see what was going on and registered the length of the base64 image and noticed that it's length was changing, although the content of the canvas wasn't changing. Why is that happening? I wrote a simple page in which you can edit the canvas content by drawing on it that shows that happening:
<!DOCTYPE html>
<html>
<head>
<title>Draw</title>
<style>
body{margin:0;}
</style>
<script>
addEventListener("load", Load, false);
var board = undefined;
var ctx = undefined;
var loaded = false;
var mousehold = false;
var mousex = 0;
var mousey = 0;
var lastx = 0;
var lasty = 0;
var firstclick = false;
function Load(e)
{
loaded = true;
board = document.getElementById("board");
ctx = board.getContext("2d");
board.width = window.innerWidth;
board.height = window.innerHeight;
addEventListener("mousedown", function(e)
{
mousehold = true;
}, false);
addEventListener("mouseup", function(e)
{
mousehold = false;
firstclick = false;
}, false);
addEventListener("mousemove", function(e)
{
mousex = e.clientX;
mousey = e.clientY;
// if(mousehold == true) console.log(mousex + " " + mousey);
}, false);
ctx.beginPath();
ctx.lineWidth = 5;
UpdateBoard();
}
function UpdateBoard()
{
if(mousehold == true)
{
if(firstclick == false)
{
lastx = mousex;
lasty = mousey;
firstclick = true;
}
ctx.moveTo(lastx, lasty);
ctx.lineTo(mousex, mousey);
ctx.stroke();
lastx = mousex, lasty = mousey;
}
window.requestAnimationFrame(UpdateBoard);
}
function send()
{
var img = board.toDataURL();
console.log(img.length);
}
</script>
</head>
<body>
<canvas id="board"></canvas>
<button style="right:10px;bottom:10px;position:fixed;z-index:999999;" onclick="send();">Send</button>
</body>
</html>
Clicking "send" button will log the base64 image length on console. If you draw something to the screen, the content of the canvas will obviously change, but if you stop drawing and click "send" button a few times (without touching canvas content) you'll see that it seems to be generating different base64 images. Why is that happening? Is it possible to prevent that from happening? My application needs to update content constantly (compressed, but I've tried it without compression and problem was the same).To demonstrate the problem I've uploaded an image to imgur: http://imgur.com/a/iQ70T (ignore the typo in the image).Thank you for your attention.

The reason why this happens is that you have attached all the event listeners to the window object and not the canvas (mousedown, the others can be on window) the mousedown will be registered also when you hit the send button.
This means the last path is redrawn for each frame since mousehold will be true, accumulating anti-aliasing pixels affecting the alpha channel, hence will change the bitmap.
Example fix (just attach the mousedown handler to canvas):
addEventListener("load", Load, false);
var board = undefined;
var ctx = undefined;
var loaded = false;
var mousehold = false;
var mousex = 0;
var mousey = 0;
var lastx = 0;
var lasty = 0;
var firstclick = false;
function Load(e) {
loaded = true;
board = document.getElementById("board");
ctx = board.getContext("2d");
board.width = window.innerWidth;
board.height = window.innerHeight;
// this must be at canvas element
board.addEventListener("mousedown", function(e) {
mousehold = true;
}, false);
addEventListener("mouseup", function(e) {
mousehold = false;
firstclick = false;
}, false);
addEventListener("mousemove", function(e) {
mousex = e.clientX;
mousey = e.clientY;
// if(mousehold == true) console.log(mousex + " " + mousey);
}, false);
ctx.beginPath();
ctx.lineWidth = 5;
UpdateBoard();
}
function UpdateBoard() {
if (mousehold == true) {
if (firstclick == false) {
lastx = mousex;
lasty = mousey;
firstclick = true;
}
ctx.moveTo(lastx, lasty);
ctx.lineTo(mousex, mousey);
ctx.stroke();
lastx = mousex, lasty = mousey;
}
window.requestAnimationFrame(UpdateBoard);
}
function send() {
var img = board.toDataURL();
console.log(img.length);
}
body {margin:0}
<canvas id="board"></canvas>
<button style="right:10px;bottom:10px;position:fixed;z-index:999999;" onclick="send();">Send</button>

Related

Let users draw rectangles with mouse in canvas with Javascript

I am going to create a canvas to let users can draw some rectangles in canvas. It can show the rectangle when the user is dragging the mouse. Also, it allows the user to draw one or more rectangles in canvas. I've found a solution like this:
// get references to the canvas and context
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
// style the context
ctx.strokeStyle = "blue";
ctx.lineWidth = 3;
// calculate where the canvas is on the window
// (used to help calculate mouseX/mouseY)
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();
// this flage is true when the user is dragging the mouse
var isDown = false;
// these vars will hold the starting mouse position
var startX;
var startY;
function handleMouseDown(e) {
e.preventDefault();
e.stopPropagation();
// save the starting x/y of the rectangle
startX = parseInt(e.clientX - offsetX);
startY = parseInt(e.clientY - offsetY);
// set a flag indicating the drag has begun
isDown = true;
}
function handleMouseUp(e) {
e.preventDefault();
e.stopPropagation();
// the drag is over, clear the dragging flag
isDown = false;
}
function handleMouseOut(e) {
e.preventDefault();
e.stopPropagation();
// the drag is over, clear the dragging flag
isDown = false;
}
function handleMouseMove(e) {
e.preventDefault();
e.stopPropagation();
// if we're not dragging, just return
if (!isDown) {
return;
}
// get the current mouse position
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
// Put your mousemove stuff here
// clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// calculate the rectangle width/height based
// on starting vs current mouse position
var width = mouseX - startX;
var height = mouseY - startY;
// draw a new rect from the start position
// to the current mouse position
ctx.strokeRect(startX, startY, width, height);
}
// listen for mouse events
$("#canvas").mousedown(function (e) {
handleMouseDown(e);
});
$("#canvas").mousemove(function (e) {
handleMouseMove(e);
});
$("#canvas").mouseup(function (e) {
handleMouseUp(e);
});
$("#canvas").mouseout(function (e) {
handleMouseOut(e);
});
http://jsfiddle.net/m1erickson/6E2yd/
However, the solution can only allow users to draw one rectangle. If users draw the second rectangle, the previous rectangle will be wiped out because it will call ctx.clearRect() every time during dragging the mouse.
Edit: Sorry for my mistake. I missed the position:relative property for the container. Now it should work.
The code in your jsfiddle redraw repeatedly to give indications of the rectangle. I think it would be better to separate this indication canvas to a new layer, and use an overlapped layer to show the drawn rectangles.
JS:
// get references to the canvas and context
var canvas = document.getElementById("canvas");
var overlay = document.getElementById("overlay");
var ctx = canvas.getContext("2d");
var ctxo = overlay.getContext("2d");
// style the context
ctx.strokeStyle = "blue";
ctx.lineWidth = 3;
ctxo.strokeStyle = "blue";
ctxo.lineWidth = 3;
// calculate where the canvas is on the window
// (used to help calculate mouseX/mouseY)
var $canvas = $("#canvas");
var canvasOffset = $canvas.offset();
var offsetX = canvasOffset.left;
var offsetY = canvasOffset.top;
var scrollX = $canvas.scrollLeft();
var scrollY = $canvas.scrollTop();
// this flage is true when the user is dragging the mouse
var isDown = false;
// these vars will hold the starting mouse position
var startX;
var startY;
var prevStartX = 0;
var prevStartY = 0;
var prevWidth = 0;
var prevHeight = 0;
function handleMouseDown(e) {
e.preventDefault();
e.stopPropagation();
// save the starting x/y of the rectangle
startX = parseInt(e.clientX - offsetX);
startY = parseInt(e.clientY - offsetY);
// set a flag indicating the drag has begun
isDown = true;
}
function handleMouseUp(e) {
e.preventDefault();
e.stopPropagation();
// the drag is over, clear the dragging flag
isDown = false;
ctxo.strokeRect(prevStartX, prevStartY, prevWidth, prevHeight);
}
function handleMouseOut(e) {
e.preventDefault();
e.stopPropagation();
// the drag is over, clear the dragging flag
isDown = false;
}
function handleMouseMove(e) {
e.preventDefault();
e.stopPropagation();
// if we're not dragging, just return
if (!isDown) {
return;
}
// get the current mouse position
mouseX = parseInt(e.clientX - offsetX);
mouseY = parseInt(e.clientY - offsetY);
// Put your mousemove stuff here
// calculate the rectangle width/height based
// on starting vs current mouse position
var width = mouseX - startX;
var height = mouseY - startY;
// clear the canvas
ctx.clearRect(0, 0, canvas.width, canvas.height);
// draw a new rect from the start position
// to the current mouse position
ctx.strokeRect(startX, startY, width, height);
prevStartX = startX;
prevStartY = startY;
prevWidth = width;
prevHeight = height;
}
// listen for mouse events
$("#canvas").mousedown(function (e) {
handleMouseDown(e);
});
$("#canvas").mousemove(function (e) {
handleMouseMove(e);
});
$("#canvas").mouseup(function (e) {
handleMouseUp(e);
});
$("#canvas").mouseout(function (e) {
handleMouseOut(e);
});
HTML:
<h4>Drag the mouse to create a rectangle</h4>
<div id = "canvasWrapper">
<canvas id="overlay" width=300 height=300></canvas>
<canvas id="canvas" width=300 height=300></canvas>
</div>
CSS:
body{ background-color: ivory; }
canvas{
border: 1px solid red;
position: absolute;
}
#canvasWrapper{
position:relative;
}
http://jsfiddle.net/xkmqz9ho/
I've never tried anything on canvas, but you could try adding ctx.save() to the mouseout function and replacing ctx.clear(...) with ctx.restore().
more information about this on: https://developer.mozilla.org/es/docs/Web/API/CanvasRenderingContext2D/save

Getting Error "addEventListener is not a function"

I want to pick my color from the color picker and then draw with this color in my canvas.
I get the Error:
Uncaught TypeError: colors.addEventListener is not a function
at window.onload
I use the npm color picker.
I get the Error at the call of the function:
colors.addEventListener('click', function(event)
My html:
<div class="picker"
acp-color="#EFE9E7"
acp-palette="#f44336|#e91e63|#9c27b0|#673ab7|#3f51b5|#2196f3|#03a9f4|#00bcd4|
#009688|#4caf50|#8bc34a|#cddc39|#cddc39|#ffeb3b|#ffc107|#ff9800|#ff5722|#795548|#9e9e9e|#20707|#befe7ee|#9e9e9e|#9e9e5e|#9e4e9e">
</div>
<div class="right-block">
<canvas id="paint-canvas" width="640" height="400"></canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/a-color-picker#1.1.8/dist/acolorpicker.js"></script>
<script src="./paint.js"></script>
My js code
var colors="#f44336";
AColorPicker.from('.picker')
.on('change', (picker, color) => {
colors= color;
});
var canvas = document.getElementById("paint-canvas");
var context = canvas.getContext("2d");
var boundings = canvas.getBoundingClientRect();
window.onload = function () {
// Definitions
// Specifications
var mouseX = 0;
var mouseY = 0;
context.strokeStyle = 'black'; // initial brush color
context.lineWidth = 1; // initial brush width
var isDrawing = false;
loadInput.addEventListener('change', (event) => this.load(event));
// Handle Colors
colors.addEventListener('click', function(event) {
context.strokeStyle = event.target.value || 'black';
});
// Mouse Down Event
canvas.addEventListener('mousedown', function(event) {
setMouseCoordinates(event);
isDrawing = true;
// Start Drawing
context.beginPath();
context.moveTo(mouseX, mouseY);
});
// Mouse Move Event
canvas.addEventListener('mousemove', function(event) {
setMouseCoordinates(event);
if(isDrawing){
context.lineTo(mouseX, mouseY);
context.stroke();
}
});
// Mouse Up Event
canvas.addEventListener('mouseup', function(event) {
setMouseCoordinates(event);
isDrawing = false;
});
// Handle Mouse Coordinates
function setMouseCoordinates(event) {
mouseX = event.clientX - boundings.left;
mouseY = event.clientY - boundings.top;
}
};
You cannot add an event listener to a string.
var colors="#f44336";
colors.addEventListener('click', function(event) {
context.strokeStyle = event.target.value || 'black';
});
String does not have this method. Given the assumption it remains a string after the picker on change event.
The thing is that, you need to change your context.strokeColor when the event fires up on the color change when picked, So you should Create a reference of the AColorPciker element and use its event emitter when your document is loaded
Then you can easily change your strokeColor, I hope this works for you.
I am adding the edited script, which should work for you.
// Initializing the color picker reference
var colorPicker = AColorPicker.from('.picker');
var canvas = document.getElementById("paint-canvas");
var context = canvas.getContext("2d");
var boundings = canvas.getBoundingClientRect();
window.onload = function () {
// Definitions
// Specifications
var mouseX = 0;
var mouseY = 0;
context.strokeStyle = 'black'; // initial brush color
context.lineWidth = 1; // initial brush width
var isDrawing = false;
// Here I am using the refernce of AColorPicker to set the context Stroke color, when the change is emitted on the color change
colorPicker.on('change', (picker, color) => {
context.strokeStyle = color;
});
// Mouse Down Event
canvas.addEventListener('mousedown', function(event) {
setMouseCoordinates(event);
isDrawing = true;
// Start Drawing
context.beginPath();
context.moveTo(mouseX, mouseY);
});
// Mouse Move Event
canvas.addEventListener('mousemove', function(event) {
setMouseCoordinates(event);
if(isDrawing){
context.lineTo(mouseX, mouseY);
context.stroke();
}
});
// Mouse Up Event
canvas.addEventListener('mouseup', function(event) {
setMouseCoordinates(event);
isDrawing = false;
});
// Handle Mouse Coordinates
function setMouseCoordinates(event) {
mouseX = event.clientX - boundings.left;
mouseY = event.clientY - boundings.top;
}
};

How do i get update to stop running when I click?

Here is a code segment where i am trying to make update stop running so that I can put a dot on the canvas. When I try to get putPoint to return clicked = true, it makes clicked equal true regardless if I click or not. I just want to return true if and only if I click.
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
//canvas.width = window.innerWidth;
//canvas.height = window.innerHeight;
var radius = 2;
var dragging = false; // wether or not the mouse button is held down
ctx.lineWidth = radius * 2;
var canvasPos = getPosition(canvas);
var mouseX = 0;
var mouseY = 0;
var clicked = false;
// here is where I declare clicked = true globally
function update() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.arc(mouseX, mouseY, radius, 0, 2 * Math.PI, true);
ctx.fill();
requestAnimationFrame(update);
}
canvas.addEventListener("mousemove", setMousePosition, false);
function setMousePosition(e) {
mouseX = e.clientX;
mouseY = e.clientY;
}
//console.log("before update " + clicked);
if (clicked != true) {
update();
//console.log("inside update " +clicked);
}
// here is the code I want to stop when I click
//console.log("after update " + clicked);
function putPoint() {
//e.clientX and e.clientY get the mouse position
ctx.beginPath();
//e.clientX and e.clientY get the mouse position
ctx.arc(mouseX - 10, mouseY - 10, radius, 0, Math.PI * 2);
//ctx.arc(e.offsetX, e.offsetY, radius, 0, Math.PI * 2);
ctx.fill();
//console.log("inside putPoint " + clicked);
}
//putPoint puts a dot on the canvas at the mouse position. But it wont fire unless
//I stop update, which tracks my dot.
//console.log("after putPoint " + clicked);
canvas.addEventListener("mousedown", putPoint);
//console.log(putPoint());
//console.log(clicked);
function getPosition(el) {
var xPosition = 0;
var yPosition = 0;
while (el) {
xPosition += (el.offsetLeft - el.scrollLeft + el.clientLeft);
yPosition += (el.offsetTop - el.scrollTop + el.clientTop);
el = el.offsetParent;
}
return {
x: xPosition,
y: yPosition
};
}
<canvas id=myCanvas>
</canvas>
below is a smaller reproduction of the problem. basically I am trying to update my variable to true when i click on the element. But when I return true or even set clicked to to true within the test function, it still reads true wether I click or not. It doesnt dynamically change. Maybe Im using the wrong event ? im not sure.
var clicked = false;
console.log(clicked);
function test () {
return true;
}
clicked = test();
console.log(clicked);
document.getElementsByTagName("h1")[0].addEventListener("mousedown", test);
I'm inferring a bit based on clues from both the used and unused (e.g. dragging variable) parts of your first snippet, but it seems to me like you are trying to draw a point that tracks with your mouse, and then once a click event has occurred you want to start drawing points dragging after the mouse until that click is released.
First, your issue with your 'clicked' tracking
I think you are misunderstanding when different statements are executed. In your second snippet all of the statements outside of the 'test' event handler function are only executed once. The 'test' function will be called with each mouse click, but simply returns true and does not change the value of 'clicked'. So, the statement:
var clicked = false;
...and the statement:
clicked = test();
...each only execute once. Here is a quick example to show you how you could track the toggling of that value. Try a simple click and also holding the click for a second before releasing to get the idea.
var clicked = false;
var clickableArea = document.getElementById("clickable");
clickableArea.addEventListener('mousedown', function() {
clicked = true;
console.log('Clicked, value of clicked var: ' + clicked);
});
clickableArea.addEventListener('mouseup', function() {
clicked = false;
console.log('Released, value of clicked var: ' + clicked);
});
<div id="clickable">Click Me</div>
What I think you are going for with your canvas rendering:
Move the mouse around and then click and drag the mouse.
var canvas, ctx;
var radius = 2;
var mouseX = 0;
var mouseY = 0;
var clicked = false;
var dragging = false;
// manages the drawing cycle
function putPoint() {
// clear the canvas if not dragging, or just before the first draw of a dragging cycle
if(!dragging) {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
dragging = clicked;
// draw
var offset = dragging ? 10 : 0;
ctx.beginPath();
ctx.arc(mouseX-offset, mouseY-offset, radius, 0, 2 * Math.PI, true);
ctx.fill();
// kick off another cycle
requestAnimationFrame(putPoint);
}
// event handlers
function trackMouse(e) {
mouseX = e.clientX;
mouseY = e.clientY;
}
function startedDragging() {
clicked = true;
}
function quitDragging() {
clicked = false;
dragging = false;
}
// only runs once when called below, sets things up, starts the drawing cycle
function start() {
canvas = document.getElementById("myCanvas");
ctx = canvas.getContext("2d");
ctx.lineWidth = radius * 2;
// attach events to handlers
canvas.addEventListener("mousemove", trackMouse, false);
canvas.addEventListener("mousedown", startedDragging);
canvas.addEventListener("mouseup", quitDragging);
requestAnimationFrame(putPoint);
}
start(); // calling start to kick things off
<canvas id="myCanvas">
</canvas>

<canvas> drawing corrupted on Firefox Mobile, HUAWEI Mediapad 10, Android 4.1.2

I'm facing an odd issue with firefox for android and html5 canvas.
I have a form that allows the customer to sign. The form will work perfectly on say chrome (screenshot 1) but will scramble the moment the customer attempts to sign on Firefox for android.
the JS code for the signature pad is from http://www.zetakey.com/codesample-signature.php
The js code is as follows:
// JavaScript Document
function signatureCapture() {
//Actual Code starts here
var parent=document.getElementById("canvas");
parent.childNodes[0].nodeValue = "";
var canvasArea=document.createElement("canvas");
canvasArea.setAttribute("id", "newSignature");
parent.appendChild(canvasArea);
var canvas = document.getElementById("newSignature");
var context = canvas.getContext("2d");
if (!context) {
throw new Error("Failed to get canvas' 2d context");
}
screenwidth = screen.width;
//if (screenwidth < 480){
// canvas.width = screenwidth - 8 ;
// canvas.height = (screenwidth * 0.63) ;
//}
//else {
canvas.width = 460 ;
canvas.height = 300 ;
//}
context.fillStyle = "#fff";
context.strokeStyle = "#444";
context.lineWidth = 1.2;
context.lineCap = "round";
context.fillRect(0, 0, canvas.width, canvas.height);
context.fillStyle = "#3a87ad";
context.strokeStyle = "#3a87ad";
context.lineWidth = 1;
context.moveTo((canvas.width*0.042),(canvas.height * 0.7));
context.lineTo((canvas.width*0.958),(canvas.height * 0.7));
context.stroke();
context.fillStyle = "#fff";
context.strokeStyle = "#444";
var disableSave = true;
var pixels = [];
var cpixels = [];
var xyLast = {};
var xyAddLast = {};
var calculate = false;
//functions
{
function remove_event_listeners() {
canvas.removeEventListener('mousemove', on_mousemove, false);
canvas.removeEventListener('mouseup', on_mouseup, false);
canvas.removeEventListener('touchmove', on_mousemove, false);
canvas.removeEventListener('touchend', on_mouseup, false);
document.body.removeEventListener('mouseup', on_mouseup, false);
document.body.removeEventListener('touchend', on_mouseup, false);
}
function get_board_coords(e) {
var x, y;
if (e.changedTouches && e.changedTouches[0]) {
var offsety = canvas.offsetTop || 0;
var offsetx = canvas.offsetLeft || 0;
x = e.changedTouches[0].pageX - offsetx;
y = e.changedTouches[0].pageY - offsety;
} else if (e.layerX || 0 == e.layerX) {
x = e.layerX;
y = e.layerY;
} else if (e.offsetX || 0 == e.offsetX) {
x = e.offsetX;
y = e.offsetY;
}
return {
x : x,
y : y
};
};
function on_mousedown(e) {
e.preventDefault();
e.stopPropagation();
canvas.addEventListener('mousemove', on_mousemove, false);
canvas.addEventListener('mouseup', on_mouseup, false);
canvas.addEventListener('touchmove', on_mousemove, false);
canvas.addEventListener('touchend', on_mouseup, false);
document.body.addEventListener('mouseup', on_mouseup, false);
document.body.addEventListener('touchend', on_mouseup, false);
empty = false;
var xy = get_board_coords(e);
context.beginPath();
pixels.push('moveStart');
context.moveTo(xy.x, xy.y);
pixels.push(xy.x, xy.y);
xyLast = xy;
};
function on_mousemove(e, finish) {
e.preventDefault();
e.stopPropagation();
var xy = get_board_coords(e);
var xyAdd = {
x : (xyLast.x + xy.x) / 2,
y : (xyLast.y + xy.y) / 2
};
if (calculate) {
var xLast = (xyAddLast.x + xyLast.x + xyAdd.x) / 3;
var yLast = (xyAddLast.y + xyLast.y + xyAdd.y) / 3;
pixels.push(xLast, yLast);
} else {
calculate = true;
}
context.quadraticCurveTo(xyLast.x, xyLast.y, xyAdd.x, xyAdd.y);
pixels.push(xyAdd.x, xyAdd.y);
context.stroke();
context.beginPath();
context.moveTo(xyAdd.x, xyAdd.y);
xyAddLast = xyAdd;
xyLast = xy;
};
function on_mouseup(e) {
remove_event_listeners();
disableSave = false;
context.stroke();
pixels.push('e');
calculate = false;
};
}//end
canvas.addEventListener('mousedown', on_mousedown, false);
canvas.addEventListener('touchstart', on_mousedown, false);
}
function signatureSave() {
var canvas = document.getElementById("newSignature");
// save canvas image as data url (png format by default)
var dataURL = canvas.toDataURL("image/png");
document.getElementById("saveSignature").src = dataURL;
};
function signaturePost() {
var canvas = document.getElementById("newSignature");
// save canvas image as data url (png format by default)
document.getElementById('postSignature').value = canvas.toDataURL('image/png');
document.forms["submit_signature"].submit()
}
/*
Reload page instead of this function:
function signatureClear() {
var parent=document.getElementById("canvas");
var child=document.getElementById("newSignature");
parent.removeChild(child);
signatureCapture();
}
*/
// http://stackoverflow.com/questions/11385471/save-canvas-image-post-the-data-string-to-php
function signatureSend() {
var canvas = document.getElementById("newSignature");
var dataURL = canvas.toDataURL("image/png");
document.getElementById("saveSignature").src = dataURL;
var sendemail = document.getElementById('sendemail').value;
var replyemail = document.getElementById('replyemail').value;
var form = document.createElement("form");
form.setAttribute("action","upload_file.php");
form.setAttribute("enctype","multipart/form-data");
form.setAttribute("method","POST");
form.setAttribute("target","_self");
form.innerHTML = '<input type="text" name="image" value="'+dataURL+'"/>'+'<input type="email" name="email" value="'+sendemail+'"/>'+'<input type="email" name="replyemail" value="'+replyemail+'"/>';
form.submit();
}
I have implemented the code, and it works nicely in Chrome
but it scrambles in firefox
I'm using firefox 29.0.1 on HUAWEI mediapad 10 running android 4.1.2
Any thoughts?
Update: Here is a fiddle that shows the whole code at work:
http://jsfiddle.net/3KHAf/
Based on the artifacts in the image, I suspect this is a bug the device graphics driver code and Firefox steps on it. Nothing unheard int the mobile world. Or it could be bug in Firefox itself too, but I find this option more unlikely.
I suggest the following steps
Check can you repeat the issue on other Android devices
Isolate the code causing graphical artifacts to a jsfiddle.net test case, where you have only the source code lines triggering the problem left. Share the link for others to test the issue.
Report a bug against Firefox Mobile https://bugzilla.mozilla.org/
If the bug is on Mozilla's side and it is repeatable, they usually get those fixed quite fast.
There is a #mobile channel on irc.mozilla.org where you can ask for further help.

Touch event initial coordinates

I was searching for an answer but couldn't find any. My problem is:
I need an object to appear on canvas when I touch it and to disappear when I cancel the touch event (lift my finger).
However, I need the object to have the initial coordinates of the original touch position, meaning I don't want it to move with my finger.
var can = document.getElementById('can');
var ctx = can.getContext('2d');
var WIDTH = can.width;
var HEIGHT = can.height;
var canX;
var canY;
var mouseIsDown = 0;
var requestAnimFrame = window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame;
var image = new Image();
image.src = '1.png';
function init(){
can.addEventListener("mousedown", mouseDown, false);
can.addEventListener("mousemove", mouseXY, false);
document.body.addEventListener("mouseup", mouseUp, false);
loop();
}
function mouseUp() {
mouseIsDown = 0;
mouseXY();
}
function mouseDown() {
mouseIsDown = 1;
mouseXY();
}
function mouseXY(e) {
if (!e)
e = event;
canX = e.pageX - can.offsetLeft;
canY = e.pageY - can.offsetTop;
}
function loop(){
if(mouseIsDown===1){
draw();
} else
ctx.clearRect(0,0,WIDTH, HEIGHT);
requestAnimFrame(loop);
}
function draw(){
ctx.clearRect(0,0,WIDTH, HEIGHT);
ctx.drawImage(image,0,0,40,40,canX-20,canY-20,40,40);
}
You need to store the initial mouse/touch position in a separate pair of variables.
var initialCanX, initialCanY;
function mouseDown(e) {
mouseIsDown = 1;
initialCanX = e.pageX - can.offsetLeft;
initialCanY = e.pageY - can.offsetTop;
mouseXY(e);
}
And then, in the drawing function, use these coordinates to draw the second image.
function draw(){
ctx.clearRect(0, 0, WIDTH, HEIGHT);
ctx.drawImage(image, canX, canY); // the moving image
ctx.drawImage(image2, initialCanX, initialCanY); // the static image
}

Categories