Saturday, October 10, 2009

IE 8 Canvas Workaround

Here's what I learned since my last post.

Putting an element with no background over the shape, stroke and fill elements used internally by excanvas does not stop them picking up mouse events through that element. This can cause undesirable behavior as your invisible element doesn't receive the mouse events you expect. The shape/stroke/fill elements seem to steal mouse events from the invisible element. This happens even if you give them a lower zOrder than the invisible element.

I found 2 ways to solve this:

  1. Accept it and give the shape, stroke and fill elements mouseover/out/move handlers to catch the events that bleed through to them.
  2. Give the invisible element a background-color and a very low opacity. Then no events bleed through to the shape, stroke & fill elements. I used an opacity of 0.01 and couldn't see the element.
I've decided to go with door number 2. I'd rather make a couple of CSS changes than have extra event handlers.

Unfortunately, your mileage may vary.

Friday, October 9, 2009

IE8 Clipping Issue?

I just solved a tricky issue. I don't 100% understand what just happened.

I'm working on my own custom area chart using jQuery and Google's excanvas. As the user moves their mouse over the chart, I wanted a partly transparent vertical line to trace the mouse movement across the chart. Later, I plan to add a little sign with the value.

To create my chart, I start with a div I call "container", then my custom jQuery plugin works as follows:
  1. Add a canvas element and do the appropriate IE setup for excanvas to work
  2. Draw a chart with canvas API calls
  3. Set a mouseover handler on container which does the following:
    1. Append 2 absolute-positioned divs to the container, so they go over the canvas. There's a "screen" div and a "tracker" div. The tracker div is the vertical line I want the user to see. It is positioned over the canvas. The screen div goes over the tracker div and the canvas. So, in Z-order from bottom to top, that's container to canvas to tracker to screen. The screen div has no background-color or image, so it's transparent.
    2. I setup a mousemove handler on the screen div which moves the tracker div wherever the mouse goes
    3. I set a mouseout handler on the screen div to remove tracker and screen divs

I found I needed the screen div because I originally had the container's mouseout event removing the tracker. Trouble is, since I was creating the tracker right under the mouse, the mouseout event for the container fired immediately because the tracker was between the mouse and the container. As a result, I got a loop of mouseout/over and the tracker would flash. I decided to put the screen div over everything to simplify matters by blocking mouse events.

I got it all working in Firefox and then tested in IE.

Odd thing was, when I got a mousemove event on the screen element, the event.pageX would be undefined sometimes (remember, I'm using jQuery, so it should be consistent). Also, my tracker div would go to the left (left:0px) on and off after I moved the mouse past a certain X coordinate. That doesn't make much sense from the code. The mousemove event must have been failing somehow.

Googling for various permutations of: "jQuery IE8 event.pageX undefined" yielded nothing.

I don't really understand what was happening, but I feel like it has something to do with the mouse events making it through the screen div. Testing confirmed this was happening, but I can't see why it would cause an issue.

Finally, I decided to give the screen a background color and a low opacity so I could see how the tracker moved. Suddenly everything started working!

I tried writing a minimal test page that I could post here to demonstrate the problem.

When I couldn't replicate it, I commented-out basically all the HTML on the page, and I commented out my fix. That replicated the problem on a mostly blank page. Then I did a "Save As" on the page and let IE save all the included JavaScript. When I opened the page from disk (instead of from the Django dev server) the issue went away.

I'm tempted to think it's a security issue, since it's disk vs. localhost. But since when do security settings change how events work?

Google Chrome Frame is starting to sound like a good idea.

This is going to bug me until I understand it.

UPDATE: I was able to produce a cut down test case. I'm still trying to isolate the cause of the tracker div's sporadic trips to the left. The problem goes away if the canvas is still present but I comment out all the calls to the 2D context. Maybe it's something to do with how Explorer canvas works?

UPDATE: Solved

Wednesday, October 7, 2009

SproutCore 1.0 Coming Soon

I discovered SproutCore a while back and it didn't really seem all that interesting at the time.

The other day I was checking using
Indeed's excellent jobtrends feature to watch  the adoption of various JavaScript toolkits (jQuery vs Dojo vs GWT vs ExtJS vs Qooxdoo). I was mainly interested in the "heavier" frameworks which have support for lots of widgets but included jQuery for reference. 


Thinking of the adoption rates of the above got me thinking about SproutCore again. So I went over to the project site and it seems that while I wasn't looking, the SproutCore guys have busily started moving towards a 1.0 release.

I spent a few hours playing with it. I had a little difficulty with some of the docs. Some of it looks out of date, other docs have 'coming soon' next to them. The
docs site seemed to be down for much of the time I was playing.

Still, I feel like this looks really promising. I'm looking forward to trying to build something with it and see how things develop over the next few months.