Wednesday, December 14, 2011

Javascript: Is date in range?

Today I encountered a little problem wich I had to solve with dates. I had to check, if today has a special event. The range is stored in a simple date format: YYYY.MM.DD-YYYY.MM.DD

Here is the solution:

var nowDate = new Date(2011, 12, 14).getTime();

var startDate = new Date(2011, 12, 13).getTime();
var endDate = new Date(2012, 1, 5).getTime();

if (startDate <= nowDate && nowDate <= endDate) {
 alert('It\'s in range!');
}


The "getTime()" method will create a timestamp from the created date. It's like a date in a number format wich can be easily compared to eachother.

Wednesday, October 26, 2011

Complete website on client side?

Javascript became very popular these days. There are countless frameworks and plugins developed to make our web developer life easier. But... I have a question.

What are the limits of Javascript? Can we make a complete website to work only on client side?

I'm developing a very interesting project recently. I have to solve everything (even content search) in the browser. The website has no contact to the internet at all...Yes. A website without internet connection or server contact. It will be an information box with touch screen on my former college. It will work as a digital doorman and it's quite nifty (and heavy like a mountain). Our designer did his job very well. It has now a very nice touch compatible interface. (Print screens and actual "in-use" images soon)

The computer runs on Ubuntu and unfortunately nobody knows the root password :) That's why I'm sticked with Firefox. The base hardware is... very environment (therefore not too user-experience) friendly, but I will do my best. Later, when I will have more time I will reinstall the system and use Chrome instead. The Javascript animations are much faster there. And I did a little test with flash. Surprisingly (at least for me) Opera handles Flash animation much more smoothly than any other browser. I designed a little active backgound for the whole system, and it looked awesome in Opera (I tested it with an Ubuntu live CD).

I have came up with a solution, I just want to test it. If it works, I will write a full post about it. If it won't than I will write it down, why it didn't worked.

But now I have a very tight deadline so I stop writing posts and go back to work :)

Sunday, October 23, 2011

JavaScript: Objects and the this keyword

Right now, I'm developing a complex jQuery plugin with a bunch of objects. Most of the these are connected together somehow in each others' definition. In one of these objects, the this keyword referenced to another object and I was not able to find a variable related to my object. The reason was I had to call one of its function in another context and with another this object. Here is the example:

var obj = function() {

    /* Private variables */ 
    var v1 = 0;
    var v2 = 0;
    
    /* Public variables */ 
    this.state = false;

    /* Public functions */
    this.update = function() {
       if(this.state) do_stuff();

       console.log(this.state); // undefined!!!
    }

};

So, when when I called the update function in another context with another this object, the this keyword referenced to the caller object, not to the object where it was. The result of this is that the state variable is undefined, because the caller object didn't have a state variable. I knew that the this keyword is the problem and I also knew that I need to reference to the object in its own functions. So the solution is to create a private variable and store a reference to the object in it.

var obj = function() {

    /* Reference to self */
    var _self = this;

    /* Private variables */ 
    var v1 = 0;
    var v2 = 0;
    
    /* Public variables */ 
    _self.state = false;

    /* Public functions */
    _self.update = function() {
       if(_self.state) do_stuff();

       console.log(_self.state); // false

       this.somethingElse = true;
    }

};

With this solution, if you create an object with the new keyword, the constructor is called and the _self variable will store a reference to itself. This won't mess up the this reference in other contexts.

Thursday, October 20, 2011

JavaScript: Drawing and appending an Image object

Let's have some fun with images tonight!

The <img/> tag is part of HTML, as you've already known from your previous studies in web technologies. :) You can create one programmatically with the Image object in JavaScript. See below:

var img = new Image();

Try to log it to the console. Right know, it's empty. To load an image, use the src tag:

var img = new Image();

// of course, don't forget to replace this url ;)
img.src = 'http://www.testsite.com/images/myimage.jpg';

The image is loaded, but you can't see it yet, because it isn't appended to the DOM. Let's use jQuery to do what is needed to do!

jQuery('#myDiv').html(img);

The image is visible right know. This JavaScript object has another property called onload. It fires when the image is loaded. Append these few lines after your code and refresh your page:

img.onload = function() {
    alert('image loaded');
}

In Internet Explorer, the onload function won't run, unless you place it before the definition of src attribute:

var img = new Image();

img.onload = function() {
    alert('image loaded');
}

img.src = 'http://www.mysite.com/images/an_image.jpg';

Go and have some fun with the onerror attribute! It runs when an error occurs while loading an image.

var img = new Image();

img.onerror = function() {
    alert('failed to load image :( ');
}

img.src = 'http://www.fakelink.com/images/non_existing_image.png';


Canvas element and Javascript drawImage function

Another way to use the image object is to draw it with the help of the canvas element. First, have one in your example html page:

<canvas id="myCanvas" width="400" height="300"></canvas>

Then, get the canvas and a context and use drawImage function.

var canvas = $("#myCanvas");

/* For browser compatibility issues, put error handling code here. I won't.. */
var ctx = canvas[0].getContext('2d');

var img = new Image();
img.src = 'http://static.yoursite.com/images/something.png';

ctx.drawImage(img, 0, 0);

The first parameter of the drawing function is the image object itself. The second and third parameters are for placing the image along the x and y coordinates. Note that the (0, 0) coordinate is the top left corner. Also note that canvas element is not supported yet in Internet Explorer.

That's all for today of the JavaScript Image object and its usage. I will tell more about the drawImage function in another post where I will talk about sprites, animation and a bit more JavaScript tricks. I hope you learned a little new today.

Tuesday, October 18, 2011

JavaScript: Types and values

Working on other's codes is like walking in a huge cellar with a bunch of old boxes: you always find some interesting things. I write about types today.

Let's work with the following variables:

var point = function() {
    this.x = 4;
    this.y = 6;
}

// var v0; Note: I commented it out with purpose to make it undefined.   
var v1;
var v2 = null;
var v3 = false;
var v4 = 'some text';
var v5 = 68;
var v6 = {};
var v7 = new point();
var v8 = new Array();
var v9 = function() {};

How can you determine the type of each variable? Use the typeof operand. It returns a string representation of the operand's type. Let's see the types of the variables above:

typeof v0; // undefined
typeof v1; // undefined
typeof v2; // object
typeof v3; // boolean
typeof v4; // string
typeof v5; // number
typeof v6; // object
typeof v7; // object
typeof v8; // object
typeof v9; // function

Look at the result of v0 and v1. Why do they have the same undefined type? v0 is not declared, it's obvious why it is undefined. But v1? Because it is not defined (just like the type tells to us)! We stated that there is a variable called v1 but we didn't give it a value.

Did you notice that v2 with null assigned to it is an object type? Yes, you see it well. As I know, the reason for this is that the null type is a special object in JavaScript.

Common mistake with types


Typeof

I see the following comparison many times in codes I meet:
if(typeof v0 === undefined) {
    alert('not executed! hah!');
}

The alert function call won't run because the comparison in the if statement is wrong. As said before, typeof returns a string, but right now it is matched against an undefined value. It won't even work with the 'equal to' operator. Let's correct it:
if(typeof v0 === 'undefined') {
    alert('executed! hah!');
}

So now, the return value of typeof is compared to a string.

Null values

Another confusion rises when comparing undefined but declared variables against null value.
var v1;

if(v1 == null) {
    // it will run
    alert('yep');
}

if(v1 === null) {
    // it won't run
    alert('nope');
}

With the 'equals to' operator, JavaScript does type casting and evaluates the v1 variable with null value. But in the second case, with the 'exactly equals to' operator, the undefined value is kept because the operator checks the value and the type too.

Infinity and NaN

Take into account that type of a variable with Infinity or NaN value is number:
var v10 = 1000 / 0; // Infinity
var v11 = 1000 / 'book'; // NaN

typeof v10; // number
typeof v11; // number


I hope you also found it interesting. :)

Sunday, October 16, 2011

Playing with Numbers in Javascript

Handling numbers is a very basic task for (web)developers, but how exactly is this working in Javascript?

Numbers are "double-precision 64-bit format IEEE 754 values". Let's see some examples how it can handle things:

console.log( 0.1 + 0.2 ); // 0.30000000000000004

// but:
console.log( (0.1*10 + 0.2*10) / 10 ); // 0.3

console.log( parseInt("123", 10) ); // 123
console.log( parseInt("010", 10) ); // 10

// The parseInt() and parseFloat() functions parse a string until 
// they reach a character that isn't valid for the specified number 
// format, then return the number parsed up to that point.
console.log( parseInt("test: 123", 10) ); // NaN
console.log( parseInt("test: 010", 10) ); // NaN
console.log( parseInt(1.23, 10) ); // 1
console.log( parseInt(1.99, 10) ); // 1
console.log( parseInt(-5.1) ); // -5
console.log( Math.floor(-5.1) ); // -6 (!!)
console.log( parseFloat("1.67") ); // 1.67 (Number)
console.log( parseInt("456test: 010", 10) ); // 456

// converting without parseInt() or parseFloat()
console.log( "456 test: 010" * 1 ); // NaN
console.log( 1 * "456 test: 010" ); // NaN
console.log( 1 * "    456     " ); // 456 (space characters are allowed)
console.log( 1 * "    .456     " ); // 0.456
console.log( 1 * "    . 456     " ); // NaN
console.log( 1 + "2" + 3 + 4 ); // 1234
console.log( 1 - "2" + 3 + 4 ); // 6 (-1 + 3 + 4)
console.log( 1 * "2" + 3 + 4 ); // 9 (2 + 3 + 4)
console.log( 1 / "2" + 3 + 4 ); // 7.5 (0.5 + 3 + 4)
console.log( 5 % "3" ); // 2
console.log( 5 % " 3 " ); // 2
console.log( 5 % " 3a " ); // NaN

console.log( parseInt("010") ); // 8 (!!)
console.log( parseFloat("010") ); // 10 (!!)
console.log( parseFloat("010.123") ); // 10.123
console.log( parseInt("11",2) ); // 3 (binary to integer)
console.log( parseFloat("11") ); // 11


// converting with unary operator
console.log( +"11" ); // 11
console.log( typeof +"11" ); // number
console.log( +"11a" ); // NaN
console.log( -"11" ); // -11
console.log( typeof -"11" ); // number

// other number types
console.log( parseInt("hello", 10) ); // NaN
console.log( typeof parseInt("hello", 10) ); // Number (!!)
console.log( parseInt("hello", 10) * 1 + 5 ); // NaN (NaN is toxic..)
console.log( isNaN(parseInt("hello", 10)) ); // true
console.log( isNaN(10) ); // false
console.log(1/0); // Infinity
console.log(-1/0); // -Infinity



My conclusion are:
  • If I'm working with floats I should round them to a limited precision.
  • The safest way to convert strings to numbers is to use parseInt() or parseFloat().
  • The parseInt() function has a second argument wich defines the base of the number system that the string has. I should always set this value, just to be clear and avoid some untrackable bugs..
  • Before I use parseInt() it's a good idea to clean the string from any letters (this is quite task dependent). I should care about this, because if a string made up of numbers it's fine. But it could have some toxic character value in it and that could kill the whole process. So be careful.
  • If I call parseInt on a float number, it will return always the integer part of the number. So it's not the same as Math.floor()
  • parseInt() on a string like (123a456) will only return the first few characters parsed as numbers.
  • Converting numbers with only " * 1" is not safe. Only if I can be absolutely sure that the string will only contain number characters or space.
  • parseFloat() uses always 10 as the base number system
  • I can convert strings into numbers with an unary operator (Wow..)
  • NaN is toxic. Very toxic.. avoid it at all cost (unless this is what I want)
  • There is an Infinity type number in Javascript but I don't quite know what is it good for. (Maybe just to indicate that the number is too big..do something with it because javascript can't handle it)

I have read the basic number handling tests on: developer.mozilla.org and I have made up some others on my own.

Friday, October 14, 2011

jQuery :contains with the exact same value

The task to do:
During my work I had to create a page scrolling effect with a dropdown menu and a (verticaly) very long content. So when someone clicks on a menu item the page has to scroll to the exact position where the content begins.

The idea of the solution:
As the menu-items' text and the title of the content parts are exactly the same, the idea is to find the title tag according to it's content. Then get the Y coordinate of it and scroll the body to this position.

The solution in jQuery:
My first (key) idea was to use jQuery's built-in ":contains" method:
jQuery("h2:contains('Some Value')")

But in this case this won't work perfectly, because there were menu items like "Product" and "Product 2.0". So I needed a ":contains" solution but with the exact values. This is what I came up with:
jQuery("#menu a")
  // disable links. We need only Javascript behavior
  .attr("href", "javascript:void(null)")
  // what shall happen if the link is clicked
  .click(function () {
   // get the text of the menu item
   var text = jQuery(this).text();
   // get the DOM object of the target title (The h2 element wich contains the exact same text of the menu item)
   var target = jQuery('h2').filter(function() {
        return jQuery(this).text() === text;
   });
   // get the position of the target element
   var pos = target.offset();
   // if the position is found...
   if (typeof pos.top != 'undefined') {
    // scroll the page there
    jQuery.scrollTo((pos.top-10) + "px", 700);
   }

  });



Note: I used Ariel Flesler's ScrollTo jQuery plugin. (Thanks Ariel by the way..)

Thursday, October 13, 2011

XHTML Strict and target _blank


This topic is quite a challange because on one side I want my websites "strict" valid. On the other hand, sometimes it's important (at least clients say so) to open links in a new window, so I did a little research (and there are a lot of informations out there to this problem)

What are the solutions for being valid and in the same time opening links in a new window?

1. I tried it with CSS: (I know, I know... CSS is for styling only, not for behavior.. I'm searching solutions right now)
Theoretically it can be done with CSS3. According to this page the code should look like this:

a {
    target-name: new;
    target-new: tab;
}

But none of the browsers responded to it so this solution is precluded.



2. Javascript:
Here we have quite interesting solutions.

Manually open a new window with "window.open(URL)":

Inline mode:
<a href="http://thinkrement.blogger.com" onclick="window.open(this.href); return false;">Read Thinkrement!</a>

This works, however it's not so elegant and it's better to keep the HTML and Javascript seperate.

So, let's improve it a bit:

HTML:
<a href="http://thinkrement.blogger.com" rel="popup">Read Thinkrement!</a>

Javascript:
window.onload = function() {
    var links = document.getElementsByTagName('a');
    for (var i=0;i < links.length;i++) {
        if (links[i].rel == 'popup') {
            links[i].onclick = function() {
                window.open(this.href);
                return false;
            };
        }
    }
};


or with jQuery:
$('a[rel="popup"]').click(function() {
    window.open(jQuery(this).attr("href"));
    return false;
});



The constrained method:

With Javascript it's similar to the previous "window.open" method with the difference, that instead of "window.open" we use:
window.onload = function() {
    var links = document.getElementsByTagName('a');
    for (var i=0;i < links.length;i++) {
        if (links[i].rel == 'popup') {
            links[i].target="_blank";
        }
    }
};

This is quite simple, however this solution is not supported by IE and Chrome.

With jQuery it a bit easier (only 1 line):
$('a[rel="popup"]').attr("target", "_blank");




3. HTML:

- Use a Transitional Doctype
- Have some "target" errors on your site
- or put it out of your mind that you want to use the target attribute. It is said that for usability reasons it's better to let users decide whether they want a new window (tab) or not.

Wednesday, October 12, 2011

Javascript Canvas trumps all others

Recently I have made a little test. I would have like to make a little active-background effect on my project and I have faced a problem with the hardware resources. What you have to know about this project is, that it will be an information panel on my college where I graduated. So, the hardware, the browser and the resolution (and pretty much everything else) is fixed.

This is the DEMO (and a simplified result):
http://jsfiddle.net/FilipFlora/cLByF/10/embedded/result/

The task was:
Create an active-background animation when the tablet is idle. So when you walk by, it'll catch your attention..

The problem:
The hardware is rather energy-efficient and has only a basic graphics-card integrated. The images to move are huge (circa 2000x1600) and they have a 5% opacity on them. (Just as I wrote these lines, I thought that another solution could be to set the opacity value with css and use gifs instead?? But I don't think that this would be better than the solution below)

The attempts to solve the problem: (not in this order, but I was diligent to find the best looking solution :) )
1. attempt: Background-image (for this I used the background-position jQuery plugin)
I tried that..yes. I created 4 layers, I have set the background-image with CSS, and created the animation with jQuery.

HTML:
<div id="index_bg_1">&nbsp;</div>
<div id="index_bg_2">&nbsp;</div>
<div id="index_bg_3">&nbsp;</div>
<div id="index_bg_4">&nbsp;</div>

CSS:
#index_bg_1,
#index_bg_2,
#index_bg_3,
#index_bg_4 {
 background-image: url("../images/index-bg-1.png");
 background-repeat: no-repeat;
 background-position: 0px 0px;
 width: 1680px;
 height: 1050px;
 position: absolute;
 left: 0px;
 top: 0px;
}

#index_bg_2 {
 background-image: url("../images/index-bg-2.png");
 background-position: 0px 0px;
}

#index_bg_3 {
 background-image: url("../images/index-bg-3.png");
 background-position: 0px 0px;
}

#index_bg_4 {
 background-image: url("../images/index-bg-4.png");
 background-position: 0px 0px;
}

Javascript:
jQuery(document).ready(function() {

 // initiate all background-image animation
 for( var i = 1; i<5; i++) {
  animateBackgroundImage("#index_bg_"+i);
 }
 
});

function animateBackgroundImage(selector) {
 
 // new target x coodinate
 var pos_x = Math.rand(-1200, 1600);
 // current x coordinate 
 var bg_x = ((jQuery(selector).css("background-position")).replace("px 0px", ""))*1;
 // animation time
 var anim_time = Math.abs(pos_x-bg_x)/24*1000;
 
 // to do this, you need the backgroundPosition plugin for jQuery
 jQuery(selector).animate({
  backgroundPosition: "("+pos_x+"px 0px)" // to keep it simple, let's animate only the x value
 }, anim_time, "linear" );
 
 // after the animation is done, create another
 setTimeout("animateBackgroundImage('"+selector+"')", anim_time);
}
// this is just a helper function to create php like random number generator
Math.rand = function (min, max) {
 return(Math.round(Math.random() * (max-min)) + min);
}


As it turned out, this was too much for the little machine..


2. attempt: with simple images
I don't want to make this post too long so I summarize it briefly. It doesn't went well. It was a little bit faster, but I needed much more.

3. attempt: Javascript Canvas
This has rocked my world again. After I have read Zsolti's article about canvas animations (thank you my dear friend :) ) I was very excited to test it on the real thing (as I was developing on my laptop). Needless to say.. it went perfectly.

Here is the code:

HTML:
<canvas width="1680" height="1050" id="index_canvas"></canvas>

Javascript:
// animation object
var indexAnim = {
 images: [], // here are the image objects
 positions: [], // the actual positions of the images
 destPositions: [] // the target coordinates of the image
}

jQuery(document).ready(function() {
 
 // init
 for( var i = 1; i<=4; i++) {
  
  // create a new image to place on canvas
  var im = new Image();
  im.src = 'images/index-bg-'+i+'.png';  
  indexAnim.images[i-1] = im;
  // place it randomly on canvas
  indexAnim.positions[i-1] = Array(Math.rand(-500, 500), Math.rand(-500, 500)); 
  // set it's destination positions
  indexAnim.destPositions[i-1] = Array(Math.rand(-500, 500), Math.rand( -500, 500));
 
 }
 
 // just for a better performance
 var length = indexAnim.images.length;
 var canvas = document.getElementById('index_canvas').getContext('2d');
 
 // let the animation begin (... WHA-HA-HAAA)
 setInterval(function () {
  
  // clear the image
  canvas.clearRect(0,0,1680,1050);  
  
  // let's redraw all the images
  for( var i = 0; i<length; i++ ) {
   
   // if a new target position is needed (either x or y)
   if( Math.abs(indexAnim.positions[i][0] - indexAnim.destPositions[i][0]) < i+1 || Math.abs(indexAnim.positions[i][1] - indexAnim.destPositions[i][1]) < i+1 ) {
    indexAnim.destPositions[i] = Array(Math.rand(0, 1050), Math.rand( -500, 500));
   }
   
   // set the new position of the image. It's only 1 pixel closer to the destination coordinate (Just like in life...)
   indexAnim.positions[i][0] = indexAnim.positions[i][0] + (indexAnim.positions[i][0] < indexAnim.destPositions[i][0] ? 1: -1);
   indexAnim.positions[i][1] = indexAnim.positions[i][1] + (indexAnim.positions[i][1] < indexAnim.destPositions[i][1] ? 1: -1);
   
   // draw image on canvas
   canvas.drawImage(indexAnim.images[i], indexAnim.positions[i][0],indexAnim.positions[i][1]);  
  
  }
 
  
 }, 41); // 41ms = 1000/24. 24 Frames are needed at least to create a smooth flow..
 
});

Math.rand = function (min, max) {
 return(Math.round(Math.random() * (max-min)) + min);
}


Maybe the animation needs some fine-tuning, but It's quite good :)

4. possible attempt: Flash
But since I don't do Flash programming, this solution depends on my brother :)


I hope you like my little solution here, and if you have a better idea share it with us.

Monday, October 10, 2011

jQuery caching

It's really simple to select an element in jQuery:

$('#name');

But if we use this selection more than once in our code, we should cache it:

var name = $('#name');
name.val("Johnson");
name.addClass("inputField");
name.parent().append('<p>Some text here</p>');

Every time we select an element with jQuery, the framework goes through the entire DOM until it founds all the elements that match the selector. In the above example, I cached the jQuery object to a variable called name. Later on my code, I can use this variable to modify my element without searching for it again. So I've just quartered the time spent on selection which means I've given a boost to performance.

If I cache multiple elements (for example: form inputs) I usually use an object literal to group them together. So later on my code, I won't get confused which variable relates to which form.

/* Registration form */
var regForm = {
 'name'  : $('#name'),
 'email'  : $('#email'),
 'address' : $('#address'),
 'phone'  : $('#phone') 
};

var contactForm = {
 'name'  : $('#name'),
 'email'  : $('#email'),
 'subject' : $('#subject'),
 'message' : $('#message') 
};

// ... some other code here

if(regForm.name.val() == "") {
 // do something
}

// ... some other code here

if(contactForm.name.val() == "") {
 // do something
}

Sunday, October 9, 2011

Javascript Array prototype and for-in

If you are developing a 3rd party application, a jQuery plugin or something similar, this will be specially useful for you.

I'm sure you've heard about it but you can extend the Javascript's core objects with the help of the prototype property. So, in this case let's see what happens if we combine Array.prototype with a for-in loop.

// let's create a simple array
var testArr = new Array(1, 2, 3);

// print it out to the console
for( var i in testArr ) {
 console.log(i+": "+testArr[i]);
}
// output: 
// 1
// 2
// 3

// extend the array object
Array.prototype.myMethod = function (arr) {
 // Do something here..
}

// loop the array again
for( var i in testArr ) {
 console.log(i+": "+testArr[i]);
}
// output: 
// 1
// 2
// 3 
// myMethod: function (arr) { }


As you can see, the second time in the loop the custom methos is also listed az an array item. This can be source of unknown bugs and I have spent a lot of time to figure this little trick out.

So, what are the solutions?
Use the Array object's "hasOwnProperty" property:
for( var i in arr) {
      if( !arr.hasOwnProperty( i ) ) continue;
      // stuff to do..
}

Or if you have jQuery loaded, use the .each method.
jQuery.each(testArr, function (key, value) {
 console.log(key+": "+value);
});


This possible bug source is kind of sneaky, yet the solution is simple :)

HowTo: Canvas colorful bouncing circle animation with JavaScript

Introduction


I've really really waited for the moment when I can start developing canvas animations. In this post I'm going to present you what I've coded and tell you a few words about its concept.

But, check out the Demo first.

So, as you've seen, the result is a canvas with bouncing and colorful circles. They are random positioned with random colors, random directions and random sizes. But, what is a canvas? Canvas is a part of Html5 specification. You can use it to draw graphics and animations with the help of JavaScript.

<canvas width="400" height="300"></canvas>

I won't go into basics of canvas element. If you are interested about it, please check out Mozilla Developer Network's Canvas Tutorial.

Animation basics

Frames. All we need is them. A frame is a 'screenshot' of the current state of a scene. A scene contains the objects and pretty much everything we want to draw to the audience. We create an animation from frames by drawing at least 24 to the screen in every second. This is the minimum amount to deceive the eye to see motion on the screen. Of course, the more frames we draw in one second, the smoother the animation gets. From frame to frame we must update and redraw all of the objects. Everytime we create an animation the following things happen:
  1. Initialization
  2. Updating scene
  3. Drawing scene
  4. While it must be drawn, jump back to the 2. point else 5.
  5. End of animation

The 2., 3. and 4. point together forms the main loop. This is where all of the scene objects' state, position, color etc. gets updated and gets drawn. If you wish to put user input to the animation (etc, mouse movement) there would be a new item in the list for input handling.

Skeleton of my animation object

var animation = function() {
 /* List of objects to draw (the particles) */
 var list = [];

 /* Frame per seconds */
 var fps = 24;

 /* Object constructor */
 var particle = function() {};
 
 /* Initialization */
 this.init = function(v) {};

 /* Updating objects state, position, etc.. */
 var update = function() {};

 /* Drawing the objects */
 var draw = function() {};

 /* Calling update() and draw() */
 var loop = function() {};

 /* Setting main loop */
 this.play = function() {};
}

The above source snippet is the skeleton of my animation object.

Initialization

Bouncing circles on the screen represented as a particle object. The animation itself has a variable called list. Every item of it will be a new particle object. Calling the init() function with a number parameter will add as much particles to the animation as much we want.

Particles

Particles object looks like this:
/* Particle object */
  var particle = function() {
    /* Coordinates */
    this.x = 0;
    this.y = 0;

    /* The radius of circles */
    this.radius = 5;

    this.speed_x = 1;
    this.speed_y = 1;

    /* Direction */
    this.dx = 0;
    this.dy = 0;

    this.color = {
      fill : '#000',
      stroke : '#000'
    }

    /* Boundaries (canvas width and height) */
    this.bounds = {
      x0 : 0,
      x1 : 600,
      y0 : 0,
      y1 : 400
    }

    /* Private function for random color but I think you've already guessed that. */
    var random_color = function(){}

    /* Function to initialise variables */
    this.init = function() {}

    /* Updater function, called at every frame. It updates positions and check boundaries. */
    this.update = function() {}
  }

To represent a circle on the screen I stored information about it such as its x and y coordinate, its x and y speed, its direction, its colors and its boundaries because I don't want it to go away from the screen leaving a blank white field to the user. Init function sets variables to random values. The update function is used to update the circles properties in every loop. It will be called by the loop's update function.

Updating and drawing

I've defined a loop function. It simply calls the update() and draw() once. To create the animation by calling the loop function multiple times in every second I have to use the setInterval() function.

/* To start animation */
this.play = function() {

 /* Animloop */                        
 setInterval(loop, 1000/fps);          
      
};

The first parameter must be a function what will be called, and the second parameter must be a number representing a ms value. Let's say I want it to call 24 times a second, then I must divide 1000 by the fps rate (24 now) to get the desired ms values.


var ANIM = new animation();
ANIM.init(25);
ANIM.play();

Final words

This is a basic animation concept. I hope you found it useful. Play with it online on this link at JsFiddle.net. If you would like to say anything or noticed something, please leave a comment.

jQuery: Checkbox howto

Once I've run into a project with a complicated form where some ajax didn't work. After digging into the code I've sadly seen a mistake that caused the functionality loss.

As you know, checkbox state can be determine at least two ways:
/* checkbox */
var chk1 = $('#chk1');   
               
chk1.attr('checked');
/* or */
chk1.is(':checked');

The previous programmer used the attr() function, however he forgot (or did not know...?) the difference between the two. While attr() function returns the attribute of the checkbox (undefined if not checked, 'checked' if checked), the second is() function returns boolean true or false. He sent the return value of attr() call as a string to a php script, but he expected 'true' or 'false', but he got 'checked' or 'undefined'.

/* checkbox */
var chk1 = $('#chk1');
chk1.attr('checked', true);

// returns 'checked' but it evaluates to boolean true in javascript
if(chk1.attr('checked')) {
    
}

// returns boolean true                
if(chk1.is(':checked')){
    
} 

Another note, to check a checkbox you can use:
chk1.attr('checked',true);

To uncheck a checkbox, you can do:
chk1.attr('checked', false);
/* or */
chk1.removeAttr('checked');

So the conclusion is to be careful out there and always know what a function will return!

Friday, October 7, 2011

jQuery speed test - sibling selector

I'll continue the previous post with a similar one. But this time I tested the sibling selector of jQuery. And as it turned out it is quite interesting but I don't want to kill the joke too early, so let's see that pic:


Well, IE is...slow, so to see things clearer I have removed it from the graph:


Obviously the fastest solution is: jQuery("h1 + h2")

BUT... there are some really interesting things going there. How can it be, that jQuery("h1").siblings("h2") is sooo much slower, than this:

jQuery("h2").filter(function () {
    return jQuery(this).prev()[0].tagName == "H1";
});


If anybody knows the answer, please share it with us!

jQuery speed test - child selector

Selecting child elements with jQuery is not a challange. However selecting it the fastest way is. I did a simple jQuery selector speed test with the latest versions of Firefox, Chrome, Opera and Internet Exporer. The values you see here are in milliseconds per 1000 cycle.

Here is what I got:


Based on the previous chart it seems... well, quite obvious that IE is the slowest and Chrome is the fastest... but returning to the topic... :)

Here are the comparisons of the fastest ways of getting the children elements (the datas from IE are excluded from the test now due to the large difference):

For all child elements the best way is:
jQuery("li > *"). It's:
  • ~29.4% faster than jQuery("li").children()
  • ~86.1% faster than jQuery("> *", li)
  • ~140% slower than li.children()

And for only link elements the best method is:
jQuery("li > a"). It's:
  • ~65.2% faster than jQuery("li").children("a")
  • ~87.5% faster than jQuery("> a", li)
  • ~47.3% faster than li.children("a")

The other thing to observe is that the loops are much faster if you store the base jQuery wrapper object in a variable.

Saturday, August 20, 2011

Javascript - pausing script flow ( sleep )

Sometimes it happens, that I need to PAUSE the flow of my script. And I mean pause, with capital letters, because these times a simple setTimeout would not help.

There is a very nice, browser independent method to do this:

1. Create a synchronous AJAX call
2. On the server side call the "sleep( [sec] )" function

To speak in code, this is the javascript (jQuery) part of it:

function pause(millisec) {
	jQuery.ajax({
		type: "GET",
		url: "index.php",
		data: {
			task: 'pause',
			pauseMillisec: millisec
		},
		async: false
	});
}


And this is the PHP part:

<?php 
if( $_GET["task"] == "pause" ) {
	sleep( $_GET["pauseMillisec"]/1000 );
} 
?>

That's all folks.. isn't it easy? :)

Feel free to share your thoughts with me.

Sunday, March 20, 2011

jQuery broken picture fixer

Description: fixes and handles pictures which are not found.

During website development there are always pictures which can not be found. In Firefox these pictures are automatically hidden, but for example in Internet Explorer they are marked with a little image with a red “X” in it (which is quite ugly by the way). It's better to show your own “nopic” picture, which suits to your own design and taste. Furthermore, when you have to alter your layout if a picture is not found, you can handle it client side with this jQuery plugin.

What is this good for? ... Well, you can:
  • mark the broken images on your site the way you like it
  • replace automatically these images to a default “nopic” picture
  • define a custom callback function, if a picture is not found
  • solve the tasks above with a jQuery plugin with a very small footprint

“Nice...this is very useful! But how can I use it?”

It's pretty simple.

Basic usage: Default “nopic” image is “images/nopic.jpg”
1
jQuery(".picture").picfix();

Default image configuration: With the “altImg” parameter.
1
2
3
jQuery(".picture").picfix({
    altImg: "images/mynopicture.jpg"
});

Error handling configuration: With the “onerror” parameter.
1
2
3
4
5
jQuery(".picture").picfix({
    onerror: function () {
        // do something...
    }
});

Files:
  • jquery.picfix.min.js (~0.53kb)
  • jquery.picfix.compressed.js (~0.58kb)
  • jquery.picfix.js (~0.79kb)
  • usage.js

Download:

Feel free to write me a comment, and if you like this little plugin please contribute my efforts.

Tuesday, March 15, 2011

Taskfreak! Desktop: the TaskFreak! desktop gadget

What is TaskFreak?

TaskFreak! is an open source web based task management software. It's very handy, uncomplicated and it can be learned quickly. It has all the requirements nessessary to manage tasks fast and effective.

And what is this desktop application?

This is a Windows gadget, that allows you to be immediately informed about the changes in your TaskFreak!'s task list. In addition, you don't have to be continuously logged in in a browser, since you can see and manage every ongoing task directly on your desktop.

How does this desktop gadget work?

After installing and configuring - which is described later - the application is in observer mode. This means, it's just checking periodically, if there are updates in your tasks. So if someone (other than you) creates a new task, writes a new comment or changes a task's status, you are informed almost instantly.

You can switch to extended view, by clicking the "bigger size" Windows-default-button on the right top of the gadget. In this view, all the unfinished tasks are listed under each other. This design structure is very similar to the web based TaskFreak!. The colorful squares on the left are the priority and the environment indicators. Next to them is the comment count button, project name and the status buttons. Below these on the left side is the task title and the deadline date on the right side. If you click on the title the full description appears.
You can even read comments, and write new ones, by clicking on the comment count icon.
To get a more detailed picture about the interface click the images below.

User interface explanation



TaskFreak! Desktop in action:


How to install TaskFreak! Desktop?


The installation is really easy. Just follow these steps:
  1. place the desktop.php file in your TaskFreak! root web folder.
  2. run taskfreakDesktop.gadget file. This is a simple archive file and all the sidebar enabled Windows systems are recognising this extension.
  3. on the settings page, type in the URL to your desktop.php. Enter your username and password to your TaskFreak! account. And make some other changes if needed.

That's it. Now you are ready to use TaskFreak! Desktop.

I hope this gadget is at least as useful for you as it is to me. Feel free to write a feedback, or request a new feature. I have some plans for further development...but I welcome any ideas, especially if they are combined with donations :)

Files:

  • desktop.php
  • taskfreakDesktop_0.1.2.gadget
  • CHANGELOG.txt
  • LICENSE.txt

Downloads:


Please donate to keep development active!

Thanks for blueBros LLC for providing this awesome design :)



Changelog

  • 0.1.2
    • Improved design, by blueBros LLC
    • Added alert volume slider in settings
    • Added updating interval input in settings
    • And fixed some minor bugs
  • 0.1.1
    • Fixed the "notask" bug
    • Fixed the "empty comment form submitted" bug
    • Logs and errors are from now on shown in the same panel
    • And fixed some minor bugs
  • 0.1.0
    • Listing unfinished tasks
    • Status changing ability
    • Hidden but recallable description
    • Listing task's comments
    • Opportunity to write a new comment
    • Smaller view (and also an extended view)
    • Observer functionality. Alert on:
      • New tasks
      • New comments
      • New status changes
    • Set custom sound alert
    • Shows changes in tasks

Saturday, March 12, 2011

PHP: Your exception classes

Exceptions

This article is the second part of PHP Exception articles. In the previous one, I've written about Exceptions, I've showed you the basic usage and I've provided some examples. It won't be different this time, but I'm going to be a little more advanced. This article is about how to write your own classes.

Reminder: Exception is a special condition that changes the normal flow of the code.


Extending exceptions

You can extend the core exception class in PHP to have your own class which will suit for the given tasks ahead. It's a good way for categorisation of errors. What I mean is, you can make input exceptions, error exceptions, email exceptions. Another example is if you use the MVC programming pattern, you can make classes related to each layer as follows: ModelException, ViewException, ControllerException. After this, you can extend more classes depending on the occuring errors in each layer.

But let's return from programming patterns to the example code below. Take a look at it. :)

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<?php

 class InputException extends Exception {};

 class SomethingBadException extends Exception {};

 class SomethingReallyBadException extends Exception {};


 // ...

 class foo {

  // ...

  function let_it_happen($input) {

   if( !validate_input($input) ) {

    throw new InputException('Invalid input given.');

   }


   if( !calculate_something($input) ) {

    throw new SomethingBadException('Something bad happenned.');

   } else
   {

    if( !generate_something($input) ) {

     throw new SomethingReallyBadException('Something really terrible happened.');

    }

   }

   // ...

  }

  // ...

 }


 // later in the code...

 $bar = new foo();

 try {


  $bar->let_it_happen();


 }
 catch (InputException $e) {

  echo 'Input error: '.$e->getMessage();

  // do something here, like logging
  log('Error: '.$e->getMessage());

 }
 catch (SomethingBadExcpetion $e) {

  echo 'Error: '.$e->getMessage();

  log('Error: '.$e->getMessage());

  handle_some_stuff();


 }
 catch (SomethingReallyBadException $e) {

  echo 'Fatal error: '.$e->getMessage();

  log('Fatal error: '.$e->getMessage());

  $email->notify_admin('www.site.com - problem',"The following thing happened: ".$e->getMessage()."\n Log in immediately.");

 }


?>

I've defined three new exceptions, and I've also written a class where these exceptions appear. Notice the multiple catch blocks. You have to catch all kind of exceptions by making catch blocks for each of the classes. If an exception occurs you can make the necessary steps in each of the blocks to set variables, warn the user, log or notify someone.

You can also add your custom properties and methods to an extended class. But be careful with this! I say this because if you add a method to your exception class that uses an object - for example email - and you throw this exception in a context where that object is not available or currently not loaded, you're shot and you can start debugging and hacking. Please, prevent this and design your application correctly. The code:

1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?php  
 
 class BadBadException extends Exception {
  
  private $__variable;
  
  function set_variable($in) {
   
   $this->__variable = $in;
   
  }
  
  function get_variable() {
   
   return $this->__variable;
   
  }
  
  function handleBadException() {
   
   log($this->getMessage());
   
   do_something_necessary();
   
  }
  
 }
 
 // ...
 
 try {
  
  throw new BadBadException('bad bad message');
  
 } 
 catch (BadBadException $e) {
  
  echo $e->getMessage();
  
  $e->handleBadException();
  
 }
 

?>

Final words

Deciding to use exceptions is a good start to make your application more logical, more understandable and what is much more important, more flexible.

Zsolt Szivák