Javascript routine works on PCs but not on touchscreen phones or tablets:

thenelson
thenelson used Ask the Experts™
on
Javascript routine works on PCs but not on touchscreen phones or tablets:

When I touch the canvas, the line is drawn halfway down the canvas instead of under the finger. If only half the canvas is displayed on the screen (the bottom half is below the screen) then the line is drawn under the finger. On a PC with a mouse, it works fine.


Here is a link to the webpage modified so it doesn't send data to me: www.barnwellmd.com/PainDiagram/Testdrawing.html.

Here is the code:
/* © 2009 ROBO Design
 * http://www.robodesign.ro
 */

var imageData, context, pixels;

function clearCanvas()
{
	context.putImageData(imageData, 0, 0);
}

function checkFields()
{
	var themessage = "Please complete the following fields:";
	if (document.form.ptname.value=="") 
		{
		themessage = themessage + "\n     Patient's Name";
		}
	if (document.form.dob.value=="") 
		{
		themessage = themessage + "\n     Birthdate";
		}
	//alert if fields are empty and cancel form submit
	if (themessage != "Please complete the following fields:") 
		{
			alert(themessage);
			return true;
		}
		else
		{
			return checkdate(document.form.dob.value);
		}
}
function checkdate(input)
{
	
	var validformat=/^\d{2}\/\d{2}\/\d{4}$/ //Basic check for format validity
	var returnval=true
	if (!validformat.test(input))
		alert("Invalid Date Format. Format: (mm/dd/yyyy) \nPlease correct and submit again.")
	else
	{ //Detailed check for valid date ranges
		var monthfield=input.split("/")[0]
		var dayfield=input.split("/")[1]
		var yearfield=input.split("/")[2]
		var dayobj = new Date(yearfield, monthfield-1, dayfield)
		if ((dayobj.getMonth()+1!=monthfield)||(dayobj.getDate()!=dayfield)||(dayobj.getFullYear()!=yearfield))
			alert("Invalid Day, Month, or Year range detected. \nPlease correct and submit again.")
		else
			returnval=false
	}
	if (returnval==true) input.select()
	return returnval
}

function saveCanvas() 
{
	if (checkFields()) return;
	clearGray();
	createPrint();
	var testCanvas = document.getElementById("imageView");  
	var img = testCanvas.toDataURL("image/png");
	newwindow = window.open()
	newwindow.document.write('<img src="' + img + '"/>');
	newwindow.document.close();
	newwindow.focus();
	newwindow.alert("You can now use your browser's print function to print the image\nor right click on the image and select \"save image as\" to save it.\n\nClose this window to return to the previous window.");
}
		
function sendCanvas()
{
	if (checkFields()) return;
	clearGray();
	createPrint();
	var testCanvas = document.getElementById("imageView");  
	var canvasData = testCanvas.toDataURL("image/png");
	//alert(canvasData);
	var ajax = new XMLHttpRequest();
	//alert ('https://www.barnwellmd.com/Uploadroutines/uploadbase64.php?name=' + document.form.ptname.value.replace(/ /g,"_"));
	ajax.open("POST",'https://www.barnwellmd.com/Uploadroutines/uploadbase64.php?name=' + document.form.ptname.value.replace(/ /g,"_"),false);
	//ajax.open("POST",'https://www.barnwellmd.com/Uploadroutines/uploadbase64.php',true);    
	ajax.setRequestHeader('Content-Type', 'canvas/upload');
	//ajax.setRequestHeader('Content-Type', 'application/upload');
	ajax.onreadystatechange=function()
	{
		if (ajax.readyState == 4)
		{
			alert(ajax.responseText);
			// Write out the filename.
			//document.getElementById("debugFilenameConsole").innerHTML="Saved as<br><a target='_blank' href='"+ajax.responseText+"'>"+ajax.responseText+"</a><br>Reload this page to generate new image or click the filename to open the image file.";
		}
	}
	ajax.send(canvasData);
}

function createPrint()
{
	context.font="25px Arial";
	context.fillStyle  = "black";
	context.fillText(document.form.ptname.value + " DOB: " + document.form.dob.value,10,640);
	context.fillText("Legend:",275,425);
	context.font="bold 25px Arial";
	context.fillStyle  = "#FF0000";
	context.fillText("Burning",275,450);
	context.fillStyle  = "#FFFF00";
	context.fillText("Aching",275,475);
	context.fillStyle  = "#8080FF";
	context.fillText("Numbness",275,500);
	context.fillStyle  = "#B26B00";
	context.fillText("Pins & needles",275,525);
	context.fillStyle  = "#FF00FF";
	context.fillText("Stabbing",275,550);
	context.fillStyle  = "#59B200";
	context.fillText("Shooting pain",275,575);
	context.fillStyle  = "#FF7F50";
	context.fillText("Referred pain",275,600);
}

function clearGray()
{
	var imageData2 = context.getImageData(0, 0, 700, 643);
	var newPixels = imageData2.data;
	for (var i = 0, il = pixels.length; i < il; i += 4) 
	{
		if((pixels[i] == 255 && pixels[i+1] == 204 && pixels[i+2] == 153) 
		|| (newPixels[i] > 235 && newPixels[i+1] < 150 && newPixels[i+2] > 75 && newPixels[i+2] < 110))
		{
		}
		else
		{
		   newPixels[i] = pixels[i];
		   newPixels[i+1] = pixels[i+1];
		   newPixels[i+2] = pixels[i+2];
		}
	}
	context.putImageData(imageData2, 0, 0);
	context.fillStyle  = "#CDCDCD";
	context.fillText("Referred pain",275,600);
}

// Keep everything in anonymous function, called on window load.
if(window.addEventListener) {
window.addEventListener('load', function () {
	var canvas, tool;
	var lastX, lastY, prevX, prevY, segCount, reptSeg;


function init () {
	// Find the canvas element.
	canvas = document.getElementById('imageView');
	if (!canvas) {
		alert('Error: I cannot find the canvas element!');
		return;
	}

	if (!canvas.getContext) {
		alert('Error: no canvas.getContext!');
		return;
	}

	// Get the 2D canvas context.
	context = canvas.getContext('2d');
	if (!context) {
		alert('Error: failed to getContext!');
		return;
	}
	
	var img=new Image();
	img.onload = function(){
		setTimeout( function(){ 
			context.drawImage(img,0,0);
			imageData = context.getImageData(0, 0, 700, 643);
			pixels = imageData.data;
		},0);
	};
	img.src="PainDiagram.png";


	// Pencil tool instance.
	tool = new tool_pencil();

	// Attach the mousedown, mousemove and mouseup event listeners.
	canvas.addEventListener('mousedown', ev_canvas, false);
	canvas.addEventListener('mousemove', ev_canvas, false);
	canvas.addEventListener('mouseup', ev_canvas, false);
	// Attach the touchstart, touchmove and touchend event listeners.
	canvas.addEventListener('touchstart', ev_canvas, false);
	canvas.addEventListener('touchmove', ev_canvas, false);
	canvas.addEventListener('touchend', ev_canvas, false);
	canvas.addEventListener('touchcancel', ev_canvas, false);
	canvas.addEventListener('touchend', clearGray, false); 
}

	// This painting tool works like a drawing pencil which tracks the mouse 
	// movements.
	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 = this.touchstart = function (ev) {
			context.lineCap = "round";
			context.strokeStyle = color_value;
			lastX = ev._x;
			lastY = ev._y;
			prevX = ev._x;
			prevY = ev._y;
			segCount = 0;
			if (color_value == "#FF7F50")	 //referred pain
			{
				context.lineWidth = 2;
				reptSeg = 7;
			}
			else
			{
				context.lineWidth = 10;
				reptSeg = 1;
			}
	
	    context.beginPath();
//        context.moveTo(ev._x, ev._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 = this.touchmove = function (ev) {
		if (tool.started) {
			if(!segCount)
			{
				prevX = lastX;
				prevY = lastY;
				lastX = ev._x;
				lastY = ev._y;
				segCount = reptSeg;
				context.lineTo(ev._x, ev._y);
				context.stroke();
			}
			segCount--;
		}
    };

	// This is called when you release the mouse button.
	this.mouseup = this.touchend = this.touchcancel = function (ev) {
		if (tool.started) 
		{
			if (color_value == "#FF7F50")
			{
				var angle = Math.atan2(lastY-prevY,lastX-prevX);
		  		context.beginPath();
				context.moveTo(lastX+15*Math.cos(angle),lastY+15*Math.sin(angle));
				context.lineTo(lastX-7*Math.cos(angle-Math.PI/4),lastY-7*Math.sin(angle-Math.PI/4));
		  		context.lineTo(lastX-7*Math.cos(angle+Math.PI/4),lastY-7*Math.sin(angle+Math.PI/4)); 
				context.closePath();
				context.fillStyle  = color_value;
				context.fill();
			}
			tool.started = false;
			tool.mousemove(ev);
			tool.touchmove(ev);
			clearGray();
			//document.form.output.value = document.form.output.value + " x= " + ev._x + ",  y= " + ev._y + "\nLX= " + lastX + ", LY= " + lastY +  "\npX= " + prevX + ", pY= " + prevY + "\nsegCount= " + segCount + "\n\n";
		}
    };
  }

	// The general-purpose event handler. This function just determines the mouse 
	// position relative to the canvas element.
  

 
	function ev_canvas (ev) {
		if (ev.offsetX || ev.offsetX == 0) { // Opera and WebKit
		ev._x = ev.offsetX;
		ev._y = ev.offsetY;
		} 
		else if (ev.layerX || ev.layerX == 0) { // Firefox
			ev._x = ev.layerX;
			ev._y = ev.layerY;
		} 
		if( ev.targetTouches ) {
			var rect = ev.target.getBoundingClientRect();
			
			ev._x = ev.targetTouches[0].pageX - rect.left;
			ev._y = ev.targetTouches[0].pageY - rect.top;
		}
		// Call the event handler of the tool.
		var func = tool[ev.type];
		if (func) {
			func(ev);
		}
	}

window.onload = init();

}, false); }


// vim:set spell spl=en fo=wan1croql tw=80 ts=2 sw=2 sts=2 sta et ai cin fenc=utf-8 ff=unix:

Open in new window

Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Multitechnician
Top Expert 2014
Commented:
I can't reproduce this... mabe my mobile phone screen is too big ?
I'm using a Pixel phone. I tried a Samsung tablet and Windows Surface Book using the touch screen. They both worked fine. I'll try some different phones.
leakim971Multitechnician
Top Expert 2014

Commented:
I tried on a nexus 6P...
Exploring SharePoint 2016

Explore SharePoint 2016, the web-based, collaborative platform that integrates with Microsoft Office to provide intranets, secure document management, and collaboration so you can develop your online and offline capabilities.

bbaoIT Consultant

Commented:
if it doesn't work well on selected pones, please share the link URL you got the for the page, so we can help you review the the source code of that specific page. please be aware that the URL might be different for desktop and mobile versions, even a specific URL for a specific OS.
The link to the page is in the original question: www.barnwellmd.com/PainDiagram/Testdrawing.html.
I tried it on several phones and tablets and only found the problem on my Pixel phone.  Probably not worth the effort to fix a problem showing up on one phone.

I have created a new question related to the website: Turn off scrolling and zooming when drawing on image with touch screen (ie: phones and tablets): www.experts-exchange.com/questions/29131033. I'd appreciate you all looking at that.

Thanks for your help.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial