Friday, 22 May 2015

SVG with RaphaelJS - Defining Object Boundaries


Welcome to this section of the weekly series SVG with RaphaelJS. In the last section, we covered how to drag and drop a RaphaelJS element. In this section, we shall cover how to detect if two RaphaelJS elements are colliding with each other.

In order to do this, we need to use a bounding box. A bounding box gives us the area around the RaphaelJS element in question. Below is a diagram that shows us this effect.

Getting a bounding box involves using the getBBox command. The parameters returned by this command are the values you see in the above diagram.

We use the same circle element as before. Once we get the bounding box of the circle, we retrieve the x and y values of the circle and use its width and height for the rectangle we want to create.

Remember that the syntax to create a rectangle is:

Paper.rect(x, y, width, height, [r]);

Comparing this to our image above, x and y would be the starting points for the bounding rectangle whlie the width and height would be the width and height of the bounding box respectively.

[r] is an optional parameter that represents the border radius. We don't need it for this case so we won't use it.

The code to do this is given below:

$(function(){ var paper = Raphael('container', 500, 500);
// Draw a circle at the left hand side of the viewport
var circle = paper.circle(100, 250, 50).attr({ 'fill' : 'red', 'stroke-width' : 5 });
// Get the bounding box of the circle
var boundingBox = circle.getBBox();
// Draw the rectangle using components from the bounding box
paper.rect(boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height);

});
The code above produces the output shown below:
Please notice the rectangle around the circle. It shows the bounding box of the circle. An important application of this concept is to check for overlaps of two elements. I will cover that next.


To illustrate this concept, I will draw another circle at the position of x = 400 and y = 250 with the radius = 50. We give the circle we are drawing a colour of blue to differentiate it from our previous circle.

I expect that at this point, you can write the code to do that so I will only show the output.


Lets add our drag methods to the first circle as before however this time in the dragend method, we add an alert method that allows us know if the two circles intersect.

In the dragstart method, we add the toFront() method to first circle to the front of the second circle when dragging starts.

The updated code or the drag functions is shown below:

$(function(){ var paper = Raphael('container', 500, 500);
// Draw a circle at the left hand side of the viewport
var circle = paper.circle(100, 250, 50).attr({ 'fill' : 'red', 'stroke-width' : 5 });
// Get the bounding box of the circle
var boundingBox = circle.getBBox();
// Draw the rectangle using components from the bounding box
paper.rect(boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height);
// Draw a circle at the left hand side of the viewport
var circle1 = paper.circle(400, 250, 50).attr({ 'fill' : 'blue', 'stroke-width' : 5 });
circle.drag(dragmove, dragstart, dragend);
function dragstart(x, y, e){
this.toFront();
this.current_transform = this.transform();
this.attr("fill", "yellow");
}
function dragmove(dx, dy, x, y, e){
this.transform(this.current_transform+'T'+dx+','+dy)
}
function dragend(e){
this.current_transform = this.transform();
this.attr("fill", "red");
// Get the bounding box for the target circle
var targetBBox = circle1.getBBox
/* Check if the bounding boxes intersect */
if(Raphael.isBBoxIntersect(boundingBox, targetBBox)){
alert("The bounding boxes intersect.");
}
else{
alert("The bounding boxes intersect.");
}
}
});

This concept is important if we decide to use SVG for collision detection. Collision detection is an important concept in game development.

This is the tenth part of this series. I have used this first 10 parts to cover basic concepts in using SVG with RaphaelJS. The purpose was to lay the ground work for projects we want to undertake.

From the next section, we shall look at how to create interactive maps. This project will tie in the concepts covered so far.

Thursday, 21 May 2015

SVG with RaphaelJS - Drag and Drop in RaphaelJS


Welcome to this section of the weekly series SVG with RaphaelJS.

The drag and drop functionality in RaphaelJS enables us to move elements from one location to another on the RaphaelJS paper.

The documentation is relatively straightforward on how to do this so an example will suffice. We start off by drawing a circle at x = 100 and y = 250 with the radius of 50. The code to do this is given below:

var circle = paper.circle(100, 250, 50).attr({ 'fill' : 'red', 'stroke-width' : 5 });

Notice that we give the circle a fill of red and a stroke-width of 5. This is shown below:


Next we write our dragstart, dragmove and dragend functions and assign them to our circle element.

Our final code is shown below.

$(function(){ var paper = Raphael('container', 500, 500);
// Draw a circle at the left hand side of the viewport
var circle = paper.circle(100, 250, 50).attr({ 'fill' : 'red', 'stroke-width' : 5 });
circle.drag(dragmove, dragstart, dragend);
function dragstart(x, y, e){
this.current_transform = this.transform();
this.attr("fill", "yellow");
}
function dragmove(dx, dy, x, y, e){
this.transform(this.current_transform+'T'+dx+','+dy)
}
function dragend(e){
this.current_transform = this.transform();
this.attr("fill", "red");
}
});

Note that in the dragstart method when we start dragging the circle, we change its fill colour to yellow.

We also get its current transform first before motion starts. This is because when motion starts, we want to move it in consideration of the transform that it had before motion.

In the dragmove function, we change the transform of the circle in consideration of how it has moved in the x and y directions. The variables dx and dy mean the difference in the motion of the circle along the x and y directions.

You can view the code for this on my dropbox or download the GitHub repository.

Wednesday, 20 May 2015

SVG with RaphaelJS - Using RaphaelJS with Other JavaScript Libraries


Welcome to this section of the weekly series SVG with RaphaelJS.

The node property is a reference to the DOM object so that you can manipulate elements in RaphaelJS using third party libraries.

In order to work with other JavaScript libraries our RaphaelJS elements must have their DOM exposed. So far we have used jQuery in our code but we haven't integrated it into RaphaelJS. In this section, we will do that.

Our template code file is given below:

$(function(){ var paper = Raphael('container', 500, 500);
});
Note that the first line is actually a jQuery command that lets the page load first before we do any other thing on the page.

Google Developer Tools
Google Chrome browser is in my opinion the best browser for a web developer because of its simplicity.

In order to use it, view the template code in the Google Chrome browser (I admit that I have always assumed you were using it). Hold down Ctrl + Shift and then press I on your keyboard. It will bring out the developer tools. The diagram is shown below:


The most important tab is the Console tab. It allows us to detect errors in our programs and will even inform you of the line causing the problem.

Accessing a RaphaelJS Element in the DOM
It is important to understand that SVG is part of the DOM structure. As a result, you can inspect SVG elements in the Chrome console.

In this example, I will use a circle to illustrate this concept. The circle will be given an id of circle using the Element.node method and we will use that reference to assign a click method to the circle in jQuery.

The code to do this is given below:

// Draw a circle at the center of your canvas var circle = paper.circle(250, 250, 50);
// Set the attributes of the circle
circle.attr({ fill: "red", cursor: "pointer" });
circle.node.id = "circle";
$("#circle").click(function(){
alert(1);
});

Copy and paste the above code below your the var paper = Raphael('container', 500, 500); in your init.js file.

You can view the repository here.

Using Qtip
Qtip is a JavaScript library that provides tooltips on DOM elements. In order to use it, simply download it and include its CSS file in the css directory of your project and the JavaScript file in the js directory of your project.

Next call them from your index.html file. The file now looks like this:

<!DOCTYPE html> <html>
<head>
<meta charset="utf-8">
<title>RaphaelJS Template</title>
<link rel="stylesheet" href="css/default.css">
<link rel="stylesheet" href="css/jquery.qtip.css">
<script src="js/jquery.js"></script>
<script src="js/jquery.qtip.js"></script>
<script src="js/raphael.js"></script>
<script src="js/init.js"></script>
</head>
<body>
<div id="container"></div>
</body>
</html>

Note the inclusion of both the CSS and JavaScript files of qtip. In order to use qtip in our code, we access the node element of the RaphaelJS element in our code. Paste the following lines of code below code in your init.js
$(circle.node).qtip({ content: { text: 'Hello. I am in the DOM' },
style: {
background: '#000000',
color: '#ffffff',
border: { width: 6, radius: 3, color: '#ff0000' }
},
position: {
my: 'left center',
at: 'bottom center',
target: 'mouse',
adjust: { x: 20, y: 25 }
}
});
console.log(circle.node);
Save your work and check it out in the browser. Now when you mouse over the circle, it pops up a message. You can view it on my dropbox.

In this section, we have looked at how to use RaphaelJS with other JavaScript libraries. This concept will prove useful when we want to create interactive maps.