Pos Terbaru Kreatifa Media

5 W 1 H dalam Layout

Wednesday, May 1, 2013


Layout yang dikerjakan melalui proses dan tahapan yang benar bukan
tidak mungkin akan berdampak positif pada tujuan apa pun yang ingin
dicapai desainer melalui karya desain  yang dibuatnya.

Bagaimana mendesain layout yang baik?
Ada beberapa pertanyaan yang pertama-tama perlu dijawab:

1. What - Apa pesan yang ingin disampaikan kepada target audience?
2. Who - Siapa target audience?
3. Where – Di mana, di media apa?
4. When - Kapan desain layout itu akan dilihat oleh audience?
5. Why - Mengapa membuat desain layoaut tersebut? (tujuan)
6. How - Bagaimana menyampaikan pesan tersebut?

Jawaban semua pertanyaan tersebut adalah konsep dasar secara umum yang harus ada sebagai panduan bagi Anda untuk mendesain sebuah layout. Semakin lengkap dan jelas konsep desain yang ada, akan semakin cepat dan tepat seorang desainer memberikan solusinya.

Konsep Dasar
Selanjutnya hal yang paling penting Anda lakukan pertama kali setelah
mengetahui konsep dasar desain (5W,1H) adalah menentukan media dan spesifikasi apa yang akan digunakan:

1. Media apa yang cocok. Misalnya buletin, majalah, brosur, spanduk, dll
2. Bahan. Misalnya kertas fancy, kertas daur ulang, kain, dll
3. Ukuran. Misalnya A4, A3, 160x60 untuk x-banner, dll
4. Posisi. Misalnya A4 tegak (vertikal/portrait) atau mendatar (landscape)
5. Kapan. Berapa lama dan di mana saja karya desain tersebut akan
didistribusikan/diperhatikan ke pada target audience.


Thumbnails dan Dummy
Berdasarkan spesifikasi media yang dipilih, anda dapat mulai
merencanakan pengorganisasian layout dengan membuat thumbnails.
Thumbnails adalah sketsa layout dalam bentuk mini. Ada baiknya dalam
membuat thumnails Anda tidak langsung menggunakan komputer, tetapi
dengan pesil dan kertas dulu. Sedangkan dummy adalah contoh jadi suatu desain nantinya. Untuk sebuah buletin Anda dapat membuat dummy buletin itu tanpa isi tulisan di dalamnya.
Dekstop Publishing
Setelah semua panduan dan material desain sudah lengkap, barulah Anda dapat menggunakan software di komputer untuk memulai eksekusi desain. Saat ini sudah beredar banyak program dekstop publishing di pasaran, seperti InDesign, PageMaker, PhotoShop, FreeHand, Illustrator, CorelDraw!, dan lain-lain
Percetakan
Pada tahap ini desainer menentukan teknik cetak apakah ynag cocok untuk karya desain yang telah dibuatnya. Misalnya:
1.     Offset: teknik yang paling umum digunakan untuk mencetak brosur, buku, majalah, tabloid, buletin, koran, kalender, dll.
2.     Flexografi/cetak tinggi: banyak digunakan untuk mencetak di atas karton gelombang atau untuk label kemasan produk.
3.     Rotogravure: umumnya untuk mencetak label berbahan plastik untuk kemasan produk.
4.     Sablon/cetak saring/screen printing: banyak digunakan untuk mencetak kaos, mug, kartu nama.
5.     Digital: cocok untuk mencetak dalam waktu singkat dengan kuantitas yang tidak terlalu besar. Biasanya untuk banner, poster, dll.
Pada dasarnya percetakan harus dipilih yang berinisiatif serta dapat bekerja sama dengan baik selain kualitas cetaknya juga prima. Percetakan yang berinisiatif tinggi, akan menguhubungi desainer bila ada sesuatu yang akan berpotensi mengurangi kualitas dalam desainnya.
Sementara itu desainer tidak bersikap pasif sewaktu desain dicetak, tapi terus berhubungan dengan percetakan tersebut untuk mengontrol status dan kualitas datanya.

How to Improving Your Site’s User Experience

Friday, April 12, 2013


Red Digital Agency
Red presents a good balance of white space, imagery, text and color to reveal its purpose and capture attention.

When it comes to web design, the quality of experience that users have with a site determines whether it’s successful or not – regardless of how visually catchy the design is. A positive experience drives sales and conversions, while a negative one deters visitors from staying or returning. Therefore performance optimization should be a central part of your design process if you’re aiming for high conversions and user satisfaction. Here are some ways to improve your site’s user experience.

Increase Site Speed

Consider how many people take out their phones to quickly check email or look something up when they have a spare second in the day. Whether it’s while waiting for the bus, standing in line for coffee or running to a meeting, they expect to achieve their goal on the web in that short amount of time. Forty percent of users will abandon a page after waiting longer than 3 seconds, and many people share their bad site experiences with others. It’s your job as a designer to make sure your site is loading fast enough to satisfy these standards and to make sure yours provides an experience that gets positive feedback.
To begin the process of improving your speed, first use a site speed testing tool to measure how it’s currently performing. Then make changes like:
  • Resize or remove large images and files
  • Reduce the number of plug-ins in your site
  • Eliminate flash files, which greatly weigh down performance
  • Cache your site so that it won’t have to take time to fully assemble every time a user accesses it
  • Always retest your speed after making changes so you know what is effective in improving it.

Clean Up Your Navigation

Reassess your navigation system: does your menu and search field honor conventions in that they are easily identifiable and usable? Minimize the number of options users have when entering your site by combining pages/content and getting rid of low-traffic pages. The fewer options there are, the more direct your site’s purpose is, and the easier it is for users to decide where they want to go. You can evaluate how users currently use your site by carrying out usability tests and referring to your site analytics data.

Aim For High Conversion Rates

You can be sure that a high converting website is also highly usable. Focus on the usability of your site, and user satisfaction (and in turn, conversions) will follow. To maximize usability:
  • Make your purpose clear. Use recognizable and concise calls-to-action so that users know exactly what they are meant to do with your site. Show users the value your product or service will add to their lives.
  • Be consistent. Make sure each page of your site sends the same message, and shares the style of design elements and layout.
  • Make text readable. Tailor your content to be easily perceived while users scan the page. Headlines, variations in font sizes and weights, and breaks in text blocks create a breathable set of information that can be retained even while glancing through it.
  • Keep it simple. Comparable to the fact that simple navigation makes it easier for users to decide what to do, simplicity in your entire site design keeps users from being overwhelmed with information. Ample white space and a unified style give users a sense of comfort and professionalism, and builds their confidence that they’ll find what they’re looking for quickly.

Build Trust

Visitors to your site will have a more positive experience if they can trust you. Whether it’s the validity of your information, your protection of their personal information or confidence in the quality of your product, it’s important to give them reason to trust you. You can do this by providing visible contact information, allowing customer feedback, presenting previous customer testimonials and/or client logos, and displaying your SSL certificate if you have a registration or checkout page.
When working to improve your site’s user experience, just remember to consider what your audience is looking for, and test and measure the changes you make to create a more effective and usable site.

source: http://tutorialzine.com/2013/04/improving-your-sites-user-experience/

Portraits: Inspirational Website

Sunday, April 7, 2013

VIEW GALLERY        -        GET INSPIRED


Portraits has a beautiful, clean and flat design brought to the next level. Subtle effects and a great color scheme make it our pick this week.

1. choose your best photo to use as the base for your works of art!
2. Give your piece of work a little personality with color, texture and a caption.
3. Share your unique portrait with friends and family online, or get a high-quality print made!

VIEW GALLERY        -        GET INSPIRED

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

Tutorial Live Album Previews with CSS3 and jQuery

Thursday, December 27, 2012

DEMO       -       DOWNLOAD


In this tutorial explain about make a script for previewing the contents of an album with a slideshow-like animation. This can be used in photo galleries, online shops, profile pages and more. The example is inspired by Facebook, where you hover over an album and get a slideshow of some of the photos contained inside it.
Let’s begin with the HTML.

The HTML

The first step is to lay down the HTML foundation of today’s example. This is a standard HTML5 document:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Album Previews with CSS3 and jQuery | Tutorialzine </title>

<!-- Our stylesheet -->
<link rel="stylesheet" href="assets/css/styles.css" />

</head>
<body>

<div id="main">

<a href="#" data-images="assets/img/thumbs/11.jpg|assets/img/thumbs/10.jpg"
class="album">
<img src="assets/img/thumbs/4.jpg" alt="People" />
<span class="preloader"></span>
</a>

<!-- More albums will go here -->

</div>

<!-- JavaScript Includes -->
<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>
<script src="assets/js/script.js"></script>
<script src="assets/js/albumPreviews.js"></script>

</body>
</html>
 
The #main div holds the markup of the albums:

<a href="#" data-images="assets/img/thumbs/11.jpg|assets/img/thumbs/10.jpg" class="album">
<img src="assets/img/thumbs/4.jpg" alt="People" />
<span class="preloader"></span>
</a>
 
Each album is a link, which would normally point to the full album page, where the user would see all the photos in the album (it points to # here). The album also includes a data attribute that holds the URLs of images contained in it (it is a good idea to point to thumbnails and not the full images). In the jQuery part of the tutorial, we will get these URLs and append them as real images to the album link, and animate them.

Inside the link, there is the initial image of the album (which would be displayed even if JavaScript is disabled). This image should be different from the ones included in the data attribute. Last is the preloader span, which displays a transparent PNG that is rotated using CSS3. I decided to go this route instead of using a GIF, as the PNG format supports proper transparency and looks better.
However, it would be too much work to write the HTML for all the albums manually. This is the perfect opportunity to throw some PHP to generate it automatically.

index.php

$albums = array(
'People' => array(
'assets/img/thumbs/4.jpg',
'assets/img/thumbs/11.jpg',
'assets/img/thumbs/10.jpg'),

// More albums go here
);

foreach ($albums as $name => $a) {

?>

<a href="#" data-images="<?php echo implode('|', array_slice($a,1))?>" class="album">
<img src="<?php echo $a[0]?>" alt="<?php echo $name?>" />
<span class="preloader"></span>
</a>

<?php

}
 

The JavaScript

As with the other tutorials on the site, I am using the jQuery library to make writing JavaScript easier.
The main functionality of this example takes the form of a portable jQuery plugin. On the mouseenter event, the plugin looks for the data-images attribute, parses it and appends the images to the album. It then starts a slideshow which is automatically stopped on the mouseleave event:

assets/js/albumPreviews.js

(function($) {

$.fn.albumPreviews = function() {

return this.each(function(){

var album = $(this),
loop = null, images = $();

if(!album.data('images')){
// The data-images attribute is missing. Skip this album.
return true;
}

var sources = album.data("images").split('|');

album.on('mouseenter', function(){

if(!images.length){
// The images have not been loaded yet

$.each(sources,function(){
images = images.add('<img src="' + this + '" />');
});

// Start the animation after the first photo is loaded
images.first().load(function() {
album.trigger('startAnimation');
});

album
.append(images)
.addClass('loading');
}
else{
// Start the animation directly
album.trigger('startAnimation');
}

}).on('mouseleave', function(){
album.trigger('stopAnimation');
});

// Custom events:

album.on('startAnimation',function(){

var iteration = 0;

// Start looping through the photos
(function animator(){

album.removeClass('loading');

// Hide the currently visible photo,
// and show the next one:

album.find('img').filter(function(){
return ($(this).css('opacity') == 1);
}).animate({
'opacity' : 0
}).nextFirst('img').animate({
'opacity' : 1
});

loop = setTimeout(animator, 1000); // Once per second

})();

});

album.on('stopAnimation',function(){

album.removeClass('loading');
// stop the animation
clearTimeout(loop);
});

});

};

// This jQuery method will return the next
// element of the specified type, or the
// first one if it doesn't exist

$.fn.nextFirst = function(e) {
var next = this.nextAll(e).first();
return (next.length) ? next : this.prevAll(e).last();
};

})(jQuery);
 
I am using two custom events to organize my code better startAnimation and stopAnimation. They are triggered on mouseenter/mouseleave. The animation is handled by the animator function, which is called once every second with a timeout. You can tweak this to your liking.
And here is how it is used:

assets/js/script.js

$(function() {

// Initialize the plugin
$('#main .album').albumPreviews();

});
 
 

 

This will activate the plugin and set up the mouseenter/mouseleave event handlers on the elements. All that we have to do now is to add some neat CSS to make it look the part.

The CSS

I will only present the more interesting part of the stylesheet here. You can see the rest of the CSS rules in the assets/css/styles.css.
The albums have the .album class. This makes it easy to style them:

.album{
width:140px;
height:140px;
margin: 15px 5px;
position:relative;

display:inline-block;
border: 4px solid #F0F0F0;
background-color: #F0F0F0;

border-radius:12px;
box-shadow:0 -2px 0 #616161;

/* Reflections below the image */
-webkit-box-reflect: below 0 -webkit-linear-gradient(rgba(255,255,255,0) 0%, rgba(255,255,255,0) 80%, rgba(255,255,255,0.1) 100%);
}

/* Showing a subtle shadow on the borders of the image */
.album:before{
content: '';
top: -1px;
left: -1px;
right: -1px;
bottom: -1px;
z-index:1000;
position: absolute;
box-shadow: 0 0 2px rgba(0, 0, 0, 0.4) inset;
border:1px solid #fff;
}

/* The album photos (hidden by default) */
.album img{
top:0;
left:0;
opacity:0;
width:140px;
height:140px;
position:absolute;
}

/* The first (the default) thumbnail is visible */
.album img:first-child{
opacity:1;
}

.album img,
.album:before{
border-radius: 10px;
}

/* The preloader PNG. It is rotated with a CSS keyframe animation */

.album .preloader{
display:none;
}

.album.loading .preloader{
content:'';
position:absolute;
width:18px;
height:18px;
background:url('../img/preloader.png') center center;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin:auto;
display:block;

/* Configure a keyframe animation for Firefox */
-moz-animation: rotate 1s linear infinite;

/* Configure it for Chrome and Safari */
-webkit-animation: rotate 1s linear infinite;
}

/* Webkit keyframe animation */
@-webkit-keyframes rotate{
0%{ -webkit-transform:rotate(0deg);}
100%{ -webkit-transform:rotate(360deg);}
}

/* Firefox Keyframe Animation */
@-moz-keyframes rotate{
0%{ -moz-transform:rotate(0deg);}
100%{ -moz-transform:rotate(360deg);}
}

The .preloader png is shown the first time you hover your mouse on the album. Then the script starts loading the images. If you are on a speedy connection you might not see it, but it is good to have, to give users on slow networks the feeling that something is happening in the background. The preloader is animated with a CSS keyframe animation which is repeated an infinite number of times.
With this our live album preview is complete!

by Martin Angelov
Source: http://tutorialzine.com/2012/12/album-photo-previews-jquery/ 

 

 

Tutorial Mini Help System with jQuery

Friday, December 14, 2012

DEMO      -      DOWNLOAD



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:

<!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>
 
 
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.

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/ 

Pickadate.js: a lightweight jQuery date picker

Saturday, December 1, 2012



Lightweight, easy-to-use and clean; that's how a date picker should be. Pickadate.js is exactly that, give it a try and you'll love it.

SOURCE: http://amsul.github.com/pickadate.js/

Tutorial Cool Instagram “Gravity” Gallery

Thursday, November 29, 2012

DEMO    -     DOWNLOAD     -     SOURCE


This will be a script that runs a search on Instagram, fetches and displays the photos in a grid, and then uses the Box2D library to simulate physical interactions between them. And all of this in less the 40 lines of JS!

Tutorial Todo List App Powered By WordPress

Sunday, October 7, 2012



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.
To develop a plugin, install a local copy of WordPress and create a new PHP file in the /wp-content/plugins folder. After this place the header comment you see below, and activate your plugin from the admin panel.
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).

Tutorial Make A Simple AJAX Note Taking App

Tuesday, September 18, 2012

DEMO     -      DOWNLOAD 

Grab a copy of the demo from the button above and read on!
In this tutorial we will be making a simple app with PHP and jQuery that lets users write notes. The notes are going to be saved in plain text files on the server. It demonstrates how to read and write files in PHP, how to resize a textarea with jQuery, depending on the text inside it, and how to create a simple AJAX interaction.

FULL TUTORIAL 

Tutorial Make a Drawing Game with Node.js

Monday, August 27, 2012

DEMO     -     DOWNLOAD     -     SOURCE

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:
1npm 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:
1node 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.

Draw Anywhere!

Draw Anywhere!

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
03var 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
09var 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
13app.listen(8080);
14
15// If the URL of the socket server is opened in a browser
16function 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
24io.set('log level', 1);
25
26// Listen for incoming connections from clients
27io.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!
 
Support : Femin Collection | Habitat Design | Kreatifa Media
Copyright © 2013. Kreatifa Media - All Rights Reserved
Template Created by Habitat Design Published by Kreatifa Media
Proudly powered by Blogger