Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Canvas script works in Firefox and IE but not Chrome

Posted on 2012-03-13
17
Medium Priority
?
1,082 Views
Last Modified: 2013-11-19
The following canvas script works in Firefox and IE but not Chrome. In Chrome, no lines are drawn.  Any ideas why it doesn't work in Chrome?
/* © 2009 ROBO Design
 * http://www.robodesign.ro
 */

// Keep everything in anonymous function, called on window load.
if(window.addEventListener) {
window.addEventListener('load', function () {
  var canvas, context, tool;

  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(){
	context.drawImage(img,0,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);
  }

  // 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 = function (ev) {
		context.beginPath();
		context.lineWidth = 5;
		context.lineCap = "round";
		context.globalAlpha=0.01;
		context.shadowColor="red";
		context.shadowBlur=10;
		context.strokeStyle = "red"; // line color
        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 = function (ev) {
      if (tool.started) {
	    //var p = context.getImageData(ev._x, ev._y, 1, 1).data; 
        //if(p[0]==255 && p[1]==204 && p[2]==153){
	        context.moveTo(ev._x, ev._y);
	        context.lineTo(ev._x, ev._y);
	        context.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) {
    if (ev.layerX || ev.layerX == 0) { // Firefox
      ev._x = ev.layerX;
      ev._y = ev.layerY;
    } else if (ev.offsetX || ev.offsetX == 0) { // Opera
      ev._x = ev.offsetX;
      ev._y = ev.offsetY;
    }

    // Call the event handler of the tool.
    var func = tool[ev.type];
    if (func) {
      func(ev);
    }
  }

  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

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Paint</title>
    <style type="text/css"><!--
      #container { position: relative; }
      #imageView { border: 1px solid #000; }
    --></style>
  </head>
  <body BGCOLOR="#CCFFFF"> 
  
    <div id="container">
      <canvas id="imageView" width="700" height="643" margin: 0 auto>
        <p>Unfortunately, your browser is currently unsupported by our web 
        application.  We are sorry for the inconvenience. Please use one of the 
        supported browsers listed below, or draw the image you want using an 
        offline tool.</p>
        <p>Supported browsers: <a href="http://www.opera.com">Opera</a>, <a 
          href="http://www.mozilla.com">Firefox</a>, <a 
          href="http://www.apple.com/safari">Safari</a>, and <a 
          href="http://www.konqueror.org">Konqueror</a>.</p>
      </canvas>
    </div>

    <script type="text/javascript" 
    src="example1.js"></script>
  </body>
</html>

Open in new window

0
Comment
Question by:thenelson
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 6
  • 4
17 Comments
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 37718594
Please look in the console

I get

Failed to load resource
file:///C:/temp/PainDiagram.png

but the next error is more likely the problem:

event.layerX and event.layerY are broken and deprecated in WebKit. They will be removed from the engine in the near future.

So I got rid of the error message by reversing the test here

  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;
    } 

Open in new window


It did not help, though...
0
 
LVL 39

Author Comment

by:thenelson
ID: 37719707
Thanks for that suggestion. I applied the change but as you mentioned, it still does not work in Google. To avoid the Failed to load resource  problem, here is the temporally link to the project while I am building it: www.barnwellmd.com/paint.html
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 37719979
I am investigating.

I found the resource here at EE too :)
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 38

Expert Comment

by:Tom Beck
ID: 37722363
On a side note, remove line 72, context.moveTo(ev._x, ev._y);, from your script and the drawn line will be much smoother.
0
 
LVL 39

Author Comment

by:thenelson
ID: 37722495
Removing context.moveTo(ev._x, ev._y); results in some jagged jumps when the mouse is moved quickly. But thanks for the suggestion:
0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 37722578
The opposite is true. With context.moveTo(ev._x, ev._y);  in the script, the moveTo method is run unnecessarily for every pixel traversed causing a delay in processing. There's no need to re-position the stroke starting point in the mousemove event, it's already been set on mousedown. The result is that when you move the cursor quickly you get dots spaced far apart. The lineTo method is all you need to call as it will draw a continuous string of dots from one point to the next to form a smooth line. Be sure to refresh everything between tests.
0
 
LVL 39

Author Comment

by:thenelson
ID: 37723305
The theory makes sense but it doesn't seem to work out that way. You can try it yourself. www.barnwellmd.com/paint2  has the line context.moveTo(ev._x, ev._y);  remarked out. http://www.barnwellmd.com/paint does not.
0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 37723379
Look again.

http://www.barnwellmd.com/paint has example1.js in which moveTo is not commented out. The drawn line is choppy.

http://www.barnwellmd.com/paint2 has example2.js in which moveTo is commented out. The drawn line is smooth.
0
 
LVL 39

Author Comment

by:thenelson
ID: 37723473
I don't know why we are getting different results.  l am using Firefox 10.0.2 on a tablet computer running Win 7.  I am using a pen with the tablet.  On the two screen print I am moving my penup and down approximately between the two green lines as I move it to the right.  
paint (with moveto)paint (with moveto)
paint2 (without moveto)paint2 (without moveto)
0
 
LVL 38

Expert Comment

by:Tom Beck
ID: 37724469
In that case, we are talking about two different things. moveTo
I'm using Firefox 9.0.1 on Vista. You are moving your pen up and down in a small area. I am sweeping the mouse quickly across the image. Why you get red lines in both cases and I get black for a pen color on one test site is a mystery to me. Leaving moveTo in may be desirable for this project. It's reasonable to anticipate that users will want to draw lines in small, concentrated areas rather than drawing in quick sweeping motions across the page. I think you have bigger problems to overcome than this (like cross browser compatibility). I should not have brought it up as it is unrelated to this question.
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 37725788
I was sure the second example was on purpose since it really gives a good idea of intensity.
I'm still investigating chrome
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 37728229
http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-moveto

This works for me identically in Chrome and Fx on Windows

I commented out BOTH moveTo and it works very well in my opinion

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>Paint</title>
    <style type="text/css"><!--
      #container { position: relative; }
      #imageView { border: 1px solid #000; }
    --></style>
  </head>
  <body BGCOLOR="#CCFFFF"> 
  
    <div id="container">
      <canvas id="imageView" width="700" height="643" margin: 0 auto>
        <p>Unfortunately, your browser is currently unsupported by our web 
        application.  We are sorry for the inconvenience. Please use one of the 
        supported browsers listed below, or draw the image you want using an 
        offline tool.</p>
        <p>Supported browsers: <a href="http://www.opera.com">Opera</a>, <a 
          href="http://www.mozilla.com">Firefox</a>, <a 
          href="http://www.apple.com/safari">Safari</a>, and <a 
          href="http://www.konqueror.org">Konqueror</a>.</p>
      </canvas>
    </div>

    <script type="text/javascript">
/* © 2009 ROBO Design
 * http://www.robodesign.ro
 */

// Keep everything in anonymous function, called on window load.
if(window.addEventListener) {
window.addEventListener('load', function () {
  var canvas, context, tool;

  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(){
	context.drawImage(img,0,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);
  }

  // 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 = function (ev) {
		context.beginPath();
		context.lineWidth = 5;
		context.lineCap = "round";
		context.globalAlpha=0.01;
		context.shadowColor="red";
		context.shadowBlur=10;
		context.strokeStyle = "red"; // line color
//        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 = function (ev) {
      if (tool.started) {
	    //var p = context.getImageData(ev._x, ev._y, 1, 1).data; 
        //if(p[0]==255 && p[1]==204 && p[2]==153){
//	        context.moveTo(ev._x, ev._y);
	        context.lineTo(ev._x, ev._y);
	        context.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) {
    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;
    } 

    // Call the event handler of the tool.
    var func = tool[ev.type];
    if (func) {
      func(ev);
    }
  }

  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:
                                      
    </script>
  </body>
</html>
                                  

Open in new window

0
 
LVL 39

Author Comment

by:thenelson
ID: 37730250
Very nice!   What changes did you make? Your version works in FF, Chrome and IE 9. I switched to a different routine  (www.barnwellmd.com/Paindiagram/PainDiagram) that works in FF & Chrome but not IE. With your version and the moveTo remmed out, the jaggedness is pronounced in FF but not so much in Chrome or IE. I doubt the jaggedness would be much of a problem.using a mouse instead of a pen since I can move the pen faster than the mouse.
0
 
LVL 75

Expert Comment

by:Michel Plungjan
ID: 37730556
I have NO jaggies in fx 10 at all
0
 
LVL 39

Author Comment

by:thenelson
ID: 37732434
I found the answer to  the problem that the code was not working in IE9: I was using a Doctype specifying Html 4
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
    Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
instead of Html 5
     <!DOCTYPE HTML>

So the webpage is working in the latest versions of FF, IE and Chrome. Although I don't know what I did to get it working in Chrome.
0
 
LVL 75

Accepted Solution

by:
Michel Plungjan earned 2000 total points
ID: 37732691
I commented out
//              context.moveTo(ev._x, ev._y);

that did it for me in Chrome
0
 
LVL 39

Author Closing Comment

by:thenelson
ID: 37732831
I have the script now working FF, IE and Chrome. Thanks for your help.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Originally, this post was published on Monitis Blog, you can check it here . Websites are getting bigger and more complicated by the day. Video, images and custom fonts are all great for showcasing your product or service. But the price to pay in…
This article discusses how to implement server side field validation and display customized error messages to the client.
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Learn how to create interesting presentations by including videos to keep your audience engaged using Prezi. Select "Insert" from the top menu in your Prezi editor: Select "YouTube Video": Paste the video URL into the prompt: "Select "Insert":…

730 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question