Posts tagged ‘javascript’

Share on TwitterDigg This

I believe this one is a problem that everyone that comes from real OO languages (like Java, C++) will face when working with Javascript.

We all learn that the pointer this references the instance of the class that is being executed. Everyone did this once:

public class Foo {
 
private String name;
 
public String say(){
return "Hello I'm " + this.name;
}
 
}

And you expect that as a result, a String “Hello I’m {yourname}” to be printed right?

Well, this is one of the foundations of encapsulation and OO.

Now, please bear with me with this example using javascript and “OO”

 
function Car(x,y){
this.x = x;
this.y=y;
 
this.update = function(){
this.x = this.speed*this.time;
}
 
}

So you go and run this code:

 
Car c = new Car(100,100);
c.update();

And it works like a charm :)

Then you try something like this:

var car;
 
function init(){
car = new Car(100,100);
setInterval("car.update()",20);
}

And now, for some reason your code is not working, and you get undefined errors on the x,y,speed “instance” variables of your car object.

It turns out, that on Javascript, this is not actually mapping to your instance, but to the owner element that is executing your code. In the above example, it was the DOMWindow. That is a FUCKING DISASTER when you have to deal with callbacks and one of my favorite features of JS, using a function as an argument to a method.

The good news, is that there is an workaround for that. You can actually use safe contained variables inside your class by creating an instance variable that points to this

function Car(x,y){
var self = this;
self.x = x;
self.y=y;
 
self.update = function(){
self.x = self.speed*self.time;
}
 
}

You’ve probably seen that before right? But (at least in my case) I had never thought about it, until I got in a two hour fight with my code about why the heck this.x was not defined.

I hope this help some folks out there having the same issue.

Cheers

Share on TwitterDigg This

Coming from a Java background, javascript syntax is not really friendly sometimes.

For instance I was creating some animations with SVG and using the very common setInterval function. This function is determined as:

setInterval ( expression, interval );
so I had this object I've created : Scene, which had a draw method. I think you can figure out the picture now.
So I ran this piece of code:

setTimeout(scene.draw,20);
 
self.draw = function(f) { .... }

The idea of the draw function was to have the current frame to be passed as an argument.
If none is defined, it then uses an internal memory to render the scene.
On Chrome that works fine, but it turns that when you call the setinterval with that syntax on firefox, it also passes as the first argument some sort of elapsed time to the called function.

Now, my function went crazy since it got some really high values being used as the f argument.

To fix it, use:

setTimeout("scene.draw()",20);

That does the trick for both Chrome/Safari and Firefox

Strange things from a strange language.

Share on TwitterDigg This




Gosh it has been a long time. From the last time I wrote something I’ve moved from Brazil to Ireland and I now work at LMI Ericsson Athlone. I’m still a java Engineer, but lately I’m having lots of fun in my spare time with Javascript, JQuery, HTML5 and other languages. After all, Oracle acquired Sun, and I belive it is time to move on …

So, I’m facing some visualization challenges at work, which made me find Raphael which is the best SVG library I could ever find.

After lots of fun, the docs are really easy to understand, I’ve started a few projects of my own. So for the introduction of Raphael, I wanna show a really useful function I’ve created.

The idea is to draw any regular polygon with it. Raphael uses the SVG Path notation, which gives lots of flexibility, but for a normal human being would be hard to code.

Remembering my trigonometry lessons from high school, I recall that one of my math teachers used to draw perfect shapes using a choke attached to a string. After creating a circle he would put points on it and connect through lines, and voilá, perfect triangles, hexagons, octagons and etc…

And that was the inspiration for my function :) . Given that I have a center (x,y), a radius, and the number of points, I could find any of the points, and them reconnect them using Raphael simple path function.

The path function takes a SVG path string. Looking like this:

“M x y  L a b”

This basically says: Move to x,y and draw a line to a,b. Simple huh?

Now, our function to draw the polygon relies on a simple triangle principle to find the a,b points for every single point entered:

a = x + (radius * cos(angle))

b = y + (radius * sin(angle));

All we have to do is vary the angle according to the number of faces, so angle would be:

angle = startAngle + (i * (1 / faces) * 2 * Math.PI);

So, if we start at angle 0 for a triangle (3 faces) we would create points at 0,120,360. You’ll see that to rotate the triangle with this function all you have to do is change the start angle of it.

This function takes a data argument that has:
data.x: X center of your circle
data.y: Y center of your circle
data.r: radius of circle
data.n: number of faces of the polygon
data.s: start angle

It also relies on 2 global vars:
points: Array
paper: Raphael instance

 function shape(data) {
 
            for (var i = 0; i < data.n; i++) {
                var point = new Object;
                var angle = data.s + (i * (1 / data.n) * 2 * Math.PI);
                point.x = Math.round(data.x + (data.r * Math.cos(angle)));
                point.y = Math.round(data.y + (data.r * Math.sin(angle)));
                points.push(point);
            }
            var strp = "M" + points[0].x + " " + points[0].y;
            for (var i = 1; i < data.n; i++) {
                strp += "L" + points[i].x + " " + points[i].y;
            }
            strp += "L" + points[0].x + " " + points[0].y;
            var comb = paper.path(strp).attr({fill:"rgb(255,255,193)"});
            comb.mouseover(function(event){
                this.attr({fill:"rgb(255,128,64)"});
            });
            comb.mouseout(function(event){
                this.animate({fill:"rgb(255,255,193)"},500);
            });
 
            points = new Array();
        }

You can play around with the function with the code bellow, just provide x,y,r, and faces to draw your shape. Mark draw inner circle if you want to see the shape inside the original circle.

Have fun:

x: y: radius:
faces: draw inner circle: