Jayant's Blog

Wednesday, December 31, 2008

Integrating SVG in blogger post

This is in response to a comment to my earlier post Integrating Dojo in blogger post.

If you want to just use SVG, the following sample works. It uses 2 external JavaScript files, one for basic SVG context and drawing (also used in the Simple SVG Shapes post) and the 2nd one for actually drawing the content.


Here is the HTML markup:

<div id="surface" style="width:300px; height:300px; border:1px solid #000;"></div>
<script type="text/javascript" src="http://ecodevil.net/dev/blog/svg.js"></script>
<script type="text/javascript" src="http://ecodevil.net/dev/blog/blogger_svg.js"></script>

I also tried with Dojo GFX. GFX is a nice abstraction layer to SVG/VML graphics. I tried integrating it into the blogger page, but that didn't worry, it kept throwing a console not found error. Here's the external JavaScript file incase you would like to try it.

Labels: ,

Wednesday, October 08, 2008

SVG events in Safari vs FF3/Opera

So don't get me wrong... FF3 is awesome, but when it comes to rendering HTML/SVG/JavaScript... I think WebKit kicks Gecko's butt! So recently while doing some R&D, where I wanted to layer 2 SVG containers on top of each other, I noticed that the events actually work differently. So check out this sample.

So this is a really simple test page. The code essentially creates and adds an svg element (z-index:0) to the root div. To this new surface, a rectangle is added to it. Next an image to the root div (z-index:1). Finally another svg element (z-index:2) is created and added to the root div and a circle added to it.

Now to test this out, make sure to have Safari/WebKit's console open and in Firefox, Firebug. Click on the 'green rect', 'image', the 'red circle' & finally the 'white background' div.

In Safari, the output looks like:
rect : rect
IMG : image
circle : circle
DIV : div

Where as in Firefox (and Opera)
svg : surface2
svg : surface2
circle : circle
svg : surface2

So basically you can see that, since the 2nd surface is above in z-ordering, it traps all events outside the itself and doesn't let it go through. But Safari seems to have a different algorithm for determining the event source/target. Googling around, I have not been able to find more details on how the each rendering engine determines the event source/target.

Labels: ,

Tuesday, September 16, 2008

iPhone SVG Events

The way the events work on a browser is pretty simple. If you want to listen to a particular event (say mousedown) on the whole document, you simply add an event listener to the document: document.addEventListener("mousedown", listenerFunction, false);. Setting 'false' for the 'useCapture' argument sets the event to bubble, which is the preferred event flow.

The test that we have is really simple. On your iPhone, the page renders a circle, a rectangle & of course these are rendered within a SVG container which is created within a background div. Tap on the circle, then rect and finally the background div. The test pages have 'touchstart' or 'click' event listeners registered by default. Click the 'Add'/'Remove' buttons to add/remove event listeners from the SVG element. There are 2 listener functions, one for logging document events and one for svg events. The events are logged with 'short function name: event.type : event.target'.

If you didn't know this already, you can enable the debug console in Safari on the iPhone.

Now, on the iPhone, the 'touchstart' event is similar to the 'mousedown' on a browser. Go to http://ecodevil.net/dev/blog/events_touch.html using your iPhone. Click on the circle, then rect and finally the white background. You should see 3 events logged.



Now click on the 'Add' button and as expected you will see 1 event (for the button). Now clear the console and click the circle, rect & background again. This time, you will have 5 events logged.



This is actually the expected behavior.

Now from your desktop Safari, go to http://ecodevil.net/dev/blog/events_click.html. You can enable your developer menu as well, see 'Safari Developer FAQ'. You will notice that you have 3 click events logged.



Now click on the 'Add' button and try the test again. You will once again have 1 + 5 events.



Again try http://ecodevil.net/dev/blog/events_click.html using your iPhone 2.1. When you run through the first set of tests, you will see no events logged.



Now click on the 'Add' button and try the test again. You will now see 4 events logged, but there is no click event on the background div.



So What?
So basically, events don't work exactly the same on the iPhone as the desktop browser. On a desktop browser, if an event listener is registered to listen to a particular event on the document, any event of the same type, on any element on the document bubbles up and will be logged, unless the event is stopped from propagating. But seems like on the iPhone, the touch/gesture events work by default on the document as well as the SVG element. But for the click/mouse* events to work on the document, there needs to be an event listener registered to listen to the SVG element. And removing this event listener will stop all click/mouse* events on the document.

Labels: , ,

Monday, September 15, 2008

Simple SVG Shapes

Here's a simple test page which will draw different SVG shapes on your canvas. Of course if your iPhone OS is not 2.1, go get it and try out http://ecodevil.net/dev/blog/shapes.html. So lets looks at the code for http://ecodevil.net/dev/blog/svg.js.

Firstly, I have 3 JavaScript functions. The createNode is the main one which creates the appropriate SVG node using the node type and applies all properties from the argument hash to the new node. The createImage & createText are just specialized uses of this function.

<javascript>
function createNode(type, hash) {
var node = svg.appendChild(document.createElementNS("http://www.w3.org/2000/svg", type));
for (var key in hash) {
node.setAttribute(key, hash[key]);
}
return node;
}

function createImage(href, hash) {
var node = createNode("image", hash);
node.setAttributeNS("http://www.w3.org/1999/xlink", "href", href);
return node;
}

function createText(text, hash) {
var node = createNode("text", hash);
node.appendChild(document.createTextNode(text));
return node;
}
</javascript>

The next is the test function which is called on document.onload. It creates a rect, circle, ellipse, line, polyline, polygon, image, text & path. I've found the Pike's SVG Tutorial to be a good quick reference for SVG syntax.

<javascript>
function test() {
var div = document.getElementById("surface");
svg = div.appendChild(document.createElementNS("http://www.w3.org/2000/svg", "svg"));
svg.setAttribute("style", "left:0px; top:0px; width:320px; height:326px;");

createNode("rect", { x:10, y:10, width:50, height:30, fill:"rgb(0,255,0)" });
createNode("circle", { cx:95, cy:25, r:15, fill:"rgb(255,0,0)" });
createNode("ellipse", { cx:170, cy:25, rx:35, ry:15, fill:"rgb(0,0,255)" });
createNode("line", { x1:230, y1:10, x2:290, y2:40, stroke:"rgb(255,0,255)", "stroke-width":3 });
createNode("polyline", { points:"10,100 10,75 65,75 65,100 120,100 120,75 175,75 175,100 230,100 230,75 285,75 285,100", stroke:"rgb(0,255,255)", "stroke-width":3, fill:"none" });
createNode("polygon", { points:"10,125 285,165 285,125 10,165 10,125", fill:"rgb(255,255,0)" });

createImage("http://news.bbc.co.uk/shared/img/v4/header_blocks.gif", { x:10, y:190, width:107, height:32 });
createText("Ola World", { x:210, y:215, "font-size":32, "text-anchor":"middle", "font-weight":"bold" });
createNode("path", { d:"M10,265 L10,300 L100,265 C100,265 300,265 200,300 H285", stroke:"rgb(0,0,0)", "stroke-width":5, fill:"none" });
}
</javascript>

Thats it. You can try this page using Safari/Firefox/Opera or Chrome... not IE.

Labels: , ,

Friday, September 12, 2008

iPhone 2.1 now supports SVG

At iPhone 2.0, SVG was to be supported but when trying using the iPhone safari browser, even simple stuff it didn't work. So it was promised that the support would be there at the next major release and well its here. There's not too much noise about it in the blogs... but this is HUGE.

Currently dojox.gfx defaults to canvas on the iPhone but the following bug will fix that, hopefully in time for v1.2.

The iPhone has had touch & gesture events since iPhone 2.0 for handling single & double-touch events respectively. With this release, there should be support for drawing vector geometry using SVG and also events on SVG elements.

More to come...

Labels: , ,