What browser am I using?
is fantastic web app that will make it easy to know what browser your client or anybody is using.
You're using Firefox 27.
Share this with your support team!
Browser details
This information may help support representatives resolve any issues you're experiencing with their website.
Operating system
Windows 7
Cookies enabled
Yes
Flash version
12.0.0
Java version
1.7.0_09
Browser size
1349 x 664
Screen size
1366 x 768
Color depth
24 bit
Your full user agent string is:
Mozilla/5.0 (Windows NT 6.1; WOW64; rv:27.0) Gecko/20100101 Firefox/27.0
Showing posts with label Modules. Show all posts
Showing posts with label Modules. Show all posts
Sunday, March 09, 2014
What browser am I using?
Label:
Modules,
TECH,
Top Sites,
Web Desaign
Friday, September 20, 2013
Tutorial jQuery Fullscreen Editor
This jQuery plugin that adds a fullscreen mode option to a common text area.
Key features
- Flexible fullscreen mode
- Works on mobile - and major desktop browsers
- Comes with two different transitions
- Only ~4kb (minified)
Instructions
Download and extract the zip file to your desired project folder. Then in your document, first include fseditor.css right before >head< tag,<link rel="stylesheet" href="fseditor.css" type="text/css" media="all">Then include jQuery +1.8 and minimized version of fseditor's core javascript file;
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="jquery.fseditor.min.js"></script>
<script>
$(".mytextarea").fseditor();
</script>
That's it! Now the magic will happen.Options
| overlay | Whether show semi-transparent overlay behind the editor in fullscreen mode. (true/false) |
| placeholder | Show placeholder on the editor. (string) |
| transition | The transition effect while switching fullscreen mode, by default it is 'fade'. ('fade', 'slide-in') |
| expandOnFocus | When set to true, the fullscreen mode will be triggered on focus. (true/false) |
| maxWidth | Maximum width for fullscreen editor. (number) |
| maxHeight | Maximum height for fullscreen editor. (number) |
| onExpand | Expand event will be triggered when editor the goes to fullscreen mode. (function) |
| onMinimize | Minimize event will be triggered when the editor goes to inline mode. (function) |
Public Methods
To trigger a public method of the plugin, you can simply call;$('#fseditor').fseditor('method');
| expand | Triggers fullscreen mode. |
| minimize | Minimize the fullscreen mode. (unless it's not expanded) |
| destroy | Removes the plugin completely and brings the native textfield back. |
Credits
This plugin was created by Burak Son (@burakson). Feel free to open a ticket on issue tracker regarding any ideas/bug report. Contribution would also be appreciated!
Label:
Inspiration,
Modules,
Multimedia,
Top Sites,
Tutorial
Sunday, September 15, 2013
Tutorial Add a Progress Bar to Your Site
In this quick tip, we will use the new NProgress jQuery plugin to add a progress bar to a web page. If you’d like to learn more, keep reading!
The NProgress Plugin
NProgress is a jQuery plugin that shows an interactive progress bar on the top of your page, inspired by the one on YouTube. It consists of a global object –NProgress which holds a number of methods that you can call to advance the progress bar. Here is a quick demo of the methods:<div>
<h1>Quick Load</h1>
<p>Show the progress bar quickly. This is useful for one-off tasks like AJAX requests and page loads.</p>
<button class="quick-load">Quick Load</button>
</div>
<div>
<h1>Incremental Load</h1>
<p>The progress bar is incremented with every element that is loaded. This can be useful in web apps that load multiple items.</p>
<button class="show-progress-bar">Show Progress Bar</button>
<button class="load-one-item">Load An Item</button>
<button class="finish">Finish Loading</button>
</div>
<div>
<h1>Percentage Load</h1>
<p>NProgress lets you set the progress bar to a specific percentage. This can be useful in apps where you know the total number of the items to be loaded, so you can calculate the percentage. This is the technique that we will use in the demo.</p>
<button class="show-progress-bar">Show Progress Bar</button>
<button class="set-to-25">Set to 25% Loaded</button>
<button class="set-to-75">Set to 75% Loaded</button>
<button class="finish">Finish Loading</button>
</div>
The plugin github page suggests that you hook up the
NProgress.start() function to your $(document).ready() callback and NProgress.done() to $(window).load()
which is a very easy way to integrate the plugin. This won’t show the
real progress (for that you will have to monitor all the resources that
are included in your page and increment the bar manually), however most
people won’t notice anyway.Now that you have a good idea of how NProgress is used, let’s make a more complicated example – a gallery that shows a progress bar while loading images. The bar will correspond to the actual number of images loaded.
The Gallery
As usual, we start off with the HTML markup. This time it is very simple, we only have need a div to hold the photos, and a load button:index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Quick Tip: Add a Progress Bar to Your Site</title>
<link href="http://fonts.googleapis.com/css?family=PT+Sans+Narrow:700" rel="stylesheet" />
<!-- The Stylesheets -->
<link href="assets/nprogress/nprogress.css" rel="stylesheet" />
<link href="assets/css/style.css" rel="stylesheet" />
</head>
<body>
<h1>Gallery Progress Bar</h1>
<div id="main"></div>
<a href="#" id="loadMore">Load More</a>
<script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="assets/nprogress/nprogress.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
I am including a custom font from Google Webfonts and two stylesheets in the <head>, and three JavaScript files before the closing </body> tag.Things get more interesting in the jQuery part of the tutorial. Here I am using the Deferred object to show the photos consecutively. This is needed, because we want the photos to download in parallel (which is much faster), but fade into view one after the other. This article is too short to explain how Deferreds work, but you can read through one of these: link, link, link. They are a powerful tool that can simplify asynchronous interactions.
assets/js/script.js
(function($){
// An array with photos to show on the page. Instead of hard
// coding it, you can fetch this array from your server with AJAX.
var photos = [
'assets/photos/1.jpg', 'assets/photos/2.jpg',
'assets/photos/3.jpg', 'assets/photos/4.jpg',
// more photos here
];
$(document).ready(function(){
// Define some variables
var page = 0,
loaded = 0,
perpage = 10,
main = $('#main'),
expected = perpage,
loadMore = $('#loadMore');
// Listen for the image-loaded custom event
main.on('image-loaded', function(){
// When such an event occurs, advance the progress bar
loaded++;
// NProgress.set takes a number between 0 and 1
NProgress.set(loaded/expected);
if(page*perpage >= photos.length){
// If there are no more photos to show,
// remove the load button from the page
loadMore.remove();
}
});
// When the load button is clicked, show 10 more images
// (controlled by the perpage variable)
loadMore.click(function(e){
e.preventDefault();
loaded = 0;
expected = 0;
// We will pass a resolved deferred to the first image,
// so that it is shown immediately.
var deferred = $.Deferred().resolve();
// Get a slice of the photos array, and show the photos. Depending
// on the size of the array, there may be less than perpage photos shown
$.each(photos.slice(page*perpage, page*perpage + perpage), function(){
// Pass the deferred returned by each invocation of showImage to
// the next. This will make the images load one after the other:
deferred = main.showImage(this, deferred);
expected++;
});
// Start the progress bar animation
NProgress.start();
page++;
});
loadMore.click();
});
// Create a new jQuery plugin, which displays the image in the current element after
// it has been loaded. The plugin takes two arguments:
// * src - the URL of an image
// * deferred - a jQuery deferred object, created by the previous call to showImage
//
// Returns a new deferred object that is resolved when the image is loaded.
$.fn.showImage = function(src, deferred){
var elem = $(this);
// The deferred that this function will return
var result = $.Deferred();
// Create the photo div, which will host the image
var holder = $('<div class="photo" />').appendTo(elem);
// Load the image in memory
var img = $('<img>');
img.load(function(){
// The photo has been loaded! Use the .always() method of the deferred
// to get notified when the previous image has been loaded. When this happens,
// show the current one.
deferred.always(function(){
// Trigger a custom event on the #main div:
elem.trigger('image-loaded');
// Append the image to the page and reveal it with an animation
img.hide().appendTo(holder).delay(100).fadeIn('fast', function(){
// Resolve the returned deferred. This will notifiy
// the next photo on the page and call its .always() callback
result.resolve()
});
});
});
img.attr('src', src);
// Return the deferred (it has not been resolved at this point)
return result;
}
})(jQuery);
The progress bar is incremented with every loaded image by the callback function that listens for the image-loaded custom event. This way the showImage function is free to handle only the loading and displaying of the photos.by Martin Angelov
source: http://tutorialzine.com/2013/09/quick-tip-progress-bar/
Label:
Education,
HTML,
Inspiration,
Modules,
Multimedia,
TECH,
Tutorial
Thursday, September 12, 2013
Tutorial AngularJS With These 5 Practical Examples
By now you’ve probably heard of AngularJS – the exciting open source framework, developed by Google, that changes the way you think about web apps. There has been much written about it, but I have yet to find something that is written for developers who prefer quick and practical examples. This changes today. Below you will find the basic building blocks of Angular apps - Models, Views, Controllers, Services and Filters - explained in 5 practical examples that you can edit directly in your browser. If you prefer to open them up in your favorite code editor, grab the zip above.
What is AngularJS?
On a high level, AngularJS is a framework that binds your HTML (views) to JavaScript objects (models). When your models change, the page updates automatically. The opposite is also true – a model, associated with a text field, is updated when the content of the field is changed. Angular handles all the glue code, so you don’t have to update HTML manually or listen for events, like you do with jQuery. As a matter of fact, none of the examples here even include jQuery!To use AngularJS, you have to include it in your page before the closing <body> tag. Google’s CDN is recommended for a faster load time:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
AngularJS gives you a large number of directives that let you associate HTML elements to models. They are attributes that start with ng-
and can be added to any element. The most important attribute that you
have to include in any page, if you wish to use Angular, is ng-app:<body ng-app>
It should be added to an element that encloses the rest of the page,
like the body element or an outermost div. Angular looks for it when the
page loads and automatically evaluates all directives it sees on its
child elements.Enough with the theory! Now let’s see some code.
1. Navigation Menu
As a first example, we will build a navigation menu that highlights the selected entry. The example uses only Angular’s directives, and is the simplest app possible using the framework. Click the “Edit” button to see the source code. It is ready for experimentation!In the code above, we are using Angular’s directives to set and read the active variable. When it changes, it causes the HTML that uses it to be updated automatically. In Angular’s terminology, this variable is called a model. It is available to all directives in the current scope, and can be accessed in your controllers (more on that in the next example).
If you have used JavaScript templates before, you are familiar with the
{{var}}
syntax. When the framework sees such a string, it replaces it with the
contents of the variable. This operation is repeated every time var is
changed.2. Inline Editor
For the second example, we will create a simple inline editor – clicking a paragraph will show a tooltip with a text field. We will use a controller that will initialize the models and declare two methods for toggling the visibility of the tooltip. Controllers are regular JavaScript functions which are executed automatically by Angular, and which are associated with your page using theng-controller directive.When the controller function is executed, it gets the special
$scope object as a parameter. Adding properties or functions to it makes them available to the view. Using the ng-model
binding on the text field tells Angular to update that variable when
the value of the field changes (this in turn re-renders the paragraph
with the value).3. Order Form
In this example, we will code an order form with a total price updated in real time, using another one of Angular’s useful features – filters. Filters let you modify models and can be chained together using the pipe character|. In the example below, I am using the currency filter,
to turn a number into a properly formatted price, complete with a
dollar sign and cents. You can easily make your own filters, as you will
see in example #4.The
ng-repeat binding (docs)
is another useful feature of the framework. It lets you loop through an
array of items and generate markup for them. It is intelligently
updated when an item is changed or deleted.Note: For a more complete version, see this tutorial, which is based on this one, written with Backbone.js.
4. Instant Search
This example will allow users to filter a list of items by typing into a text field. This is another place where Angular shines, and is the perfect use case for writing a custom filter. To do this though, we first have to turn our application into a module.Modules are a way of organizing JavaScript applications into self-contained components that can be combined in new and interesting ways. Angular relies on this technique for code isolation and requires that your application follows it before you can create a filter. There are only two things that you need to do to turn your app into a module:
- Use the
angular.module("name",[])function call in your JS. This will instantiate and return a new module; - Pass the name of the module as the value of the
ng-appdirective.
filter() method on the module object returned by angular.module("name", []).Filters follow the Angular.js philosophy – every piece of code that you write should be self-contained, testable and reusable. You can use this filter in all your views and even combine it with others through chaining.
5. Switchable Grid
Another popular UI interaction is switching between different layout modes (grid or list) with a click of a button. This is very easy to do in Angular. In addition, I will introduce another important concept – Services. They are objects that can be used by your application to communicate with a server, an API, or another data source. In our case, we will write a service that communicates with Instagram’s API and returns an array with the most popular photos at the moment.Note that for this code to work, we will have to include one additional Angular.js file in the page:
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular-resource.min.js"></script>
This includes the ngResource module for easily working with AJAX APIs (the module is exposed as the $resource variable in the code). This file is automatically included in the editor below.Services are entirely self-contained, which makes it possible to write different implementations without affecting the rest of your code. For example, while testing, you might prefer to return a hard-coded array of photos which would speed up your tests.
more info:http://tutorialzine.com/2013/08/learn-angularjs-5-examples/
Label:
Inspiration,
Modules,
Tutorial
Saturday, August 03, 2013
Download: File Type Icons
File Type Icons by Web Icon Set is a great set of 62 stylish file extension icons in AI, ICO and PNG.
File Type Icons is a set of 62 different file extension icons in AI, ICO and PNG format. They are designed in long shadow flat design style, which looks very neat and modern. You can easily change the colors as well.
File Type Icons is free for download. You can see some of the most popular filename extensions like .png, .jpg, .exe, .dmg and .txt. If you need an icon that is not in the list, you can easily make or add one by yourself by modifying the AI source file. We will be adding more file types in the future.
File Type Icons come with AI, ICO and PNG format. They can be resized and can easily change colors. You can use the royalty-free icons for any personal, commercial project including web design, software, application, advertising, film, video, computer game, gui design, illustration.
source: http://www.webiconset.com/file-type-icons/
File Type Icons is a set of 62 different file extension icons in AI, ICO and PNG format. They are designed in long shadow flat design style, which looks very neat and modern. You can easily change the colors as well.
File Type Icons is free for download. You can see some of the most popular filename extensions like .png, .jpg, .exe, .dmg and .txt. If you need an icon that is not in the list, you can easily make or add one by yourself by modifying the AI source file. We will be adding more file types in the future.
File Type Icons come with AI, ICO and PNG format. They can be resized and can easily change colors. You can use the royalty-free icons for any personal, commercial project including web design, software, application, advertising, film, video, computer game, gui design, illustration.
source: http://www.webiconset.com/file-type-icons/
Label:
EPS,
FLA,
HTML,
Icon,
Inspiration,
Label,
Logo,
Modules,
Multimedia,
PSD,
Vector,
Web Desaign
Thursday, July 18, 2013
Tabulous.js - jQuery Tabs Module
If you think that tabs are our of fashion and boring, think again and
take a look at this stylish jQuery tabs module by Aaron Lumsden.
Documentation
..:: Getting Started
Include the relevant files
Firstly include jQuery and the tabulous.css and tabulous.js files. Place these before</head> section<link href='tabulous.css' rel='stylesheet' type='text/css'> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script type="text/javascript" src="tabulous.js"></script>
Create the tabs
<div id="tabs"> <ul> <li><a href="#tabs-1" title="">Tab 1</a></li> <li><a href="#tabs-2" title="">Tab 2</a></li> <li><a href="#tabs-3" title="">Tab 3</a></li> </ul> <div id="tabs_container"> <div id="tabs-1"> <!--tab content--> </div> <div id="tabs-2"> <!--tab content--> </div> <div id="tabs-3"> <!--tab content--> </div> </div><!--End tabs container--> </div><!--End tabs-->
Initiate the plugin
Once you have created your tabs you will need to initiate the plugin.At its most basic level you can initiate the plugin like:
$(document).ready(function ($) {
$('#tabs').tabulous({);
});
If you want to initiate the plugin with an effect then you can do so like:$('#tabs').tabulous({
effect: 'scale'
});
..:: Options
| Variable | Default Value | Description | Valid Options |
|---|---|---|---|
| effect | scale | The effect to use for the transition | scale / slideLeft / scaleUp / flip |
Sunday, April 07, 2013
Tutorial: 3D-ifying Documents Using CSS Transforms
Note: the demos in this blog post require IE 9+ (preferably 10), Firefox, or any WebKit browser. If you’re on a mobile device, you might need to click the open in new page button to view the demos properly.
Label:
HTML,
Modules,
Multimedia,
TECH,
Tutorial,
Web Desaign
Padlet: Create Anything on a Blank "Wall" and Share
Padlet give you a blank wall. You put anything you want on it, anywhere. Simple, yet powerful.
you can create anything on a blank "wall" and share it with others.
checkout examples of Padlet used for
teaching, wishing friends, noticeboards, bookmarking, discussions, brainstorming, notetaking, quizzes, planning events, making lists, watching videos, collecting feedback
Friday, December 14, 2012
Tutorial Mini Help System with jQuery
In this tutorial are going to create a mini help system with jQuery. This will be a small widget which will display help text or a guide to users of your web application. The widget content is going to be searchable in real time, and all matching terms will be highlighted.
For this example to work, here is what we have to do:
- We have to listen for the input event on the text box. I prefer this to keypress, as input catches events like cut/paste and undo/redo. It is not supported in older browsers (<IE9) though, so you might want to replace it with keypress if you want this example to work there;
- We will write a jQuery plugin, aptly named “highlight”, that will replace the matched text with
<span>elements; - We will use the jQuery.scrollTo plugin to smoothly scroll the
<span>elements into view.
Let’s start with the markup.
The first step is to lay down the HTML of the page that we will be working on:
There’s nothing out of the ordinary here – we are including a stylesheet in the head (you might want to take a look at it yourself, I won’t present it in this tutorial), jQuery and the scrollTo plugin at the bottom, along with two more js files that we will be discussing next. The widget has a text field (inside a #header div) and the #content holder. Inside the latter, you should put the help guide for your application.<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Mini Help System with jQuery | Tutorialzine </title>
<!-- Our stylesheet -->
<link rel="stylesheet" href="assets/css/styles.css" />
</head>
<body>
<div id="widget">
<div id="header">
<input type="text" id="search" placeholder="Search in the text" />
</div>
<div id="content">
<!-- Your help text goes here -->
</div>
</div>
<!-- JavaScript Includes -->
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="assets/js/highlight.jquery.js"></script>
<script src="assets/js/jquery.scrollTo.min.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
The jQuery Code
Now we’re going to write a jQuery plugin that searches for specific words in the #content element, and replaces the occurrences with span elements. For example searching for
javascript in the text javascript is awesome would yield <span class="match">javascript</span> is awesome. We will later style the .match spans with an orange background so they are easily distinguishable.The plugin will take two arguments – a search term (as a string), and an optional callback function that will be executed when the search/replace process is complete. As you will see later, we will use the callback to hook the scrollTo plugin and scroll the #content div to reveal the matches.
Before you start reading this code, keep in mind that you can’t simply fetch the inner html of the div, and call replace() on it to replace the search occurrences with span elements, as this way you will break your markup. If someone entered “div” as a search term this would cause all your
<div> elements to be replaced with <<span class="match">div</span>>, witch is just asking for trouble.The solution is a bit more complex (but not difficult once you get the idea) – we will use the contents() jQuery method to fetch all children of the element, and replace() the text only on the text nodes (they are guaranteed to not contain any html). We will then loop through all the element’s non-textnode children recursively, and repeat the steps.
assets/js/hight.jquery.js
(function($) {
var termPattern;
$.fn.highlight = function(term, callback) {
return this.each(function() {
var elem = $(this);
if (!elem.data('highlight-original')) {
// Save the original element content
elem.data('highlight-original', elem.html());
} else {
// restore the original content
elem.highlightRestore();
}
termPattern = new RegExp('(' + term + ')', 'ig');
// Search the element's contents
walk(elem);
// Trigger the callback
callback && callback(elem.find('.match'));
});
};
$.fn.highlightRestore = function() {
return this.each(function() {
var elem = $(this);
elem.html(elem.data('highlight-original'));
});
};
function walk(elem) {
elem.contents().each(function() {
if (this.nodeType == 3) { // text node
if (termPattern.test(this.nodeValue)) {
// wrap the match in a span:
$(this).replaceWith(this.nodeValue.replace(termPattern, '<span class="match">$1</span>'));
}
} else {
// recursively call the function on this element
walk($(this));
}
});
}
})(jQuery);
And voila, our text is full with pretty highlights! Don’t worry if you don’t quite understand how this works – it is packaged as an easy to use jQuery plugin, so you can drop it in your project without much thought.
Here is how to use the plugin:
assets/js/script.js
$(function() {
var search = $('#search'),
content = $('#content'),
matches = $(), index = 0;
// Listen for the text input event
search.on('input', function(e) {
// Only search for strings 2 characters or more
if (search.val().length >= 2) {
// Use the highlight plugin
content.highlight(search.val(), function(found) {
matches = found;
if(matches.length && content.is(':not(:animated)')){
scroll(0);
}
});
} else {
content.highlightRestore();
}
});
search.on('keypress', function(e) {
if(e.keyCode == 13){ // The enter key
scrollNext();
}
});
function scroll(i){
index = i;
// Trigger the scrollTo plugin. Limit it
// to the y axis (vertical scroll only)
content.scrollTo(matches.eq(i), 800, { axis:'y' } );
}
function scrollNext(){
matches.length && scroll( (index + 1) % matches.length );
}
});
In the callback, I trigger the scroll(0) function. This animates the #content div so it shows the first match of the series. There is another function for scrolling – scrollNext, which is called when you hit the return key while typing. This will cause the holder to reveal the next match. With this our mini help system is complete!
by Martin Angelov
source : http://tutorialzine.com/2012/12/mini-help-system-jquery/
Friday, November 30, 2012
Tutorial: Dropbox File Uploader With Twitter Bootstrap
A few weeks ago, Dropbox introduced a neat new feature – the Dropbox Chooser. By embedding it into your website, you give users a button with which they can attach files from their online storage.
Today we are going to use this feature to create a simple application that allows people to attach a photo from their Dropbox account, crop an area with the Jcrop plugin, and download the result. Additionally, we will make use of Twitter Bootstrap to show dialog windows, and PHP on the backend for the actual photo cropping.
Saturday, November 10, 2012
Tutorial Colorful CSS3 Animated Navigation Menu
In this short tutorial, we will be creating a colorful dropdown menu using only CSS3 and the Font Awesome icon font. An icon font is, as the name implies, a font which maps characters to icons instead of letters. This means that you get pretty vector icons in every browser which supports HTML5 custom fonts (which is practically all of them). To add icons to elements, you only need to assign a class name and the icon will be added with a :before element by the font awesome stylesheet.
Sunday, October 07, 2012
Tutorial Todo List App Powered By WordPress
In this tutorial, we are going to make a WordPress plugin that hooks into the API. It will then present a simple, AJAX-ed todo list application on the /todo URL of your WordPress site. The best thing is that this is a plugin and not a theme, which means you can use it on any WordPress site regardless of the theme. Let’s get started!
Your First WordPress Plugin
If you haven’t written a WordPress plugin before, here is what you need to know:- Plugins are PHP files that reside in the /wp-content/plugins folder;
- Plugins can be either a single PHP file with a unique name, or a folder with that file inside it, along with additional includes and resources (read the getting started guide);
- Plugins are described by a comment header in the main PHP file. You need this for your plugin to be recognized;
- Plugins do their business by hooking up to specific events in the WordPress execution. There is a reference with all available filters and actions;
- The documentation is your friend.
If you only wish to test out the Todo app we are writing today, you can simply grab the download zip, and install it from WordPress’ admin panel (choose Plugins->Upload).
Monday, August 27, 2012
Tutorial Make a Drawing Game with Node.js
By now you have probably heard of node.js. It is an asynchronous web server built ontop of Google’s V8 JavaScript engine (the same one that makes Chrome lighning fast). Using node, you can write scalable web services in JavaScript, that can handle a huge number of simultaneous connections, which makes it perfect as the backend of games, web chats and other real time tasks.
The Idea
Today we will be making a simple online drawing game. The app will let users draw on the page by dragging and moving their mice, and will display the results on a large canvas element. What sets is apart from all the other similar experiments though, is that people will see each other in real time as they do so. To achieve this, we will leverage the socket.io
library for node.js, which uses a range of technologies from websockets to AJAX long polling to give us a real time data channel. Because of this, the example works in all modern browsers.
Installing node.js
To run the game you will need to install node.js. It shouldn’t take more than a few minutes and is fairly straightforward. If you are on Windows, you can go ahead and download the installer from its official site. If you are on Linux or OSX, you will need to run this set of commands in your terminal (you only need to run the first script: node-and-npm-in-30-seconds.sh).
After you finish installing, you will also get access to npm, or node package manager. With this utility you can install useful libraries and bits of code that you can import into your node.js scripts. For this example, we will need the socket.io library I mentioned above, and node-static, which will serve the HTML, CSS and JS files of the drawing application. Again, open up your terminal (or a new command prompt window if you are on Windows) and write the following command:
1 | npm install socket.io node-static |
This shouldn’t take more than a few minutes to complete.
Running the Application
If you want to just grab the files and test the app on your computer, you will need to download the archive from the button above, and extract it somewhere on your hard drive. After this, open a command prompt / terminal and navigate to the folder (of course you remember how the cd command works, don’t you?). After this, type this command and hit return:
1 | node app.js |
You should be greeted with a socket.io debug message (otherwise probably your path is wrong; keep practicing with that cd command!). This means that everything is up and running! Now open http://localhost:8080 and you should see your very own copy of the demo. Nice!
These instructions also apply if you are following the steps of the article and are building the app from scratch. Which brings us back to the tutorial:
The HTML
The first step is to create a new HTML document. Inside it, we will put the canvas element which users will be drawing upon, and a div for holding the mouse pointers. Each mouse pointer will be a div with the .pointer css class that is absolutely positioned on the page (we won’t be discussing the styling in this article, open assets/css/styles.css to take a look).
index.html
01 | <!DOCTYPE html> |
02 | <html> |
03 | <head> |
04 | <meta charset="utf-8" /> |
05 | <title>Node.js Multiplayer Drawing Game | Tutorialzine Demo</title> |
06 |
07 | <!-- The stylesheets --> |
08 | <link rel="stylesheet" href="assets/css/styles.css" /> |
09 |
10 | <!--[if lt IE 9]> |
11 | <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> |
12 | <![endif]--> |
13 | </head> |
14 |
15 | <body> |
16 | <div id="cursors"> |
17 | <!-- The mouse pointers will be created here --> |
18 | </div> |
19 |
20 | <canvas id="paper" width="1900" height="1000"> |
21 | Your browser needs to support canvas for this to work! |
22 | </canvas> |
23 |
24 | <hgroup id="instructions"> |
25 | <h1>Draw anywhere!</h1> |
26 | <h2>You will see everyone else who's doing the same.</h2> |
27 | <h3>Tip: if the stage gets dirty, simply reload the page</h3> |
28 | </hgroup> |
29 |
30 | <!-- JavaScript includes. Notice that socket.io.js is served by node.js --> |
31 | <script src="/socket.io/socket.io.js"></script> |
32 | <script src="http://code.jquery.com/jquery-1.8.0.min.js"></script> |
33 | <script src="assets/js/script.js"></script> |
34 |
35 | </body> |
36 | </html> |
You can see that the canvas is set to a fixed width of 1900px and height of 1000px, but users with smaller displays will see only a part of it. A possible enhancement would be to enlarge or reduce the canvas in relation to the screen size, but I will leave that to you.
For the real-time communication channel between the users’s browser and node.js to work, we need to include the socket.io library in both places, however you won’t find the socket.io.js file included in the bottom of index.html in the download archive. This is because socket.io intercepts requests to /socket.io/socket.io.js and serves it itself so you don’t have to explicitly upload this file with your application.
The Client Side
In other tutorials, we would usually name this section JavaScript, but this time we have JavaScript on both the client (the person’s browser) and the server (node.js), so proper distinction must be made.
The code you see below runs in the person’s browser. It uses socket.io to connect to the server and notifies us when an event occurs. That event is a message emitted by other clients and relayed back to us by node.js. The messages contain mouse coordinates, unique id for the user, and whether they are drawing or not in the moment.
assets/js/script.js
001 | $(function(){ |
002 |
003 | // This demo depends on the canvas element |
004 | if(!('getContext' in document.createElement('canvas'))){ |
005 | alert('Sorry, it looks like your browser does not support canvas!'); |
006 | return false; |
007 | } |
008 |
009 | // The URL of your web server (the port is set in app.js) |
010 | var url = 'http://localhost:8080'; |
011 |
012 | var doc = $(document), |
013 | win = $(window), |
014 | canvas = $('#paper'), |
015 | ctx = canvas[0].getContext('2d'), |
016 | instructions = $('#instructions'); |
017 |
018 | // Generate an unique ID |
019 | var id = Math.round($.now()*Math.random()); |
020 |
021 | // A flag for drawing activity |
022 | var drawing = false; |
023 |
024 | var clients = {}; |
025 | var cursors = {}; |
026 |
027 | var socket = io.connect(url); |
028 |
029 | socket.on('moving', function (data) { |
030 |
031 | if(! (data.id in clients)){ |
032 | // a new user has come online. create a cursor for them |
033 | cursors[data.id] = $('<div class="cursor">').appendTo('#cursors'); |
034 | } |
035 |
036 | // Move the mouse pointer |
037 | cursors[data.id].css({ |
038 | 'left' : data.x, |
039 | 'top' : data.y |
040 | }); |
041 |
042 | // Is the user drawing? |
043 | if(data.drawing && clients[data.id]){ |
044 |
045 | // Draw a line on the canvas. clients[data.id] holds |
046 | // the previous position of this user's mouse pointer |
047 |
048 | drawLine(clients[data.id].x, clients[data.id].y, data.x, data.y); |
049 | } |
050 |
051 | // Saving the current client state |
052 | clients[data.id] = data; |
053 | clients[data.id].updated = $.now(); |
054 | }); |
055 |
056 | var prev = {}; |
057 |
058 | canvas.on('mousedown',function(e){ |
059 | e.preventDefault(); |
060 | drawing = true; |
061 | prev.x = e.pageX; |
062 | prev.y = e.pageY; |
063 |
064 | // Hide the instructions |
065 | instructions.fadeOut(); |
066 | }); |
067 |
068 | doc.bind('mouseup mouseleave',function(){ |
069 | drawing = false; |
070 | }); |
071 |
072 | var lastEmit = $.now(); |
073 |
074 | doc.on('mousemove',function(e){ |
075 | if($.now() - lastEmit > 30){ |
076 | socket.emit('mousemove',{ |
077 | 'x': e.pageX, |
078 | 'y': e.pageY, |
079 | 'drawing': drawing, |
080 | 'id': id |
081 | }); |
082 | lastEmit = $.now(); |
083 | } |
084 |
085 | // Draw a line for the current user's movement, as it is |
086 | // not received in the socket.on('moving') event above |
087 |
088 | if(drawing){ |
089 |
090 | drawLine(prev.x, prev.y, e.pageX, e.pageY); |
091 |
092 | prev.x = e.pageX; |
093 | prev.y = e.pageY; |
094 | } |
095 | }); |
096 |
097 | // Remove inactive clients after 10 seconds of inactivity |
098 | setInterval(function(){ |
099 |
100 | for(ident in clients){ |
101 | if($.now() - clients[ident].updated > fefbfb){ |
102 |
103 | // Last update was more than 10 seconds ago. |
104 | // This user has probably closed the page |
105 |
106 | cursors[ident].remove(); |
107 | delete clients[ident]; |
108 | delete cursors[ident]; |
109 | } |
110 | } |
111 |
112 | },fefbfb); |
113 |
114 | function drawLine(fromx, fromy, tox, toy){ |
115 | ctx.moveTo(fromx, fromy); |
116 | ctx.lineTo(tox, toy); |
117 | ctx.stroke(); |
118 | } |
119 |
120 | }); |
The basic idea is that we use socket.emit() to send a message to the node.js server on every mouse movement. This can generate a large number of packets, so we are rate-limiting it to one packet every 30 ms (the $.now() function is defined by jQuery and returns the number of milliseconds since the epoch).
The mousemove event is not called on every pixel of the movement, but we are using a trick to draw solid lines instead of separate dots – when drawing on the canvas, we are using the lineTo method, so that the distance between the mouse coordinates are joined with a straight line.
Now let’s take a look at the server!
Server Side
After reading through the client side code you might be worried that the code on the server is even longer. But you will be mistaken. The code on the server side is much shorter and simpler. What it does is serve files when people access the url of the app in their browsers, and relay socket.io messages. Both of these tasks are aided by libraries so are as simple as possible.
app.js
01 | // Including libraries |
02 |
03 | var app = require('http').createServer(handler), |
04 | io = require('socket.io').listen(app), |
05 | static = require('node-static'); // for serving files |
06 |
07 | // This will make all the files in the current folder |
08 | // accessible from the web |
09 | var fileServer = new static.Server('./'); |
10 |
11 | // This is the port for our web server. |
12 | // you will need to go to http://localhost:8080 to see it |
13 | app.listen(8080); |
14 |
15 | // If the URL of the socket server is opened in a browser |
16 | function handler (request, response) { |
17 |
18 | request.addListener('end', function () { |
19 | fileServer.serve(request, response); // this will return the correct file |
20 | }); |
21 | } |
22 |
23 | // Delete this row if you want to see debug messages |
24 | io.set('log level', 1); |
25 |
26 | // Listen for incoming connections from clients |
27 | io.sockets.on('connection', function (socket) { |
28 |
29 | // Start listening for mouse move events |
30 | socket.on('mousemove', function (data) { |
31 |
32 | // This line sends the event (broadcasts it) |
33 | // to everyone except the originating client. |
34 | socket.broadcast.emit('moving', data); |
35 | }); |
36 | }); |
With this our drawing app is complete!
Subscribe to:
Posts (Atom)








RSS Feed
Twitter
Facebook