<?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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0"><channel><title>a Hint of Creative</title> <link>http://joelb.me/blog</link> <description>The personal blog of Joel Besada</description> <lastBuildDate>Fri, 04 May 2012 19:03:55 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/ahoc" /><feedburner:info uri="ahoc" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item><title>Fun with Cross-Site Scripting (XSS)</title><link>http://feedproxy.google.com/~r/ahoc/~3/iJV5h7P0tss/</link> <comments>http://joelb.me/blog/2012/fun-with-cross-site-scripting-xss/#comments</comments> <pubDate>Fri, 04 May 2012 19:03:55 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://joelb.me/blog/?p=408</guid> <description><![CDATA[<p>I recently started seeing data in my Google Analytics from two pages that aren&#8217;t mine, which is something that usually happens when someone copies your HTML source code without paying much attention. The traffic data assumes that the root URL &#8230; <a
href="http://joelb.me/blog/2012/fun-with-cross-site-scripting-xss/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/fun-with-cross-site-scripting-xss/">Fun with Cross-Site Scripting (XSS)</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p> I recently started seeing data in my Google Analytics from two pages that aren&#8217;t mine, which is something that usually happens when someone copies your HTML source code without paying much attention. The traffic data assumes that the root URL of all page hits is yours and therefore hides it, but searching for the relative path on Google quickly uncovered the perpetrator.</p><p><img
src="http://joelb.me/blog/assets/HackerPS.png" alt="Guy Fawkes mask" title="Pr0 Hacker" width="180" height="180" style="margin-top: -20px;" class="alignright size-full wp-image-411" /></p><p> To my surprise, it was the Turkish website of LG Electronics that was using my Google Analytics tracking code. On top of that, they were also hotlinking to one of my locally hosted copies of <em>prefixfree.js</em>, which I&#8217;m not even sure they&#8217;re getting any use of. One would think that a big company such as LG would have web developers that knew better.</p><p> So, seeing that they&#8217;re hotlinking to one of my script files, I decided to have some fun with <a
href="http://en.wikipedia.org/wiki/Cross-site_scripting">cross-site scripting</a>. To not get into any trouble, I figured I should stay away from trying to break the site, although there would have been lots of fun things that I could have done (like inserting and playing around with <a
href="http://fooljs.com/">fool.js</a>). But what if I could at least use the injected script to prevent the Google Analytics code from sending data to my account?</p><p><span
id="more-408"></span></p><p> With that goal in mind, let&#8217;s look at some of the code that they copied:</p><pre class="brush: xml; title: ; notranslate">
&lt;script type=&quot;text/javascript&quot; src=&quot;http://joelb.me/scrollpath/script/lib/prefixfree.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-25206568-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
&lt;/script&gt;
</pre><p>At the top you&#8217;ll see the hotlinked script and below that is the Google Analytics code.</p><p> There are two things that are important to note here, the first is that the hotlinked script is included before the Google Analytics code. Secondly, look closer at line 3:</p><pre class="brush: jscript; first-line: 3; title: ; notranslate">
var _gaq = _gaq || [];
</pre><p>This line of code sets the <code>_gaq</code> variable to an empty array, but only if the variable has not already been defined. This means that we are free to define our own version of <code>_gaq</code> in the injected script, without it being overridden. The next two lines (4 and 5) use the <code>push</code> method to set the tracking options, so we need to have that defined on our object to avoid run-time errors.</p><p> There are probably a lot of things that can be done with the <code>_gaq</code> variable to prevent the rest of the code from sending any data to Google Analytics, but I decided to set up an object that replaces the <code>UA-25206568-1</code> tracking code with <code>UA-XXXXXXXX-X</code>, by using the <code>push</code> method. By replacing the tracking code, the Google Analytics servers won&#8217;t be able to identify the account to send the data to, thus preventing the site from cluttering up my traffic data. Here&#8217;s the object with its <code>push</code> method:</p><pre class="brush: jscript; title: ; notranslate">
_gaq = {
  push: function(value) {
    if (value[0] === &quot;_setAccount&quot; &amp;&amp; value[1] === &quot;UA-25206568-1&quot;) {
      _gaq = [[&quot;_setAccount&quot;, &quot;UA-XXXXXXXX-X&quot;]];
    } else {
      _gaq = [value];
    }
  }
};
</pre></p><p> When the <code>push</code> method of <code>_gaq</code> is used and the tracking code is set to mine, the method overrides the <code>_gaq</code> object to a regular array containing the replaced tracking code. I&#8217;ve also set a fallback in case they decide to change the code to something that doesn&#8217;t concern me.</p><p> The last thing I added was a message that gets printed out to the console when you <a
href="http://www.lg.com/tr/cinema-screen/index.jsp">visit the page</a>, which you&#8217;ll be able to see until they remove the copied source code. It will be interesting to see how long it takes for them to notice this.</p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/fun-with-cross-site-scripting-xss/">Fun with Cross-Site Scripting (XSS)</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/iJV5h7P0tss" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2012/fun-with-cross-site-scripting-xss/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://joelb.me/blog/2012/fun-with-cross-site-scripting-xss/</feedburner:origLink></item> <item><title>Something I’m Working On…</title><link>http://feedproxy.google.com/~r/ahoc/~3/GlDYpnOUC8Q/</link> <comments>http://joelb.me/blog/2012/something-im-working-on/#comments</comments> <pubDate>Sat, 07 Apr 2012 20:26:44 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://joelb.me/blog/?p=401</guid> <description><![CDATA[<p></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/something-im-working-on/">Something I&#8217;m Working On&#8230;</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p><a
href="http://progrss.me"><img
src="http://joelb.me/blog/assets/launchpage_b.png" alt="ProgRSS launch page" title="ProgRSS - Track and Share your Weekly Progress" width="590" height="350" class="aligncenter size-full wp-image-402 featured" /></a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/something-im-working-on/">Something I&#8217;m Working On&#8230;</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/GlDYpnOUC8Q" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2012/something-im-working-on/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://joelb.me/blog/2012/something-im-working-on/</feedburner:origLink></item> <item><title>Maintaining CSS Style States using “Infinite” Transition Delays</title><link>http://feedproxy.google.com/~r/ahoc/~3/JgSsKHN7hqg/</link> <comments>http://joelb.me/blog/2012/maintaining-css-style-states-using-infinite-transition-delays/#comments</comments> <pubDate>Mon, 19 Mar 2012 01:48:46 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://joelb.me/blog/?p=345</guid> <description><![CDATA[<p>Earlier today I discovered an interesting way to keep (store) a CSS style on an element using CSS transitions. This is probably best explained with an example, so here goes: RedGreenBlueThis text will only have the color while the button &#8230; <a
href="http://joelb.me/blog/2012/maintaining-css-style-states-using-infinite-transition-delays/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/maintaining-css-style-states-using-infinite-transition-delays/">Maintaining CSS Style States using &#8220;Infinite&#8221; Transition Delays</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p> Earlier today I discovered an interesting way to keep (store) a CSS style on an element using CSS transitions. This is probably best explained
with an example, so here goes:</p><style>
.inline-demo {
   background: rgba(117, 109, 77, 0.1);
   text-align: left;
   padding: 10px 20px;
   border-radius: 5px;
   margin-bottom: 20px;
}
.red, .green, .blue {
     margin: 10px;
}
.red:active ~ p.perm,.green:active ~ p.perm,.blue:active ~ p.perm {
	-webkit-transition: color 0;
	-moz-transition: color 0s;
	-o-transition: color 0;
	-ms-transition: color 0;
	transition: color 0;
}

.red:active ~ p {
	color: red;
}

.green:active ~ p {
	color: green;
}

.blue:active ~ p {
	color: blue;
}

p.perm {
	-webkit-transition: color 0 9999999s;
	-moz-transition: color 0s 9999999s;
	-o-transition: color 0 9999999s;
	-ms-transition: color 0 9999999s;
	transition: color 0 9999999s;
}
</style><img
src="http://joelb.me/blog/assets/HourglassPS.png" alt="an hourglass" title="Hourglass" width="200" height="200" class="alignright size-full wp-image-374" style="margin-top: 7px;" /><div
class="inline-demo"> <button
class="red button">Red</button><button
class="green button">Green</button><button
class="blue button">Blue</button><p>This text will only have the color while the button is pressed down.</p><p
class="perm"> This text will keep the given color even after the button is released.<p></div><p> As far as CSS only solutions go, there are two other tricks that can be used to achieve this similar behavior: using either the <a
href="http://css-tricks.com/functional-css-tabs-revisited/">:checked</a> or the <a
href="http://css-tricks.com/css3-tabs/">:target</a> pseudo selectors. In this post, I&#8217;ll show you my CSS transition technique used above, followed by a
slightly cooler example that I&#8217;ve been working on.</p> <span
id="more-345"></span><h2>The HTML</h2><pre class="brush: xml; title: ; notranslate">
&lt;button class=&quot;red&quot;&gt;Red&lt;/button&gt;
&lt;button class=&quot;green&quot;&gt;Green&lt;/button&gt;
&lt;button class=&quot;blue&quot;&gt;Blue&lt;/button&gt;

&lt;p&gt;
This text will only have the color while the button is pressed down.
&lt;/p&gt;
&lt;p class=&quot;perm&quot;&gt;
This text will keep the given color even after the button is released.
&lt;p&gt;
</pre><h2>The CSS</h2><p>The prefixes below have been omitted for brevity.<p><pre class="brush: css; title: ; notranslate">
/* The large delay prevents the color from changing */
p.perm {
	transition: color 0s 9999999s;
}

/* When a button is pressed, overwrite the transition property
   to remove the delay, so that we can instantly change the color */
.red:active ~ p.perm, .green:active ~ p.perm, .blue:active ~ p.perm {
	transition: color 0s; 
}
.red:active ~ p {
	color: red;
}
.green:active ~ p { 
	color: green; 
}
.blue:active ~ p {
	color: blue;
}
</pre><h2>The JavaScript</h2><pre class="brush: jscript; title: ; notranslate">
// Absolutely none
</pre><h2>How It Works</h2><p> It&#8217;s actually pretty simple. With our first CSS declaration, we&#8217;ve made it so that any changes to the color property will be delayed by approximately 116 days ( :D ). This virtually infinite delay makes sure that the color stays the same once we&#8217;ve set it.</p><p> The trick now is to somehow temporary get around this delay, so we can apply the different colors with the buttons. This is done by overriding the transition property during the button press, setting the delay to 0. Now when we release the button, the old transition property will kick back in, setting the delay to 116 days. This will make sure that the text will keep the new color instead of going back to the default.</p><p> As far as I know, this only works with <a
href="https://developer.mozilla.org/en/CSS/CSS_transitions#List_of_animatable_CSS_properties">animatable properties</a>, but a cool fact is that you can end a transition halfway through and have the property still keep the exact value that it had at that point in the transition. So for example, let&#8217;s say we have a linear transition from opacity 1 to 0 over two seconds, but only let it run for one second. The opacity value should now be stuck at 0.5 because the delay prevents it from going back. If we now were to run the opacity transition again, it would <em>continue</em> from 0.5 instead of starting over from the beginning.</p><p> Now, before you run off and start using this technique all over the web, keep in mind that this is a very dirty hack for achieving something with CSS that ideally should be done with JavaScript.</p><h2>Taking it a step further</h2><p> As I mentioned, I&#8217;ve been working on something cool to show this off, so make sure to check out the demo below.</p> <a
href="http://dabblet.com/gist/2076449" class="button">Demo</a><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/maintaining-css-style-states-using-infinite-transition-delays/">Maintaining CSS Style States using &#8220;Infinite&#8221; Transition Delays</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/JgSsKHN7hqg" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2012/maintaining-css-style-states-using-infinite-transition-delays/feed/</wfw:commentRss> <slash:comments>49</slash:comments> <feedburner:origLink>http://joelb.me/blog/2012/maintaining-css-style-states-using-infinite-transition-delays/</feedburner:origLink></item> <item><title>jQuery Scroll Path</title><link>http://feedproxy.google.com/~r/ahoc/~3/9kc2L1Zx5ao/</link> <comments>http://joelb.me/blog/2012/jquery-scroll-path/#comments</comments> <pubDate>Thu, 09 Feb 2012 16:23:29 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://joelb.me/blog/?p=297</guid> <description><![CDATA[<p>I released a jQuery plugin a couple of days ago and I haven&#8217;t had time to write about it here until now. The plugin is based on a slightly crazy idea, but it has been getting some good response on &#8230; <a
href="http://joelb.me/blog/2012/jquery-scroll-path/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/jquery-scroll-path/">jQuery Scroll Path</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p><img
src="http://joelb.me/blog/assets/ComputerMousePS.png" alt="A computer mouse" title="Old school computer mouse" width="200" height="200" class="alignright size-full wp-image-316" style="margin-top: 1em;" /></p><p> I released a jQuery plugin a couple of days ago and I haven&#8217;t had time to write about it here until now. The plugin is based on a slightly crazy idea, but it has been getting some good response on Forrst and Twitter (my follower count has <del
datetime="2012-02-10T01:37:29+00:00">tripled</del> quadrupled since the release).</p><p> Most people seem to think that it&#8217;s a pretty cool plugin, but struggle in coming up with good practical uses of it. It might not be of much use on any &#8220;serious&#8221; website, but I think it can create quite a nice effect on personal portfolios and presentation pages, if used creatively.</p><p><span
id="more-297"></span></p><p> So what does the plugin do exactly? Well, it lets you define a custom path for the window to follow when scrolling up and down, and you can also throw rotations into the mix. You draw the path with methods that work exactly the same way as the canvas methods for drawing lines and arcs.</p><p> To make it easy to see how your path is coming along, I&#8217;ve added an option to display the path on an overlaid canvas. Enable this while your building your site, and you should have no problem with shaping the path exactly the way you want it.</p><p> After creating the demo I&#8217;ve learnt that the way you present your social &#8220;follow me&#8221; and &#8220;share&#8221; links can have a big impact on the rate of people that actually click on them. This time, I decided to only include links for following me and sharing the page on Twitter, completely disregarding all other social networks. This increased the amount of social shares tremendously compared to previous demos that I&#8217;ve made. Also, instead of using the default tweet button, I made my own custom tweet link that fits in better with the design, using my <a
href="http://joelb.me/blog/2012/tutorial-creating-a-custom-tweet-button-with-counter/">previously described technique</a>. I&#8217;ll be keeping this in mind once I get around to re-designing parts of this blog.</p><p> The source code and documentation is on <a
href="https://github.com/JoelBesada/scrollpath">GitHub</a>. Let me know if you use the plugin to build something creative, I&#8217;d love to see it!</p><p><a
href="http://joelb.me/scrollpath/" class="button">Demo</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/jquery-scroll-path/">jQuery Scroll Path</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/9kc2L1Zx5ao" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2012/jquery-scroll-path/feed/</wfw:commentRss> <slash:comments>32</slash:comments> <feedburner:origLink>http://joelb.me/blog/2012/jquery-scroll-path/</feedburner:origLink></item> <item><title>Tutorial — Creating a Custom Tweet Button with a Counter</title><link>http://feedproxy.google.com/~r/ahoc/~3/3_5NV0d4e5s/</link> <comments>http://joelb.me/blog/2012/tutorial-creating-a-custom-tweet-button-with-counter/#comments</comments> <pubDate>Thu, 19 Jan 2012 21:51:41 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://joelb.me/blog/?p=241</guid> <description><![CDATA[<p>Tweet buttons are a great way to spread your content to the public. Twitter provides an easy way to include their button on your site, but this comes at the cost of not having a very customizable style. The button &#8230; <a
href="http://joelb.me/blog/2012/tutorial-creating-a-custom-tweet-button-with-counter/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/tutorial-creating-a-custom-tweet-button-with-counter/">Tutorial &mdash; Creating a Custom Tweet Button with a Counter</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p><img
src="http://joelb.me/blog/assets/TweetButton.png" alt="custom tweet buttons" title="Some sweet custom tweet buttons" width="560" height="300" class="alignright size-full wp-image-242 featured" /></p><p> Tweet buttons are a great way to spread your content to the public. Twitter provides an easy way to include their button on your site, but this comes at the cost of not having a very customizable style.</p><p> The button is served inside an <code>iframe</code>, which restricts CSS and Javascript access. This can make it hard to get the button to fit in with the rest of the design. What&#8217;s even worse is that while the button wrapper is set at a fixed width, the counter inside isn&#8217;t. Once the page starts getting more tweets and the counter increases, the width of the button expands, but since the parent iframe has a fixed width, it&#8217;s impossible for us to know the actual width of the button.</p><p> Something that can also be seen as an issue is the size (46.5 kB) of the <code>widget.js</code> script that Twitter injects with the default button. In most cases though, this script file should already be in the visitor&#8217;s cache.</p><p><span
id="more-241"></span></p><h2>Building the Button</h2><p> At its core, building a tweet button is as easy as creating a link to <a
href="https://dev.twitter.com/docs/intents#tweet-intent">Twitter&#8217;s tweet intent</a>, with some added URL parameters to set the tweet text. But you probably also want to display the tweet count of the page, to brag about how popular and awesome your site is. This requires us to use Twitter&#8217;s count API.</p><p><img
src="http://joelb.me/blog/assets/TwitterBirdPS.png" alt="The twitter bird" title="Tweety Bird" width="175" height="175" class="alignright size-full wp-image-258" style="margin-top:-20px" /></p><p> The count API is currently a &#8220;private&#8221; API, which in other words mean that it&#8217;s not linked to in any of Twitter&#8217;s developer documentation. This doesn&#8217;t mean we can&#8217;t access it though, and by looking through the <code>widget.js</code> script, the <a
href="http://cdn.api.twitter.com/1/urls/count.json?url=http://www.example.com">URL</a> is easily found.</p><p> The reason Twitter labels the API as private is because they&#8217;re concerned about scaling, but if we were to use the default button, we would still be using this same exact API. In this case, we aren&#8217;t adding any extra load to Twitter&#8217;s servers, we are actually using less of their bandwidth, since we aren&#8217;t downloading the <code>widget.js</code> file with each visit.</p><p> Alright, let&#8217;s get to the code!</p><h2>The HTML</h2><pre class="brush: xml; title: ; notranslate">
&lt;a href=&quot;#&quot; class=&quot;tweet&quot; data-via=&quot;JoelBesada&quot; data-hashtags=&quot;cool&quot;&gt;
       &lt;span class=&quot;count&quot;&gt;0&lt;/span&gt;
       &lt;span class=&quot;message&quot;&gt;Tweet&lt;/span&gt;
&lt;/a&gt;
</pre><p> In the HTML, we can set different options for the tweet with the data attributes, using the same syntax as the <a
href="https://twitter.com/about/resources/buttons#tweet">Twitter button builder</a>. The href is left empty, as we are going to parse the data attributes and create the tweet intent link with Javascript.</p><p> In my example, I want the tweet count to display first, and the text &#8220;Tweet&#8221; when the button is hovered over, so I have two <code>span</code> elements for this.</p><h2>The CSS</h2><p>The vendor prefixes below have been omitted to keep the CSS clean.</p><pre class="brush: css; title: ; notranslate">
.tweet {
    position: relative;
    display: inline-block;
    padding: 7px 10px;
    width: auto;
    min-width: 50px;

    text-align: center;
    font: 16px Helvetica, Arial, sans-serif;
    color: white;
    text-shadow: 1px 1px 0 #021D2B;
    text-decoration: none;

    background: blue;
    background-color: #209adb;
    background-image: repeating-linear-gradient(-45deg, transparent, transparent 5px, rgba(0,0,0,.1) 5px, rgba(0,0,0,.1) 10px),
                      linear-gradient(top, #5ab9ed 0%,#209adb 100%);

    border: 1px solid #04141C;
    border-bottom-width: 3px;
    box-shadow: 0 2px 3px rgba(0,0,0,0.1),
                inset 0 1px 0 rgba(255,255,255,0.4),
                inset 0 0 3px rgba(255,255,255,0.5);

}

/* Twitter icon */
.tweet:before {
    content: &quot;&quot;;
    display: block;
    position: absolute;
    left: -35px;
    top: 7px;
    width: 24px;
    height: 24px;

    /* Base64 PNG icon shortened down to prevent chaos */
    background-image:url(data:image/png;base64,iVBORw0KGgo...);

    pointer-events: none;
}

/* Extra shadow */
.tweet:after {
    content: &quot;&quot;;
    display: block;
    position: absolute;
    z-index: -1;
    left: 0;
    bottom: 20px;
    width: 100%;
    height: 20px;

    box-shadow: 0 26px 10px rgba(0,0,0,0.35);
}

.tweet .count {
    position: relative;
    z-index: 2;
    transition: opacity 0.25s ease-out;
}

.tweet .message {
    display: block;
    position: absolute;
    padding-top: inherit;
    top: 0;
    left: 0;

    width: 100%;
    height: 100%;

    opacity: 0;
    text-align: center;

    transition: opacity 0.25s ease-out;
}

.tweet:hover {
    animation: bgpos 0.3s infinite linear;
}

.tweet:hover .count {
    opacity: 0;
}

.tweet:hover .message {
    opacity: 1;
}

.tweet:active {
    border-bottom: 1px solid #04141C;
    top: 2px;

    box-shadow: inset 0 2px 3px rgba(0,0,0,0.7),
                0 1px 0 rgba(255,255,255,0.2),
                inset 0 0 3px rgba(0,0,0,0.5);

    background-image: repeating-linear-gradient(-45deg, transparent, transparent 5px, rgba(0,0,0,.1) 5px, rgba(0,0,0,.1) 10px),
                      linear-gradient(top, #106491 0%, #106491 100%);
}

.tweet:active:after {
    display: none;
}

.tweet:active:before {
    top: 5px;
}

@keyframes bgpos {
    from { background-position: 0 0; }
    to { background-position: 14px 0; }
}
</pre><p> I might have gone a little bit overboard with the CSS on this one, but I&#8217;ll explain some of the trickier parts before we get on to the Javascript.</p><p> The background is created with multiple gradients, which are comma-separated and ordered so that the topmost layer is defined first. The striped pattern is created with a repeating linear gradient, to see more of these I recommend you check out this <a
href="http://lea.verou.me/css3patterns/">awesome gallery</a> with different CSS3 patterns by <a
href="http://lea.verou.me">Lea Verou</a>. Below the stripes, we have a simple linear gradient between two shades of light blue.</p><p> To create some depth in the button, I&#8217;m using several box shadows. The shiny and sharp look is achieved by using inset bright shadows, one on the top and another one around the whole border. By increasing the size of the bottom border, we get a sense of height. This effect is also amplified by adding another thicker shadow below the button with the help of the <code>:after</code> pseudo element.</p><p> Something that can&#8217;t be seen from the picture, but is apparent in the demo, is the looping animation that displays when hovering over the button. By animating the background position, the stripes move across the button and we get a cool looking hover effect. For doing this, we use a simple <code>@keyframe</code> definition with start and end <code>background-position</code> values, calibrating the end x-value to make sure that the animation looks seamless when looped.</p><p> For the active state (button pressed down), we darken the background colors, and set some dark inset shadows. We also replace the extra bottom border width and the drop-shadow with a one pixel highlight.</p><h2>The Javascript (using jQuery)</h2><pre class="brush: jscript; title: ; notranslate">
var API_URL = &quot;http://cdn.api.twitter.com/1/urls/count.json&quot;,
    TWEET_URL = &quot;https://twitter.com/intent/tweet&quot;;

$(&quot;.tweet&quot;).each(function() {
    var elem = $(this),
    // Use current page URL as default link
    url = encodeURIComponent(elem.attr(&quot;data-url&quot;) || document.location.href),
    // Use page title as default tweet message
    text = elem.attr(&quot;data-text&quot;) || document.title,
    via = elem.attr(&quot;data-via&quot;) || &quot;&quot;,
    related = encodeURIComponent(elem.attr(&quot;data-related&quot;)) || &quot;&quot;,
    hashtags = encodeURIComponent(elem.attr(&quot;data-hashtags&quot;)) || &quot;&quot;;

    // Set href to tweet page
    elem.attr({
        href: TWEET_URL + &quot;?hashtags=&quot; + hashtags + &quot;&amp;original_referer=&quot; +
                encodeURIComponent(document.location.href) + &quot;&amp;related=&quot; + related +
                &quot;&amp;source=tweetbutton&amp;text=&quot; + text + &quot;&amp;url=&quot; + url + &quot;&amp;via=&quot; + via,
        target: &quot;_blank&quot;
    });

    // Get count and set it as the inner HTML of .count
    $.getJSON(API_URL + &quot;?callback=?&amp;url=&quot; + url, function(data) {
        elem.find(&quot;.count&quot;).html(data.count);
    });
});
</pre><p> I&#8217;ve written the code to be reusable so that anyone can easily copy and paste it into their own sites. The code looks for elements with the class <code>tweet</code> and uses its data attributes to create a tweet intent link with the correct URL parameters. If not set, the URL and text parameters default to the URL and title of the current page, respectively. You can use the the <a
href="https://twitter.com/about/resources/buttons#tweet">Twitter button builder</a> to generate the different data attributes for your button.</p><p> The count is retrieved by sending a GET request to the <a
href="http://cdn.api.twitter.com/1/urls/count.json?url=http://www.example.com">Twitter count API</a>, with a parameter set to the URL we want to get the tweet count on. AJAX requests are usually restricted by the <em>same origin policy</em>, which means we can&#8217;t make requests to services on other domains. There are two solutions to this, <a
href="http://en.wikipedia.org/wiki/Cross-Origin_Resource_Sharing">CORS (Cross-Origin Resource Sharing)</a> and <a
href="http://en.wikipedia.org/wiki/JSONP">JSONP (JSON with padding)</a>.</p><p> The API we&#8217;re accessing is not CORS enabled, but it does have support for JSONP. What this means is that when we set the callback parameter to for example <code>callMe</code>, the API will set the return value as an argument to the callback function, <a
href="http://cdn.api.twitter.com/1/urls/count.json?url=http://www.example.com&#038;callback=callMe">like this</a>.</p><p> The jQuery <code>getJSON</code> function handles this automatically when given an url with the callback parameter set to &#8220;?&#8221;. The second argument of the <code>getJSON</code> function gets called when the data is returned, and from there we can easily set the HTML of the <code>.count</code> element to the returned value.</p><h2>Demo</h2><p> That&#8217;s basically all there is to it, I hope you find some value in what I&#8217;ve covered here. I&#8217;ve created a demo on JSFiddle for everyone to check out, go ahead and click the button below!</p><p><a
href="http://jsfiddle.net/JoelBesada/6nHuT/" class="button alignright">Demo</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2012/tutorial-creating-a-custom-tweet-button-with-counter/">Tutorial &mdash; Creating a Custom Tweet Button with a Counter</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/3_5NV0d4e5s" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2012/tutorial-creating-a-custom-tweet-button-with-counter/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://joelb.me/blog/2012/tutorial-creating-a-custom-tweet-button-with-counter/</feedburner:origLink></item> <item><title>accentColor Script</title><link>http://feedproxy.google.com/~r/ahoc/~3/3S2Aot2zAKA/</link> <comments>http://joelb.me/blog/2011/accentcolor-script/#comments</comments> <pubDate>Sat, 17 Dec 2011 17:25:09 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://joelb.me/blog/?p=204</guid> <description><![CDATA[<p>Out of curiosity, I started coding on a script to get the accent colors of external websites, kind of like Chrome does it in the most visited sites thumbnails. The script can be used to automatically give your outgoing links &#8230; <a
href="http://joelb.me/blog/2011/accentcolor-script/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/accentcolor-script/">accentColor Script</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p> Out of curiosity, I started coding on a script to get the accent colors of external websites, kind of like Chrome does it in the most visited sites thumbnails. The script can be used to automatically give your outgoing links appropriate colors and make them look more interesting.</p><p><img
src="http://joelb.me/blog/assets/JigsawPS.png" alt="a jigsaw piece" title="The solution to all your problems!" width="150" height="150" class="alignleft size-full wp-image-211" /></p><p> The script works by calculating the dominant color of the site&#8217;s favicon, which usually works pretty well to determine the web page&#8217;s signature color. I&#8217;m using a canvas object to analyze the pixel data, which restricts the browser suppport to more modern browsers. It would be possible to widen the browser support by parsing the image file data directly, but considering that favicons come in many different formats, this would require too much work and code for such a small visual effect.</p><p> <a
href="http://enable-cors.org">CORS</a> is used to connect to <a
href="http://g.etfv.co">getFavicon</a>, a service by <a
href="http://www.jasoncartwright.com">Jason Cartwright</a> that retrieves the favicon of any given URL. There is also a PHP proxy file that you can use on your own server as fallback for browsers without CORS support.</p><p> I&#8217;ve created a pretty demo page for the script, check it out below.</p><p><a
href="http://joelb.me/accentcolor" class="button">Demo</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/accentcolor-script/">accentColor Script</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/3S2Aot2zAKA" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2011/accentcolor-script/feed/</wfw:commentRss> <slash:comments>0</slash:comments> <feedburner:origLink>http://joelb.me/blog/2011/accentcolor-script/</feedburner:origLink></item> <item><title>Code Snippet — Accessing Clipboard Images with Javascript</title><link>http://feedproxy.google.com/~r/ahoc/~3/4KVg4eLk5aU/</link> <comments>http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/#comments</comments> <pubDate>Sat, 03 Dec 2011 19:21:45 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://joelb.me/blog/?p=178</guid> <description><![CDATA[<p>The system clipboard is a feature that most of us heavy computer users probably couldn&#8217;t survive a day without. While it&#8217;s mostly used for copying and pasting text, images can also be stored in the clipboard, by for example using &#8230; <a
href="http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/">Code Snippet &mdash; Accessing Clipboard Images with Javascript</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p><img
src="http://joelb.me/blog/assets/ClipboardPS.png" alt="a clipboard" title="A Real World Clipboard" style="margin-top: 10px;" width="150" height="150" class="alignright size-full wp-image-181" /><br
/> The system clipboard is a feature that most of us heavy computer users probably couldn&#8217;t survive a day without. While it&#8217;s mostly used for copying and pasting text, images can also be stored in the clipboard, by for example using the print screen key. Today I want to share with you how you can access these images with a bit of Javascript code. This works in modern versions of Chrome and Firefox, but the technique differs a bit between them.<br
/> <span
id="more-178"></span><br
/> Here&#8217;s the code:</p><pre class="brush: jscript; title: ; notranslate">
// We start by checking if the browser supports the
// Clipboard object. If not, we need to create a
// contenteditable element that catches all pasted data
if (!window.Clipboard) {
	var pasteCatcher = document.createElement(&quot;div&quot;);

	// Firefox allows images to be pasted into contenteditable elements
	pasteCatcher.setAttribute(&quot;contenteditable&quot;, &quot;&quot;);

	// We can hide the element and append it to the body,
	pasteCatcher.style.display = &quot;none&quot;;
	document.body.appendChild(pasteCatcher);

	// as long as we make sure it is always in focus
	pasteCatcher.focus();
	document.addEventListener(&quot;click&quot;, function() { pasteCatcher.focus(); });
}
// Add the paste event listener
window.addEventListener(&quot;paste&quot;, pasteHandler);

/* Handle paste events */
function pasteHandler(e) {
	// We need to check if event.clipboardData is supported (Chrome)
	if (e.clipboardData) {
		// Get the items from the clipboard
		var items = e.clipboardData.items;
		if (items) {
			// Loop through all items, looking for any kind of image
			for (var i = 0; i &lt; items.length; i++) {
				if (items[i].type.indexOf(&quot;image&quot;) !== -1) {
					// We need to represent the image as a file,
					var blob = items[i].getAsFile();
					// and use a URL or webkitURL (whichever is available to the browser)
					// to create a temporary URL to the object
					var URLObj = window.URL || window.webkitURL;
					var source = URLObj.createObjectURL(blob);

					// The URL can then be used as the source of an image
					createImage(source);
				}
			}
		}
	// If we can't handle clipboard data directly (Firefox),
	// we need to read what was pasted from the contenteditable element
	} else {
		// This is a cheap trick to make sure we read the data
		// AFTER it has been inserted.
		setTimeout(checkInput, 1);
	}
}

/* Parse the input in the paste catcher element */
function checkInput() {
	// Store the pasted content in a variable
	var child = pasteCatcher.childNodes[0];

	// Clear the inner html to make sure we're always
	// getting the latest inserted content
	pasteCatcher.innerHTML = &quot;&quot;;

	if (child) {
		// If the user pastes an image, the src attribute
		// will represent the image as a base64 encoded string.
		if (child.tagName === &quot;IMG&quot;) {
			createImage(child.src);
		}
	}
}

/* Creates a new image from a given source */
function createImage(source) {
	var pastedImage = new Image();
	pastedImage.onload = function() {
		// You now have the image!
	}
	pastedImage.src = source;
}
</pre><p>With Chrome we can access the image in the clipboard through the clipboardData object, but this can only be done inside a paste event handler. Inside the event handler, we loop through all items and search for an image. If we find one, we create a <a
href="https://developer.mozilla.org/en/DOM/Blob">Blob</a> of the image, and use the URL of it as the image source.</p><p>Firefox on the other hand does not have the clipboardData object, but we can work around this. In Firefox, it&#8217;s possible to paste images into elements with the <em>contenteditable</em> attribute set. By creating an invisible contenteditable element which always is focused, we can catch everything that the user pastes. So, everytime the user pastes something, we read through the content in the catcher element and check if it was an image. If it is, we simply take the source of that image and clear the element.</p><p>That nasty bit of code you see on line 48, <code>setTimeout(checkInput, 1);</code>, is a way to work around the fact that contenteditable elements don&#8217;t trigger oninput events in Firefox. Since the paste event triggers <em>before</em> anything is inserted into the element, we set a 1 ms timeout before we read the element&#8217;s content. This is enough time for the pasted content to be inserted.</p><p>Once we have the image, we can do anything we want with it, e.g append it to the page, draw it onto a canvas, upload it to a server, etc.</p><h2>Shameless Self Promotion</h2><p>I have not created a demo specifically for this, but I&#8217;m using this technique on one of my sites: <a
href="http://www.pasteshack.net">PasteShack</a>. PasteShack is an image uploading site that makes screenshot sharing <strong>super duper</strong> easy, by using the technique above.</p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/">Code Snippet &mdash; Accessing Clipboard Images with Javascript</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/4KVg4eLk5aU" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/feed/</wfw:commentRss> <slash:comments>4</slash:comments> <feedburner:origLink>http://joelb.me/blog/2011/code-snippet-accessing-clipboard-images-with-javascript/</feedburner:origLink></item> <item><title>CSS Mask Tutorial — Rotating Image Gallery</title><link>http://feedproxy.google.com/~r/ahoc/~3/5Y0ZIygtBBo/</link> <comments>http://joelb.me/blog/2011/css-mask-tutorial-rotating-image-gallery/#comments</comments> <pubDate>Thu, 24 Nov 2011 21:12:16 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://192.168.0.196/wordpress/?p=124</guid> <description><![CDATA[<p>I&#8217;ve been trying out different things that you can do with the CSS mask property lately. With a CSS mask, you can mask or clip any element to a desired shape. The mask is either a PNG image, or an &#8230; <a
href="http://joelb.me/blog/2011/css-mask-tutorial-rotating-image-gallery/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/css-mask-tutorial-rotating-image-gallery/">CSS Mask Tutorial — Rotating Image Gallery</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p
style="text-align: center;"><img
class="aligncenter size-full wp-image-127 featured" title="Rotating Image Gallery" src="http://joelb.me/blog/assets/GalleryWheel.jpg" alt="Gallery Wheel" width="560" height="370" /></p><p>I&#8217;ve been trying out different things that you can do with the <a
href="http://www.webkit.org/blog/181/css-masks/">CSS mask property</a> lately. With a CSS mask, you can <em>mask</em> or <em>clip</em> any element to a desired shape. The mask is either a PNG image, or an SVG image.</p><p>I coupled this with the CSS transform and transition properties, and came up with a pretty cool concept for an image gallery.</p><p>I&#8217;ve put together a <a
href="http://www.joelb.me/sandbox/gallerywheel">demo</a> for Chrome and Webkit nightly builds. Firefox also supports the CSS mask property, but doesn&#8217;t seem to play well with rotated masked images, so I&#8217;ve only used <em>-webkit</em> prefixes for this demo.</p><p>I&#8217;ll run through all the different steps in making this gallery wheel below, starting with the markup.</p><p><span
id="more-124"></span></p><h2>The HTML</h2><pre class="brush: xml; title: ; notranslate">
&lt;div id=&quot;gallery&quot;&gt;
   &lt;div id=&quot;gallery-wheel&quot;&gt;
      &lt;img class=&quot;active&quot; src=&quot;pic1.png&quot; alt=&quot;&quot; /&gt;
      &lt;img src=&quot;pic2.png&quot; alt=&quot;&quot; /&gt;
      &lt;img src=&quot;pic3.png&quot; alt=&quot;&quot; /&gt;
      &lt;img src=&quot;pic4.png&quot; alt=&quot;&quot; /&gt;
      &lt;img src=&quot;pic5.png&quot; alt=&quot;&quot; /&gt;
      &lt;img src=&quot;pic6.png&quot; alt=&quot;&quot; /&gt;
   &lt;/div&gt;
&lt;/div&gt;
</pre><p>The structure is pretty straightforward. We have a wrapper element which contains the rotating outer wheel, and the centerpiece which remains still. The images are random shots from <a
href="http://www.dribbble.com">Dribbble</a>.</p><h2>The Mask</h2><p><svg
xmlns="http://www.w3.org/2000/svg" width="150" height="150" class="aligncenter">  <path
d="M150,300 L25,83 A250,250 0 0,1 275,83 z" transform="scale(0.5,0.5)"/> </svg></p><pre class="brush: xml; title: ; notranslate">
&lt;svg xmlns=&quot;http://www.w3.org/2000/svg&quot; width=&quot;300&quot; height=&quot;300&quot;&gt;
  &lt;path d=&quot;M150,300 L25,83 A250,250 0 0,1 275,83 z&quot;/&gt;
&lt;/svg&gt;
</pre><p>The SVG mask is saved in it&#8217;s own .svg file, and is the same size as the images we want to apply it to.</p><p><img
src="http://joelb.me/blog/assets/PiePS-150x150.png" alt="a happy pie" title="Happy Pie" width="150" height="150" class="alignright size-thumbnail wp-image-157" /></p><p>Since we have six images in the wheel, our mask will be a sixth of a circle. We draw this out by using the <em>path</em> svg tag. The shape of the path is defined by the <em>d</em> attribute, which takes a number of options. I&#8217;m not going to go into exactly what the parameters mean, just know that this draws a 60&deg; segment of a circle, with a radius of 250 pixels. <a
href="http://www.codestore.net/store.nsf/unid/EPSD-5DTT4L">This article</a> has a good explanation on how to draw pie shapes in SVG images.</p><h3>Why choose SVG over PNG masking?</h3><p>You might think that it would be a lot simpler to just draw your desired shape in an image editor, save it as a PNG image, and use that as the CSS mask instead. This might be true, but what if you wanted to quickly change the number of images in the wheel? If we instead wanted to have 12 images, we would have to go back into our image editor and make a new PNG. This could become a lot more cumbersome than just changing some parameters in the SVG.</p><p>And what if you would like your gallery to be completely dynamic? There might be cases when you cannot determine beforehand how many pictures the gallery will contain. Our SVG mask could just as easily be generated and put in the DOM by Javascript code that takes into account how many images the gallery contains.</p><p>That said, the only browser that at the moment supports embedded/inline SVG images as CSS masks is Firefox which, as I stated earlier, doesn&#8217;t seem to rotate masked images correctly.</p><h2>The CSS</h2><pre class="brush: css; highlight: [19,20,30,31,32,33,34]; title: ; notranslate">
#gallery {
	margin: 0 auto;
	position: relative;
	background: white;
	width: 520px;
	height: 520px;
	border-radius: 50%;
	border: 5px solid white;
}

#gallery-wheel {
	position: relative;
	width: 100%;
	height: 100%;
}

#gallery-wheel img {
	position: absolute;
	-webkit-mask-box-image: url(&quot;../mask.svg&quot;) round;
	-webkit-transform-origin: 50% 100%;
	padding: 5px;
	top: 0;
	margin-top: -50px;
	left: 50%;
	margin-left: -155px;
	cursor: pointer;
}
#gallery-wheel img:hover { opacity: 0.5; }

#gallery-wheel img:nth-child(2) { -webkit-transform: rotate(60deg); }
#gallery-wheel img:nth-child(3) { -webkit-transform: rotate(120deg); }
#gallery-wheel img:nth-child(4) { -webkit-transform: rotate(180deg); }
#gallery-wheel img:nth-child(5) { -webkit-transform: rotate(240deg); }
#gallery-wheel img:nth-child(6) { -webkit-transform: rotate(300deg); }

#gallery-center {
	position: absolute;
	background-image: url(&quot;../pic1.png&quot;);
	background-position: center;
	top: 50%;
	left: 50%;
	margin-left: -160px;
	margin-top: -160px;
	width: 300px;
	height: 300px;
	border-radius: 50%;
	border: 10px solid white;
}

.fade-overlay {
	position: absolute;
	background-position: center;
	opacity: 0.0;
	width: 100%;
	height: 100%;
	border-radius: 50%;
}
</pre><p>Most of this is all pretty basic styling, so let&#8217;s just look at the CSS <em>mask</em> and <em>transform</em> parts, which I&#8217;ve highlighted above.</p><p>The <code>-webkit-mask-box-image: url(../mask.svg) round</code> rule on line 19 sets our CSS mask to the SVG that we created, stretching it to cover the whole image.</p><p>The next line, <code>-webkit-transform-origin: 50% 100%</code>, puts the pivot point of the rotation to the bottom center of the CSS mask. This will be the exact center of the gallery wheel.</p><p>Lines 30 to 34 rotate the 5 other images around the wheel. For every image, we add 60 degrees to the rotation. This fills the entire circle with our pie-slices.</p><p>The <em>fade-overlay</em> class is used by the Javascript code, which I&#8217;ll explain next.</p><h2>The Javascript — Making it Rotate</h2><pre class="brush: jscript; title: ; notranslate">
$(document).ready(init);

var galleryWheel;
var galleryCenter;
var galleryItems;
var animating;

function init() {
	galleryWheel = $(&quot;#gallery-wheel&quot;);
	galleryCenter = $(&quot;#gallery-center&quot;);
	galleryItems = $(&quot;#gallery img&quot;);

	galleryItems.click(clickImage);
}

function clickImage(e) {
	var target = $(e.target);
	if (!target.hasClass(&quot;active&quot;) &amp;&amp; !animating) {
		animating = true;
		var activeElement = galleryWheel.find(&quot;.active&quot;);

		// Calculate the number of elements between the active (top) image and the clicked
      // one, and multiply that by the inner angle that each slice has.
		var rotateBy = -360/galleryItems.length * (target.index() - activeElement.index());

		// Make sure the shortest path is taken, the maximum length the wheel should spin
      // is 180 degrees.
		if (rotateBy &gt;= 180) {
			rotateBy -= 360;
		} else if(rotateBy &lt; -180) {
			rotateBy += 360;
		}

		// Create a temporary overlay element that fades in over the center image.
		// When the opacity is full, change the image of the center element behind,
		// and remove the overlay.
		$('&lt;div class=&quot;fade-overlay&quot;&gt;')
          .css(&quot;backgroundImage&quot;, &quot;url(&quot; + target.attr(&quot;src&quot;) + &quot;)&quot;)
              .appendTo(galleryCenter).animate({opacity: 1.0}, 500, function() {
                   galleryCenter.css(&quot;backgroundImage&quot;, &quot;url(&quot; + target.attr(&quot;src&quot;) + &quot;)&quot;);
                   $(this).remove();
               });

      activeElement.removeClass(&quot;active&quot;);
      target.addClass(&quot;active&quot;);

      galleryWheel.animate({rotate: &quot;+=&quot; + rotateBy + 'deg'}, 500, function() { animating = false; } );
   }
}
</pre><p>To get the gallery to rotate on user input, we use jQuery coupled with the <a
href="https://github.com/heygrady/transform/wiki/">jQuery 2D Transformation Plugin</a> by Grady Kuhnline.</p><p><img
src="http://joelb.me/blog/assets/HamsterPS.png" alt="hamster in wheel" title="Hard Working Hamster" width="200" height="200" class="alignleft size-full wp-image-149" style="margin-top: 20px;"/><br
/> When the user clicks on an image in the wheel, we calculate the distance in degrees to that image from the current active image. We can make sure that the wheel always rotates the shortest path to the new position, by limiting the rotation values between -180 and 180 degrees.</p><p>While rotating the wheel to the new position, the new image fades in. Since we can&#8217;t fade between background images on a single element, we need to overlay a temporary element over the center. This temporary element contains the image we want to display next, and fades in above the center. When the temporary image is at full opacity, we switch the image of the underlying center element and remove the overlay element. This creates the illusion of a seamless transition between background images.</p><h2>Conclusion</h2><p>A small annoyance with the final product is that the bounding box of the center image blocks the hover events of the images below. <del
datetime="2011-11-27T16:01:18+00:00">I&#8217;m almost certain I&#8217;ve seen some CSS property that enables you to hover behind elements, but I just can&#8217;t seem to find it now.</del></p><p><strong>UPDATE:</strong> The property I was looking for is <code>pointer-events: none;</code>.<br
/> Although using that makes hovering over the center more confusing, since the hover areas of the images overlap eachother in weird ways.</p><p>This gallery is rather gimmicky, so I doubt there&#8217;s any real use for this. My intention has mainly been to show off some cool things you can do with modern CSS properties. I guess you could make some kind of fancy menu using this technique, but with the current lack of browser support, it probably shouldn&#8217;t be used on any real world website. Anyhow, I hope someone will be able to learn something new from what I&#8217;ve shown today.</p><p>Below is a link to the final demo for the gallery wheel. Note that this only works in Chrome and Webkit nightly builds. I might add Firefox support once they fix the rotated masks issue.</p><p><a
class="button alignright" href="http://www.joelb.me/sandbox/gallerywheel">Demo</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/css-mask-tutorial-rotating-image-gallery/">CSS Mask Tutorial — Rotating Image Gallery</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/5Y0ZIygtBBo" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2011/css-mask-tutorial-rotating-image-gallery/feed/</wfw:commentRss> <slash:comments>8</slash:comments> <feedburner:origLink>http://joelb.me/blog/2011/css-mask-tutorial-rotating-image-gallery/</feedburner:origLink></item> <item><title>A Brief Introduction</title><link>http://feedproxy.google.com/~r/ahoc/~3/eEGfGOkNlbI/</link> <comments>http://joelb.me/blog/2011/a-brief-introduction/#comments</comments> <pubDate>Wed, 23 Nov 2011 15:54:13 +0000</pubDate> <dc:creator>Joel Besada</dc:creator> <category><![CDATA[General]]></category><guid isPermaLink="false">http://192.168.0.196/wordpress/?p=80</guid> <description><![CDATA[<p>I&#8217;m going to let my first post serve as an introduction to future readers for what this blog most likely is going to be about. But first, let me briefly introduce myself. My name is Joel Besada, I&#8217;m a computer science &#8230; <a
href="http://joelb.me/blog/2011/a-brief-introduction/">Continued</a></p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/a-brief-introduction/">A Brief Introduction</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p>]]></description> <content:encoded><![CDATA[<p>I&#8217;m going to let my first post serve as an introduction to future readers for what this blog most likely is going to be about. But first, let me briefly introduce myself.</p><p> My name is Joel Besada, I&#8217;m a computer science student at the Royal Institute of Technology in Stockholm, Sweden. Roughly one year ago, I took my first steps into web development/design. Since then, I&#8217;ve undertaken several personal projects creating websites, plugins and themes. My most notable project thus far is <a
href="http://www.joelb.me/jsmanipulate">JSManipulate</a> — an open-source Javascript image manipulation library.</p><p> I&#8217;m starting this blog because I want to write about what I&#8217;m working on, share my thoughts about the web, and show some useful web development tricks. Hopefully, I&#8217;ll some day have an audience here that finds what I write helpful and/or interesting. Until then, this blog will serve as an archive for myself in which I solidify all the things that go through my head while I&#8217;m programming and designing.</p><p> As an added bonus, I figured it would be a fun idea to dust off my old Wacom tablet and do some drawings for each blog post. Beware though, I&#8217;m not doing this because I&#8217;m particularly good at drawing, I&#8217;m doing this because I&#8217;m <strong>not</strong>. As the say, practice makes perfect, so here&#8217;s a drawing of a whale!<br
/> <img
class="aligncenter" title="Introduction Whale says Hello!" src="http://joelb.me/blog/assets/WhalePS.png" alt="Introduction Whale" width="200" height="200" /><br
/> That&#8217;s enough of an introduction! Now I&#8217;ll start writing on some <em>actual</em> content to kick off this blog with.</p><p><br/> Post Source: <a
href="http://joelb.me/blog/2011/a-brief-introduction/">A Brief Introduction</a> <br/> Site: <a
href="http://joelb.me/blog">a Hint of Creative</a></p><img src="http://feeds.feedburner.com/~r/ahoc/~4/eEGfGOkNlbI" height="1" width="1"/>]]></content:encoded> <wfw:commentRss>http://joelb.me/blog/2011/a-brief-introduction/feed/</wfw:commentRss> <slash:comments>1</slash:comments> <feedburner:origLink>http://joelb.me/blog/2011/a-brief-introduction/</feedburner:origLink></item> </channel> </rss><!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced

Served from: joelb.me @ 2012-05-04 19:04:10 -->

