<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0">

<channel>
	<title />
	
	<link>http://www.flash-to-html5.net/blog</link>
	<description>HTML5 samples, showcases, tools, tutorials &amp; more...</description>
	<lastBuildDate>Thu, 24 May 2012 03:43:22 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/flashtohtml5" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="flashtohtml5" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Up close and personal with HTML5 IndexedDB</title>
		<link>http://www.flash-to-html5.net/blog/up-close-and-personal-with-html5-indexeddb-3</link>
		<comments>http://www.flash-to-html5.net/blog/up-close-and-personal-with-html5-indexeddb-3#comments</comments>
		<pubDate>Thu, 24 May 2012 03:43:22 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tutorials]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[html5 tutorial]]></category>
		<category><![CDATA[IndexedDB]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1286</guid>
		<description><![CDATA[Over the years, the web has increasingly transformed from being a repository of content to a marketplace of full-fledged functional apps.  The suite of technologies that fall under the “HTML5” banner have, as a fundamental goal, the capabilities to build within this new breed of software.  In this article, I’ll review a technology that solves [...]]]></description>
			<content:encoded><![CDATA[<p>Over the years, the web has increasingly transformed from being a repository of content to a marketplace of full-fledged functional apps.  The suite of technologies that fall under the “HTML5” banner have, as a fundamental goal, the capabilities to build within this new breed of software.  In this article, I’ll review a technology that solves an important piece of the application puzzle—managing storage and retrieval of user-specific data on the client side—called “IndexedDB.”</p>
<h3>What is IndexedDB?</h3>
<p>An IndexedDB is basically a persistent data store in the browser—a database on the client side.  Like regular relational databases, it maintains indexes over the records it stores and developers use the IndexedDB JavaScript API to locate records by key or by looking up an index.  Each database is scoped by “origin,” i.e. the domain of the site that creates the database.</p>
<p>IndexedDB is also a great example of how web standards evolve.  Through standards working groups and HTML5 Labs (a site that publishes prototype implementations of various HTML5 specifications so you can try them out and provide feedback), IndexedDB will soon be ready for prime time site use.</p>
<p><span id="more-1286"></span>If you’re new to IndexedDB, start here:</p>
<ol>
<li>Cookbook demo on <a href="http://ie.microsoft.com/testdrive/HTML5/Cookbook/" target="_blank">IETestDrive</a></li>
<li>Developers guide on <a href="http://msdn.microsoft.com/en-us/ie/hh440436.aspx#_IndexedDB" target="_blank">MSDN</a></li>
<li>Spec on <a href="http://www.w3.org/TR/IndexedDB/" target="_blank">W3C</a></li>
</ol>
<p>Now let’s get up close and personal by building our own app.</p>
<h3>Setting your development environment up</h3>
<p>Begin with an install:</p>
<ol>
<li>Download the prototype by clicking on the link “Download the Protoype now!” from <a href="http://html5labs.interoperabilitybridges.com/prototypes/indexeddb/indexeddb/info" target="_blank">here</a>.</li>
<li>Unzip the downloaded file.</li>
<li>If you are running a 32-bit version of Windows then run <em>vcredist_x86.exe</em>.</li>
<li>Register “sqlcejse40.dll” by running the following command from an elevated command prompt:</li>
</ol>
<h3>regsvr32 sqlcejse40.dll</h3>
<p>If everything goes well, then you should see this screen:</p>
<p><img src="data:image/png;base64,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" alt="" /></p>
<p><a href="http://bit.ly/npkR2M">Internet Explorer 10 Platform Preview</a> ships with support for IndexedDB.  Or you can get a recent version of <em>Google Chrome</em> or <em>Firefox</em> and you should be all set.</p>
<h3>Building an offline note-taking app</h3>
<p>We are going to build a client side data layer for a note-taking web app:</p>
<p>From a data model point of view, it’s about as simple as it can get.  The app allows users to write text notes and tag them with specific key words.  Each note will have a unique identifier that will serve as its key, and apart from the note text, it will be associated with a collection of tag strings.</p>
<p>Here’s a sample note object represented in JavaScript object literal notation:</p>
<div>
<p>var note = {</p>
<p>id: 1,</p>
<p>text: &#8220;Note text.&#8221;,</p>
<p>tags: ["sample", "test"]</p>
<p>};</p>
</div>
<p>We’ll build a NotesStore object that has the following interface:</p>
<div>
<p>var NotesStore = {</p>
<p>init: function(callback) {</p>
<p>},</p>
<p>addNote: function(text, tags, callback) {</p>
<p>},</p>
<p>listNotes: function(callback) {</p>
<p>}</p>
<p>};</p>
</div>
<p>It should be obvious what each method does.  All method calls execute asynchronously (that is, when results are reported via callbacks), and where a result is to be returned to the caller, the interface accepts a reference to a callback that is to be invoked with the result.  Let’s see what it takes to efficiently implement this object using an indexed database.</p>
<h3>Testing for IndexedDB</h3>
<p>The root object that you deal with when talking to the IndexedDB API is called indexedDB.  You can check for the presence of this object to see whether the current browser supports IndexedDB or not.  Like so:</p>
<div>
<p>if(window[“indexedDB”] === undefined) {</p>
<p>// nope, no IndexedDB!</p>
<p>} else {</p>
<p>// yep, we’re good to go!</p>
<p>}</p>
</div>
<p>Alternatively, you can use the <a href="http://www.modernizr.com/" target="_blank">Modernizr</a> JavaScript library to test for support for IndexedDB like so:</p>
<div>
<p>if(Modernizr.indexeddb) {</p>
<p>// yep, go indexeddb!</p>
<p>} else {</p>
<p>// bleh! No joy!</p>
<p>}</p>
</div>
<h3>Asynchronous requests</h3>
<p>The asynchronous API calls work through what are known as “request” objects.  When an asynchronous API call is made, it would return a reference to a “request” object, which exposes two events—onsuccess and onerror.</p>
<p>Here’s what a typical call looks like:</p>
<div>
<p>var req = someAsyncCall();</p>
<p>req.onsuccess = function() {</p>
<p>// handle success case</p>
<p>};</p>
<p>req.onerror = function() {</p>
<p>// handle error</p>
<p>};</p>
</div>
<p>As you work with the indexedDB API, it will eventually become hard to keep track of all the callbacks.  To make it somewhat simpler, I’ll define and use a small utility routine that abstracts the “request” pattern away:</p>
<div>
<p>var Utils = {</p>
<p>errorHandler: function(cb) {</p>
<p>return function(e) {</p>
<p>if(cb) {</p>
<p>cb(e);</p>
<p>} else {</p>
<p>throw e;</p>
<p>}</p>
<p>};</p>
<p>},</p>
<p>request: function (req, callback, err_callback) {</p>
<p>if (callback) {</p>
<p>req.onsuccess = function (e) {</p>
<p>callback(e);</p>
<p>};</p>
<p>}</p>
<p>req.onerror = errorHandler(err_callback);</p>
<p>}</p>
<p>};</p>
</div>
<p>Now, I can write my async calls like so:</p>
<div>
<p>Utils.request(someAsyncCall(), function(e) {</p>
<p>// handle completion of call</p>
<p>});</p>
</div>
<h3>Creating and opening the database</h3>
<p>Creating/opening a database is done by calling the open method of the indexedDB object.</p>
<p>Here’s an implementation of the NotesStore object’s init method:</p>
<div>
<p>var NotesStore = {</p>
<p>name: “notes-db”,</p>
<p>db: null,</p>
<p>ver: “1.0”,</p>
<p>init: function(callback) {</p>
<p>var self = this;</p>
<p>callback = callback || function () { };</p>
<p>Utils.request(window.indexedDB.open(“open”, this.name), function(e) {</p>
<p>self.db = e.result;</p>
<p>callback();</p>
<p>});</p>
<p>},</p>
<p>…</p>
</div>
<p>The open method opens the database if it already exists. It is doesn’t, it will create a new one. You can think of this as the object that represents the connection to the database.  When this object is destroyed the connection to the database is terminated.</p>
<p>Now that the database exists, let’s create the rest of the database objects.  But first, you’ll have to get acquainted with some important IndexedDB constructs.</p>
<h3>Object stores</h3>
<p>Object stores are the IndexedDB equivalent of “tables” from the relational database world.  All data is stored inside object stores and serves as the primary unit of storage.</p>
<p>A database can contain multiple object stores and each store is a collection of records.  Each record is a simple key/value pair.  Keys must uniquely identify a particular record and can be auto-generated.  The records in an object store are automatically sorted in ascending order by keys.  And finally, object stores can be created and deleted only under the context of “version change” transactions.  (More on that later.)</p>
<h3>Keys and Values</h3>
<p>Each record in the object store is uniquely identified by a “key.”  Keys can be arrays, strings, dates, or numbers.  For comparison’s sake, arrays are greater than strings, which are greater than dates, which are greater than numbers.</p>
<p>Keys can be “in-line” keys or not.  By “in-line,” we indicate to IndexedDB that the key for a particular record is actually a part of the value object itself.  In our notes store sample, for instance, each note object has an id property that contains the unique identifier for a particular note.  This is an example of an “in-line” key—the key is a part of the value object.</p>
<p>Whenever keys are “in-line,” we must also specify a “key path”—a string that signifies how the key value can be extracted from the value object.</p>
<p>The key path for “notes” objects for instance is the string “id” since the key can be extracted from note instances by accessing the “id” property.  But this scheme allows for the key value to be stored at an arbitrary depth in the value object’s member hierarchy. Consider the following sample value object:</p>
<div>
<p>var product = {</p>
<p>info: {</p>
<p>name: “Towel”,</p>
<p>type: “Indispensable hitchhiker item”,</p>
<p>},</p>
<p>identity: {</p>
<p>server: {</p>
<p>value: “T01”</p>
<p>},</p>
<p>client: {</p>
<p>value: “TC01”</p>
<p>},</p>
<p>},</p>
<p>price: “Priceless”</p>
<p>};</p>
</div>
<p>Here, the following key path might be used:</p>
<div>
<p>identity.client.value</p>
</div>
<h3>Database versioning</h3>
<p>IndexedDB databases have a version string associated with them.  This can be used by web applications to determine whether the database on a particular client has the latest structure or not.</p>
<p>This is useful when you make changes to your database’s data model and want to propagate those changes to existing clients who are on the previous version of your data model.  You can simply change the version number for the new structure and check for it the next time the user runs your app. If needed, upgrade the structure, migrate the data, and change the version number.</p>
<p>Version number changes must be performed under the context of a “version change” transaction.  Before we get to that, let’s quickly review what “transactions” are.</p>
<h3>Transactions</h3>
<p>Like relational databases, IndexedDB also performs all of its I/O operations under the context of transactions.  Transactions are created through connection objects and enable atomic, durable data access and mutation.  There are two key attributes for transaction objects:</p>
<h4>1.     Scope</h4>
<p>The scope determines which parts of the database can be affected through the transaction.  This basically helps the IndexedDB implementation determine what kind of isolation level to apply during the lifetime of the transaction.  Think of the scope as simply a list of tables (known as “object stores”) that will form a part of the transaction.</p>
<h4>2.     Mode</h4>
<p>The transaction mode determines what kind of I/O operation is permitted in the transaction.  The mode can be:</p>
<p><strong>a.      Read only</strong></p>
<p>Allows only “read” operations on the objects that are a part of the transaction’s scope.</p>
<p><strong>b.      Read/write</strong></p>
<p>Allows “read” and “write” operations on the objects that are a part of the transaction’s scope.</p>
<p><strong>c.      Version change</strong></p>
<p>The “version change” mode allows “read” and “write” operations and also allows the creation and deletion of object stores and indexes.</p>
<p>Transaction objects auto-commit themselves unless they have been explicitly aborted.  Transaction objects expose events to notify clients of:</p>
<ul>
<li>when they complete</li>
<li>when they abort and</li>
<li>when they timeout</li>
</ul>
<h3>Creating the object store</h3>
<p>Our notes store database will contain only a single object store to record the list of notes.  As discussed earlier, object stores must be created under the context of a “version change” transaction.</p>
<p>Let’s go ahead and extend the init method of the NotesStore object to include the creation of the object store.  I’ve highlighted the changed bits in bold.</p>
<div>
<p>var NotesStore = {</p>
<p>name: “notes-db”,</p>
<p>store_name: “notes-store”,</p>
<p>store_key_path: “id”,</p>
<p>db: null,</p>
<p>ver: “1.0”,</p>
<p>init: function (callback) {</p>
<p>var self = this;</p>
<p>callback = callback || function () { };</p>
<p>Utils.request(window.indexedDB.open(“open”, this.name), function (e) {</p>
<p>self.db = e.result;</p>
<p>// if the version of this db is not equal to</p>
<p>// self.version then change the version</p>
<p>if (self.db.version !== self.version) {</p>
<p>Utils.request(self.db.setVersion(self.ver), function (e2) {</p>
<p>var txn = e2.result;</p>
<p>&nbsp;</p>
<p>// create object store</p>
<p>self.db.createObjectStore(self.store_name,</p>
<p>self.store_key_path,</p>
<p>true);</p>
<p>txn.commit();</p>
<p>callback();</p>
<p>});</p>
<p>} else {</p>
<p>callback();</p>
<p>}</p>
<p>});</p>
<p>},</p>
<p>…</p>
</div>
<p>Object stores are created by calling the createObjectStore method on the database object.  The first parameter is the name of the object store.  This is followed by the string identifying the key path, and finally a Boolean flag indicating whether the key value should be auto-generated by the database when new records are added.</p>
<h3>Adding data to object stores</h3>
<p>New records can be added to an object store by calling the put method on the object store.  A reference to the object store instance can be retrieved through the transaction object.  Let’s implement the addNote method of our NotesStore object and see how we can go about adding a new record:</p>
<div>
<p>    …</p>
<p>addNote: function (text, tags, callback) {</p>
<p>var self = this;</p>
<p>callback = callback || function () { };</p>
<p>var txn = self.db.transaction(null, TransactionMode.ReadWrite);</p>
<p>var store = txn.objectStore(self.store_name);</p>
<p>Utils.request(store.put({</p>
<p>text: text,</p>
<p>tags: tags</p>
<p>}), function (e) {</p>
<p>txn.commit();</p>
<p>callback();</p>
<p>});</p>
<p>},</p>
<p>…</p>
</div>
<p>This method can be broken down into the following steps:</p>
<p>Invoke the transaction method on the database object to start off a new transaction.  The first parameter is the names of the object stores that are going to be a part of the transaction.  Passing null causes all the object stores in the database to be a part of the scope.  The second parameter indicates the transaction mode.  This is basically a numeric constant which we have declared like so:</p>
<div>
<p>// IndexedDB transaction mode constants</p>
<p>var TransactionMode = {</p>
<p>ReadWrite: 0,</p>
<p>ReadOnly: 1,</p>
<p>VersionChange: 2</p>
<p>};</p>
<p>Once the transaction has been created we acquire a reference to the object store in question through the transaction object’s objectStore method.</p>
<p>Once we have the object store handy, adding a new record is just a matter of issuing an asynchronous API call to the object store’s put method passing in the new object to be added to the store.  Note that we <em>do not</em> pass a value for the id field of the new note object.  Since we passed true for the auto-generate parameter while creating the object store, the IndexedDB implementation should take care of automatically assigning a unique identifier for the new record.</p>
<p>Once the asynchronous put call completes successfully, we commit the transaction.</p>
</div>
<h3>Running queries with cursors</h3>
<p>The IndexedDB way of enumerating records from an object store is to use a “cursor” object.  A cursor can iterate over records from an underlying object store or an index.  A cursor has the following key properties:</p>
<ol>
<li>A <strong><em>range</em></strong> of records in either an index or an object store.</li>
<li>A <strong><em>source</em></strong> that references the index or object store that the cursor is iterating over.</li>
<li>A <strong><em>position</em></strong> indicating the current position of the cursor in the given range of records.</li>
</ol>
<p>While the concept of a cursor is fairly straightforward, writing the code to actually iterate over an object store is somewhat tricky given the asynchronous nature of all the API calls.  Let’s implement the listNotes method of our NotesStore object and see what the code looks like.</p>
<div>
<p>    listNotes: function (callback) {</p>
<p>var self = this,</p>
<p>txn = self.db.transaction(null, TransactionMode.ReadOnly),</p>
<p>notes = [],</p>
<p>store = txn.objectStore(self.store_name);</p>
<p>Utils.request(store.openCursor(), function (e) {</p>
<p>var cursor = e.result,</p>
<p>iterate = function () {</p>
<p>Utils.request(cursor.move(), function (e2) {</p>
<p>// if &#8220;result&#8221; is true then we have data else</p>
<p>// we have reached end of line</p>
<p>if (e2.result) {</p>
<p>notes.push(cursor.value);</p>
<p>// recursively get next record</p>
<p>iterate();</p>
<p>}</p>
<p>else {</p>
<p>// we are done retrieving rows; invoke callback</p>
<p>txn.commit();</p>
<p>callback(notes);</p>
<p>}</p>
<p>});</p>
<p>};</p>
<p>// set the ball rolling by calling iterate for the first row</p>
<p>iterate();</p>
<p>});</p>
<p>},</p>
</div>
<p>Let’s break this implementation down:</p>
<ol>
<li>First, we acquire a transaction object by calling the database object’s transaction method.  Note that this time we’re indicating that we require a “read-only” transaction.</li>
<li>Next we retrieve a reference to the object store via the objectStore method of the transaction object.</li>
<li>Then we issue an async call to the openCursor API on the object store.  The tricky part here is that every single iteration over a record in the cursor is itself an async operation!  To prevent the code from drowning in a sea of callbacks, we define a local function called iterate to encapsulate the logic of iterating over every record in the cursor.</li>
<li>This iterate function makes an async call to the cursor object’s move method and recursively invokes itself again in the callback if it detects that there are more rows to be retrieved.  Once all the rows in the cursor have been retrieved we finally invoke the callback method passed by the caller handing in the retrieved data as a parameter.</li>
</ol>
<h3>Dive even deeper!</h3>
<p>This is, by no means, comprehensive coverage of the API, despite what you may think! I only covered:</p>
<p>Available options for implementing client-side storage today</p>
<p>The various key aspects of the IndexedDB API, including:</p>
<p>A. Testing whether the browser supports it</p>
<p>B. Managing asynchronous API calls</p>
<p>C. Creating/opening databases</p>
<p>D. Key parts of the API including object stores, keys/values, versioning, and transactions</p>
<p>E. Creating object stores</p>
<p>F. Adding records to object stores</p>
<p>G. Enumerating object stores using cursors</p>
<p>Hopefully it was up close and personal enough!</p>
<p>Now, if you&#8217;re ready for more, the <a href="http://www.w3.org/TR/IndexedDB/" target="_blank">W3C specification document</a> is a good reference and is short enough to be readable!  I’d encourage you to experiment—having access to a functional database on the client side opens up a range of new scenarios for web applications.</p>
<p>Another good resource is the <a href="http://bit.ly/sQE9GG" target="_blank">IndexedDB/AppCache sample</a> on the <a href="http://bit.ly/u9VYpu" target="_blank">IE Test Drive</a> site.  This sample covers a scenario where the two specifications complement each other in providing the user with a rich experience…even when she’s not connected to the internet. The sample also demonstrates using new features in IE10 like CSS3 3D transforms and CSS3 transitions.</p>
<p>via: <a href="http://www.htmlgoodies.com/html5/client/up-close-and-personal-with-html5-indexeddb.html#fbid=BrK5l1s16Hq" target="_blank">HTML5 Goodies</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/up-close-and-personal-with-html5-indexeddb-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Canvas: A Deep Dive to Applications and Tools (1)</title>
		<link>http://www.flash-to-html5.net/blog/html5-canvas-a-deep-dive-to-applications-and-tools-1</link>
		<comments>http://www.flash-to-html5.net/blog/html5-canvas-a-deep-dive-to-applications-and-tools-1#comments</comments>
		<pubDate>Mon, 21 May 2012 03:02:25 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tools]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[Canvas applications]]></category>
		<category><![CDATA[Canvas tool]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[html5 tools]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1263</guid>
		<description><![CDATA[As the new language for structuring and presenting content, HTML5 is taking the web by storm. It boasts many new revolutionary features for web development and web design. For months, I’ve collected more than 70 HTML5 tools for developers and designers to create new innovative projects and stay ahead of the field! Today in this [...]]]></description>
			<content:encoded><![CDATA[<p>As the new language for structuring and presenting content, HTML5 is taking the web by storm. It boasts many new revolutionary features for web development and web design. For months, I’ve collected more than 70 <a href="http://www.flash-to-html5.net/blog/category/html5-tools" target="_blank">HTML5 tools</a> for developers and designers to create new innovative projects and stay ahead of the field!</p>
<p>Today in this article, I will go deep dive to the HTML5 Canvas, one of the most remarkable features of HTML5. I will introduce the Canvas element and position the Canvas as a powerful technology for your Web applications.  With that in mind, I’ll focus on the various areas that HTML5 Canvas applied as well as the related applications and tools.</p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/HTML5-Canvas.jpg" target="_blank"><img class="alignleft size-full wp-image-1264" title="HTML5 Canvas" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/HTML5-Canvas.jpg" alt="HTML5 Canvas" width="571" height="204" /></a></p>
<h3>What’s the HTML5 &lt;Canvas&gt; element?</h3>
<p>According to <a href="http://en.wikipedia.org/wiki/Canvas_element" target="_blank">Wikipedia</a>, the Canvas element is part of HTML5 and allows for dynamic and scriptable rendering of 2D shapes and bitmap images. As a drawing surface with a rich set of JavaScript APIs, HTML5 Canvas gives you the power to create and manipulate images and animations on the fly.</p>
<p><span id="more-1263"></span>Actually, the &lt;Canvas&gt; element is only a container for graphics with height and width attributes. That’s why you need a script to draw the graphics. Canvas provides several approaches for drawing paths, circles, boxes, characters and adding images. To create a Canvas, you need to specify the id, width, and height of the &lt;Canvas&gt; element. You may see the following syntax:</p>
<p>&lt;Canvas id=&#8221;Canvas1&#8243; width=&#8221;300&#8243; height=&#8221;200&#8243;&gt;</p>
<p>Fallback content</p>
<p>&lt;/Canvas&gt;</p>
<p>The content between the &lt;Canvas&gt;&lt;/Canvas&gt; tags is &#8220;fallback content&#8221;, namely, it will be displayed only if the Canvas cannot be displayed. Also you can apply multiple Canvas elements in a web page by individualizing each Canvas with an id to target a specific Canvas through JavaScript.</p>
<p>As a HTML5 technology, the Canvas&#8217; cross-platform support is promising. It works perfectly across most modern Web browsers of Mozilla Firefox, Google Chrome, Internet Explorer, Safari, Konqueror and Opera as well as the mobiles of iPhone/iPad and Android.</p>
<h3>What is HTML5 Canvas used for?</h3>
<p>Canvas enables you to draw directly in the web browser without the use of third-party plug-ins like Adobe Flash. Working with JavaScript libraries and CSS3, HTML5 Canvas helps you create charts and graphs, special image effects, photo slideshows, animations and web-based games.</p>
<p>The examples provided below will give you some clear ideas what you can do with &lt;Canvas&gt; element before you start building your own implementations.</p>
<h4><strong>1.   Graphics Design</strong></h4>
<p>Canvas allows you to draw all kinds of graphics &#8211; shapes, images, text, lines, etc, almost anything you want. HTML5 Canvas can be used as basic drawings of rectangles, coordinates, gradient fills, opacity, paths, text and advanced graphic drawings like transforms, state saving, clipping. Thus many people try to use Canvas in the areas of charts, graphs and even 3D website design.</p>
<p>Another hidden power of HTML5 Canvas is the special image manipulation. This is also the difference between Canvas and SVG. With the Canvas element, you can perform image effects on pixel based artworks. It is easy to design a new image or import an image in the Canvas and operate it as you want. In web design, you may employ Canvas to design awesome images with special effects like sepia, glow, grayscale image hover, emboss, page turn effects, blur, white &amp; black, and etc.</p>
<p>The Canvas graphic applications below would give you some inspiration of what Canvas can do for graphic design.</p>
<p><strong>FlowerPower</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/FlowerPower.jpg" target="_blank"><img class="size-full wp-image-1266 alignnone" title="FlowerPower" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/FlowerPower.jpg" alt="FlowerPower" width="573" height="410" /></a></p>
<p><a href="http://www.openrise.com/lab/FlowerPower/" target="_blank">FlowerPower</a> is a JavaScript experiment developed by mhepekka using JavaScript and Canvas. This Canvas application inspired by nature uses blooms as brushes. With this simple and beautiful drawing tool, you can design different typography or images for your web design project.</p>
<p><strong>Lucid Chart</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Lucid-Chart.jpg" target="_blank"><img class="size-full wp-image-1267 alignnone" title="Lucid Chart" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Lucid-Chart.jpg" alt="Lucid Chart" width="573" height="454" /></a></p>
<p>I was deeply impressed by this Canvas application – <a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%E2%80%93-lucid-chart" target="_blank">Lucid Chart</a>. It features the visual collaboration that makes drawing diagrams fast and easy. This HTML5-based Web app includes many of the UI elements. If you are a Visio user, you should really give this professional Canvas application a try.</p>
<p><strong>iGrapher</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/iGrapher.jpg" target="_blank"><img class="size-full wp-image-1268 alignnone" title="iGrapher" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/iGrapher.jpg" alt="iGrapher" width="573" height="382" /></a></p>
<p>As a Canvas application as well as a Canvas tool, <a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%E2%80%93-igrapher" target="_blank">iGrapher</a> is used for charting, analysis and prediction of different stock, currency and commodity markets. This free web-based financial market visualization tool uses Canvas to draw the graphs of financial data.</p>
<p><strong>Gartic Canvas Sketch</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Gartic-Canvas-Sketch.jpg" target="_blank"><img class="size-full wp-image-1269 alignnone" title="Gartic Canvas Sketch" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Gartic-Canvas-Sketch.jpg" alt="Gartic Canvas Sketch" width="573" height="390" /></a></p>
<p>This is another graphic drawing application of Canvas. It is called <a href="http://gartic.uol.com.br/sketch/" target="_blank">Gartic Canvas Sketch</a> and released by Gartic. It uses Canvas tag for featuring the usual pencil, eraser, line and shape tools, flood fill, color picker, undo, etc, Gartic Canvas Sketch also enables you to watch an animation of how you sketched your artwork and the output formant is PNG, GIF or JPG.</p>
<p><strong>SketchPad</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/SketchPad.jpg" target="_blank"><img class="size-full wp-image-1270 alignnone" title="SketchPad" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/SketchPad.jpg" alt="SketchPad" width="573" height="376" /></a></p>
<p><a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%E2%80%93-sketchpad" target="_blank">Sketchpad</a> by Mugtug is an excellent HTML5 Canvas application. This effective sketching tool helps users create painting applications using Javascript and Canvas element. Sketchpad consists of the most popular options of brush, pencil, fill, text items and tools for spirographs, unusual shapes or stamps. You may apply this no-flash-required Canvas application to paint any color in any shade or opacity.</p>
<p><strong>Canvas Cycle</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Canvas-Cycle.jpg" target="_blank"><img class="size-full wp-image-1271 alignnone" title="Canvas Cycle" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Canvas-Cycle.jpg" alt="Canvas Cycle" width="573" height="381" /></a></p>
<p>This demo is a Canvas applications showcasing different weather effects. It is an implementation of a full 8-bit color <a href="http://www.chromeexperiments.com/detail/canvas-cycle/" target="_blank">cycling engine</a>. You may choose many color cycling scenes with some ambient environmental soundtracks to match.</p>
<h4>2.   <strong>Images and </strong><strong>Photo galleries</strong></h4>
<p>It is very easy to create much more beautiful image or photo galleries with HTML5 Canvas. To animate using the Canvas tag, you should create a loop and then set the times per second that you redraw the entire Canvas. For example, if you want to animate an image or photos, you need to hold a proper reference to that image and then redraw the image by placing it in a different position on the Canvas on every tick of the loop. Such images or photo galleries by Canvas may be used for web picture showcasing, product displaying or even for customers to drop products into a shopping cart.</p>
<p>Here are 3 Canvas applications used for images or photo gallery. Some are developed with amazing interactions, which gives a fabulous experience to users.</p>
<p><strong>Dynamic Image Collage</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Dynamic-Image-Collage.jpg" target="_blank"><img class="alignnone size-full wp-image-1272" title="Dynamic Image Collage" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Dynamic-Image-Collage.jpg" alt="Dynamic Image Collage" width="573" height="360" /></a></p>
<p><a href="http://www.canvasdemos.com/2009/10/17/dynamic-image-collage/" target="_blank">Dynamic Image Collage</a> is built using Canvas element, allowing you search for images from Flickr. This application will automatically create the images or photos you added to Canvas as a new layer. You can manipulate the layers in various ways, including: move, scale, rotate, move layer up and down, remove layer, change opacity, change blending mode and enable or disable shadow. It helps you create a personal image gallery.</p>
<p><strong>Surface Photo Gallery</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Surface-Photo-Gallery.jpg" target="_blank"><img class="alignnone size-full wp-image-1273" title="Surface Photo Gallery" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Surface-Photo-Gallery.jpg" alt="Surface Photo Gallery" width="573" height="390" /></a></p>
<p>This Canvas photo experiment is created by Ernest Delgado. It’s a UI Canvas implementation that closely follows the “photo table” application of Microsoft Surface. This HTML5 <a href="http://www.ernestdelgado.com/public-tests/canvasphoto/demo/canvas.html" target="_blank">Canvas application</a> allows users to create surface photo gallery with drag &amp; drop instead of redrawing every image each time when one of them is dragged</p>
<p><strong>Coulisse photo slideshow</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Coulisse-photo-slideshow.jpg" target="_blank"><img class="alignnone size-full wp-image-1274" title="Coulisse photo slideshow" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Coulisse-photo-slideshow.jpg" alt="Coulisse photo slideshow" width="573" height="397" /></a></p>
<p><a href="http://coulisse.luvdasun.com/#index=28" target="_blank">Coulisse</a> is a Canvas slideshow created by Elmer. This is a Canvas application with cover flow effect using the Canvas element. Click the photos in the demo, and you will enjoy a new and exciting type of slideshow with its own animated transitioning effect.</p>
<h4>3.   Animations</h4>
<p>HTML5 Canvas has changed the way JavaScript used to be and allows JavaScript to operate like paint. To create animation with the HTML5 Canvas tag, you need to know the basic structure of the animation loop in HTML5 Canvas, including: initializations, determine the frame rate, evaluate the current state, modify sprite data and redraw all sprites. Now, With HTML5 Canvas technology, designers can animate things up on the Canvas without plug-ins of Flash.  The best thing is that Canvas animation is supported in most modern browsers and mobiles, which help the web animation to win much more viewers.</p>
<p>Take a look at the following three Canvas applications and get inspired by the powerful Canvas animation.</p>
<p><strong>Leaf Transform</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Leaf-Transform.jpg" target="_blank"><img class="alignnone size-full wp-image-1275" title="Leaf Transform" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Leaf-Transform.jpg" alt="Leaf Transform" width="573" height="402" /></a></p>
<p>This simple 3D simulation of a leaf floating within the forest is created by Andrés Fernández . He places the leaf in a Canvas on the forest background modifying its transformation matrix to show the animation of <a href="http://www.disegnocentell.com.ar/ejemplos/transform/lab.php" target="_blank">leaf floating</a>.</p>
<p><strong>Fish IE Tank</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Fish-IE-Tank.jpg" target="_blank"><img class="alignnone size-full wp-image-1276" title="Fish IE Tank" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Fish-IE-Tank.jpg" alt="Fish IE Tank" width="573" height="389" /></a></p>
<p><a href="http://ie.microsoft.com/testdrive/Performance/FishIETank/" target="_blank">FishIE Tank</a> is also a Canvas animation. It is an adaptation of the Microsoft embedded in a PowerBASIC application instead of running it in a browser.</p>
<p><strong>Crazier Tentacles</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Crazier-Tentacles.jpg" target="_blank"><img class="alignnone size-full wp-image-1277" title="Crazier Tentacles" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Crazier-Tentacles.jpg" alt="Crazier Tentacles" width="573" height="401" /></a></p>
<p><a href="http://grantkot.com/tentacles.html" target="_blank">Crazier Tentacles</a> is a physics-based version of Canvas animation. This HTML5 application uses the same formula to generate the target shape and elastic rod physics, making it go towards that shape.</p>
<h4>4.   <strong></strong>Games <strong></strong></h4>
<p>The Canvas element contains a drawable region defined in HTML code with height and width attributes, allowing for dynamically generated graphics. Due to this feature, HTML5 Canvas is popularly used for gaming development. Now, with the advent of the HTML5 Canvas element, you can create snazzy looking web games easier than ever before without using Flash.</p>
<p>Here are two of my favorite games by HTML5 Canvas. Check out and you will be amazed that Canvas is really capable of powering online games.</p>
<p><strong>Pirates Love Daisies</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Pirates-Love-Daisies.jpg" target="_blank"><img class="alignnone size-full wp-image-1278" title="Pirates Love Daisies" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Pirates-Love-Daisies.jpg" alt="Pirates Love Daisies" width="573" height="394" /></a></p>
<p><a href="http://www.pirateslovedaisies.com/" target="_blank">Pirates Love Daisies</a> is a Canvas game about pirates fighting all kinds of sea creatures (and seagulls) to protect their daisy patch.</p>
<p><strong>Mayhem</strong></p>
<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Mayhem.jpg"><img class="alignnone size-full wp-image-1279" title="Mayhem" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/Mayhem.jpg" alt="Mayhem" width="573" height="405" /></a></p>
<p>This math based <a href="http://labs.hyperandroid.com/mathmayhem" target="_blank">HTML5 Canvas game</a> will stress your brain while having a nice game experience. The idea is to select the number tiles to give the exact total that has been asked. Therefore, the more bricks you use, the more points you’ll get.</p>
<h3>Other useful free online HTML5 Canvas tools</h3>
<p>Since HTML5 Canvas is definitely change the way we create website and web apps, there are plenty of Canvas resources and tutorials online. Although one can easily integrate Canvas into the web pages, you will require some programming and mathematical skills for creating the interactive effects, graphs, games, animations and functions. Here, I just show you some free online Canvas tools for you to simplify or optimize your HTML5 Canvas project in the above areas.</p>
<p><a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%E2%80%93-html5-online-3d-sketch-tool" target="_blank">Online 3D Sketch Tool</a> – A sketching tool uses HTML5 Canvas to make 3D drawing.</p>
<p><a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-paper-js" target="_blank">Paper.js</a> &#8211; An open source HTML5 Canvas vector graphics scripting tool.</p>
<p><a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%E2%80%93-harmony" target="_blank">Harmony</a> &#8211; An HTML5-based tool lets you draw on white Canvas using different brushes.</p>
<p><a href="../html5-tool-of-the-day-%E2%80%93-cloud-canvas">Cloud Canvas</a> &#8211; A HTML5 image creator and editor.</p>
<p><a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%E2%80%93-svg-to-html5-canvas-tool" target="_blank">SVG to Canvas</a> – A tool converts SVG into HTML5 Canvas JavaScript.</p>
<p><a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-canvas-creator" target="_blank">Canvas Creator</a> – A HTML5 game tool needs your login in.</p>
<p><a href="http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%E2%80%93-canvasloader-creator" target="_blank">CanvasLoader Creator</a> &#8211; A tool for you to generate scripted preloaders and create spinners using the HTML5 Canvas object.</p>
<h3>What do you think?</h3>
<p>Alright, we will come to the end of this part. The Canvas element really represents a big forward in graphics capabilities in the web development. Hopefully this deep dive into HTML5 Canvas introducing its usage areas as well as applications and tools is helpful for you. If you have any ideas about the HTML5 Canvas technology, feel free to share with us in the comment.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/html5-canvas-a-deep-dive-to-applications-and-tools-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Tool Of The Day – Lucid Chart</title>
		<link>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-lucid-chart</link>
		<comments>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-lucid-chart#comments</comments>
		<pubDate>Fri, 18 May 2012 07:45:41 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tools]]></category>
		<category><![CDATA[Canvas application]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[html5 tool]]></category>
		<category><![CDATA[HTML5 Web app]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1256</guid>
		<description><![CDATA[This fantastic free Canvas application – Lucid Chart has a big impact on me. It shows us how an HTML5 Web app can offer functionality comparable to a desktop application on any platform. It uses canvas to simplify the online creation of professional flowcharts, diagrams, graphs and representations. This online software is easy to use [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/16.jpg" target="_blank"><img class="size-full wp-image-1257 alignnone" title="HTML5 Tool Of The Day – Lucid Chart" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/16.jpg" alt="Lucid Chart" width="560" height="444" /></a></p>
<p>This fantastic free Canvas application – <a href="https://www.lucidchart.com/documents/edit?demo#4419-17fc-4fb5fccc-af84-5d850abeb545?demo=on" target="_blank">Lucid Chart</a> has a big impact on me. It shows us how an HTML5 Web app can offer functionality comparable to a desktop application on any platform. It uses canvas to simplify the online creation of professional flowcharts, diagrams, graphs and representations. This online software is easy to use with a few clicks. It is loaded with diagram tools, collaborate flow charts, sitemaps, wireframes, network diagrams, mind maps, iPhone mockups, business process diagrams, UML models and etc. Lucid Chart also supports Microsoft Visio import.</p>
<p><span id="more-1256"></span>This HTML5-based visual collaboration tool allows you to work together with an unlimited number of others to create and edit diagrams in real time. Thus, it is great for team collaboration or working with clients. Moreover, with this freeware, you may drag new lines out of any object, add your own images, export to PDF, PNG and JPG, embed diagrams in blogs or wikis and much more. Since this HTML5 tool provides you large numbers of features and functionalities, you can draw diagrams with clarity and precision. If you are a Visio user, you should really give this professional Canvas application a try.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-lucid-chart/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Overview of the Web Storage API</title>
		<link>http://www.flash-to-html5.net/blog/an-overview-of-the-web-storage-api</link>
		<comments>http://www.flash-to-html5.net/blog/an-overview-of-the-web-storage-api#comments</comments>
		<pubDate>Wed, 16 May 2012 05:27:40 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Basics]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[HTML5 features]]></category>
		<category><![CDATA[Stored Data]]></category>
		<category><![CDATA[Web Storage API]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1250</guid>
		<description><![CDATA[Web developers have long yearned for a way to store data long term. Cookies are an option, but they can only store 4KB of data. Additionally, cookies are sent to the server with each HTTP request. This means that cookies, especially large ones, can consume considerable network bandwidth. There have been other attempts to implement [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/15.jpg"><img class="alignleft size-full wp-image-1251" title="HTML5 Web Storage" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/15.jpg" alt="HTML5 Web Storage" width="337" height="286" /></a>Web developers have long yearned for a way to store data long term. Cookies are an option, but they can only store 4KB of data. Additionally, cookies are sent to the server with each HTTP request. This means that cookies, especially large ones, can consume considerable network bandwidth. There have been other attempts to implement storage techniques, but for the most part they have been hacks. Then, along came HTML5 and the Web Storage API to the rescue.</p>
<p>The Web Storage API defines two types of storage areas ― local storage and session storage. Local storage is persistent data which remains until it is explicitly deleted, or until the browser’s cache is cleared. According to the specification, browsers should allocate at least 5MB of local storage per domain. The second storage type, session storage, is also persistent data, however the data is tied to a “top-level browsing context” (i.e. a browser tab or window). Session data remains until it is either deleted or the browsing context is closed. Session storage is particularly useful when a user is interacting with multiple instances of the same website. In such a situation, using local storage could result in the different instances overwriting each others data.</p>
<p><span id="more-1250"></span>The two types of storage areas are accessed through global objects named “localStorage” and “sessionStorage”.  Both storage areas implement the exact same API.  Data is stored as key/value pairs, and all data is stored in string form.  When adding data to storage, it is implicitly converted to a string.  However, when the string data is retrieved from storage it needs to be explicitly converted to the appropriate data type using functions such as <a title="parseInt() Documentation" href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt" target="_blank">parseInt()</a>.  When dealing with objects, the <a title="Native Browser Support for JSON (Part 1 of 2)" href="http://cjihrig.com/blog/native-browser-support-for-json-part-1/" target="_blank">JSON.parse()</a> and <a title="Native Browser Support for JSON (Part 2 of 2)" href="http://cjihrig.com/blog/native-browser-support-for-json-part-2-of-2/" target="_blank">JSON.stringify()</a> methods should be used for serialization and deserialization.</p>
<h3>Detecting Storage Support</h3>
<p dir="ltr">The Web Storage API, like many other HTML5 features, is not supported by all browsers.  To check if a browser supports storage, use the function shown below.  The function checks for the existence of the global “localStorage” object.  A similar function could be created to check for session storage, but it can be safely assumed that if one storage area exists, then so does the other.</p>
<pre>function localStorageSupported() {
  try {
    return "localStorage" in window &amp;&amp; window["localStorage"] !== null;
  } catch (e) {
    return false;
  }
}</pre>
<h3>Storing Data</h3>
<p>Data is added to storage using the setItem() method.  setItem() takes a key and value as arguments.  If the key does not already exist in storage, then the key/value pair is added.  If the key is already present, then the value is updated.  Several example setItem() usages are shown below.  The examples show how to add data of various types to local and session storage.  Notice that the “key” argument must always be a string, while the type of “value” can vary.</p>
<pre>localStorage.setItem("key", "value");
sessionStorage.setItem("foo", 3.14);
localStorage.setItem("bar", true);
sessionStorage.setItem("baz", JSON.stringify(object));</pre>
<p dir="ltr">Data can also be added to storage using object property assignment statements.  The previous setItem() examples have been rewritten below using assignment statements. Note that the assignment to “key” on the first line will fail silently.  This is because the storage areas have a built in function named key() that will be covered later.  For this reason, the API methods are the preferred way to access storage.</p>
<pre>localStorage.key = "value"; // this fails silently
sessionStorage.foo = 3.14;
localStorage["bar"] = true;
sessionStorage["baz"] = JSON.stringify(object);</pre>
<p>If a site attempts to store too much data, eventually the browser’s storage quota will be exceeded and an exception will be thrown.  To handle this case, try-catch blocks should be used when storing data.  An example of this is shown below.</p>
<pre>try {
  localStorage.setItem("key", "value");
} catch (e) {
  alert("Exceeded Storage Quota!");
}</pre>
<h3>Reading Stored Data</h3>
<p>To read data from storage, the getItem() method is used.  getItem() takes a lookup key as its sole argument.  If the key exists in storage, then the corresponding value is returned.  If the key does not exist, then null is returned.  The following examples use the getItem() method to retrieve the data stored in the setItem() examples.</p>
<pre>var string = localStorage.getItem("key");
var number = sessionStorage.getItem("foo");
var boolean = localStorage.getItem("bar");
var object = JSON.parse(sessionStorage.getItem("baz"));</pre>
<p>Stored data can also be accessed by reading properties of the “localStorage” and “sessionStorage” objects.  The previous getItem() examples have been rewritten below using object property syntax.</p>
<pre>var string = localStorage.key;
var number = sessionStorage.foo;
var boolean = localStorage["bar"];
var object = JSON.parse(sessionStorage["baz"]);</pre>
<h3>Iterating Over Stored Data</h3>
<p>Often times, it is necessary to programmatically loop over all of the items in storage.  The loop’s upper bound is determined by the “length” property of the particular storage area.  The stored keys can be retrieved one at a time using the key() method.  key() takes a single integer parameter that acts as an index to the storage area.  An example of looping over each key/value pair in “localStorage” is shown below.  Of course, session storage can be processed in a similar fashion by substituting “sessionStorage” for “localStorage”.</p>
<pre>for (var i = 0; i &lt; localStorage.length; i++) {
  var key = localStorage.key(i);
  var value = localStorage.getItem(key);
  // do something with the key and value
}</pre>
<h3>Deleting Stored Data</h3>
<p>When data is no longer needed, it should be explicitly removed.  This is especially true for local storage, as it will persist even after the browser is closed.  To delete individual key/value pairs from storage, the removeItem() method is used.  The removeItem() method takes the key to be deleted as its only parameter.  If the key is not present then nothing will happen.  Examples of the removeItem() method are shown below.</p>
<pre>localStorage.removeItem("key");
sessionStorage.removeItem("foo");
localStorage.removeItem("bar");
sessionStorage.removeItem("baz");</pre>
<p>The delete operator can also be used to remove stored data.  The previous example is rewritten below using delete instead of removeItem().</p>
<pre>delete localStorage.key;
delete sessionStorage.foo;
delete localStorage["bar"];
delete sessionStorage["baz"];</pre>
<p dir="ltr">While removeItem() is used to delete individual pieces of data, the clear() method is used to delete all stored data.  Usages of the clear() method are shown below.</p>
<pre>localStorage.clear();
sessionStorage.clear();</pre>
<h3>The storage Event</h3>
<p>A user can potentially have several instances of the same site open at any given time.  Changes made to a storage area in one instance need to be reflected in the other instances.  The Web Storage API accomplishes this synchronization using the “storage” event.  When a storage area is changed, a “storage” event is fired for any other tabs/windows that are sharing the storage area.  Note that a “storage” event is <em>not</em> fired for the tab/window that changes the storage area.</p>
<p>Storage areas can be changed by calls to setItem(), removeItem(), and clear().  However, not all calls to these methods actually change the storage area.  For example, calling clear() on an empty storage area or removeItem() on a key that does not exist will not change the storage area, and therefore will not fire an event.</p>
<p>The “storage” event object has several fields of interest which are described below.  Following the description of the fields is an example “storage” event handler.</p>
<ul>
<li>“key” ― This field is the key argument of setItem() or removeItem(), or null when clear() caused the event to be fired.</li>
<li>“newValue” ― The “value” argument to setItem() is reflected in this field.  Calls to removeItem() and clear() cause this field to be null.</li>
<li>“oldValue” ― This field holds the key’s value prior to a call to setItem() or removeItem().  Calls to clear() cause this field to be null.</li>
<li>“url” ― The “url” field stores the address of the page whose storage area was affected.</li>
<li>“storageArea” ― The “storageArea” field corresponds to the local or session storage area that was changed.</li>
</ul>
<pre>window.addEventListener("storage", function(event) {
  var key = event.key;
  var newValue = event.newValue;
  var oldValue = event.oldValue;
  var url = event.url;
  var storageArea = event.storageArea;
  // handle the event
});</pre>
<h3>Example Page</h3>
<p>The following code implements a sample page for manipulating local storage.  The page is also available online <a title="Web Storage Example" href="http://www.cjihrig.com/development/html5/storage.htm" target="_blank">here</a>.  The example covers the entire local storage API, including the “storage” event.  In order to see the “storage” event in action, the page must be open in at least two separate tabs/windows of the same browser.  The “storage” event will also only work if the page is served over HTTP (i.e. the file:// protocol will not work).</p>
<pre>&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Web Storage Example&lt;/title&gt;
  &lt;meta charset="UTF-8" /&gt;
  &lt;script&gt;
    "use strict";
    window.addEventListener("load", function(event) {
      var key = document.getElementById("key");
      var value = document.getElementById("value");
      var add = document.getElementById("add");
      var remove = document.getElementById("remove");
      var clear = document.getElementById("clear");
      var content = document.getElementById("content");
      add.addEventListener("click", function(event) {
        if (key.value !== "") {
          try {
            localStorage.setItem(key.value, value.value);
          } catch (e) {
            alert("Exceeded Storage Quota!");
          }
          refreshContents();
        }
      });
      remove.addEventListener("click", function(event) {
        if (key.value !== "") {
          localStorage.removeItem(key.value);
          refreshContents();
        }
      });
      clear.addEventListener("click", function(event) {
        localStorage.clear();
        refreshContents();
      });
      window.addEventListener("storage", function(event) {
        var k = event.key;
        var newValue = event.newValue;
        var oldValue = event.oldValue;
        var url = event.url;
        var storageArea = event.storageArea;
        alert("EVENT:\n" + k + "\n" + newValue + "\n" + oldValue + "\n" + url + "\n" + storageArea);
        refreshContents();
      });
      function refreshContents() {
        var str = "";
        for (var i = 0, len = localStorage.length; i &lt; len; i++) {
          var k = localStorage.key(i);
          var v = localStorage.getItem(k);
          str += "'" + k + "' = '" + v + "'&lt;br /&gt;";
        }
        key.value = "";
        value.value = "";
        content.innerHTML = str;
      }
      refreshContents();
    });
  &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  Key:  &lt;input type="text" id="key" /&gt;&lt;br /&gt;
  Value: &lt;input type="text" id="value" /&gt;&lt;br /&gt;
  &lt;input type="button" id="add" value="Add to Storage" /&gt;&amp;nbsp;
  &lt;input type="button" id="remove" value="Remove from Storage" /&gt;&amp;nbsp;
  &lt;input type="button" id="clear" value="Clear Storage" /&gt;&lt;br /&gt;
  Contents of Local Storage:&lt;br /&gt;
  &lt;span id="content"&gt;&lt;/span&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
<h3>Things to Remember</h3>
<ul>
<li>Local storage persists until it is explicitly deleted or the browser’s cache is cleared.</li>
<li>Session storage persists until it is explicitly deleted or the browsing context is closed.</li>
<li>Data stored by one browser is not accessible by another browser.  For example, data stored by Chrome is not seen by Firefox.</li>
<li>Objects should be stored as JSON strings.</li>
<li>For security reasons, sensitive data should not be stored, especially in local storage.</li>
<li>Changes to a storage area cause a “storage” event to be fired.</li>
<li>As with many other HTML5 features, web storage is not yet implemented consistently.</li>
</ul>
<p>via: <a title="sitepoint" href="http://www.sitepoint.com/an-overview-of-the-web-storage-api/" target="_blank">sitepoint</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/an-overview-of-the-web-storage-api/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Tool Of The Day – HTML 5 Outliner</title>
		<link>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-html-5-outliner</link>
		<comments>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-html-5-outliner#comments</comments>
		<pubDate>Thu, 10 May 2012 08:11:12 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tools]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[HTML5 markup]]></category>
		<category><![CDATA[HTML5 outliner]]></category>
		<category><![CDATA[html5 tool]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1240</guid>
		<description><![CDATA[HTML5 outliner is a great tool that allows you check Your HTML Structure. By examining the outline of your HTML5 markup, you will get an overview of your document. Thus, you may make sure whether you have used headings and sections elements correctly. This HTML5 tool enables you paste in your code, point it to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/14.jpg"><img class="alignnone size-full wp-image-1241" title="HTML 5 Outliner" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/14.jpg" alt="HTML 5 Outliner" width="560" height="348" /></a></p>
<p><a href="http://gsnedders.html5.org/outliner/" target="_blank">HTML5 outliner</a> is a great tool that allows you check Your HTML Structure. By examining the outline of your HTML5 markup, you will get an overview of your document. Thus, you may make sure whether you have used headings and sections elements correctly.</p>
<p>This HTML5 tool enables you paste in your code, point it to a URL or upload a file easily. With these new elements, you are able to make your content flow in a logical manner. As a web designer or developer, the HTML5 outliner is truly another useful tool to have in your toolkit.</p>
<p><span id="more-1240"></span>Moreover, there is another HTML5 outliner (<a href="http://code.google.com/p/h5o/" target="_blank">h5o</a>), which is an implementation of the algorithm in JavaScript. This tool aims to produce outlines in decent browsers and has a Google Chrome extension, which uses the HTML5 outline algorithm to create a table of contents. Try it if necessary.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-html-5-outliner/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Safeguard Your Site with HTML5 Sandbox</title>
		<link>http://www.flash-to-html5.net/blog/how-to-safeguard-your-site-with-html5-sandbox</link>
		<comments>http://www.flash-to-html5.net/blog/how-to-safeguard-your-site-with-html5-sandbox#comments</comments>
		<pubDate>Tue, 08 May 2012 08:38:39 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tools]]></category>
		<category><![CDATA[HTML5 Tutorials]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[HTML5 sandbox]]></category>
		<category><![CDATA[Sandbox]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1224</guid>
		<description><![CDATA[Today’s web applications are mash ups of new experiences into one experience. Think Twitter widgets showing the latest tweets about a product. Or Facebook comments discussing an article. Or even just integrated web pages through an iframe element. These experiences can increase security breaches to your site. Don’t stress … there’s a new kid on [...]]]></description>
			<content:encoded><![CDATA[<p>Today’s web applications are mash ups of new experiences into one experience. Think Twitter widgets showing the latest tweets about a product. Or Facebook comments discussing an article. Or even just integrated web pages through an <code>iframe</code> element. These experiences can increase security breaches to your site.</p>
<p>Don’t stress … there’s a new kid on the block to help you out: the HTML5 sandbox. But before I get to that, let’s quickly review <code>iframe</code> element issues.</p>
<h3>A Black Box</h3>
<p>Embedding content with an <code>iframe</code> is like announcing a party publicly on Facebook. You think you know who you invited, but really you have no idea who passed it on and who’ll show up.</p>
<p>The same is true for framing content. You know what you are referencing, but you have no clue how the site will evolve in the future. Content or functionality (or both) can change any time. Without you knowing … and without your approval.</p>
<h3>Security Concerns Using Iframe</h3>
<p>Browsers handle pages that use <code>iframe</code> just like any other web page. Forms can be used to retrieve user input, scripts can be executed, the page can navigate within the browser window, and browser plugins can be executed. And just like the party crashers who get out of hand, you have no control what the hosted content will do.</p>
<p><span id="more-1224"></span>There is one mechanism in place by default that prevents some kinds of attacks: the cross-domain policy.</p>
<h3>Re-hosting Content From Another Domain</h3>
<p>If hosted content is coming from another domain, cross-domain policy comes into play and it prohibits the “foreign” content from accessing the parent’s document object model.</p>
<p><a href="http://www.flash-to-html5.net/blog/?attachment_id=54022" rel="attachment wp-att-54022" target="_blank"><img title="Unique origin: iframe originating from xyz.com within an HTML5 page originating from mydomain.com" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/Screen-Shot-2012-04-27-at-2.05.07-PM.png" alt="" width="678" height="333" /></a></p>
<p>So, the embedded page is not able to read, for instance, cookies or the browser’s local storage for the hosted domain. But there are still risks left.</p>
<p>Hosted content can still re-navigate on the top level. By displaying content the user would expect, the site could attempt to phish confidential information from the user. Or, by using a similarly styled form, attempt to maliciously capture user information that way.</p>
<p>That’s why, even with the cross-domain policy in place, there are still big security risks.</p>
<h3>Re-hosting Content From the Same Domain</h3>
<p><strong>The case for re-hosting content from the same domain is even worse.</strong></p>
<p>When the content comes from the same domain, there are no default security restrictions in place. Embedded content can access the complete loaded browser DOM and manipulate everything.</p>
<p>It kind of makes sense that content on the same domain should be safe. The risk here primarily stems from user-generated content that is re-hosted in the <code>iframe</code>.</p>
<p><a href="http://www.flash-to-html5.net/blog/?attachment_id=54023" rel="attachment wp-att-54023" target="_blank"><img title="Same origin: iframe originating from mydomain.com within an HTML5 page originating from mydomain.com" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/Screen-Shot-2012-04-27-at-2.05.21-PM.png" alt="" width="677" height="300" /></a></p>
<h3>A Sandboxed Approach</h3>
<p>These valid security concerns hadn’t been properly addressed by a standards body for a long time. Without a clear W3C standard, it was essential to somehow secure the host from framed content. For example, Microsoft provided a <a href="http://blogs.msdn.com/b/ie/archive/2008/01/18/using-frames-more-securely.aspx" target="_blank">proprietary implementation</a> of <code>iframe</code> security in Internet Explorer 8. Others picked it up and <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=341604" target="_blank">discussed</a> it as the baseline for their browsers as well. But standards have matured greatly since IE8.</p>
<p>Modern browsers including Chrome, Firefox, and <a href="http://msdn.microsoft.com/en-us/ie/hh272905.aspx#_HTML5Sandbox" target="_blank">IE10 Platform Preview</a> are based on the <a href="http://dev.w3.org/html5/spec-author-view/the-iframe-element.html#attr-iframe-sandbox" target="_blank">W3C iframe sandbox attribute</a>.</p>
<p>Here’s what we’ll build today with sandbox. See <a href="http://kouder.net/images/demos/sandbox/index.html" target="_blank">the demo here</a>.</p>
<p><a href="http://www.flash-to-html5.net/blog/?attachment_id=53944" rel="attachment wp-att-53944"><img title="HTML5 IFrame Sandbox Demo" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/Screen-Shot-2012-04-27-at-2.05.34-PM.png" alt="" width="315" height="394" /></a></p>
<p>Let’s begin by applying the sandbox. Just add it as empty attribute to the <code>iframe</code> element:</p>
<pre>&lt;iframe sandbox src="http://somewebsite.com/default.html"&gt;&lt;/iframe&gt;</pre>
<p>That’s it!</p>
<p>Now, <code>iframe</code> sandboxed content is re-hosted in the browser with the following restrictions:</p>
<ul>
<li>Plugins are disabled. Any kind of ActiveX, Flash, or Silverlight plugin will not be executed.</li>
<li>Forms are disabled. The hosted content is not allowed to make forms post back to any target.</li>
<li>Scripts are disabled. JavaScript is disabled and will not execute.</li>
<li>Links to other browsing contexts are disabled. An anchor tag targeting different browser levels will not execute.</li>
<li>Unique origin treatment. All content is treated under a unique origin. The content is not able to traverse the DOM or read cookie information.</li>
</ul>
<p>This means that even content coming from the same domain is treated with the cross-domain policy, as each <code>iframe</code> content will be viewed as a unique origin.</p>
<p><a href="http://www.flash-to-html5.net/blog/?attachment_id=53945" rel="attachment wp-att-53945"><img title="Unique origin: iframe originating from mydomain.com with a sandbox attribute within an HTML5 page originating from mydomain.com" src="http://www.sitepoint.com/wp-content/uploads/1/files/2012/04/Screen-Shot-2012-04-27-at-2.05.48-PM.png" alt="" width="673" height="303" /></a></p>
<p>Embedded content is only permitted to display information. No other actions can be done inside the <code>iframe</code> that could compromise the hosting website or take advantage of the users’ trust.</p>
<h3>Checking for the Sandbox Attribute</h3>
<p>We know that an <code>iframe</code> is an open gate. We know that the <code>sandbox</code> attribute locks down security of hosted content. The decision is clear: Use <code>iframe</code> elements just with the <code>sandbox</code> attribute!</p>
<p>You can confirm that the browser supports the <code>iframe</code> <code>sandbox</code> attribute with a simple check in JavaScript:</p>
<pre>if("sandbox" in document.createElement("iframe")) {
  // render the iframe element ...
} else {
  // embed content through other ways,
  // as the browser does not support the sandbox
}</pre>
<p>If it is supported, just use the <code>sandbox</code> attribute. If not, try to embed the content through other ways or encourage the user with a message that they should upgrade to a <a href="http://www.ietestdrive.com/" target="_blank">modern browser</a>.</p>
<h3>Customizing the Sandbox</h3>
<p>There are cases where you’ll need some level of customization on the restrictions, which is absolutely possible.</p>
<p>Several attribute values relax the standard sandbox policy …</p>
<p>allow-forms</p>
<p>If you want to enable forms post back within the <code>iframe</code> element, you just specify the <code>allow-forms</code> value for the <code>sandbox</code> attribute.</p>
<pre>&lt;iframe sandbox="allow-forms" src="xyz.html"&gt;&lt;/iframe&gt;</pre>
<p>If this value is present, the embedded page is allowed to post back using a form submit within the frame.</p>
<p>allow-scripts</p>
<p>JavaScript is a powerful language and is often used to have dynamic interactions on the client side without resending information to the server. But that power also brings risks when re-hosting foreign web pages.</p>
<p>Therefore, you should carefully consider whether you really want to enable JavaScript in <code>iframe</code> scenarios—especially when the content is from an unknown source.</p>
<p>Enabling JavaScript is done through the <code>allow-scripts</code> value.</p>
<pre>&lt;iframe sandbox="allow-scripts" src="xyz.html"&gt;&lt;/iframe&gt;</pre>
<p>allow-same-origin</p>
<p>By default, an <code>IFRAME</code> page from the same domain has the possibility to access the parent’s document object model.</p>
<p>With the <code>sandbox</code> attribute in place, the page will be treated as not being from the same origin. This page has no access to the resources, even when coming from the same domain.</p>
<p>To re-enable same-origin treatment in a sandboxed scenario, you have to specify the <code>allow-same-origin</code> attribute.</p>
<pre>&lt;iframe sandbox="allow-same-origin" src="xyz.html"&gt;&lt;/iframe&gt;</pre>
<p>The value itself is not very helpful, as you need some script capabilities to make use of it.</p>
<p>For example, if you want to access the local storage of the current domain like this:</p>
<pre>function loadFromStorage(key) {
  if(localStorage) {
    return localStorage.getItem(key);
  }
});</pre>
<p>… you also need the <code>allow-scripts</code> value:</p>
<pre>&lt;iframe sandbox="allow-scripts allow-same-origin" src="xyz.html"&gt;&lt;/iframe&gt;</pre>
<p>Now access works!</p>
<p>But be warned: allowing multiple scripts in the same sandbox can lead to security vulnerabilities. For example, your hosted content can manipulate the attributes of the sandbox and remove further restrictions.</p>
<p>allow-top-navigation</p>
<p>When you use the <code>sandbox</code> attribute, anchor targeting other browsing contexts are ignored and not executed by default. This protects the website hosting the <code>iframe</code> content from being replaced by the hosted content.</p>
<p>For example, this link would not be executed in the default sandbox, as the target would replace the complete web page:</p>
<pre>&lt;a href="xyz.html" target="_top"&gt;Click me&lt;/a&gt;</pre>
<p>Relaxing this policy is only recommended if you trust the content you host.</p>
<pre>&lt;iframe sandbox="allow-top-navigation" src="xyz.html"&gt;&lt;/iframe&gt;</pre>
<p>ms-allow-popups</p>
<p>Sometimes it is useful to allow embedded content opening up new popup windows. A perfect example is a mapping service like Bing Maps.</p>
<p>When embedding Bing Maps, additional functionality like driving directions or destination details can be looked up in popup windows. But since <code>sandbox</code> prohibits this, there’s a setting in Internet Explorer 10 that will enable popups without compromising the sandbox.</p>
<p>The following code shows how to set up <code>ms-allow-popups</code>:</p>
<pre>&lt;iframe sandbox="ms-allow-popups" src="xyz.html"&gt;&lt;/iframe&gt;</pre>
<p>When setting this value, embedded sites are able to display information in a new window.</p>
<pre>&lt;a href="xyz.html" target="_new"&gt;Show Info&lt;/a&gt;</pre>
<h3>Putting it all together</h3>
<p>You can combine several attribute values on one sandbox. For instance, if you want to enable forms post-back, top-level navigation, and JavaScript, just specify:</p>
<pre>&lt;iframe sandbox="allow-forms allow-top-navigation allow-scripts" src="xyz.html"&gt;&lt;/iframe&gt;</pre>
<p>It is also good to know that the sandbox behaves correctly when used in hierarchical situations, using several nested <code>iframe</code>s with different <code>sandbox</code> attribute values. The top-level <code>sandbox</code> always dominates down the hierarchy.</p>
<h3>Get Hands On!</h3>
<p>You can play around with the HTML <code>sandbox</code> in <a href="http://kouder.net/storage/demos/sandbox/index.html" target="_blank">this demo</a>. And you can download a <a href="https://github.com/writeline/HTML5-Sandbox-Demo">copy of this demo</a> from GitHub. To enable the form post-back demo, just open the project folder in WebMatrix and start the project from there.</p>
<p>Then, download a modern browser (like <a href="http://ie.microsoft.com/testdrive/Default.html">Internet Explorer 10 Platform Preview</a>) and familiarize yourself with the <code>sandbox</code> by reading the <a href="http://msdn.microsoft.com/de-de/ie/gg192966.aspx">IE developer guide</a>. This single attribute is a big step toward a more secure web … and modern browsers are finally ready to sandbox embedded content.</p>
<p>via: <a href="http://www.sitepoint.com/how-to-safeguard-your-site-with-html5-sandbox/" target="_blank">sitepoint</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/how-to-safeguard-your-site-with-html5-sandbox/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Tool Of The Day – Cloudkick Viz</title>
		<link>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-cloudkick-viz</link>
		<comments>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-cloudkick-viz#comments</comments>
		<pubDate>Fri, 04 May 2012 03:48:26 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tools]]></category>
		<category><![CDATA[canvas]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[HTML5 canvas tool]]></category>
		<category><![CDATA[html5 tool]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1220</guid>
		<description><![CDATA[Cloudkick Viz is another HTML5 canvas tool. Built on HTML5, canvas, and JavaScript, it displays cloud server monitoring information when checking your servers. Servers are plotted in 3D space in real time on basis of performance metrics like CPU usage, Memory usage, and Ping latency. Each server will blink when monitoring data is updated, and [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/13.jpg"><img class="alignnone size-full wp-image-1221" title="HTML5 Tool Of The Day – Cloudkick Viz" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/13.jpg" alt="HTML5 Tool Of The Day – Cloudkick Viz" width="558" height="345" /></a></p>
<p align="left"><a href="https://www.cloudkick.com/viz/mozilla/" target="_blank">Cloudkick Viz</a> is another HTML5 canvas tool. Built on HTML5, canvas, and JavaScript, it displays cloud server monitoring information when checking your servers. Servers are plotted in 3D space in real time on basis of performance metrics like CPU usage, Memory usage, and Ping latency. Each server will blink when monitoring data is updated, and if there is a check goes critical, it shakes and turns an angry red. What’s more, if you hover over a server, this canvas tool will show you its name and a ghost trail based on performance history. If you click it, you will get detailed monitoring data.</p>
<p align="left"><span id="more-1220"></span>As you can see from the screenshot, the circles represent your servers. And of cause that more powerful servers will be larger than less powerful ones. The help page of this app will inform you that red pulsing circles indicate servers in a warning or critical state, and flashing circles indicate a server being updated with new data. With this HTML5 canvas tool, you can also rotate the view by clicking and dragging in an empty area or by operating with the arrow keys.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-cloudkick-viz/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Tool Of The Day – Visual Form Builder</title>
		<link>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-visual-form-builder</link>
		<comments>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-visual-form-builder#comments</comments>
		<pubDate>Thu, 03 May 2012 02:22:56 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tools]]></category>
		<category><![CDATA[HTML coding]]></category>
		<category><![CDATA[html5]]></category>
		<category><![CDATA[HTML5 application]]></category>
		<category><![CDATA[HTML5 forms]]></category>
		<category><![CDATA[html5 tool]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1217</guid>
		<description><![CDATA[Just as its name implies, Visual Form Builder allows you to build and manage all kinds of beautiful HTML5 forms for your website. This HTML5 tool is a plug-in to create fully functional contact forms with a few clicks using a simple and clean interface. No PHP, CSS, or HTML coding requirement. These forms include [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/12.jpg"><img class="alignnone size-full wp-image-1218" title="HTML5 Tool Of The Day – Visual Form Builder" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/12.jpg" alt="HTML5 Tool Of The Day – Visual Form Builder" width="519" height="364" /></a></p>
<p>Just as its name implies, <a href="http://codecanyon.net/item/visual-form-builder-beautiful-forms-in-seconds/162388?ref=zbiskup" target="_blank">Visual Form Builder</a> allows you to build and manage all kinds of beautiful HTML5 forms for your website. This HTML5 tool is a plug-in to create fully functional contact forms with a few clicks using a simple and clean interface. No PHP, CSS, or HTML coding requirement. These forms include jQuery validation, a basic logic-based verification system, and entry tracking. Something to keep in mind is using Visual Form Builder requires a modern browser. However, the forms built by this HTML5 application are compatible with all browsers.</p>
<p align="left"><span id="more-1217"></span>Visual Form Builder enables client and server side validation, and each form you create has its integrated side validation built in. With the powerful and simple validation options, the script will automatically validate HTML5 fields based on their type. This HTML5 form creator supports all field type (Text, Text Area, Select, Radio, Checkbox, Password, File, Email, Number, URL, Date, and Range) and even HTML5 fields. In addition, you can easily add your own additional themes to this application.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-visual-form-builder/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML5 Tool Of The Day – iGrapher</title>
		<link>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-igrapher</link>
		<comments>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-igrapher#comments</comments>
		<pubDate>Wed, 02 May 2012 07:33:25 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 Tools]]></category>
		<category><![CDATA[HTML5 canvas]]></category>
		<category><![CDATA[HTML5 canvas tool]]></category>
		<category><![CDATA[html5 tool]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1213</guid>
		<description><![CDATA[iGrapher is a HTML5 canvas tool, also we may call it a canvas app. It is used for charting, analysis and prediction of different stock, currency and commodity markets. With this tool, you are able to make a schematic and technical drawing of different international stocks from the major markets. These stocks range from the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/11.jpg"><img class="alignnone size-full wp-image-1214" title="HTML5 Tool Of The Day – iGrapher" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/11.jpg" alt="HTML5 Tool Of The Day – iGrapher" width="584" height="414" /></a></p>
<p align="left"><a href="http://igrapher.com/" target="_blank">iGrapher</a> is a HTML5 canvas tool, also we may call it a canvas app. It is used for charting, analysis and prediction of different stock, currency and commodity markets. With this tool, you are able to make a schematic and technical drawing of different international stocks from the major markets. These stocks range from the FTSE to Dow Jones against different commodities including gold and global currencies. At the same time, you can also plot the news activity of a stock to make clear of the correlations between news reports and stock market movements.</p>
<p align="left"><span id="more-1213"></span>iGrapher has many more features like algorithmic analysis of the trends. This web based financial market visualization tool is free of charge and employs canvas to draw the graphs of those financial data. The best thing is this HTML5 tool is very easy to use. What you need to do is make some selections from the right hand menu, then iGrapher will help you draw a graph to compare each selection. Meanwhile, you can check out the value of each selection on the highlighted date by hovering over the graph.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/html5-tool-of-the-day-%e2%80%93-igrapher/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Fluid CSS3 Slideshow with Parallax Effect</title>
		<link>http://www.flash-to-html5.net/blog/fluid-css3-slideshow-with-parallax-effect</link>
		<comments>http://www.flash-to-html5.net/blog/fluid-css3-slideshow-with-parallax-effect#comments</comments>
		<pubDate>Wed, 02 May 2012 03:15:49 +0000</pubDate>
		<dc:creator>Sophie.Y</dc:creator>
				<category><![CDATA[HTML5 & CSS3]]></category>
		<category><![CDATA[CSS3 properties]]></category>
		<category><![CDATA[CSS3 tutorial]]></category>
		<category><![CDATA[parallax effect]]></category>

		<guid isPermaLink="false">http://www.flash-to-html5.net/blog/?p=1206</guid>
		<description><![CDATA[View demo Download source In this tutorial, we are going to create a slideshow with a parallax effect with the help of some CSS3 properties. We’ll use radio buttons and sibling combinators for controlling which slide is shown. There will be two backgrounds and the idea is to change the background positions and the position [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://tympanus.net/Tutorials/CSS3FluidParallaxSlideshow/" target="_blank"><img class="alignnone size-full wp-image-1207" title="CSS3FluidParallaxSlideshow" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/1.jpg" alt="CSS3FluidParallaxSlideshow" width="558" height="259" /></a></p>
<p><a href="http://tympanus.net/Tutorials/CSS3FluidParallaxSlideshow/" target="_blank">View demo</a> <a href="http://tympanus.net/Tutorials/CSS3FluidParallaxSlideshow/CSS3FluidParallaxSlideshow.zip" target="_blank">Download source</a></p>
<p>In this tutorial, we are going to create a slideshow with a parallax effect with the help of some CSS3 properties. We’ll use radio buttons and sibling combinators for controlling which slide is shown. There will be two backgrounds and the idea is to change the background positions and the position of the slider with transitions in order to create a slight parallax effect.</p>
<p>The graphics used in the demo are by: <a href="http://5milli.deviantart.com/art/Global-Map-Vector-100880703" target="_blank">5Milli</a> (Global Vector Map) and by <a href="http://wegraphics.net/downloads/free-vector-infographic-kit/" target="_blank">WeGraphics</a> (Free Vector Infographic Kit).</p>
<div><a href="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/2.jpg"><img class="alignnone size-full wp-image-1208" title="supported browsers" src="http://www.flash-to-html5.net/blog/wp-content/uploads/2012/05/2.jpg" alt="supported browsers" width="821" height="79" /></a></div>
<div><strong><br />
</strong></div>
<h4><strong>The Markup</strong></h4>
<p>We will “connect” the input elements to the division with the class sp-content by using the general sibling combinator. For that we will leave the inputs on the same level like the sp-content div. When we click on an input we will change the background color and background position of it (grid pattern) and also the background-position of the sp-parallax-bg div (the world map) with transitions. The respective slide will be shown by moving the sp-slider ul to the right position. The markup looks as follows:</p>
<p><span id="more-1206"></span></p>
<div>
<div id="highlighter_414319">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
<div>20</div>
<div>21</div>
<div>22</div>
<div>23</div>
<div>24</div>
<div>25</div>
<div>26</div>
<div>27</div>
<div>28</div>
<div>29</div>
<div>30</div>
<div>31</div>
<div>32</div>
<div>33</div>
<div>34</div>
<div>35</div>
</td>
<td>
<div>
<div><code>&lt;</code><code>div</code> <code>class</code><code>=</code><code>"sp-slideshow"</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>input</code> <code>id</code><code>=</code><code>"button-1"</code> <code>type</code><code>=</code><code>"radio"</code> <code>name</code><code>=</code><code>"radio-set"</code> <code>class</code><code>=</code><code>"sp-selector-1"</code> <code>checked</code><code>=</code><code>"checked"</code> <code>/&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-1"</code> <code>class</code><code>=</code><code>"button-label-1"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>input</code> <code>id</code><code>=</code><code>"button-2"</code> <code>type</code><code>=</code><code>"radio"</code> <code>name</code><code>=</code><code>"radio-set"</code> <code>class</code><code>=</code><code>"sp-selector-2"</code> <code>/&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-2"</code> <code>class</code><code>=</code><code>"button-label-2"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>input</code> <code>id</code><code>=</code><code>"button-3"</code> <code>type</code><code>=</code><code>"radio"</code> <code>name</code><code>=</code><code>"radio-set"</code> <code>class</code><code>=</code><code>"sp-selector-3"</code> <code>/&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-3"</code> <code>class</code><code>=</code><code>"button-label-3"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>input</code> <code>id</code><code>=</code><code>"button-4"</code> <code>type</code><code>=</code><code>"radio"</code> <code>name</code><code>=</code><code>"radio-set"</code> <code>class</code><code>=</code><code>"sp-selector-4"</code> <code>/&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-4"</code> <code>class</code><code>=</code><code>"button-label-4"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>input</code> <code>id</code><code>=</code><code>"button-5"</code> <code>type</code><code>=</code><code>"radio"</code> <code>name</code><code>=</code><code>"radio-set"</code> <code>class</code><code>=</code><code>"sp-selector-5"</code> <code>/&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-5"</code> <code>class</code><code>=</code><code>"button-label-5"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-1"</code> <code>class</code><code>=</code><code>"sp-arrow sp-a1"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-2"</code> <code>class</code><code>=</code><code>"sp-arrow sp-a2"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-3"</code> <code>class</code><code>=</code><code>"sp-arrow sp-a3"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-4"</code> <code>class</code><code>=</code><code>"sp-arrow sp-a4"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>label</code> <code>for</code><code>=</code><code>"button-5"</code> <code>class</code><code>=</code><code>"sp-arrow sp-a5"</code><code>&gt;&lt;/</code><code>label</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;</code><code>div</code> <code>class</code><code>=</code><code>"sp-content"</code><code>&gt;</code></div>
<div><code>        </code><code>&lt;</code><code>div</code> <code>class</code><code>=</code><code>"sp-parallax-bg"</code><code>&gt;&lt;/</code><code>div</code><code>&gt;</code></div>
<div><code>        </code><code>&lt;</code><code>ul</code> <code>class</code><code>=</code><code>"sp-slider clearfix"</code><code>&gt;</code></div>
<div><code>            </code><code>&lt;</code><code>li</code><code>&gt;&lt;</code><code>img</code> <code>src</code><code>=</code><code>"images/image1.png"</code> <code>alt</code><code>=</code><code>"image01"</code> <code>/&gt;&lt;/</code><code>li</code><code>&gt;</code></div>
<div><code>            </code><code>&lt;</code><code>li</code><code>&gt;&lt;</code><code>img</code> <code>src</code><code>=</code><code>"images/image2.png"</code> <code>alt</code><code>=</code><code>"image02"</code> <code>/&gt;&lt;/</code><code>li</code><code>&gt;</code></div>
<div><code>            </code><code>&lt;</code><code>li</code><code>&gt;&lt;</code><code>img</code> <code>src</code><code>=</code><code>"images/image3.png"</code> <code>alt</code><code>=</code><code>"image03"</code> <code>/&gt;&lt;/</code><code>li</code><code>&gt;</code></div>
<div><code>            </code><code>&lt;</code><code>li</code><code>&gt;&lt;</code><code>img</code> <code>src</code><code>=</code><code>"images/image4.png"</code> <code>alt</code><code>=</code><code>"image04"</code> <code>/&gt;&lt;/</code><code>li</code><code>&gt;</code></div>
<div><code>            </code><code>&lt;</code><code>li</code><code>&gt;&lt;</code><code>img</code> <code>src</code><code>=</code><code>"images/image5.png"</code> <code>alt</code><code>=</code><code>"image05"</code> <code>/&gt;&lt;/</code><code>li</code><code>&gt;</code></div>
<div><code>        </code><code>&lt;/</code><code>ul</code><code>&gt;</code></div>
<div><code>    </code><code>&lt;/</code><code>div</code><code>&gt;</code><code>&lt;!-- sp-content --&gt;</code></div>
<div><code>&lt;/</code><code>div</code><code>&gt;</code><code>&lt;!-- sp-slideshow --&gt;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The list elements are the wrappers for each slide and although we are using simply images here, you can use any kind of content.</p>
<h4><strong>The CSS</strong></h4>
<p>We’ll set the width of the main container to 80% and set the width of the divisions with class sp-content and class sp-parallax-bg to 100%. The sp-content div will have a background color and a background image (grid) that we will move whenever we slide the slider ul. The sp-parallax-bg div will have a map as background image and we will also move the background position.</p>
<div>
<div id="highlighter_602624">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
<div>20</div>
<div>21</div>
<div>22</div>
<div>23</div>
<div>24</div>
<div>25</div>
<div>26</div>
<div>27</div>
<div>28</div>
<div>29</div>
<div>30</div>
</td>
<td>
<div>
<div><code>.sp-slideshow {</code></div>
<div><code>    </code><code>position</code><code>: </code><code>relative</code><code>;</code></div>
<div><code>    </code><code>margin</code><code>: </code><code>10px</code> <code>auto</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>80%</code><code>;</code></div>
<div><code>    </code><code>max-width</code><code>: </code><code>1000px</code><code>;</code></div>
<div><code>    </code><code>min-width</code><code>: </code><code>260px</code><code>;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>460px</code><code>;</code></div>
<div><code>    </code><code>border</code><code>: </code><code>10px</code> <code>solid</code> <code>#fff</code><code>;</code></div>
<div><code>    </code><code>border</code><code>: </code><code>10px</code> <code>solid</code> <code>rgba(</code><code>255</code><code>,</code><code>255</code><code>,</code><code>255</code><code>,</code><code>0.9</code><code>);</code></div>
<div><code>    </code><code>box-shadow: </code><code>0</code> <code>2px</code> <code>6px</code> <code>rgba(</code><code>0</code><code>,</code><code>0</code><code>,</code><code>0</code><code>,</code><code>0.2</code><code>);</code></div>
<div><code>}</code></div>
<div><code>.sp-content {</code></div>
<div><code>    </code><code>background</code><code>: </code><code>#7d7f72</code> <code>url</code><code>(../images/grid.png) </code><code>repeat</code> <code>scroll</code> <code>0</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>position</code><code>: </code><code>relative</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>    </code><code>overflow</code><code>: </code><code>hidden</code><code>;</code></div>
<div><code>}</code></div>
<div><code>.sp-parallax-bg {</code></div>
<div><code>    </code><code>background</code><code>: </code><code>url</code><code>(../images/map.png) </code><code>repeat-x</code> <code>scroll</code> <code>0</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>background-</code><code>size</code><code>: cover;</code></div>
<div><code>    </code><code>position</code><code>: </code><code>absolute</code><code>;</code></div>
<div><code>    </code><code>top</code><code>: </code><code>0</code><code>;</code></div>
<div><code>    </code><code>left</code><code>: </code><code>0</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>    </code><code>overflow</code><code>: </code><code>hidden</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The styles of the inputs and the labels:</p>
<div>
<div id="highlighter_140762">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
<div>20</div>
<div>21</div>
<div>22</div>
<div>23</div>
<div>24</div>
<div>25</div>
<div>26</div>
<div>27</div>
<div>28</div>
<div>29</div>
<div>30</div>
<div>31</div>
<div>32</div>
<div>33</div>
<div>34</div>
<div>35</div>
<div>36</div>
<div>37</div>
<div>38</div>
<div>39</div>
<div>40</div>
<div>41</div>
<div>42</div>
<div>43</div>
<div>44</div>
</td>
<td>
<div>
<div><code>.sp-slideshow input {</code></div>
<div><code>    </code><code>position</code><code>: </code><code>absolute</code><code>;</code></div>
<div><code>    </code><code>bottom</code><code>: </code><code>15px</code><code>;</code></div>
<div><code>    </code><code>left</code><code>: </code><code>50%</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>9px</code><code>;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>9px</code><code>;</code></div>
<div><code>    </code><code>z-index</code><code>: </code><code>1001</code><code>;</code></div>
<div><code>    </code><code>cursor</code><code>: </code><code>pointer</code><code>;</code></div>
<div><code>    </code><code>opacity: </code><code>0</code><code>;</code></div>
<div><code>}</code></div>
<div><code>.sp-slideshow input + label {</code></div>
<div><code>    </code><code>position</code><code>: </code><code>absolute</code><code>;</code></div>
<div><code>    </code><code>bottom</code><code>: </code><code>15px</code><code>;</code></div>
<div><code>    </code><code>left</code><code>: </code><code>50%</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>6px</code><code>;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>6px</code><code>;</code></div>
<div><code>    </code><code>display</code><code>: </code><code>block</code><code>;</code></div>
<div><code>    </code><code>z-index</code><code>: </code><code>1000</code><code>;</code></div>
<div><code>    </code><code>border</code><code>: </code><code>3px</code> <code>solid</code> <code>#fff</code><code>;</code></div>
<div><code>    </code><code>border</code><code>: </code><code>3px</code> <code>solid</code> <code>rgba(</code><code>255</code><code>,</code><code>255</code><code>,</code><code>255</code><code>,</code><code>0.9</code><code>);</code></div>
<div><code>    </code><code>border-radius: </code><code>50%</code><code>;</code></div>
<div><code>    </code><code>transition: background-color linear </code><code>0.1</code><code>s;</code></div>
<div><code>}</code></div>
<div><code>.sp-slideshow input:checked + label {</code></div>
<div><code>    </code><code>background-color</code><code>: </code><code>#fff</code><code>;</code></div>
<div><code>    </code><code>background-color</code><code>: rgba(</code><code>255</code><code>,</code><code>255</code><code>,</code><code>255</code><code>,</code><code>0.9</code><code>);</code></div>
<div><code>}</code></div>
<div><code>.sp-selector</code><code>-1</code><code>, .button-label</code><code>-1</code> <code>{</code></div>
<div><code>    </code><code>margin-left</code><code>: </code><code>-36px</code><code>;</code></div>
<div><code>}</code></div>
<div><code>.sp-selector</code><code>-2</code><code>, .button-label</code><code>-2</code> <code>{</code></div>
<div><code>    </code><code>margin-left</code><code>: </code><code>-18px</code><code>;</code></div>
<div><code>}</code></div>
<div><code>.sp-selector</code><code>-4</code><code>, .button-label</code><code>-4</code> <code>{</code></div>
<div><code>    </code><code>margin-left</code><code>: </code><code>18px</code><code>;</code></div>
<div><code>}</code></div>
<div><code>.sp-selector</code><code>-5</code><code>, .button-label</code><code>-5</code> <code>{</code></div>
<div><code>    </code><code>margin-left</code><code>: </code><code>36px</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>We’ve set the opacity of the inputs to 0 so that they are not visible. The labels are under the radio button and we will make it look like a little circle. All the inputs and labels will be positioned absolutely and we will place them next to each other by applying a left margin.</p>
<p>Next, we will style the arrows which are simply labels with the respective <em>for</em> attribute. Note, that clicking on a label to active an associated input might not work in mobile browsers. But anyway, you can navigate using the dots since we are actually clicking on the inputs.</p>
<p>The arrow labels have the following style:</p>
<div>
<div id="highlighter_796223">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
</td>
<td>
<div>
<div><code>.sp-arrow {</code></div>
<div><code>    </code><code>position</code><code>: </code><code>absolute</code><code>;</code></div>
<div><code>    </code><code>top</code><code>: </code><code>50%</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>28px</code><code>;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>38px</code><code>;</code></div>
<div><code>    </code><code>margin-top</code><code>: </code><code>-19px</code><code>;</code></div>
<div><code>    </code><code>display</code><code>: </code><code>none</code><code>;</code></div>
<div><code>    </code><code>opacity: </code><code>0.8</code><code>;</code></div>
<div><code>    </code><code>cursor</code><code>: </code><code>pointer</code><code>;</code></div>
<div><code>    </code><code>z-index</code><code>: </code><code>1000</code><code>;</code></div>
<div><code>    </code><code>background</code><code>: </code><code>transparent</code> <code>url</code><code>(../images/arrows.png) </code><code>no-repeat</code><code>;</code></div>
<div><code>    </code><code>transition: opacity linear </code><code>0.3</code><code>s;</code></div>
<div><code>}</code></div>
<div><code>.sp-arrow:hover{</code></div>
<div><code>    </code><code>opacity: </code><code>1</code><code>;</code></div>
<div><code>}</code></div>
<div><code>.sp-arrow:active{</code></div>
<div><code>    </code><code>margin-top</code><code>: </code><code>-18px</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Now, let’s define when each arrow is shown. On the first slide we, for example, don’t want to show the left arrow. And on the last slide we don’t want to show the right arrow:</p>
<div>
<div id="highlighter_928260">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
</td>
<td>
<div>
<div><code>.sp-selector</code><code>-1:</code><code>checked ~ .sp-arrow.sp-a</code><code>2</code><code>,</code></div>
<div><code>.sp-selector</code><code>-2:</code><code>checked ~ .sp-arrow.sp-a</code><code>3</code><code>,</code></div>
<div><code>.sp-selector</code><code>-3:</code><code>checked ~ .sp-arrow.sp-a</code><code>4</code><code>,</code></div>
<div><code>.sp-selector</code><code>-4:</code><code>checked ~ .sp-arrow.sp-a</code><code>5</code> <code>{</code></div>
<div><code>    </code><code>right</code><code>: </code><code>15px</code><code>;</code></div>
<div><code>    </code><code>display</code><code>: </code><code>block</code><code>;</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>top</code> <code>right</code><code>;</code></div>
<div><code>}</code></div>
<div><code>.sp-selector</code><code>-2:</code><code>checked ~ .sp-arrow.sp-a</code><code>1</code><code>,</code></div>
<div><code>.sp-selector</code><code>-3:</code><code>checked ~ .sp-arrow.sp-a</code><code>2</code><code>,</code></div>
<div><code>.sp-selector</code><code>-4:</code><code>checked ~ .sp-arrow.sp-a</code><code>3</code><code>,</code></div>
<div><code>.sp-selector</code><code>-5:</code><code>checked ~ .sp-arrow.sp-a</code><code>4</code> <code>{</code></div>
<div><code>    </code><code>left</code><code>: </code><code>15px</code><code>;</code></div>
<div><code>    </code><code>display</code><code>: </code><code>block</code><code>;</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>top</code> <code>left</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>When an input is selected, the sp-content div will have a transition for the <em>background-position</em> and the <em>background-color</em>. The second transition is going to take a bit longer:</p>
<div>
<div id="highlighter_373819">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
</td>
<td>
<div>
<div><code>.sp-slideshow input:checked ~ .sp-content {</code></div>
<div><code>    </code><code>transition: background-position linear </code><code>0.6</code><code>s, background-color linear </code><code>0.8</code><code>s;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The div with the world map (sp-parallax-bg) will also have a transition for the background-position:</p>
<div>
<div id="highlighter_239565">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
</td>
<td>
<div>
<div><code>.sp-slideshow input:checked ~ .sp-content .sp-parallax-bg {</code></div>
<div><code>    </code><code>transition: background-position linear </code><code>0.7</code><code>s;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>In this way we can add a background parallax effect.</p>
<p>Let’s define the changes to color and background-position for the sp-content div:</p>
<div>
<div id="highlighter_852626">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
<div>20</div>
<div>21</div>
<div>22</div>
<div>23</div>
<div>24</div>
</td>
<td>
<div>
<div><code>input.sp-selector</code><code>-1:</code><code>checked ~ .sp-content {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>0</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>background-color</code><code>: </code><code>#727b7f</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-2:</code><code>checked ~ .sp-content {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-100px</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>background-color</code><code>: </code><code>#7f7276</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-3:</code><code>checked ~ .sp-content {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-200px</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>background-color</code><code>: </code><code>#737f72</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-4:</code><code>checked ~ .sp-content {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-300px</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>background-color</code><code>: </code><code>#79727f</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-5:</code><code>checked ~ .sp-content {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-400px</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>background-color</code><code>: </code><code>#7d7f72</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>… and the sp-parallax-bg div:</p>
<div>
<div id="highlighter_364694">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
</td>
<td>
<div>
<div><code>input.sp-selector</code><code>-1:</code><code>checked ~ .sp-content .sp-parallax-bg {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>0</code> <code>0</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-2:</code><code>checked ~ .sp-content .sp-parallax-bg {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-200px</code> <code>0</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-3:</code><code>checked ~ .sp-content .sp-parallax-bg {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-400px</code> <code>0</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-4:</code><code>checked ~ .sp-content .sp-parallax-bg {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-600px</code> <code>0</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-5:</code><code>checked ~ .sp-content .sp-parallax-bg {</code></div>
<div><code>    </code><code>background-position</code><code>: </code><code>-800px</code> <code>0</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>The unordered list with the class sp-slider will have a width of 500%. This is because we have 5 slides. It will have a transition for the left value, that we will change depening on the input that is checked:</p>
<div>
<div id="highlighter_80557">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
</td>
<td>
<div>
<div><code>.sp-slider {</code></div>
<div><code>    </code><code>position</code><code>: </code><code>relative</code><code>;</code></div>
<div><code>    </code><code>left</code><code>: </code><code>0</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>500%</code><code>;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>    </code><code>list-style</code><code>: </code><code>none</code><code>;</code></div>
<div><code>    </code><code>margin</code><code>: </code><code>0</code><code>;</code></div>
<div><code>    </code><code>padding</code><code>: </code><code>0</code><code>;</code></div>
<div><code>    </code><code>transition: </code><code>left</code> <code>ease-in </code><code>0.8</code><code>s;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Each list element is a slide and it will also have a transition for the opacity. We will give both, the slide and the image inside the box-sizing property of “border-box”. This will allow us to set a padding but also use 100% values for heights and widths and not worry about any overflow:</p>
<div>
<div id="highlighter_347195">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
</td>
<td>
<div>
<div><code>.sp-slider &gt; li {</code></div>
<div><code>    </code><code>color</code><code>: </code><code>#fff</code><code>;</code></div>
<div><code>    </code><code>width</code><code>: </code><code>20%</code><code>;</code></div>
<div><code>    </code><code>box-sizing: border-box;</code></div>
<div><code>    </code><code>height</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>    </code><code>padding</code><code>: </code><code>0</code> <code>60px</code><code>;</code></div>
<div><code>    </code><code>float</code><code>: </code><code>left</code><code>;</code></div>
<div><code>    </code><code>text-align</code><code>: </code><code>center</code><code>;</code></div>
<div><code>    </code><code>opacity: </code><code>0.4</code><code>;</code></div>
<div><code>    </code><code>transition: opacity ease-in </code><code>0.4</code><code>s </code><code>0.8</code><code>s;</code></div>
<div><code>}</code></div>
<div><code>.sp-slider &gt; li img{</code></div>
<div><code>    </code><code>box-sizing: border-box;</code></div>
<div><code>    </code><code>display</code><code>: </code><code>block</code><code>;</code></div>
<div><code>    </code><code>margin</code><code>: </code><code>0</code> <code>auto</code><code>;</code></div>
<div><code>    </code><code>padding</code><code>: </code><code>40px</code> <code>0</code> <code>50px</code> <code>0</code><code>;</code></div>
<div><code>    </code><code>max-height</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>    </code><code>max-width</code><code>: </code><code>100%</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Now we need to set the correct left values for each selected slide:</p>
<div>
<div id="highlighter_888949">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
<div>8</div>
<div>9</div>
<div>10</div>
<div>11</div>
<div>12</div>
<div>13</div>
<div>14</div>
<div>15</div>
<div>16</div>
<div>17</div>
<div>18</div>
<div>19</div>
</td>
<td>
<div>
<div><code>input.sp-selector</code><code>-1:</code><code>checked ~ .sp-content .sp-slider {</code></div>
<div><code>    </code><code>left</code><code>: </code><code>0</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-2:</code><code>checked ~ .sp-content .sp-slider {</code></div>
<div><code>    </code><code>left</code><code>: </code><code>-100%</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-3:</code><code>checked ~ .sp-content .sp-slider {</code></div>
<div><code>    </code><code>left</code><code>: </code><code>-200%</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-4:</code><code>checked ~ .sp-content .sp-slider {</code></div>
<div><code>    </code><code>left</code><code>: </code><code>-300%</code><code>;</code></div>
<div><code>}</code></div>
<div><code>input.sp-selector</code><code>-5:</code><code>checked ~ .sp-content .sp-slider {</code></div>
<div><code>    </code><code>left</code><code>: </code><code>-400%</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>Each current slide will then get opacity 1:</p>
<div>
<div id="highlighter_52536">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
<div>7</div>
</td>
<td>
<div>
<div><code>input.sp-selector</code><code>-1:</code><code>checked ~ .sp-content .sp-slider &gt; li:first-child,</code></div>
<div><code>input.sp-selector</code><code>-2:</code><code>checked ~ .sp-content .sp-slider &gt; li:nth-child(</code><code>2</code><code>),</code></div>
<div><code>input.sp-selector</code><code>-3:</code><code>checked ~ .sp-content .sp-slider &gt; li:nth-child(</code><code>3</code><code>),</code></div>
<div><code>input.sp-selector</code><code>-4:</code><code>checked ~ .sp-content .sp-slider &gt; li:nth-child(</code><code>4</code><code>),</code></div>
<div><code>input.sp-selector</code><code>-5:</code><code>checked ~ .sp-content .sp-slider &gt; li:nth-child(</code><code>5</code><code>){</code></div>
<div><code>    </code><code>opacity: </code><code>1</code><code>;</code></div>
<div><code>}</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<p>That’s all, hope you like it!</p>
<p><a href="http://tympanus.net/Tutorials/CSS3FluidParallaxSlideshow/" target="_blank">View demo</a> <a href="http://tympanus.net/Tutorials/CSS3FluidParallaxSlideshow/CSS3FluidParallaxSlideshow.zip" target="_blank">Download source</a></p>
<p>Via: <a href="http://tympanus.net/codrops/2012/04/30/fluid-css3-slideshow-with-parallax-effect/" target="_blank">codrops</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.flash-to-html5.net/blog/fluid-css3-slideshow-with-parallax-effect/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

