Creating a simple glass effect with Raphaël

You may be wondering what the point is of creating virtual glass. Well, just like in the offline world, glass is used when you want to protect something but still be able to see what lies underneath. Besides that, with a little imagination you can create some cool effects for enhancing your web presentations or games.

As a practical example, we’ll be creating an over-simplified version of a graphic which is taken from a real-world training product, just to get familiar with the concept but without a high level of 3D detail, we will make some glass with just basic shapes and around 60 lines of code. You can use that as a basis to launch more ambitious projects of your own later.

Here’s a demo of what we’ll be building.

Now the other thing that you will surely be aware of is that we can create the image easily in an application like Illustrator or InkScape. This is beyond dispute. But creating the image in code allows us to manipulate each individual component of the drawing very easily, which is important if you are creating a dynamic image.

We will be using CSS, HTML, JavaScript, jQuery, and a special JS graphics library called Raphaël to create and manipulate our image. Yes, you can use HTML5 and direct SVG commands, but Raphaël takes all the complexity out, and also gives you the added advantage that it will work in other versions of HTML than just HTML5.

The first step we need to take is to set up the environment that we’ll be working with in our project. Start by creating a CSS file that we’ll call “main.css”, and add the following CSS commands:

#canvas {
width: 502px;
height: 302px;
position: relative;
top: 0px;
left: 7%;
}
#paper {
width: 500px;
height: 300px;
position: relative;
left: 2px;
top: 0px;
cursor: pointer;
}

That last line about the cursor pointer is how we indicate to the user that this is an active object that they can do something with.

Next we need a simple HTML template, which you can modify later for any other kind of project. This is what you need to create (using HTML5 in this example):

<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="main.css" />
</head>
<body>
<div id="canvas">
<div id="paper"></div>
</div>
<script src="jquery.js"></script>
<script src="raphael.js"></script>
<script src="drawing.js"></script>
</body>
</html>

Now obviously you will need to download jQuery and download Raphaël. Take note of all the licensing information and make sure you agree with it before proceeding further.

The next thing we need to do is create that “drawing.js” file. This is where the fun part happens. To start, everything happens inside a jQuery function, so we add that like this:

window.onload = function () {
}

All the other code for the application needs to be nested within the braces of this function.

We need a name for our image object, so in this case we will just call it “image”, declared this way:

window.onload = function () {
var image = {};
}

Then we need to create the Raphaël object.

window.onload = function () {
var image = {};
var R = Raphael("paper", 500, 300);
}

The browser recognizes “Raphael” as an object type defined in “raphael.js”. Next we are going to add some optional global variables that help to reduce typing if we create many other similar objects.

window.onload = function () {
var image = {};
var R = Raphael("paper", 500, 300);
var bodyAttr = {fill: "#AAAAAA", stroke: "#000000", "stroke-width": 1, "stroke-linejoin": "round"};
var btnAttr = {fill: "#000000", stroke: "#000000", "stroke-width": 1, "stroke-linejoin": "round"};
var btnLgtAttr = {fill: "#990000", stroke: "#000000", "stroke-width": 1, "stroke-linejoin": "round"};
var btnCvrAttr = {fill: "#000000", stroke: "#000000", "stroke-width": 1, "stroke-linejoin": "round"};
var safetyGlassAttr = {fill: "#CCCCCC", stroke: "#CCCCCC", "stroke-width": 1, "stroke-linejoin": "round"};
var safetyFrameAttr = {fill: "none", stroke: "#DD0000", "stroke-width": 5, "stroke-linejoin": "round"};
var safetyMsgAttr = {fill: "#0000000", "font-size": 35, "font-family":"monospace"};
}

Now there will be two devices created. The first is the main device, that also includes the background panel, and the second is the safety device, which is the glass tab that fits over the top. To create the main device, we just use a simple function by adding the following lines before the closing brace of the main “window.onload” function.

///////////////////////////////////////////////////////
function createMainDevice(){
image.body = R.rect(0,0,450,210).attr(bodyAttr);
image.button = R.rect(100,50,80,80).attr(btnAttr);
image.light = R.circle(140,90,20).attr(btnLgtAttr);
image.light.animate({opacity:0.4});
};
////////////////////////////////////////////////////////
createMainDevice();

The first line creates a rectangle at position 0,0 (of our paper div) that will be 450px horizontally and 210px vertically. The stroke and fill attributes were set in global variable “bodyAttr”.

Then we create the small black button in a similar way,and use a circle on top of that to represent a red LED light that will indicate the button’s status (on/off). We use the “animate” method to change the opacity of the LED so it looks like it is dimmed.

Next we need to place our safety device over the top, so that people won’t accidentally click the button.

///////////////////////////////////////////////////////
function createMainDevice(){
image.body = R.rect(0,0,450,210).attr(bodyAttr);
image.button = R.rect(100,50,80,80).attr(btnAttr);
image.light = R.circle(140,90,20).attr(btnLgtAttr);
image.light.animate({opacity:0.4});
};
function createSafetyDevice(){
image.safetyGlass = R.rect(70,30,140,120).attr(safetyGlassAttr);
image.safetyMsg = R.text(140,90,"SAFE").attr(safetyMsgAttr);
image.setSafetyDev=R.set();
image.setSafetyDev.push(image.safetyGlass,image.safetyMsg);
image.setSafetyDev.animate({opacity:0.55});
image.safetyFrame = R.rect(65,30,145,125).attr(safetyFrameAttr);
image.setSafetyDev.push(image.safetyFrame);
};
////////////////////////////////////////////////////////
createMainDevice();
createSafetyDevice();

This function contains all the necessary instructions for drawing the safety device on top of the main device, and there is a command to call the function. The order in which these two commands are called is important.

The glass effect is created by setting opacity to 0.55 so it can be seen through. Placing text on top enhances the effect.

We need to make it responsive, so we add an event handler for clicking on each of the objects. We should also add a boolean to our global vars for on/off status.

var image = {};
var R = Raphael("paper", 500, 700);
var deviceStatus = 0; /* 0 for off, 1 for on */

And then add this function after the “createSafteyDevice” function:

function onOff(){
if(deviceStatus==0){
deviceStatus=1;
image.light.animate({opacity:1.00});
} else {
deviceStatus=0;
image.light.animate({opacity:0.55});
};
};

And finish off with adding the following just before the closing brace of “window.onload”:

image.safetyGlass.node.onclick = function(){
image.setSafetyDev.remove();
};
image.button.node.onclick = function(){
onOff();
};
image.light.node.onclick = function(){
onOff();
};

If you click the safety glass, it will be removed. If you then click the button it will brighten or dim to show it is on or off.

This was just a really simple example, and of course you should expand on what was shown here to create your own more realistic and useful products.

To get more interesting effects, try tinting the glass by adding a little color, or you could even use path objects to simulate cracking the glass, or enlarge what is under the glass slightly to create a “magnifier” effect. In the latter case, as the user moves the glass object around, the surrounding objects should be enlarged or reduced as appropriate using jQuery and CSS.

Emma Grant is a professional freelance content writer from Ireland. Over the past three years she has travelled the world while running her business from her laptop. You find her at www.florencewritinggale.com More articles by Emma Grant
Home CSS Deals HTML HTML5 Java JavaScript jQuery Miscellaneous Mobile MySQL News PHP Resources Security Snippet Tools Tutorial Web Development Web Services WordPress