<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>xion.log &#187; Internet</title>
	<atom:link href="http://xion.org.pl/category/it/internet/feed/" rel="self" type="application/rss+xml" />
	<link>http://xion.org.pl</link>
	<description>Programming on (many) different levels of abstraction</description>
	<lastBuildDate>Tue, 14 Feb 2012 20:32:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>The &#8220;Wat&#8221; of Python</title>
		<link>http://xion.org.pl/2012/01/31/the-wat-of-python/</link>
		<comments>http://xion.org.pl/2012/01/31/the-wat-of-python/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 20:19:43 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[caveats]]></category>
		<category><![CDATA[memes]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[talks]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=3347</guid>
		<description><![CDATA[It is quite likely you are familiar with the Wat talk by Gary Bernhardt. It is sweeping through the Internet, giving some good laugh to pretty much anyone who watches it. Surely it did to me! The speaker is making fun of Ruby and JavaScript languages (although mostly the latter, really), showing totally unexpected and [...]]]></description>
			<content:encoded><![CDATA[<p>It is quite likely you are familiar with the <a href="https://www.destroyallsoftware.com/talks/wat"><em>Wat</em> talk</a> by Gary Bernhardt. It is sweeping through the Internet, giving some good laugh to pretty much anyone who watches it. Surely it did to me!<br />
The speaker is making fun of Ruby and JavaScript languages (although mostly the latter, really), showing totally unexpected and baffling results of some seemingly trivial operations - like adding two arrays. It turns out that in JavaScript, the result is an empty string. (And <a href="http://stackoverflow.com/a/9033306/434799">the reasons for that</a> provoke even bigger "wat").</p>
<p><img style="float:right; margin-left:8px" src="http://xion.org.pl/wp-content/uploads/2012/01/wat-gigantic-duck.jpg" alt="" title="Wat the duck!" />After watching the talk for about five times (it hardly gets old), I started to wonder whether it is only those two languages that exhibit similarly confusing behavior... The answer is of course "No", and that should be glaringly obvious to anyone who knows at least a bit of C++ ;) But beating on <em>that</em> horse would be way too easy, so I'd rather try something more ambitious.<br />
Hence I ventured forth to search for "wat" in Python 2.x. The journey wasn't short enough to stop at mere addition operator but nevertheless - and despite me being nowhere near Python expert - I managed to find some candidates rather quickly.</p>
<p>I strove to keep with the original spirit of Gary's talk, so I only included those quirks that can be easily shown in interactive interpreter. The final result consists of three of them, arranged in the order of increasing puzzlement. They are given without explanation or rationale, hopefully to encourage some thought beyond amusement :)</p>
<p>Behold, then, the <em>Wat</em> of Python!</p>
<p><span id="more-3347"></span></p>
<h3>3. Strange loop</h3>
<div class="syntax_hilite">
<div id="code-4">
<div class="code">&gt;&gt;&gt; f = lambda: map<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>yield<span style="color:#006600; font-weight:bold;">&#41;</span>, range<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&gt;&gt;&gt; for x in f<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>: print x<br />
...<br />
<span style="">None</span></div>
</div>
</div>
<p>
<code>None</code> shall <code>pass</code>!</p>
<h3>2. Can't catch me</h3>
<div class="syntax_hilite">
<div id="code-5">
<div class="code">&gt;&gt;&gt; try: raise KeyError<br />
... <span style="">except</span> ValueError, KeyError:<br />
...&nbsp; &nbsp; &nbsp;<span style="">print</span> <span style="color:#CC0000;">"Batman!"</span><br />
...<br />
<span style="">Traceback</span> <span style="color:#006600; font-weight:bold;">&#40;</span>most recent call last<span style="color:#006600; font-weight:bold;">&#41;</span>:<br />
&nbsp; File <span style="color:#CC0000;">"&lt;stdin&gt;"</span>, line <span style="color:#800000;">1</span>, in &lt;module&gt;<br />
KeyError</div>
</div>
</div>
<p>
It takes much more to summon Batman, you know.</p>
<h3>1. The truth is out there</h3>
<div class="syntax_hilite">
<div id="code-6">
<div class="code">&gt;&gt;&gt; True, False = False, True<br />
&gt;&gt;&gt; True<br />
False</div>
</div>
</div>
<p>
You had probably seen it coming.... Yeah, you certainly had.</p>
<p><small>If you know any similar quirks of Python, be sure to present them in comments!</small></p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2012/01/31/the-wat-of-python/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Self-Replacing Script Blocks for Dynamic Lists</title>
		<link>http://xion.org.pl/2012/01/17/self-replacing-script-blocks-for-dynamic-lists/</link>
		<comments>http://xion.org.pl/2012/01/17/self-replacing-script-blocks-for-dynamic-lists/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 07:52:19 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Jinja]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[templates]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=3316</guid>
		<description><![CDATA[On contemporary websites and web applications, it is extremely common task to display a list of items on page. In any reasonable framework and/or templating engine, this can be accomplished rather trivially. Here's how it could look like in Jinja or Django templates: &#60;ul&#62; &#123;% for item in items %&#125; &#160; &#160; &#60;li&#62;&#123;&#123; item &#125;&#125;&#60;/li&#62; [...]]]></description>
			<content:encoded><![CDATA[<p>On contemporary websites and web applications, it is extremely common task to display a list of items on page. In any reasonable framework and/or templating engine, this can be accomplished rather trivially. Here's how it could look like in Jinja or Django templates:</p>
<div class="syntax_hilite">
<div id="code-12">
<div class="code">&lt;ul&gt;<br />
<span style="color:#006600; font-weight:bold;">&#123;</span>% for item in items %<span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; &lt;li&gt;<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#123;</span> item <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span>&lt;/li&gt;<br />
<span style="color:#006600; font-weight:bold;">&#123;</span>% endfor %<span style="color:#006600; font-weight:bold;">&#125;</span><br />
&lt;/ul&gt;</div>
</div>
</div>
<p>
But it's usually not too long before our list grows big and it becomes unfeasible to render it all on the server. Or maybe, albeit less likely, we want it to be updated in real-time, without having to reload the whole page. Either case requires to incorporate some JavaScript code, talking to the server and obtaining next portion of data whenever it's needed.</p>
<p>Obviously, that data has to be rendered as well, and there is one option of doing it on the server side, serving actual HTML directly to JS. An arguably better solution is to respond with JSON or similar representation of our items. This is conceptually simpler, feels less messy and is potentially reusable as a part of website's external API. There is just one drawback: it forces rendering to be done also in JavaScript.<br />
<span id="more-3316"></span><br />
While it isn't a hindrance by itself (there are many great tools to help, including <a href="https://github.com/janl/mustache.js">Mustache</a> or - sadly discontinued - <a href="http://api.jquery.com/category/plugins/templates/">jQuery Templates</a>), it raises an issue of code duplication. Ideally, we would still want some initial data to be displayed just when the page itself is loaded. And at first, this seems as to require <em>both</em> server-side <em>and</em> client-side rendering functions... I hope I do not really have to explain why it would be a mighty bad idea to create, use and (try to) maintain them.</p>
<h3>Client is king</h3>
<p>That's why we would opt for rendering exclusively in the browser. Fortunately, it is not only possible, but also quite easy if we already have the logic for handling AJAX calls. Using it, we can prepare initial items in JSON format and put them directly inside some <code>&lt;script></code> block:</p>
<div class="syntax_hilite">
<div id="javascript-13">
<div class="javascript">&lt;script type=<span style="color: #3366CC;">"text/javascript"</span>&gt;<br />
&nbsp; &nbsp; $<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> items = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#123;</span> items|json <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; renderItems<span style="color: #66cc66;">&#40;</span>$<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'#items'</span><span style="color: #66cc66;">&#41;</span>, items<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<br />
&lt;/script&gt;</div>
</div>
</div>
<p>
Here, the <code>|json</code> filter represents the before mentioned logic, while <code>renderItems</code> draws the objects-turned items as children of given element. What it does inside can vary from manipulating HTML strings directly (eww!), creating DOM objects (slightly better) or invoking some JS templating engine (best).</p>
<h3>Striving for modularity</h3>
<p>A simple solution, outlined above, looks sufficient for many practical applications. It is far from ideal, though. For one, it suffers from an acute disconnection, since the actual place where the data is displayed (<code>$('#items')</code>) can be arbitrarily far from the <code>&lt;script></code> tag. But more importantly, it scales poorly and lacks modularity: should we need to use our list on more than one site, we may need to carefully tailor several moving parts - such as the <code>'#items'</code> selector.</p>
<p>Incidentally, both of those issues can be resolved at once. Let's create a <em>self-replacing</em> <code>&lt;script></code>: quite similar to the one above, but with some interesting twists. Rather than referencing some DOM element via hard-coded selector, it shall render the items "where they stand": exactly where the very <code>&lt;script></code> is located. And just as a final touch, the script will even remove itself from the DOM tree when it's no longer needed.</p>
<h3>The solution...</h3>
<p>Sounds like a pretty clever trick, but it's not exactly complicated at all. In its entirety, it can look somewhat like this:</p>
<div class="syntax_hilite">
<div id="javascript-14">
<div class="javascript">&lt;script type=<span style="color: #3366CC;">"text/javascript"</span>&gt;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> $script = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">last</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> items = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#123;</span> items|json <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderItems<span style="color: #66cc66;">&#40;</span>$script.<span style="color: #006600;">parent</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, items<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $script.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&lt;/script&gt;</div>
</div>
</div>
<p>
What makes it work is the fact that <code>var $script = ...;</code> line lies <em>outside</em> of the <code>$document.ready</code> function. Thanks to that, it is executed as soon as the <code>&lt;script></code> block is parsed - before the rest of document is processed, and way before the <code>$(document).ready</code> callback is invoked.<br />
At that early time, this script is therefore the last <code>&lt;script></code> element in the DOM tree. In other words, it's exactly what <code>$('script').last()</code> will return! What we are doing in the first line is therefore nothing else, but obtaining a reference to the enclosing <code>&lt;script></code>.</p>
<p>How's that useful, though?... Well, if we have indeed dropped this <code>&lt;script></code> right where we wanted our dynamic list to display, its <code>parent()</code> would be the element to render our items in. And because we don't mind cleaning up after ourselves when done, we finish this by <code>remove()</code>-ing the script. Nice and tidy.</p>
<h3>...and how to use it</h3>
<p>What makes it a pretty powerful technique is easy and flexible integration with modern templating engines. We can almost effortlessly made this snippet into a reusable template part, such as Jinja macro:</p>
<div class="syntax_hilite">
<div id="javascript-15">
<div class="javascript"><span style="color: #66cc66;">&#123;</span>% macro render<span style="color: #66cc66;">&#40;</span>items<span style="color: #66cc66;">&#41;</span> %<span style="color: #66cc66;">&#125;</span><br />
&lt;script type=<span style="color: #3366CC;">"text/javascript"</span>&gt;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> $script = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">'script'</span><span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">last</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; $<span style="color: #66cc66;">&#40;</span>document<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">ready</span><span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> items = <span style="color: #66cc66;">&#123;</span><span style="color: #66cc66;">&#123;</span> items|json <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderItems<span style="color: #66cc66;">&#40;</span>$script.<span style="color: #006600;">parent</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>, items<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $script.<span style="color: #006600;">remove</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&lt;/script&gt;<br />
<span style="color: #66cc66;">&#123;</span>% endmacro %<span style="color: #66cc66;">&#125;</span></div>
</div>
</div>
<p>
The final usage would be then extremely clean and simple:</p>
<div class="syntax_hilite">
<div id="html-16">
<div class="html"><span style="color: #009900;"><a href="http://december.com/html/4/element/div.html"><span style="color: #000000; font-weight: bold;">&lt;div</span></a> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">"items"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><br />
&nbsp; &nbsp; {{ render(items) }}<br />
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/div&gt;</span></span></div>
</div>
</div>
<p></p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2012/01/17/self-replacing-script-blocks-for-dynamic-lists/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Text Ellipsis with Gradient Fade in Pure CSS</title>
		<link>http://xion.org.pl/2011/12/26/text-ellipsis-with-gradient-fade-in-pure-css/</link>
		<comments>http://xion.org.pl/2011/12/26/text-ellipsis-with-gradient-fade-in-pure-css/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 17:56:28 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[text formatting]]></category>
		<category><![CDATA[web browsers]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=3231</guid>
		<description><![CDATA[The other day I encountered a small but very interesting effect, visible in Bitbucket issues' table. Some of the cells were slightly too narrow for the text they contained, and it had to be ellipsized. Usually this is done by cropping some of the text's trailing chars and replacing them with dots - mostly because [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:right; margin:8px" src="http://xion.org.pl/wp-content/uploads/2011/12/bitbucket-issues-table.png" alt="" title="Bitbucket issues table" />The other day I encountered a small but very interesting effect, visible in <a href="http://bitbucket.org">Bitbucket</a> issues' table. Some of the cells were slightly too narrow for the text they contained, and it had to be ellipsized. Usually this is done by cropping some of the text's trailing chars and replacing them with dots - mostly because that's what the <code>text-ellipsis</code> style is doing. Here, however, I saw something much more original: the text was <strong>fading out</strong> in gradient-like style, going from full black to full transparent/white over a distance of about 30 pixels. It made quite of an eye-catching effect.</p>
<p>So, I decided to bring up Firebug and find out how this nifty trick actually works. Taught by past experiences, I expected a tightly coupled mis-mash of DOM and CSS hacks, with lots of moving parts that need to be carefully adjusted in face of any changes. Alas, I was wrong: it turned out to only use CSS, in succinct and elegant manner. After simple reverse-engineering, I uncovered a clever solution involving gradients, opacity and <code>:before</code>/<code>:after</code> pseudo-elements. It definitely deserves some press, so let's look into it.<br />
<span id="more-3231"></span></p>
<h3>CSS is just not there yet</h3>
<p>As far as I am aware, there is no portable way to do graphical post-processing of element's content using just CSS attributes (IE-specific <code>filter</code> styles and early CSS4 drafts notwithstanding). In other words, CSS is far below in sophistication and power when compared even to first generation of pixel shaders - an ancient technology from <em>two decades ago</em>. Any techniques that appear to use such magic anyway - like multiplicative blending of text with gradient texture - are therefore just faking it, most likely with smart tricks involving overlapping layers, images and backgrounds, carefully positioned one over another.</p>
<p>The gradient-fade text ellipsis, which I'm describing here, is no different. It uses the sole type of per-pixel transformation that is easily accessible in present-day CSS: <strong>alpha blending</strong>. Thanks to years of standarization and growing pressure on browser vendors, the power of opacity control is now at our disposal, ready to take us into the semi-transparent future...<br />
But while the simple <code>opacity</code> property is often the exact thing we need, it's not the case if we want to apply a gradient over text. Mostly because it wouldn't be really <span style="opacity:0.83">s</span><span style="opacity:0.66">m</span><span style="opacity:0.49">o</span><span style="opacity:0.32">o</span><span style="opacity:0.15">t</span><span style="opacity:0.00">h</span> (especially for larger font), and partially because of the ugly markup it would result in, with <em>every character</em> wrapped up in its own <code>&lt;span&gt;</code>... Eww! Surely there must be a better way.</p>
<h3>If it's going out, then something is covering it</h3>
<p>And indeed, there exists a much cleaner solution. It involves placing an additional layer over the text - one with an <strong>actual gradient background</strong>. In CSS3, it is possible to generate such background on the fly by using the <a href="https://developer.mozilla.org/en/CSS/linear-gradient"><code>linear-gradient</code> function</a>:</p>
<div class="syntax_hilite">
<div id="code-20">
<div class="code">background: linear-gradient<span style="color:#006600; font-weight:bold;">&#40;</span>left center, rgba<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;">255</span>, <span style="color:#800000;">255</span>, <span style="color:#800000;">255</span>, <span style="color:#800000;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>, #FFFFFF<span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p>
This will create a pattern going (left to right) from transparent to opaque white. When applied to a block element, this style turns it into a "dimmer" which can be placed over content that we want to be fading out. Provided we do this correctly, the browser's alpha blending mechanism will take care of rest.</p>
<p><small>Note that <code>linear-gradient</code> is a CSS3 feature. For maximum compatibility, you should include the vendor-specific versions of it, prefixed by <code>-moz-</code>, <code>-webkit-</code>, <code>-o-</code> and <code>-ms-</code>. This is yet another reason to use a CSS preprocessor such as <a href="http://lesscss.org">LESS</a>.</small></p>
<h3>How to <code>position</code> it properly</h3>
<p>CSS veterans probably know all crooks and crannies of the infamous <code>position</code> property and the exact rationale behind choosing specific value for it. Mere mortals (like us) just vaguely remember some tidbits, such as the need of using <code>position:absolute</code> if you want to organize your content into layers. That's just part of the puzzle, though - you also need <code>position:relative</code> on the <strong>parent</strong> element:</p>
<div class="syntax_hilite">
<div id="code-21">
<div class="code">&lt;style type=<span style="color:#CC0000;">"text/css"</span>&gt;<br />
&nbsp; &nbsp; .<span style="">gradientEllipsis</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; position: relative;<br />
&nbsp; &nbsp; &nbsp; &nbsp; white-space: nowrap;<br />
&nbsp; &nbsp; &nbsp; &nbsp; overflow-x: hidden;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; .<span style="">gradientEllipsis</span> .<span style="">dimmer</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; position: absolute;<br />
&nbsp; &nbsp; &nbsp; &nbsp; right: <span style="color:#800000;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; top: <span style="color:#800000;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; bottom: <span style="color:#800000;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; width: 50px;<br />
&nbsp; &nbsp; &nbsp; &nbsp; background: linear-gradient<span style="color:#006600; font-weight:bold;">&#40;</span>left center, rgba<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;">255</span>, <span style="color:#800000;">255</span>, <span style="color:#800000;">255</span>, <span style="color:#800000;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>, #FFFFFF<span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&lt;/style&gt;<br />
&lt;div class=<span style="color:#CC0000;">"gradientEllipsis"</span> style=<span style="color:#CC0000;">"width: 150px"</span>&gt;<br />
&nbsp; &nbsp; Foo, bar, and lorem ipsum.<br />
&nbsp; &nbsp; &lt;div class=<span style="color:#CC0000;">"dimmer"</span>/&gt;<br />
&lt;/div&gt;</div>
</div>
</div>
<p>
<img style="float:right; margin:15px" src="http://xion.org.pl/wp-content/uploads/2011/12/gradient-ellipsis.png" alt="" />Specifying 0 for both <code>top</code> and <code>bottom</code> will automatically set the correct height of our <code>.dimmer</code> element, while <code>right:0</code> will align it properly. Its width can be specified as either percentage or <code>px</code>; this adds some flexibility should we want to apply this effect to elements of varying sizes.</p>
<h3>Tidying up</h3>
<p>Our solution is not yet complete, as one inconvenience still remains. We require the <code>.dimmer</code> element to be included in HTML, nullifying our effort to only use CSS for the effect. Thankfully, it isn't quite a big of an obstacle as it may look at first glance.</p>
<p>Yet another CSS feature comes handy here: the <a href="https://developer.mozilla.org/en/CSS/:before"><code>:before</code></a>/<a href="https://developer.mozilla.org/en/CSS/:after"><code>:after</code></a> pseudo-elements. Essentially, they give us two "free", virtual children for any DOM element - a first and last one, respectively. Coupled with <code>content</code> and <code>counter-*</code> properties, they allow for some really clean and powerful constructs, such as automatic insertion of quote chars around given text or out-of-the-box numbering (without <code>&lt;ol&gt;</code>).</p>
<p>But for our gradient trick, we don't need these features. We just want to turn one of those pseudo-elements into functional equivalent of the <code>.dimmer</code> <code>&lt;div&gt;</code>, so we don't have to insert it into DOM anymore. As it turns out, this isn't at all difficult:</p>
<div class="syntax_hilite">
<div id="code-22">
<div class="code">&lt;style type=<span style="color:#CC0000;">"text/css"</span>&gt;<br />
&nbsp; &nbsp; .<span style="">gradientEllipsis</span> <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; position: relative;<br />
&nbsp; &nbsp; &nbsp; &nbsp; white-space: nowrap;<br />
&nbsp; &nbsp; &nbsp; &nbsp; overflow-x: hidden;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; &nbsp; .<span style="">gradientEllipsis</span>:after <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; display: block;<br />
&nbsp; &nbsp; &nbsp; &nbsp; position: absolute;<br />
&nbsp; &nbsp; &nbsp; &nbsp; right: <span style="color:#800000;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; top: <span style="color:#800000;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; bottom: <span style="color:#800000;">0</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; width: 50px;<br />
&nbsp; &nbsp; &nbsp; &nbsp; background: linear-gradient<span style="color:#006600; font-weight:bold;">&#40;</span>left center, rgba<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#800000;">255</span>, <span style="color:#800000;">255</span>, <span style="color:#800000;">255</span>, <span style="color:#800000;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span>, #FFFFFF<span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; content: <span style="color:#CC0000;">""</span>;<br />
&nbsp; &nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&lt;/style&gt;<br />
&lt;div class=<span style="color:#CC0000;">"gradientEllipsis"</span> style=<span style="color:#CC0000;">"width: 150px"</span>&gt;<br />
&nbsp; &nbsp; Foo, bar, and lorem ipsum.<br />
&lt;/div&gt;</div>
</div>
</div>
<p>
Here we used the <code>:after</code> element as it seemed more logical, but it is perfectly valid to style the <code>:before</code> one instead. The important bit is getting rid of the inner <code>&lt;div&gt;</code>: since we use a pseudo-element, it is not needed anymore. Our implementation is now purely CSS-based.</p>
<p>Success!</p>
<h3>:last</h3>
<p>In its current incarnation, CSS is not nearly as powerful and convenient as we (especially programmers) would like it to be. Still, it might allow for neat &#038; tidy solutions - if we know where to look for relevant features and have some creativity to assemble them together.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/12/26/text-ellipsis-with-gradient-fade-in-pure-css/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Podaj bloga</title>
		<link>http://xion.org.pl/2011/08/31/podaj-bloga/</link>
		<comments>http://xion.org.pl/2011/08/31/podaj-bloga/#comments</comments>
		<pubDate>Wed, 31 Aug 2011 18:29:47 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[blog]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2927</guid>
		<description><![CDATA[Podobno dzisiaj - czyli 31 sierpnia - obchodzimy międzynarodowy BlogDay. Piszę 'podobno', bo oficjalna strona tej inicjatywy pamięta jeszcze zeszły rok, ale chociażby ruch na Twitterze sugeruje, że nie jest to zupełnie zapomniane wydarzenie. A skoro tak, to pozwolę sobie również je zauważyć :) Jego celebracja w założeniu polega na napisaniu notki, w której polecamy [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left" src="http://xion.org.pl/wp-content/uploads/2011/08/blog-bubble.jpg" alt=""/>Podobno dzisiaj - czyli 31 sierpnia - obchodzimy międzynarodowy <a href="http://www.blogday.org/">BlogDay</a>. Piszę 'podobno', bo oficjalna strona tej inicjatywy pamięta jeszcze zeszły rok, ale chociażby <a href="http://twitter.com/search/%23blogday">ruch na Twitterze</a> sugeruje, że nie jest to zupełnie zapomniane wydarzenie. A skoro tak, to pozwolę sobie również je zauważyć :)</p>
<p>Jego celebracja w założeniu polega na napisaniu notki, w której polecamy swoim czytelnikom pięć innych blogów - na przykład takich, które regularnie czytujemy. Nic prostszego, prawda? Wystarczy przecież spojrzeć na listę w swoim czytniku RSS - i już...<br />
Cóż, niezupełnie - a przynajmniej nie w moim przypadku. Chociaż bowiem lista nie jest pusta, to nie wydaje mi się, żebym mógł się nią jakoś specjalnie chwalić. Widnieją na niej głównie klasyki, które powinny być wszystkim znane - takie jak <a href="http://www.codinghorror.com">Coding Horror</a> czy <a href="http://www.joelonsoftware.com">Joel on Software</a> - lub wyspecjalizowane blogi poświęcone wąskiemu tematowi - jak <a href="http://blog.notdot.net/">blog Nicka Johnsona o Google App Engine</a>. Nie widzę specjalnego sensu w szczegółowym opisywaniu któregokolwiek z nich. Mógłbym co najwyżej wspomnieć o rzadko aktualizowanych perełkach w stylu <a href="http://linuxhaters.blogspot.com/">Linux Hater's</a> czy <a href="http://hyperboleandahalf.blogspot.com/">Hyperbole and a Half</a>, ale wolałbym nie obdarzać was zbyt wielką liczbą narzędzi wspomagających prokrastynację ;)</p>
<p>Dlatego też postanowiłem odwrócić "tradycję" Dnia Blogowania i <strong>poprosić czytelników</strong> o polecenie innych blogów podobnych do niniejszego - lub nawet zupełnie odmiennych, o ile tylko zachowamy ustalone proporcje (4 do 1). Przy odrobinie szczęścia długość powstałej w ten sposób listy interesujących blogów powinna o wiele rzędów wielkości przekroczyć 5 :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/08/31/podaj-bloga/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Canvas, czyli programowanie grafiki w HTML</title>
		<link>http://xion.org.pl/2011/07/31/canvas-czyli-programowanie-grafiki-w-html/</link>
		<comments>http://xion.org.pl/2011/07/31/canvas-czyli-programowanie-grafiki-w-html/#comments</comments>
		<pubDate>Sat, 30 Jul 2011 22:09:00 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Canvas]]></category>
		<category><![CDATA[game development]]></category>
		<category><![CDATA[graphics programming]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2852</guid>
		<description><![CDATA[Spośród wielu nowości wprowadzonych w HTML5, API do rysowania dwuwymiarowej grafiki rastrowej bez użycia wtyczek typu Flash jest z pewnością jednym z najbardziej interesujących. Wielu zresztą twierdzi (wliczając w to prominentne figury świata IT), że zwiastuje to początek końca wspomnianych pluginów. Czy rzeczywiście tak będzie, to oczywiście zobaczymy w niedalekiej przyszłości. Już teraz jednak można [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/07/html5-canvas.jpg" alt="" />Spośród wielu nowości wprowadzonych w <a href="http://xion.org.pl/tag/html5/">HTML5</a>, API do rysowania dwuwymiarowej grafiki rastrowej bez użycia wtyczek typu Flash jest z pewnością jednym z najbardziej interesujących. Wielu zresztą twierdzi (wliczając w to <a href="http://www.apple.com/hotnews/thoughts-on-flash/">prominentne figury</a> świata IT), że zwiastuje to początek końca wspomnianych <em>pluginów</em>. Czy rzeczywiście tak będzie, to oczywiście zobaczymy w niedalekiej przyszłości. Już teraz jednak można <a href="http://chrome.angrybirds.com/">zobaczyć</a> liczne <a href="http://entanglement.gopherwoodstudios.com/">przykłady</a> na to, że technologia ta oferuje naprawdę spore możliwości.</p>
<p>W ramach zapoznawania się z poszczególnymi składowymi HTML5, nie mogłem więc nie przyjrzeć się bliżej elementowi <code>&lt;canvas></code> - bo to o nim oczywiście mowa. Tradycyjnym testem dla tego rodzaju rozwiązań (tj. graficznych bibliotek 2D), który zawsze staram się zaimplementować na początku, jest... chmara odbijających się piłeczek :) Nie inaczej było i w tym przypadku, czego efekty zamieszczam tutaj wraz z krótkim opisem i wprowadzeniem w podstawy <em>Canvasa</em>.<br />
<span id="more-2852"></span></p>
<h3>Gotowe demo</h3>
<p><canvas width="600" height="350" style="border: 1px solid black">Twoja przeglądarka nie obsługuje elementu canvas.</canvas><br />
<script type="text/javascript" src="http://xion.org.pl/wp-content/uploads/2011/07/bouncingBalls.js"></script><br />
<script type="text/javascript">
<!--
bouncingBalls();
// --></script><br />
Rezultat końcowy powinien być widoczny powyżej - a przynajmniej takie jest założenie :) Jeśli przykład uruchamia się poprawnie, to oprócz podziwiania trzech piłeczek, które są w nim już od razu, możemy dodawać nowe poprzez klikanie w obszar <em>canvasa</em>.<br />
Robiąc to wystarczająco uparcie możemy dokonać prostej oceny efektywności renderowania w naszej przeglądarce. Wystarczy obserwować, jak zmienia się licznik FPS w miarę dodawania kolejnych obiektów. Nie obiecuję jednak, że zauważymy jakiekolwiek interesujące zmiany zanim zabawa nam się znudzi ;)</p>
<h3>Jak to jest zrobione</h3>
<p>Całość przykładu od strony kodu HTML zamyka się w jednym jedynym znaczniku <code>&lt;canvas></code>:</p>
<div class="syntax_hilite">
<div id="html-30">
<div class="html"><span style="color: #009900;">&lt;canvas <span style="color: #000066;">width</span>=<span style="color: #ff0000;">"500"</span> <span style="color: #000066;">height</span>=<span style="color: #ff0000;">"350"</span><span style="color: #000000; font-weight: bold;">&gt;</span></a></span><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;</span></a>/canvas&gt;</span></div>
</div>
</div>
<p>
Pod względem zachowania wobec innych elementów strony, jest on bardzo podobny do znacznika <code>&lt;img></code>, czyli zwykłego obrazka. Różnica polega oczywiście na tym, że można w nim swobodnie rysować. Trzeba tylko pamiętać o ustawieniu wymaganych atrybutów <code>width</code> i <code>height</code> na wartości w pikselach - użycie stylów CSS niestety nie wystarczy.</p>
<p>Narysowanie czegokolwiek wymaga już kodu przez nieco większe K, czyli JavaScriptu. Dla wygody założę, że dysponujemy biblioteką <a href="http://jquery.com">jQuery</a>. Jeśli nie jest to prawdą, to właśnie jest doskonała okazja, żeby naprawić to niedopatrzenie ;P Biblioteka ta nie jest wprawdzie pomocna do samego rysowania po <em>canvasie</em>, ale znakomicie ułatwia wszystkie inne czynności, które są z tym związane.</p>
<h3>Kontekst rysowania</h3>
<p>Graficzne API elementu <code>&lt;canvas></code> jest w całości zamknięte w obiekt <strong>kontekstu</strong>. Jest to odpowiednik kontekstu urządzenia z Windows GDI, obiektu <code>Graphics</code> z GDI+ i pewnie jeszcze wielu podobnych obiektów z innych bibliotek. Wszystkie wywołania, które rysują cokolwiek albo zmieniają parametry rysowania, wykonywane są na tym właśnie obiekcie.<br />
Kontekst pobieramy z obiektu DOM <em>canvasa</em> metodą <code>getContext</code>:</p>
<div class="syntax_hilite">
<div id="javascript-31">
<div class="javascript"><span style="color: #003366; font-weight: bold;">var</span> canvas = $<span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"canvas"</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#93;</span>;<br />
<span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>canvas.<span style="color: #006600;">getContext</span><span style="color: #66cc66;">&#41;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> ctx = canvas.<span style="color: #006600;">getContext</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"2d"</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #000066; font-weight: bold;">else</span><br />
&nbsp; &nbsp; $<span style="color: #66cc66;">&#40;</span>canvas<span style="color: #66cc66;">&#41;</span>.<span style="color: #006600;">html</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"Element canvas nie jest obsługiwany"</span><span style="color: #66cc66;">&#41;</span>;</div>
</div>
</div>
<p>
...oczywiście po wcześniejszym sprawdzeniu, czy jest ona dostępna. Od razu też rozwieję nadzieje: niestety, obecnie <code>"2d"</code> jest jedyną pewną opcją :)</p>
<h3>Funkcja <code>update</code></h3>
<p>Używając kontekstu możemy od razu coś narysować, ale jeśli nie chcemy prezentować tylko statycznych obrazków, to musimy jakoś zapewnić regularne wywoływanie kodu renderującego. Nie możemy oczywiście wpaść w pętlę, więc typowym rozwiązaniem jest funkcja <code>setTimeout</code> z odpowiednio krótkim interwałem. W HTML5 istnieje jednak teoretycznie lepsze rozwiązanie w postaci <a href="http://paulirish.com/2011/requestanimationframe-for-smart-animating/">funkcji <code>requestAnimationFrame</code></a>. Ponieważ jednak z jego obsługą w różnych przeglądarkach jest różnie, trzeba sobie niestety zapewnić odpowiedni <em>fallback</em>:</p>
<div class="syntax_hilite">
<div id="javascript-32">
<div class="javascript"><span style="color: #003366; font-weight: bold;">var</span> requestAnimFrame = window.<span style="color: #006600;">requestAnimationFrame</span><br />
&nbsp; &nbsp; || window.<span style="color: #006600;">mozRequestAnimationFrame</span><br />
&nbsp; &nbsp; || window.<span style="color: #006600;">webkitRequestAnimationFrame</span><br />
&nbsp; &nbsp; || window.<span style="color: #006600;">oRequestAnimationFrame</span><br />
&nbsp; &nbsp; || window.<span style="color: #006600;">msRequestAnimationFrame</span><br />
&nbsp; &nbsp; || <span style="color: #003366; font-weight: bold;">function</span><span style="color: #66cc66;">&#40;</span>animFunc, elem<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; setTimeout<span style="color: #66cc66;">&#40;</span>animFunc, <span style="color: #CC0000;">1000</span> / <span style="color: #CC0000;">60</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span>;</p>
<p>requestAnimFrame<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> update <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #009900; font-style: italic;">// (tutaj będziemy rysować)</span><br />
&nbsp; &nbsp;requestAnimFrame<span style="color: #66cc66;">&#40;</span>update, canvas<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span>, canvas<span style="color: #66cc66;">&#41;</span>;</div>
</div>
</div>
<p>
W zamian możemy liczyć na wywołania zwrotne z częstotliwością ok. 60 na sekundę i - przynajmniej w teorii - optymalizację rysowania po elemencie DOM wskazanym jako drugi parametr.</p>
<h3>Rysujemy piłki</h3>
<p>Jak nietrudno zauważyć, piłeczki które odbijają się powyżej to po prostu wypełnione okręgi. Narysowanie takiej jakże skomplikowanej figury geometrycznej nie jest może wielkim wyzwaniem, ale wymaga zastosowania kilku koncepcji z API elementu <code>&lt;canvas></code>.<br />
I tak zaczynamy od ustawienia <strong>stylu wypełnienia</strong> na jednolity kolor fioletowy:</p>
<div class="syntax_hilite">
<div id="javascript-33">
<div class="javascript">ctx.<span style="color: #006600;">fillStyle</span> = <span style="color: #3366CC;">"purple"</span>;</div>
</div>
</div>
<p>
Styl ten może być nie tylko dowolnym kolorem (w formacie CSS, czyli np. <code>#ffffff</code> lub <code>rgba(...)</code>), ale także <a href="https://developer.mozilla.org/en/Canvas_tutorial/Applying_styles_and_colors#Gradients">gradientem</a> lub powtarzalnym <a href="https://developer.mozilla.org/en/Canvas_tutorial/Applying_styles_and_colors#Patterns">wzorem</a> złożonym z kopii obrazka. Przypomina więc to np. obiekt typu <em>brush</em> z GDI.<br />
Samo rysowanie kółek jest trochę bardziej złożone niż można by się spodziewać, bo wymaga w sumie trzech wywołań:</p>
<div class="syntax_hilite">
<div id="javascript-34">
<div class="javascript"><span style="color: #000066; font-weight: bold;">for</span> <span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> i = <span style="color: #CC0000;">0</span>; i &lt;balls.<span style="color: #006600;">length</span>; ++i<span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; ctx.<span style="color: #006600;">beginPath</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; ctx.<span style="color: #006600;">arc</span><span style="color: #66cc66;">&#40;</span>ball.<span style="color: #006600;">x</span>, ball.<span style="color: #006600;">y</span>, BALL_RADIUS, <span style="color: #CC0000;">0</span>, <span style="color: #CC0000;">2</span> * Math.<span style="color: #006600;">PI</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; ctx.<span style="color: #006600;">fill</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span></div>
</div>
</div>
<p>
Jest tak dlatego, że kształty na <em>canvasie</em> opisujemy w formie <strong>ścieżek</strong> (<em>paths</em>), które potem wypełniamy (metodą <code>fill</code>) lub obrysowujemy (<code>stroke</code>). Kształt każdej piłki to nowa ścieżka (<code>beginPath</code>), składająca się z jednego łuku okręgu (<code>arc</code>), który opisujemy pozycją środka, promieniem oraz zakresem kątów. Nas oczywiście interesuje pełne koło, więc ów zakres ustalamy na <img src="http://xion.org.pl/wp-content/ql-cache/quicklatex.com-c5131db8b8c33dd6a6b3bf38aa836cfe_l3.png" class="ql-img-inline-formula" alt="&#91;&#48;&#59;&#50;&#92;&#112;&#105;&#93;" title="Rendered by QuickLaTeX.com" style="vertical-align: -5px;"/>.</p>
<h3>Trochę tekstu</h3>
<p>Poza samymi piłkami na ekranie widoczna jest też ich ilość oraz, naturalnie, licznik FPS-ów :) Wartość dla tego ostatniego liczymy dokładnie tak samo, jak w każdej innej sytuacji, tj. pobierając w każdej klatce aktualny czas (tutaj <a href="http://api.jquery.com/jQuery.now/">funkcją <code>now</code> z jQuery</a>) i odejmując od niego poprzedni rezultat, a następnie uśredniając wynik:</p>
<div class="syntax_hilite">
<div id="javascript-35">
<div class="javascript"><span style="color: #003366; font-weight: bold;">var</span> lastTime = $.<span style="color: #006600;">now</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #003366; font-weight: bold;">var</span> fps = <span style="color: #CC0000;">0</span>, framesCount = <span style="color: #CC0000;">0</span>, frameTime = <span style="color: #CC0000;">0</span>;<br />
requestAnimFrame<span style="color: #66cc66;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span> update <span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> time = $.<span style="color: #006600;">now</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> dt = <span style="color: #66cc66;">&#40;</span>time - lastTime<span style="color: #66cc66;">&#41;</span> / <span style="color: #CC0000;">1000</span>;<br />
&nbsp; &nbsp; lastTime = time;</p>
<p>&nbsp; &nbsp; frameTime += dt; framesCount++;<br />
&nbsp; &nbsp; <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #66cc66;">&#40;</span>frameTime&gt;= <span style="color: #CC0000;">1</span>.<span style="color: #CC0000;">0</span><span style="color: #66cc66;">&#41;</span> <span style="color: #66cc66;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; fps = Math.<span style="color: #006600;">floor</span><span style="color: #66cc66;">&#40;</span>framesCount / frameTime<span style="color: #66cc66;">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; frameTime = framesCount = <span style="color: #CC0000;">0</span>;<br />
&nbsp; &nbsp; <span style="color: #66cc66;">&#125;</span><br />
&nbsp; &nbsp; <span style="color: #009900; font-style: italic;">// ...</span><br />
&nbsp; &nbsp; requestAnimFrame<span style="color: #66cc66;">&#40;</span>update, canvas<span style="color: #66cc66;">&#41;</span>;<br />
<span style="color: #66cc66;">&#125;</span>, canvas<span style="color: #66cc66;">&#41;</span>;</div>
</div>
</div>
<p>
Komu powyższy kod nie wydaje się do końca zrozumiały (przy wzięciu poprawki na język programowania, rzecz jasna ;]), polecam chociażby <a href="http://xion.org.pl/productions/texts/coding/game-programming/real-time-loop/">mój artykuł</a> na temat pętli czasu rzeczywistego, gdzie powyższa konstrukcja jest dokładnie opisana.<br />
Tutaj zajmiemy się natomiast wypisaniem obliczonej wartości FPS oraz aktualnej ilości piłek. Nie jest to bynajmniej trudne:</p>
<div class="syntax_hilite">
<div id="javascript-36">
<div class="javascript">ctx.<span style="color: #006600;">strokeStyle</span> = <span style="color: #3366CC;">"black"</span>;<br />
ctx.<span style="color: #006600;">textAlign</span> = <span style="color: #3366CC;">"left"</span>;<br />
ctx.<span style="color: #006600;">strokeText</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"Balls: "</span> + balls.<span style="color: #006600;">length</span>, <span style="color: #CC0000;">0</span>, <span style="color: #CC0000;">10</span><span style="color: #66cc66;">&#41;</span>;<br />
ctx.<span style="color: #006600;">strokeText</span><span style="color: #66cc66;">&#40;</span><span style="color: #3366CC;">"FPS: "</span> + fps, <span style="color: #CC0000;">0</span>, <span style="color: #CC0000;">25</span><span style="color: #66cc66;">&#41;</span>;</div>
</div>
</div>
<p>
Tym razem ustawiamy <strong>styl obrysowania</strong> i wyrównywanie tekstu względem pozycji rysowania. Tekst wypisujemy funkcją <code>strokeText</code>, przyjmującą też współrzędne X i Y.</p>
<h3>Reszta...</h3>
<p>To w zasadzie tyle, jeśli chodzi o samo rysowanie po <em>canvasie</em>. Do poprawnego działania przykład potrzebuje oczywiście jeszcze kilku innych rzeczy, takich jak choćby implementacja poruszania się i odbijania piłek oraz obsługę kliknięć. Ponieważ jednak nie dotyczą one bezpośrednio API graficznego, nie będę im poświęcał miejsca w tym i tak już zdecydowanie przydługim wpisie. Można się im oczywiście przyjrzeć, czytając <a href="http://xion.org.pl/wp-content/uploads/2011/07/bouncingBalls.js">pełny kod przykładu</a> działającego wyżej.</p>
<p>Jeśli zaś ktoś chciałby dalszych informacji na temat możliwości i wykorzystania elementu <code>&lt;canvas></code>, to dobrym punktem wyjścia jest <a href="https://developer.mozilla.org/en/Canvas_tutorial">tutorial na stronach Mozilli</a>. Zawsze też można odwołać bezpośrednio do <a href="http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html">standardu</a> :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/07/31/canvas-czyli-programowanie-grafiki-w-html/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>HTML nr 5 &#8211; książka</title>
		<link>http://xion.org.pl/2011/07/23/html-nr-5-ksiazka/</link>
		<comments>http://xion.org.pl/2011/07/23/html-nr-5-ksiazka/#comments</comments>
		<pubDate>Sat, 23 Jul 2011 12:53:05 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Books]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[web apps]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2819</guid>
		<description><![CDATA[Właśnie skończyłem lekturę książki Wprowadzenie do HTML5 autorstwa Bruce'a Lawsona i Remy'ego Sharpa, wydanej w wersji polskiej przez Helion. Zakupiłem ją z nadzieją, że wprowadzi nieco porządku w cały ten buzz odnośnie HTML5, którego trudno nie zauważyć, jeśli tylko robi się cokolwiek chociaż pośrednio związanego z tą tematyką. I od razu mogę stwierdzić, że pod [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/07/html5-intro.jpg" alt="" title="&quot;Wprowadzenie do HTML5&quot; (okładka)"/>Właśnie skończyłem lekturę książki <em>Wprowadzenie do HTML5</em> autorstwa Bruce'a Lawsona i Remy'ego Sharpa, wydanej w <a href="http://helion.pl/ksiazki/wprowadzenie-do-html5-autorytety-informatyki-bruce-lawson-remy-sharp,whtmai.htm">wersji polskiej</a> przez Helion. Zakupiłem ją z nadzieją, że wprowadzi nieco porządku w cały ten <em>buzz</em> odnośnie HTML5, którego trudno nie zauważyć, jeśli tylko robi się cokolwiek chociaż pośrednio związanego z tą tematyką. I od razu mogę stwierdzić, że pod tym względem moje oczekiwania zostały rzeczywiście spełnione.</p>
<p>W książce można bowiem znaleźć przegląd kilku elementów składających się na standard HTML5 oraz paru technologii pobocznych, które formalnie do standardu nie należą, ale często są uwzględniane pod parasolem szerszej definicji całego zjawiska/technologii/ruchu/trendu/czegokolwiek-czym-to-jest. Wśród nich mamy takie podstawy jak nowe elementy strukturalne, nowe i przedefiniowane znaczniki opisu tekstu, poszerzone możliwości formularzy i różne drobne usprawnienia składniowo-semantyczne. Nie są one może tak ekscytujące jak "gwiazdy" technologii HTML5, ale fakt ich porządnego uwzględnienia jest według mnie tym bardziej godny uwagi.<br />
Oczywiście nie zabrakło też wielu "nowych wspaniałych API", dzięki którym możemy chociażby tworzyć SQL-owe bazy danych po stronie klienta i wykonywać szereg innych niezbędnych a właściwych dla stron WWW czynności ;D I tak możemy na przykład dowiedzieć się, co to właściwie jest ten <em>Canvas</em>, w jaki sposób zapewnić wsparcie dla techniki <em>drag &#038; drop</em> i do czego w zasadzie mogą przydać się te całe webowe gniazdka (czyli <em>Web Sockets</em>). Ponieważ wszystko pokazane jest na prostych przykładach, opanowanie podstaw każdego z tych rozwiązań dla ogarniętego programisty nie stanowi żadnego problemu.</p>
<p><img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/07/html5-logo.png" alt="" />Kluczowym słówkiem są tu jednak owe 'podstawy'. Chociaż różne tematy są tu opisane z różnym poziomem szczegółowości - czasem nawet zbyt dużym, jak choćby w przypadku <code>&lt;audio>/&lt;video></code> - to jednak w żaden nie jest opisany wyczerpująco. Nie wskazuję tego jako wady, bo przecież mówimy o książce z wyraźnym napisem "<strong>wprowadzenie</strong>" na okładce. Poza tym w prawie każdym miejscu, gdzie autorzy świadomie coś pomijają, podawane są inne (zwykle internetowe) źródła, z których można czerpać bardziej szczegółowe informacje. Trzeba też powiedzieć szczerze, że właściwie żaden z opisywanych tematów (może poza <em>Canvasem</em>) osobno nie prezentuje się jako specjalnie skomplikowany bądź obszerny. Skondensowane wprowadzenie może więc równie dobrze być całkowicie wystarczające.</p>
<p>Podsumowując więc: lektura okazała się jak najbardziej pożyteczna. Książkę czyta się szybko i bez wielkiego wysiłku, a jednocześnie można się z niej dowiedzieć wielu interesujących rzeczy. Jeśli nawet nie zamierzamy - za przeproszeniem - programować w HTML5, to przeczytanie tej książki da nam ciekawy wgląd w technologie będące podobno przyszłością Internetu czy nawet aplikacji jako takich.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/07/23/html-nr-5-ksiazka/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Stosu przepełnienie</title>
		<link>http://xion.org.pl/2011/07/16/stosu-przepelnienie/</link>
		<comments>http://xion.org.pl/2011/07/16/stosu-przepelnienie/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 16:44:16 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Thoughts]]></category>
		<category><![CDATA[forum]]></category>
		<category><![CDATA[karma]]></category>
		<category><![CDATA[Stack Overflow]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2807</guid>
		<description><![CDATA[Większość programistów zna (albo powinna znać) serwis Stack Overflow. Dla niezorientowanych wyjaśniam, że jest to specyficznego rodzaju forum dyskusyjne dla koderów, nastawione przede wszystkim na zadawanie pytań i udzielanie na nie odpowiedzi. Ze względu na swoje rozmiary mierzone liczbą zgromadzonej wiedzy, stanowi ono też doskonałe źródło szybkiej informacji w tych częstych przypadkach, gdy potrzebujemy prostego [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float:left; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/07/so-logo.png" alt="" />Większość programistów zna (albo powinna znać) serwis <a href="http://stackoverflow.com"><em>Stack Overflow</em></a>. Dla niezorientowanych wyjaśniam, że jest to specyficznego rodzaju forum dyskusyjne dla koderów, nastawione przede wszystkim na zadawanie pytań i udzielanie na nie odpowiedzi. Ze względu na swoje rozmiary mierzone liczbą zgromadzonej wiedzy, stanowi ono też doskonałe źródło szybkiej informacji w tych częstych przypadkach, gdy potrzebujemy prostego rozwiązania jakiegoś niezbyt skomplikowanego problemu.<br />
Oprócz bycia nieocenioną pomocą w pracy programisty, SO jest też ciekawym przypadkiem sprawnie działającej społeczności, na straży której nie stoją całe zastępy moderatorów. Zamiast tego to sami użytkownicy - za pomocą sukcesywnie zdobywanych <a href="http://stackoverflow.com/privileges">przywilejów</a>, takich jak edycja czy tagowanie pytań - wcielają w życie zasady dyskusji. Podobno fachowo idea ta nazywa się <em>crowdsourcingiem</em>; możemy dołączyć to słówko do pokaźnej już liczby dziwnych pojęć spod znaku Web 2.0 :)</p>
<p>Centralnym mechanizmem, wokół którego kręci się światek <em>Stack Overflow</em> (oraz niezliczonych <a href="http://stackexchange.com/sites">innych stron</a> opartych na tym samym silniku) jest <strong>reputacja</strong> poszczególnych użytkowników. To zwykły numer, w swoim znaczeniu podejrzanie podobny do tzw. karmy, nad której <a href="http://xion.org.pl/2009/03/06/koniec-pory-karmienia/">obecnością</a> na <a href="http://forum.warsztat.gd">forum Warsztatu</a> raz się nawet nieco <a href="http://xion.org.pl/2008/03/18/forumowa-numerologia/">rozpisałem</a>. Reputacja jest zwiększana między innymi wtedy, gdy nasze pytania lub odpowiedzi zostaną poparte (<em>upvote</em>) przez innych użytkowników. To nam daje punkty, które w większej ilości przekładają się na przywileje <em>quasi</em>-moderatorskie. W sumie jest to więc klasyczny przykład <strong>sprzężenia zwrotnego dodatniego</strong> (<em>positive feedback loop</em>), występującego w świecie w najprzeróżniejszych formach - od giełdy po <em>FarmVille</em>.</p>
<p>Jak w każdym takim systemie, także i tutaj wszystkie trybiki nie zawsze jednak działają idealnie. Ponieważ reputacja w serwisie SO jest dobrem mającym wartość także poza nim, nie dziwi duża chęć do jej zwiększania, występująca u wielu użytkowników. Nie jest to wbrew pozorom nic trudnego - nawet mimo obecności licznych ekspertów z niemal każdej poddziedziny związanej z programowaniem, którzy weryfikują i oceniają udzielane odpowiedzi.<br />
Jest tak z prostej przyczyny: w serwisie pojawia się całe mnóstwo pytań trywialnych, na które bez problemu odpowie każda średnio zaawansowana w danym temacie osoba. Ze względu na ilość użytkowników (ponad 700 tysięcy) fakt ten generuje dość komiczne sytuacje, gdy w przeciągu mniej niż minuty pojawiają się trzy albo cztery niemal dokładnie identyczne odpowiedzi. Zabawa czasami zamienia się więc raczej w <a href="http://meta.stackoverflow.com/questions/9731/fastest-gun-in-the-west-problem">konkurs szybkiego pisania na klawiaturze</a> :)</p>
<p>Mimo tych wad muszę stwierdzić, że uczestnictwo w dyskusjach na SO jest w ogólnym rozrachunku bez wątpienia pożyteczne. Wymierną osobistą korzyścią jest oczywiście sama reputacja, przeliczalna rozmiar ego po bardzo korzystnym kursie ;] Ważniejsza jest aczkolwiek możliwość utrwalania i poszerzania swojej wiedzy w wybranych działkach koderskiej działalności.</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/07/16/stosu-przepelnienie/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mniej CSS-a</title>
		<link>http://xion.org.pl/2011/07/11/mniej-css-a/</link>
		<comments>http://xion.org.pl/2011/07/11/mniej-css-a/#comments</comments>
		<pubDate>Mon, 11 Jul 2011 17:28:11 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2800</guid>
		<description><![CDATA[Ktokolwiek, kto pisał dłuższy lub bardziej skomplikowany arkusz stylów CSS, wie jakim bólem siedzenia potrafi to być. Nie chodzi tu nawet o same style, których interakcje między sobą oraz z zawierającymi je selektorami mogą czasem być cokolwiek zagadkowe (tak, marginy i paddingi - o was mówię). Rzecz w tym, że sam język CSS jest po [...]]]></description>
			<content:encoded><![CDATA[<p>Ktokolwiek, kto pisał dłuższy lub bardziej skomplikowany arkusz stylów CSS, wie jakim bólem siedzenia potrafi to być. Nie chodzi tu nawet o same style, których interakcje między sobą oraz z zawierającymi je selektorami mogą czasem być cokolwiek zagadkowe (tak, <em>marginy</em> i <em>paddingi</em> - o was mówię). Rzecz w tym, że sam <strong>język CSS</strong> jest po prostu biedny - nie tyle w zakresie możliwości (w końcu jest <a href="http://lemire.me/blog/archives/2011/03/08/breaking-news-htmlcss-is-turing-complete/">zupełny w sensie Turinga</a>), co wygody użytkowania. Brakuje mu chociażby kilku kluczowych konstrukcji, jakich można by się spodziewać. Dobrym przykładem są stałe (zmienne) i możliwość wykonywania na nich operacji arytmetycznych - choćby w celu policzenia zależnych od siebie marginesów.</p>
<p>Z tą bolączką można sobie oczywiście radzić we własnym zakresie, podłączając na przykład arkusze CSS pod system szablonów normalnie używany do generowania stron HTML na poziomie serwera. Nie wydaje się to jednak najlepszym możliwym sposobem na zużywanie jego zasobów. Istnieją też na pewno bardziej interesujące rzeczy, które mógłby zrobić programista w czasie, gdy będzie takie (z natury raczej specyficzne) rozwiązanie implementował.</p>
<p><img style="float:left; margin: 5px" src="http://xion.org.pl/wp-content/uploads/2011/07/less-logo.png" alt="" />I tutaj pojawia się bardzo ciekawy projekt o nazwie <a href="http://lesscss.org">LESS</a>, rozszerzający składnię CSS-a o <a href="http://lesscss.org/#docs">wiele przydatnych elementów</a>, jakich domyślnie w nim nie uświadczymy. Najfajniejsze jest przy tym to, że trik ten odbywa się po stronie klienta przy pomocy odpowiedniego skryptu JavaScript. Możemy więc korzystać z niego niezależnie od <em>backendu</em> naszego serwera czy nawet w ogóle bez serwera, tj. do stron bez dynamicznie generowanej treści. Integracja jest zaś bardzo prosta: sprowadza się do dodania jednego znacznika <code>&lt;script></code> (oczywiście) oraz lekkiej modyfikacji referencji do arkuszy stylów, czyli znaczników <code>&lt;link rel="stylesheet"></code>.</p>
<p>Co dostajemy w zamian? Oprócz wspomnianych na początku zmiennych i operacji na nich, mamy też w LESS-ie <a href="http://lesscss.org/#-mixins">"funkcje"</a> (czy raczej makra) <a href="http://lesscss.org/#-parametric-mixins">z parametrami</a>. Pozwala to chociażby na łatwiejsze dostarczanie stylów specyficznych dla przeglądarek. Możliwe jest też np. <a href="http://lesscss.org/#-importing">importowanie</a> kodu z innych arkuszy LESS, <a href="http://lesscss.org/#-nested-rules">zagnieżdżanie selektorów</a> oraz... <a href="http://lesscss.org/#-comments">wstawianie komentarzy</a> w stylu C++ :)<br />
Powyższe wyliczenie dodatków nie brzmi może bardzo imponująco, lecz nie jest to wcale dziwne. Tak naprawdę sam CSS już dawno powinien oferować tego rodzaju możliwości. Wiemy jednak, jak jest w rzeczywistości. Sądzę więc, że tym bardziej warto jest używać rozwiązania, które zamienia CSS w coś, czego można w końcu normalnie używać :)</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/07/11/mniej-css-a/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Wielki atraktor Wikipedii</title>
		<link>http://xion.org.pl/2011/05/25/wielki-atraktor-wikipedii/</link>
		<comments>http://xion.org.pl/2011/05/25/wielki-atraktor-wikipedii/#comments</comments>
		<pubDate>Wed, 25 May 2011 21:29:02 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Culture]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[atractor]]></category>
		<category><![CDATA[memes]]></category>
		<category><![CDATA[Wikipedia]]></category>
		<category><![CDATA[xkcd]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2688</guid>
		<description><![CDATA[Za sprawą najnowszego komiksu z xkcd - a właściwie tekstu, który pojawia się po najechaniu myszką na obrazek - w Internecie robi karierę mem na temat rzekomej "zbieżności" artykułów Wikipedii do hasła 'filozofia'. Zbieżność ta była zdefiniowana przez kolejne kliknięcia w pierwszy (z paroma wyjątkami) link w każdym artykule i kolejne powtarzanie tego procesu. W [...]]]></description>
			<content:encoded><![CDATA[<p>Za sprawą <a href="http://xkcd.com/903/">najnowszego komiksu</a> z <a href="http://xkcd.com"><em>xkcd</em></a> - a właściwie tekstu, który pojawia się po najechaniu myszką na obrazek - w Internecie robi karierę mem na temat rzekomej "zbieżności" artykułów Wikipedii do <a href="http://en.wikipedia.org/wiki/Philosophy">hasła 'filozofia'</a>. Zbieżność ta była zdefiniowana przez kolejne kliknięcia w pierwszy (z paroma wyjątkami) link w każdym artykule i kolejne powtarzanie tego procesu. W końcu powinniśmy trafić na wspomniany tekst o filozofii.<br />
Zabawną cechą tego memu jest fakt, iż stosuje się do niego swego rodzaju zasada nieoznaczoności: samym swoim istnieniem (i popularnością) oddziałuje on na zjawisko, które zdaje się opisywać. W końcu mówimy tutaj o serwisie, którego zawartość edytują tysiące użytkowników, a dzięki całej tej plotce ich uwaga jest tym bardziej skupiona na tekstach leżących na ścieżce do tej nieszczęsnej 'filozofii'... jeśli takowa faktycznie istnieje.</p>
<p>A czy istnieje? No właśnie :) Traktując to jako swego rodzaju pouczającą zabawę, postanowiłem zbadać sprawę i wysmażyłem <a href="http://www.nopaste.pl/11ni">odpowiedni program</a>, który potrafi automatycznie wykonywać procedurę opisaną na początku, tj. kolejno przechodzić przez teksty w Wikipedii i "klikać" w pierwsze linki z ich treści. Szybko zorientowałem się wtedy, że twierdzenie o zbieżności do <em>Philosophy</em> jest tylko wycinkiem większej, bardziej interesującej całości.<br />
<img style="float:right; margin:5px" src="http://xion.org.pl/wp-content/uploads/2011/05/atraktor.png" alt="" />Okazało się bowiem, że Wikipedia ma coś w rodzaju <strong>uniwersalnego atraktora</strong>, którego 'filozofia' jest częścią. Ma on postać cyklu zmieniającego się w czasie (z powodu edycji, oczywiście) i obejmuje interesujący zestaw pojęć, które semantycznie są połączone zależnością rekurencyjną. Obserwując kształt owego cyklu w dłuższym przedziale czasowym, można by zapewne wyodrębnić terminy zupełnie podstawowe, które są w nim obecne stale lub wypadają tylko na krótką chwilę. Kto wie, może w ten sposób udało by się dokonać jakiegoś fundamentalnego odkrycia z dziedziny filozofii, na przykład <a href="http://en.wikipedia.org/wiki/42_%28number%29">odpowiedzieć na pytanie o życie, Wszechświat i całą resztę</a>? ;-)</p>
<p>Nieco mniej ambitnym wyzwaniem jest zbadanie, <strong>jak daleko</strong> od atraktora znajdują się pewne hasła. Innymi słowy, ile kliknięć dzieli nas od wpadnięcia w cykl zapętlających się pojęć, jeśli zaczynamy od danego artykułu? Jeśli zastanowimy się nad tym chwilę, to można dojść do wniosku, że odpowiedź byłaby miarą odwrotności "stopnia abstrakcji" danego pojęcia. Skoro bowiem w atraktorze znajdują się terminy bardzo ogólne, oddalanie się od niego powinno nas przybliżać do konkretów. Czy tak jest w rzeczywistości?...<br />
Wygląda na to, że faktycznie coś w tym jest. Poniżej przedstawiam tendencyjne wyniki sprawdzenia pewnej liczby bynajmniej wcale nie losowo wybranych haseł. i obliczenia odległości każdej z nich od Czarnej Dziury Abstrakcji:</p>
<table width="100%">
<tr>
<td><em>blog</em></td>
<td>14</td>
<td><em>Internet</em></td>
<td>7</td>
<td><em>programming</em></td>
<td>8</td>
</tr>
<tr>
<td><em>compiler</em></td>
<td>6</td>
<td><em>Turing machine</em></td>
<td>5</td>
<td><em>Angry Birds</em></td>
<td>18</td>
</tr>
<tr>
<td><em>Sun</em></td>
<td>4</td>
<td><em>velociraptor</em></td>
<td>2</td>
<td><em>Boeing 747</em></td>
<td>22</td>
</tr>
<tr>
<td><em>South Park</em></td>
<td>28</td>
<td><em>Darth Vader</em></td>
<td>8</td>
<td><em>Julius Caesar</em></td>
<td>34</td>
</tr>
</table>
<p>Nie jestem wprawdzie do końca pewien, co oznacza to, że <em>Angry Birds</em> są niemal dwa razy bardziej abstrakcyjne od Juliusza Cezara, ale na pewno musi to coś znaczyć ;]</p>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/05/25/wielki-atraktor-wikipedii/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Do czego przydaje się AJAX</title>
		<link>http://xion.org.pl/2011/04/16/do-czego-przydaje-sie-ajax/</link>
		<comments>http://xion.org.pl/2011/04/16/do-czego-przydaje-sie-ajax/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 20:44:58 +0000</pubDate>
		<dc:creator>Xion</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://xion.org.pl/?p=2570</guid>
		<description><![CDATA[Kiedyś wymyślono, że statyczne strony WWW są nieco nudne i że trochę bardziej zaawansowanej logiki mogłoby dodać im funkcjonalności. Powstał więc język JavaScript, który po pewnym czasie (gdy minął okres wykorzystywania go do animowanych zegarków, spadających płatków śniegu i innych niepoważnych zastosowań) znacząco zyskał na funkcjonalności. Dorobił się między innymi możliwości wysyłania dodatkowych żądań HTTP, [...]]]></description>
			<content:encoded><![CDATA[<p>Kiedyś wymyślono, że statyczne strony WWW są nieco nudne i że trochę bardziej zaawansowanej logiki mogłoby dodać im funkcjonalności. Powstał więc język JavaScript, który po pewnym czasie (gdy minął okres wykorzystywania go do animowanych zegarków, spadających płatków śniegu i innych niepoważnych zastosowań) znacząco zyskał na funkcjonalności. Dorobił się między innymi możliwości wysyłania dodatkowych żądań HTTP, niezależnie od pierwotnego <em>requestu</em>, wczytującego całą stronę.<br />
Technika ta jest znana jako AJAX, czyli <em>Asynchronous Javascript And XML</em>. Ten łatwo wpadający w oko akronim jest <em>notabene</em> jednym z najbardziej nietrafnych, jakie da się znaleźć w całej szerokiej domenie informatyki. Jest tak dlatego, gdyż żądania HTTP wysyłane ze skryptów strony WWW:</p>
<ul>
<li>wcale nie muszą być asynchroniczne, chociaż zwykle są</li>
<li>wcale nie muszą być kodowane w języku JavaScript (chociaż niemal zawsze są)</li>
<li>wcale nie muszą zwracać wyniku w formacie XML, bo zwykle używa się prostszych formatów</li>
</ul>
<p>Ważna jest tu zwłaszcza uwaga ostatnia. Chociaż API do wysyłania żądań HTTP składa się z klasy o nazwie <code>XMLHTTPRequest</code>, to w istocie nie ma obowiązku korzystania z wbudowanego w nią parsera XML. Równie dobrze potrafi ona zwrócić odpowiedź serwera HTTP w postaci tekstowej, którą możemy potem przetworzyć ręcznie. W praktyce chyba najbardziej popularnym formatem zwrotnym dla zapytań AJAX-owych jest <a href="http://xion.org.pl/2010/11/24/json-czyli-co-dobrego-dal-swiatu-javascript/">opisywany już przeze mnie</a> JSON.<br />
Oczywiście, nikt przy zdrowych zmysłach nie pisze samodzielnie kodu do owego "przetwarzania ręcznego" odpowiedzi z serwera. Zarówno ten końcowy etap, jak i samo wysyłanie żądania zostało bowiem opakowane w kilka użytecznych <em>frameworków</em>. Jednym z nich jest choćby <a href="http://jquery.com">jQuery</a>, który poza ukrywaniem zbędnych szczegółów AJAX-u posiada też mnóstwo innych przydatnych funkcji ogólnego przeznaczenia.</p>
<p>Do czego może przydać się możliwość łączenia się z serwerem HTTP z poziomu Javascript? Żeby znaleźć odpowiedź, wystarczy dobrze przyjrzeć się właściwie dowolnej bardziej skomplikowanej stronie internetowej..Prawie na pewno znajdziemy na niej mechanizmy, które w tle pobierają dodatkowe dane z macierzystego serwera lub wysyłają doń jakieś informacje. Dzięki temu mogą one realizować takie funkcje jak:</p>
<ul>
<li><strong>Dynamicznie pobieranie nowych treści</strong>, które pojawiły się od czasu przeładowania witryny. Ładnym przykładem takie zachowania jest <a href="http://twitter.com">Twitter</a>. Jeśli zostawimy stronę otwartą w zakładce przeglądarki, wówczas po jakimś czasie możemy odnaleźć na niej ramkę z napisem w rodzaju "2 new tweet(s)", po kliknięciu której zobaczymy od razu nowe statusy.</li>
<li><strong>Doczytywanie starszych elementów</strong> w trakcie przewijania. To odwrotny (chronologicznie) przypadek do powyższego, będący alternatywą dla stronicowania. Przykładem strony świetnie stosującej to rozwiązanie jest <a href="http://dzone.com">dzone</a>.</li>
<li><strong>Wyświetlanie szczegółów elementu</strong>, na przykład w dymku (<em>tooltip</em>) po najechaniu na niego kursorem myszy lub po rozwinięciu do większej postaci. Oczywiście ma to sens głównie wtedy, gdy treść do pobrania jest na tyle duża, że nie jest rozsądne dostarczanie jej wraz z pierwotną treścią strony.</li>
<li><strong>Wysyłanie formularzy bez przeładowywania strony</strong>. Normalnie przesłanie formularza na stronie skutkuje jej przeładowaniem w wyniku żądania typu <em>POST</em> (rzadziej <em>GET</em>). Można jednak przechwycić zdarzenie wysłania formularza i zamiast niego przesłać zapytanie AJAX-owe. Sensownym wykorzystaniem tej techniki jest weryfikacja nazwy użytkownika po wciśnięciu osobnego przycisku w formularzy rejestracyjnym do wielu serwisów sieciowych.</li>
<li><strong>Podpowiadanie zapytań</strong> w przypadku wyszukiwania. Tutaj nietrudno o przykłady, bo robią to wszystkie wyszukiwarki internetowe ogólnego przeznaczenia, a także sporo dedykowanych mechanizmów wyszukiwania obecnych w serwisach sieciowych.</li>
<li>Synchronizacja edytowanego dokumentu (<a href="http://docs.google.com">Google Docs</a>), obsługa czata (<a href="http://facebook.com">Facebook</a>), map (<a href="http://maps.google.com">Google Maps</a>) i wielu innych zaawansowanych logicznie aplikacji webowych.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://xion.org.pl/2011/04/16/do-czego-przydaje-sie-ajax/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

