<?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>Smashinglabs</title>
	<atom:link href="http://www.smashinglabs.pl/feed" rel="self" type="application/rss+xml" />
	<link>http://www.smashinglabs.pl</link>
	<description>Sebastian Poręba&#039;s blog</description>
	<lastBuildDate>Mon, 20 Feb 2012 08:51:56 +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>3D Tetris with Three.js tutorial &#8211; part 2</title>
		<link>http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-2</link>
		<comments>http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-2#comments</comments>
		<pubDate>Mon, 20 Feb 2012 08:51:02 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[Tetris tutorial]]></category>
		<category><![CDATA[WebGL]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=664</guid>
		<description><![CDATA[Second part of tutorial is about adding static blocks. It will be short but very important. Joined or separated? Think about the way we play Tetris. When the block is moving, we transform and rotate it freely. Cubes that make block are clearly connected and it&#8217;s intuitive that their representation in code should be as<a href="http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-2">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>Second part of tutorial is about adding static blocks. It will be short but very important.<br />
<span id="more-664"></span></p>
<!-- Content included by AmberPanther WP Include File --> 
<ul>
  <li><a href="http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-1">Part 1: Introduction and game loop</a></li>
  <li><a href="http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-2">Part 2: Static blocks and keeping score</a></li>
</ul>

<!-- End of included content -->

<h2>Joined or separated?</h2>
<p>Think about the way we play Tetris. When the block is moving, we transform and rotate it freely. Cubes that make block are clearly connected and it&#8217;s intuitive that their representation in code should be as well. On the other hand, when we try to complete a slice (in 2D &#8211; a row) and we succed, the cubes are removed and the block that was their origin doesn&#8217;t matter at this point. In fact, it shouldn&#8217;t matter &#8211; some boxes from a block may be removed and other not. Tracing an origin of a box would require constant splitting and merging geometries and trust me &#8211; that would be a crazy mess. In original 2D Tetris sometimes the color of a square was the indicator of the origin block. In 3D however we need a quick way to show z-axis and color is perfect for this.</p>
<p>In our game cubes will be connected when are dynamic and static when they are not. At the end of tutorial we will further optimize static cubes.</p>
<h2>Adding a static block</h2>
<p>Lets start with a moment when a moving block touches the floor (or another block). The moving block (with merged geometry of few cubes) is transformed into static, separated cubes that don&#8217;t move anymore. It&#8217;s convenient to keep these cubes in a 3D array.</p>
<pre class="brush: jscript; title: ; notranslate">
Tetris.staticBlocks = [];
Tetris.zColors = [
  0x6666ff, 0x66ffff, 0xcc68EE, 0x666633, 0x66ff66, 0x9966ff, 0x00ff66, 0x66EE33, 0x003399, 0x330099, 0xFFA500, 0x99ff00, 0xee1289, 0x71C671, 0x00BFFF, 0x666633, 0x669966, 0x9966ff
];
Tetris.addStaticBlock = function(x,y,z) {
  if(Tetris.staticBlocks[x] === undefined) Tetris.staticBlocks[x] = [];
  if(Tetris.staticBlocks[x][y] === undefined) Tetris.staticBlocks[x][y] = [];

  var mesh = THREE.SceneUtils.createMultiMaterialObject(new THREE.CubeGeometry( Tetris.blockSize, Tetris.blockSize, Tetris.blockSize), [
    new THREE.MeshBasicMaterial({color: 0x000000, shading: THREE.FlatShading, wireframe: true, transparent: true}),
    new THREE.MeshBasicMaterial({color: Tetris.zColors[z]})
  ] );

  mesh.position.x = (x - Tetris.boundingBoxConfig.splitX/2)*Tetris.blockSize + Tetris.blockSize/2;
  mesh.position.y = (y - Tetris.boundingBoxConfig.splitY/2)*Tetris.blockSize + Tetris.blockSize/2;
  mesh.position.z = (z - Tetris.boundingBoxConfig.splitZ/2)*Tetris.blockSize + Tetris.blockSize/2;
  mesh.overdraw = true;

  Tetris.scene.add(mesh);
  Tetris.staticBlocks[x][y][z] = mesh;
};
</pre>
<p>There is a lot to explain here. </p>
<h3>Colors and materials</h3>
<p>Tetris.zColors keeps a list of colors that indicate position of a cube on z-axis. I&#8217;d like to have a good looking cube, so it should have a color AND outlined border. I&#8217;m going to use something that is not very popular in Three.js tutorials &#8211; multiMaterials. There is a function in Three.js SceneUtils that takes a geometry and <strong>an array</strong> (notice brackets []) of materials. If you look in Three.js source:</p>
<pre class="brush: jscript; title: ; notranslate">
  createMultiMaterialObject : function ( geometry, materials ) {
  var i, il = materials.length, group = new THREE.Object3D();
  for ( i = 0; i &lt; il; i ++ ) {
    var object = new THREE.Mesh( geometry, materials[ i ] );
    group.add( object );
  }
  return group;
},
</pre>
<p>It&#8217;s a very simple hack that creates a mesh for every material. With pure WebGL there are better ways to achieve the same result (f.e. calling draw two times, once with gl.LINES and second with gl.something) but the usual use of this function is to for example to merge textures and materials at the same time &#8211; not different types of drawing.</p>
<h3>Position in 3D space</h3>
<p>Now, why the hell does position look like that?</p>
<pre class="brush: jscript; title: ; notranslate">
mesh.position.x = (x - Tetris.boundingBoxConfig.splitX/2)*Tetris.blockSize + Tetris.blockSize/2;
</pre>
<p>Our board <strong>center</strong> on init was placed in the (0,0,0) point. It is not a very good spot, as it means that some cubes will have negative position and others positive. It would be better to specify a corner of an object in our case. Moreover, we would like to think of our boxes positions as a discrete values from 1 to 6, or at least 0 to 5. Three.js (and WebGL, OpenGL and everything else) uses its own units that rather relate to meters or pixels. If you remember, in config we put a value</p>
<pre class="brush: jscript; title: ; notranslate">
Tetris.blockSize = boundingBoxConfig.width/boundingBoxConfig.splitX;
</pre>
<p>that is responsible for conversion. So as a summary:</p>
<pre class="brush: jscript; title: ; notranslate">
 // transform 0-5 to -3 - +2
(x - Tetris.boundingBoxConfig.splitX/2)
 // scale to Three.js units
*Tetris.blockSize
 // we specify cube center, not a corner - we have to shift position
 + Tetris.blockSize/2
</pre>
<h2>Nice test</h2>
<p>Our game is still very static, but you can open your console and run:</p>
<pre class="brush: jscript; title: ; notranslate">
var i = 0, j = 0, k = 0, interval = setInterval(function() {if(i==6) {i=0;j++;} if(j==6) {j=0;k++;} if(k==6) {clearInterval(interval); return;} Tetris.addStaticBlock(i,j,k); i++;},30)
</pre>
<p>It should animate filling the board with cubes.</p>
<h2>Keeping score</h2>
<p>A small utility function to keep score:</p>
<pre class="brush: jscript; title: ; notranslate">
Tetris.currentPoints = 0;
Tetris.addPoints = function(n) {
  Tetris.currentPoints += n;
  Tetris.pointsDOM.innerHTML = Tetris.currentPoints;
  Cufon.replace('#points');
}
</pre>
<p>You can call it from console as well.</p>
<div class="summarybox">
<h2>After this tutorial you should:</h2>
<ul>
<li>Know the difference between connected and separated geometries.</li>
<li>Understand basics of materials and how to mix them.</li>
<li>Understand what exactly does position mean in Three.js.</li>
</ul>
<p>   <a href="https://github.com/fridek/Threejs-Tetris-Tutorial/tree/Tutorial_part_2"><img src="http://www.smashinglabs.pl/wp-content/themes/Horcrux/images/github.png"> Grab source from github</a><br />
   If you have trouble with any of these, check tutorial again or ask a question in the comments below.
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-2/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>3D Tetris with Three.js tutorial &#8211; part 1</title>
		<link>http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-1</link>
		<comments>http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-1#comments</comments>
		<pubDate>Mon, 20 Feb 2012 08:50:22 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[Tetris tutorial]]></category>
		<category><![CDATA[WebGL]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=652</guid>
		<description><![CDATA[Learning Three.js is fairly easy. This series may be not the best tutorial ever, but I&#8217;ll share my experiences from writing a game &#8211; 3D Tetris. I hope you find it useful. Preparation First you need to download Three.js: https://github.com/mrdoob/three.js I also use Stats from mrdoob: https://github.com/mrdoob/stats.js In both cases you need only files from build directory.<a href="http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-1">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>Learning Three.js is fairly easy. This series may be not the best tutorial ever, but I&#8217;ll share my experiences from writing a game &#8211; <a href="https://github.com/fridek/Threejs-Tetris">3D Tetris</a>. I hope you find it useful.</p>
<p><span id="more-652"></span></p>
<!-- Content included by AmberPanther WP Include File --> 
<ul>
  <li><a href="http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-1">Part 1: Introduction and game loop</a></li>
  <li><a href="http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-2">Part 2: Static blocks and keeping score</a></li>
</ul>

<!-- End of included content -->

<h2>Preparation</h2>
<p>First you need to download Three.js: <a href="https://github.com/mrdoob/three.js">https://github.com/mrdoob/three.js</a></p>
<p>I also use Stats from mrdoob: <a href="https://github.com/mrdoob/stats.js">https://github.com/mrdoob/stats.js</a></p>
<p>In both cases you need only files from build directory.</p>
<p>Blox is a nice font for menu and points: <a href="http://www.dafont.com/blox.font">http://www.dafont.com/blox.font</a></p>
<p>To use it you have to convert it with Cufon: <a href="http://cufon.shoqolate.com/generate/">http://cufon.shoqolate.com/generate/</a></p>
<p>In my project all JS files go to js folder, music into music folder and html in root.</p>
<h2>HTML</h2>
<p>I&#8217;m lazy so all the CSS goes directly into html header. It&#8217;s not as bad as it sounds &#8211; it&#8217;s very short and there is only one page so caching is unnecessary anyway. There is not much to explain, just some CSS for the intro and score counter. Also you have to include all js and init cufon.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Three.js Tetris&lt;/title&gt;
	&lt;style&gt;
		body {margin: 0; padding: 0; overflow: hidden;}

		#menu {
			position: absolute;
			width: 200px;
			height: 250px;

			top: 50%; left: 50%;
			margin: -125px 0 0 -100px;

			text-align: center;

			border: 3px solid #fff;
			border-radius: 15px;

			background-color: #E36B23;
			box-shadow: 2px 10px 5px #888;
		}

    #menu p {font-weight: bold; color: #fff;}
    #menu p a {color: #fff;}

		#menu button {
			width: 80px;
			height: 25px;

			background-color: #C44032;

			border: 3px solid #fff;
			border-radius: 5px;	

			font-size: 14px;
			font-weight: bold;
			color: #fff;
		}

		#points {
			position: absolute;
			width: 120px;
			height: 16px;	

			padding: 12px;

			top: 20px;
			right: 80px;

			border: 3px solid #fff;
			border-radius: 15px;

			background-color: #E36B23;
			box-shadow: 2px 10px 5px #888;	

			font-size: 14px;
			font-weight: bold;
			color: #fff;	

			text-align: right;

			display: none;
		}
	&lt;/style&gt;
    &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;/&gt;
	&lt;/head&gt;
  &lt;body&gt;
	&lt;div id=&quot;menu&quot;&gt;
		&lt;h1&gt;Three.js Tetris&lt;/h1&gt;
    &lt;p&gt;
      Movement: arrows&lt;br&gt;
      Rotation: AD/SW/QE&lt;br&gt;
      Author: &lt;a href=&quot;http://www.smashinglabs.pl&quot;&gt;smashinglabs.pl&lt;/a&gt;
    &lt;/p&gt;
		&lt;button id=&quot;play_button&quot;&gt;Play&lt;/button&gt;
	&lt;/div&gt;

	&lt;div id=&quot;points&quot;&gt;
		0
	&lt;/div&gt;

	&lt;script type=&quot;text/javascript&quot; src=&quot;js/Three.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;js/Stats.js&quot;&gt;&lt;/script&gt;
	&lt;script type=&quot;text/javascript&quot; src=&quot;js/tetris.js&quot;&gt;&lt;/script&gt;

	&lt;script src=&quot;js/cufon-yui.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;
	&lt;script src=&quot;js/Blox_400.font.js&quot; type=&quot;text/javascript&quot;&gt;&lt;/script&gt;	

	&lt;script type=&quot;text/javascript&quot;&gt;
		Cufon.replace('#menu h1');
		Cufon.replace('#points');
	&lt;/script&gt;
  &lt;/body&gt;
&lt;/html&gt;
</pre>
<h2>Basic Structure and Three.js init</h2>
<p>There are many ways of organizing your game. If you want to host it on a gaming portal, you may need to use some kind of closure (i.e. not use global variables). If your game is very complex, inheritance becomes useful. But for the simple game working fullscreen all these concepts show as hard to maintain and not without some impact on preformace. The project will use one global namespace</p>
<pre class="brush: jscript; title: ; notranslate">
var Tetris = {};
</pre>
<p>All objects, functions and variables will be a member of Tetris. It&#8217;s a very useful way to maintain your code and to avoid usage of &#8220;this&#8221;. To make things even better, every object I use is a singleton. There are some drawbacks &#8211; it&#8217;s <a href="http://en.wikipedia.org/wiki/God_object">a classic god object</a> and a mixture of everything, but as long as it&#8217;s small I don&#8217;t care and you shouldn’t either.</p>
<p>We will focus on this structure later, now lets initialize Three.js. I used a tutorial by <a href="http://www.aerotwist.com/tutorials/getting-started-with-three-js/">Aerotwist</a> which is very simple, but plain and good enough. You should probably read it before you proceed.</p>
<pre class="brush: jscript; title: ; notranslate">
Tetris.init = function() {
  // set the scene size
  var WIDTH = window.innerWidth,
      HEIGHT = window.innerHeight;

  // set some camera attributes
  var VIEW_ANGLE = 45,
      ASPECT = WIDTH / HEIGHT,
      NEAR = 0.1,
      FAR = 10000;

  // create a WebGL renderer, camera
  // and a scene
  Tetris.renderer = new THREE.WebGLRenderer();
  Tetris.camera = new THREE.PerspectiveCamera(  VIEW_ANGLE,
                                  ASPECT,
                                  NEAR,
                                  FAR  );
  Tetris.scene = new THREE.Scene();

  // the camera starts at 0,0,0 so pull it back
  Tetris.camera.position.z = 600;
  Tetris.scene.add(Tetris.camera);

  // start the renderer
  Tetris.renderer.setSize(WIDTH, HEIGHT);

  // attach the render-supplied DOM element
  document.body.appendChild(Tetris.renderer.domElement);

  // to be continued...
</pre>
<p>The introduced Tetris.init is creating a Three.js objects and store them in global namespace. There is a renderer, a scene and a camera. I want the game to be fullscreen so I use window.innerWidth and window.innerHeight. You may want to experiment with <a href="http://learningthreejs.com/blog/2011/11/17/lets-make-a-3d-game-make-it-fullscreen/">fullscreen API</a> there. The camera needs to be pulled back and an exact distance should be determined by the size and position of the game world you use.</p>
<p>Our game world is a 3D wireframe box with lines showing where boxes can be dropped. When you work on a game it&#8217;s important to realize that the final effect is what matters most. <strong>Don&#8217;t be afraid to cheat!</strong> In this case, there is no good reason to draw lines on bounding box. We may as well use a normal box geometry, place a vertex on every line cross and connect vertices with lines instead of usual triangles. And luckily there is a Three.js syntax just for that!</p>
<pre class="brush: jscript; title: ; notranslate">
  // configuration object
  var boundingBoxConfig = {
    width: 360,
    height: 360,
    depth: 1200,
    splitX: 6,
    splitY: 6,
    splitZ: 20
  };

  Tetris.boundingBoxConfig = boundingBoxConfig;
  Tetris.blockSize = boundingBoxConfig.width/boundingBoxConfig.splitX;

  var boundingBox = new THREE.Mesh(
    new THREE.CubeGeometry(
      boundingBoxConfig.width, boundingBoxConfig.height, boundingBoxConfig.depth,
      boundingBoxConfig.splitX, boundingBoxConfig.splitY, boundingBoxConfig.splitZ),
    new THREE.MeshBasicMaterial( { color: 0xffaa00, wireframe: true } )
  );
  Tetris.scene.add(boundingBox);

  // first render
  Tetris.renderer.render(Tetris.scene, Tetris.camera);
  // to be continued...
</pre>
<p>A Three.js API describes <a href="http://threejs.org/io/s/CubeGeometry">CubeGeometry</a> constructor as: </p>
<pre class="brush: jscript; title: ; notranslate">
(width &lt;Number&gt;, height &lt;Number&gt;, depth &lt;Number&gt;, segmentsWidth &lt;Number&gt;, segmentsHeight &lt;Number&gt;, segmentsDepth &lt;Number&gt;, materials &lt;Array&gt;, sides &lt;Object&gt;)
</pre>
<p>and we make use of &#8220;segmentX&#8221; options to define how many boxes can be fitted into our gameboard. We use also MeshBasicMaterial option wireframe to draw lines instead of triangles.</p>
<p>Last things to do in init function:</p>
<pre class="brush: jscript; title: ; notranslate">
  Tetris.stats = new Stats();
  Tetris.stats.domElement.style.position = 'absolute';
  Tetris.stats.domElement.style.top = '10px';
  Tetris.stats.domElement.style.left = '10px';
  document.body.appendChild( Tetris.stats.domElement );

  document.getElementById(&quot;play_button&quot;).addEventListener('click', function (event) {
    event.preventDefault();
    Tetris.start();
  });
};
</pre>
<p>We add FPS stats and bind Tetris.start() to the play button. What should be done in start()?</p>
<pre class="brush: jscript; title: ; notranslate">
Tetris.start = function() {
   document.getElementById(&quot;menu&quot;).style.display = &quot;none&quot;;
   Tetris.pointsDOM = document.getElementById(&quot;points&quot;);
   Tetris.pointsDOM.style.display = &quot;block&quot;;

   Tetris.animate();
};
</pre>
<p>Hide instructions, show score box and start first animate() function. </p>
<h2>Game loop</h2>
<p>You may wonder why there was no setInterval for animation. There is a much better function for that &#8211; requestAnimationFrame(). It calls specified functions when the browser is not busy, but no more than 60 times per second. It means that you will have exactly the number of FPS that is possible to render. No need to worry about calculating the best time step for setInterval or clots if you try to render more FPS than it&#8217;s possible to calculate. The function is still something new, so on top of our script we will place a compatibility code:</p>
<pre class="brush: jscript; title: ; notranslate">
if ( !window.requestAnimationFrame ) {
  window.requestAnimationFrame = ( function() {
    return window.webkitRequestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.oRequestAnimationFrame ||
    window.msRequestAnimationFrame ||
    function( /* function FrameRequestCallback */ callback, /* DOMElement Element */ element ) {
      window.setTimeout( callback, 1000 / 60 );
    };
  })();
}
</pre>
<p>Now we need to write animate() function. Tetris is real-time, but a step of game is quite long, like one z-axis move per second. We need to calculate when to move our block forward, so some time-related variables have to be introduced:</p>
<pre class="brush: jscript; title: ; notranslate">
Tetris.gameStepTime = 1000;

Tetris.frameTime = 0; // ms
Tetris.cumulatedFrameTime = 0; // ms
Tetris._lastFrameTime = Date.now(); // timestamp

Tetris.gameOver = false;
</pre>
<p>Now, the animate function in simplified version has to call Three.js render method and call itself again using requestAnimationFrame. This would make our game static, so we need to calculate a passage of time and act if it was long enough.</p>
<pre class="brush: jscript; title: ; notranslate">
Tetris.animate = function() {
  var time = Date.now();
  Tetris.frameTime = time - Tetris._lastFrameTime;
  Tetris._lastFrameTime = time;
  Tetris.cumulatedFrameTime += Tetris.frameTime;

  while(Tetris.cumulatedFrameTime &gt; Tetris.gameStepTime) {
    // block movement will go here
    Tetris.cumulatedFrameTime -= Tetris.gameStepTime;
  }

  Tetris.renderer.render(Tetris.scene, Tetris.camera);

  Tetris.stats.update();

  if(!Tetris.gameOver) window.requestAnimationFrame(Tetris.animate);
}
</pre>
<p>If you noticed stats update, you may think it&#8217;s a little redundant. Stats are obviously counting FPS and we do the same thing. You may want to dig into stats code and re-use some data, but I&#8217;ve found it simpler to write my own few lines of code. Stats were not intended for such usage and the overhead is close to zero. Besides, if you&#8217;d like to remove FPS counter from your game when it&#8217;s released, it could be a problem. The less dependencies the better.</p>
<p>And, at last, we should call init() when the page is loaded:</p>
<pre class="brush: jscript; title: ; notranslate">
window.addEventListener(&quot;load&quot;, Tetris.init);
</pre>
<div class="summarybox">
<h2>After this tutorial you should:</h2>
<ul>
<li>Know how to setup a renderer and scene with Three.js.</li>
<li>Understand what a game loop is and</li>
<li>why requestAnimationFrame is great.</li>
<li>Know that if it looks good, it&#8217;s good.</li>
</ul>
<p>   <a href="https://github.com/fridek/Threejs-Tetris-Tutorial/tree/Tutorial_part_1"><img src="http://www.smashinglabs.pl/wp-content/themes/Horcrux/images/github.png"> Grab source from github</a><br />
   If you have trouble with any of these, check tutorial again or ask a question in the comments below.
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/3d-tetris-with-three-js-tutorial-part-1/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>gMap 3.3.0 released</title>
		<link>http://www.smashinglabs.pl/gmap-3-3-0-released</link>
		<comments>http://www.smashinglabs.pl/gmap-3-3-0-released#comments</comments>
		<pubDate>Wed, 21 Dec 2011 21:05:36 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[featured]]></category>
		<category><![CDATA[gMap]]></category>
		<category><![CDATA[Google Map]]></category>
		<category><![CDATA[google maps]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[release]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=625</guid>
		<description><![CDATA[Christmas came early! New version of gMap is ready! As always, you can download it from github. I had a lot of feature requests since last version and I hope I covered them all. Here is what&#8217;s new in 3.3.0: clustering fixAfterResize &#8211; fixing issues with loading gMaps in tabs changeSettings &#8211; works with most<a href="http://www.smashinglabs.pl/gmap-3-3-0-released">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>Christmas came early! New version of gMap is ready!</p>
<p><span id="more-625"></span></p>
<p><a href="http://www.smashinglabs.pl/wp-content/uploads/2011/08/gmap_example2.jpg"><img class="aligncenter size-medium wp-image-282" title="Gmap image" src="http://www.smashinglabs.pl/wp-content/uploads/2011/08/gmap_example2-300x175.jpg" alt="" width="300" height="175" /></a></p>
<p>As always, you can <a href="https://github.com/fridek/gmap">download it from github</a>.</p>
<p>I had a lot of feature requests since last version and I hope I covered them all.<br />
Here is what&#8217;s new in 3.3.0:</p>
<ul>
<li>clustering</li>
<li>fixAfterResize &#8211; fixing issues with loading gMaps in tabs</li>
<li>changeSettings &#8211; works with most of initial options</li>
<li>mapclick(callback) &#8211; bind for map click event</li>
<li>geocode(address, callback) &#8211; shorthand for geocoding</li>
<li>draggable markers (thanks to theMarvin)</li>
</ul>
<p>I&#8217;m getting close to the point where I&#8217;ll consider gMap completed. Now it&#8217;s just about the time to improve documentation, which is still in 3.1.0 (sorry for that) and to complete test coverage.</p>
<p>I&#8217;d like to share a link to Magic Gallery WordPress Plugin: <a href="http://www.magicgalleryplugin.com/">http://www.magicgalleryplugin.com/</a> It uses gMap and has a very nice design.</p>
<p>If you want to support my work and make my Christmas even better, please consider donating (button on the right sidebar).</p>
<p>That&#8217;s all the news, merry Christmas everyone!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/gmap-3-3-0-released/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>JavaScript performance lecture followup</title>
		<link>http://www.smashinglabs.pl/javascript-performance-lecture-followup</link>
		<comments>http://www.smashinglabs.pl/javascript-performance-lecture-followup#comments</comments>
		<pubDate>Sat, 17 Dec 2011 23:09:47 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[GTUG]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JIT]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=586</guid>
		<description><![CDATA[After my last lecture I got some comments, found some resources and I updated my slides. Some highlights of things that has changed: Trace JIT is no more I was surprised by the news that trace JIT was removed from Firefox trunk. I hoped that it will grow and replace method JIT completely one day. Post from from<a href="http://www.smashinglabs.pl/javascript-performance-lecture-followup">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>After <a title="Lecture for GTUG: JavaScript performance" href="http://www.smashinglabs.pl/lecture-for-gtug-javascript-performance">my last lecture</a> I got some comments, found some resources and I updated my slides.</p>
<p>Some highlights of things that has changed:</p>
<p><span id="more-586"></span></p>
<h3>Trace JIT is no more</h3>
<p>I was surprised by the news that trace JIT was removed from Firefox trunk. I hoped that it will grow and replace method JIT completely one day. <a href="http://blog.mozilla.com/dmandelin/2011/11/29/js-development-newsletter-1123-1129/">Post from from David Mandelin</a> explains details behind this  decision.</p>
<h3>Method JIT works better than I expected</h3>
<p>During my talk I stated that using config object (which e.g. jQuery plugins do) may break JIT and that the safest way is to use integer and float arguments only.</p>
<p>I got a very detailed description from Rob Brackett on how JIT works with objects:</p>
<blockquote><p>Passing config objects to functions can often cause them to run slower — most engines use a concept of &#8220;shape&#8221; to JIT code related to objects (shape is basically the set of keys on your object, so {a:&#8221;a&#8221;, b:&#8221;b&#8221;} and {a:&#8221;c&#8221;, b:&#8221;d&#8221;} are the same shape but {a:&#8221;a&#8221;, c:&#8221;b&#8221;} is a different shape). The function will generally have to be JITed once for each shape that is passed in. Some engines stop re-JITing after they&#8217;ve seen a certain number of shapes (the threshold is different for different engines) and some do not.</p></blockquote>
<p>My second statement, about integers and floats was based on NanoJIT capabilities. Since it was removed from Firefox with Trace JIT, I can now safely say that any argument type that fulfill static &#8220;shape&#8221; description above can be JITed.</p>
<p>Source: <a href="http://groups.google.com/group/jsmentors/browse_thread/thread/9286c04c908cd722">http://groups.google.com/group/jsmentors/browse_thread/thread/9286c04c908cd722</a></p>
<h3>Reflow is blocking</h3>
<p>I got a question, if reflow has been or could be moved to separated thread, so it won&#8217;t be blocking. The short answer is &#8220;no&#8221;. There are plenty of functions that depend on calculated result and it would require synchronizing very often. <a href="http://gent.ilcore.com/2011/03/how-not-to-trigger-layout-in-webkit.html">The list of functions that require reflow to be completed</a>.</p>
<h3>More</h3>
<p>It was linked in my slides, but I&#8217;d like to say it again &#8211; read David Madelin&#8217;s slides <a href="http://blog.mozilla.com/dmandelin/2011/06/16/know-your-engines-at-oreilly-velocity-2011/">Know Your Engines</a> from Velocity Conf 2011. It&#8217;s the most detailed source about engines I&#8217;ve found so far.</p>
<p><a href="http://groups.google.com/group/jsmentors/browse_thread/thread/9286c04c908cd722">I&#8217;ve asked some questions on JSMentors group</a>, you may want to check it out.</p>
<p>Bonus: some <a href="https://picasaweb.google.com/107595839032738148454/KRKOptymalizacjaJavaScriptuGWTGAE#">photos from the event</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/javascript-performance-lecture-followup/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lecture for GTUG: JavaScript performance</title>
		<link>http://www.smashinglabs.pl/lecture-for-gtug-javascript-performance</link>
		<comments>http://www.smashinglabs.pl/lecture-for-gtug-javascript-performance#comments</comments>
		<pubDate>Wed, 07 Dec 2011 22:22:15 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[featured]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[garbage collector]]></category>
		<category><![CDATA[GC]]></category>
		<category><![CDATA[GTUG]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[JIT]]></category>
		<category><![CDATA[optimization]]></category>
		<category><![CDATA[performance]]></category>
		<category><![CDATA[reflow]]></category>
		<category><![CDATA[repaint]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=579</guid>
		<description><![CDATA[Today I gave a lecture for GTUG Krakow about optimizations in JS. My main topics were: Optimization in general DOM Reflow/repaint Garbage collector JIT Google Closure (Compiler/Tools/Library) You can check my slides here. I collected plenty of links and wrote a few examples. Feel free to comment and criticize. I&#8217;ll be happy to add anything that<a href="http://www.smashinglabs.pl/lecture-for-gtug-javascript-performance">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>Today I gave a lecture for <a href="http://krakow.gtug.pl/">GTUG Krakow</a> about optimizations in JS.</p>
<p><span id="more-579"></span></p>
<p><img class="aligncenter size-medium wp-image-581" style="border-style: initial; border-color: initial;" title="gtug cracow 2 sign 1" src="http://www.smashinglabs.pl/wp-content/uploads/2011/12/gtug-cracow-2-sign-1-300x139.png" alt="" width="300" height="139" /></p>
<p>My main topics were:</p>
<ul>
<li>Optimization in general</li>
<li>DOM</li>
<li>Reflow/repaint</li>
<li>Garbage collector</li>
<li>JIT</li>
<li>Google Closure (Compiler/Tools/Library)</li>
</ul>
<p>You can check my slides <a href="http://smashinglabs.pl/lectures/js-performance/" target="_blank">here</a>. I collected plenty of links and wrote a few examples.<br />
<a href="http://www.smashinglabs.pl/wp-content/uploads/2011/12/gtug-cracow-2-sign-1.png"><br />
</a>Feel free to comment and criticize. I&#8217;ll be happy to add anything that I&#8217;ve missed or to correct any mistakes. There are few good optimization resources and I had some doubts in few cases.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/lecture-for-gtug-javascript-performance/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Makefile for Google Closure Compiler</title>
		<link>http://www.smashinglabs.pl/makefile-for-google-closure</link>
		<comments>http://www.smashinglabs.pl/makefile-for-google-closure#comments</comments>
		<pubDate>Tue, 22 Nov 2011 19:04:47 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[Closure Compiler]]></category>
		<category><![CDATA[compilation]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=568</guid>
		<description><![CDATA[I&#8217;ve been using online version of Google Closure Compiler as a minifier for my projects for some time now. I always wondered how the advanced compilation works, but never really gave it a shot. Lately I started working on a university project and as you may know, academics do not like JavaScript in general. To<a href="http://www.smashinglabs.pl/makefile-for-google-closure">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using <a href="http://closure-compiler.appspot.com/home">online version of Google Closure Compiler</a> as a minifier for my projects for some time now. I always wondered how the advanced compilation works, but never really gave it a shot. Lately I started working on a university project and as you may know, academics do not like JavaScript in general. To make it even worse for them, I decided to prepare a very complex JS setup, with fully annotated Google Closure code. Not only out of spice, but also to prove that using a proper approach, it can be fast and well-structured.</p>
<p><span id="more-568"></span>I&#8217;m not going to describe here how the Compiler works in detail. In short words, it scans your files looking for comments in a specific, JSDoc-like format and makes use of them. There is also a tool called calcdeps which is a linker &#8211; it scans files for dependencies and helps compiler to merge files in the correct order.</p>
<div id="attachment_571" class="wp-caption aligncenter" style="width: 251px"><a href="http://www.smashinglabs.pl/wp-content/uploads/2011/11/folders.png"><img class="size-full wp-image-571" title="folders" src="http://www.smashinglabs.pl/wp-content/uploads/2011/11/folders.png" alt="" width="241" height="343" /></a><p class="wp-caption-text">My project structure</p></div>
<p>To make it even more fun, I decided to write a Makefile which will be a final jaw-dropper.</p>
<pre class="brush: jscript; title: ; notranslate">
PYTHON   = python
CALCDEPS = ~/closure/closure-library-read-only/closure/bin/calcdeps.py
CLOSURECOMPILER = ~/closure/compiler.jar

all:
	$(PYTHON) $(CALCDEPS) -p src -i src/init.js -o compiled -c $(CLOSURECOMPILER) &gt; scripts/ai-bot-compiled.js
</pre>
<p>It works like charm, &#8220;make&#8221; is compiling all required files from src folder, merging them into one.<br />
I was surprised how easy it was &#8211; calcdeps takes a path (-p) where you store all your libraries and an initial file (-i). The rest is based on goog.require(classname) and goog.provide(classname) calls from files. I barely used Google Closure Tools so far, but the Compiler is absolutely great!</p>
<p>Google Closure: <a href="http://code.google.com/intl/pl/closure/">http://code.google.com/intl/pl/closure/</a><br />
Book: <a href="http://www.amazon.com/Closure-Definitive-Guide-Michael-Bolin/dp/1449381871">http://www.amazon.com/Closure-Definitive-Guide-Michael-Bolin/dp/1449381871</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/makefile-for-google-closure/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Unit testing for jQuery plugins &#8211; part 3</title>
		<link>http://www.smashinglabs.pl/unit-testing-for-jquery-plugins-part-3</link>
		<comments>http://www.smashinglabs.pl/unit-testing-for-jquery-plugins-part-3#comments</comments>
		<pubDate>Sun, 13 Nov 2011 14:49:08 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[featured]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[QUnit]]></category>
		<category><![CDATA[test driven development]]></category>
		<category><![CDATA[unit testing]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=518</guid>
		<description><![CDATA[In part 1 I described basics of unit testing in JS, and part 2 was focused on CSS tests. It was an introduction to what I&#8217;m about to show now, so don&#8217;t forget to read these too. jQuery plugin testing means for me having to deal with a lot of unknowns. You don&#8217;t know how long code<a href="http://www.smashinglabs.pl/unit-testing-for-jquery-plugins-part-3">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>In <a title="Unit testing for jQuery plugins – part 1" href="http://www.smashinglabs.pl/unit-testing-for-jquery-plugins-part-1">part 1</a> I described basics of unit testing in JS, and <a title="Unit testing for jQuery plugins – part 2" href="http://www.smashinglabs.pl/unit-testing-for-jquery-plugins-%e2%80%93-part-2">part 2</a> was focused on CSS tests. It was an introduction to what I&#8217;m about to show now, so don&#8217;t forget to read these too. jQuery plugin testing means for me having to deal with a lot of unknowns. You don&#8217;t know how long code execution will take, you don&#8217;t know how other plugins you depend on work internally and you certainly never know when AJAX call or async function will end.</p>
<h2>Asynchronous testing in QUnit</h2>
<p>The most important part to understand is how to deal with code that is asynchronous. Consider this example:</p>
<pre class="brush: jscript; title: ; notranslate">
test('addTwo test', function() {
   elem.slideDown();
   equal(elem.height(), 200);
}
</pre>
<p>In this very simple piece of code very common problem is hidden. There are plenty of such functions, related to animating elements, showing popups, highlighting, querying data, waiting for loading data and so on. They all share one concept &#8211; the call is made, function is working on something, but the rest of the code is executed at the same time. It&#8217;s considered to be very good &#8211; lets us code non-blocking scripts and provides means of creating very active content. But what we lose here is the ability to use a result of function immediately after its call. In this case, for test purposes.</p>
<h2>Asynchronous &#8211; the good way</h2>
<p>The good way of dealing with such code is a great example of why writing tests is so important. It always reminds me hacking &#8211; it forces you to think about all possible outcomes and to stretch your application to its limits. In this case writing tests shows what almost every plugin should have, an onComplete function. By providing it you may internally check if everything is finished and if other code may proceed. I decided that I need it when I discovered how long it takes for Google Maps to load markers with addresses instead of coordinates. This is a good practice that jQuery, jQuery UI and a most of other serious libraries use. Testing with onComplete function is simple:</p>
<pre class="brush: jscript; title: ; notranslate">
test(&quot;map with address markers&quot;, function() {
    map = createNewMap();
    map.gMap({
        markers: [...], // some markers
        zoom: 12,
        onComplete: function() {
            data = map.data('gmap');
            ok(data.markers[0].getPosition().lat() &amp;&amp; data.markers[0].getPosition().lng(), 'marker position correct');
        }
    });
});
</pre>
<p>This is a part of my gMap tests. Something is still missing here and you may have noticed. Using an onComplete function does not prevent code from moving on. Plugin init is called and immediately test function is finished. Depending on your testing framework it may still work, assertion will be called eventually and its result will be shown. The problem is, that meanwhile the state of your testing suite may change. You can see here, that my test starts with createMap() function, which clears old map and creates a new one. This is an obvious case where running two tests at the same time can&#8217;t work. QUnit solves it like that (explanation in code comments):</p>
<pre class="brush: jscript; title: ; notranslate">
test(&quot;map with address markers&quot;, function() {
    map = createNewMap();
    map.gMap({
        markers: [...], // some markers
        zoom: 12,
        onComplete: function() {
            data = map.data('gmap');
            ok(data.markers[0].getPosition().lat() &amp;&amp; data.markers[0].getPosition().lng(), 'marker position correct');
            start(); // let other tests continue
        }
    });
    stop(); // when the end of the function is reached, do not run any other test until start() is called
});
</pre>
<h2>Asynchronous &#8211; the ugly way</h2>
<p>The problems start when you are depending on some function that doesn&#8217;t support onComplete callback. For example, if you open an popup in Google Maps, animation takes some time but there is no callback (sorry for referring to maps all the time, but it&#8217;s what I know best). It makes sense from their point of view, as nobody sane would ever call anything when html is loaded to a popup. Well, but I don&#8217;t care too much about my sanity and I had to, so what now? This is quite long listing, but shows the popup problem described above.</p>
<pre class="brush: jscript; title: ; notranslate">
test(&quot;infowindow&quot;, function() {
    map = createNewMap();
    map.gMap({
        markers: [
            {
                latitude: 50.083,
                longitude: 19.917,
                html: '&lt;div class=&quot;test_marker&quot;&gt;marker 1&lt;/div&gt;'
            }
        ],
        zoom: 12,
        onComplete: function() {
            data = map.data('gmap');
            equal(data.infoWindow, null, 'infowindow empty');
            equal($('.test_marker').size(), 0, 'no .test_marker');
            google.maps.event.trigger(data.markers[0], 'click');
            window.setTimeout(function() {
                ok(data.infoWindow, 'infowindow set');
                equal($('.test_marker').size(), 1, '.test_marker present');
                start();
            }, 1000);
        }
    });
    stop();
});
</pre>
<p>The dirty hack here is calling a test in setTimeout. It works almost the same way as onComplete, except for the part where you have to guess how long may it take. You have to be very careful with that. If your guess is to low, your test may fail at random. Also you should think, whether too long execution time may affect normal user. If so, you should either document it very well or think about some other way of implementing it. Using our example, you may push the popup problem forward to the user and let him ignore it or fix it, or you may create another wrapper with onComplete callback. Considering performance and code length I usually choose the first option.</p>
<h2>Accessing internal parts of plugin</h2>
<p>A good plugin is not changing your global variables. It&#8217;s cool, but causes a problem when you want to test internal functions. Testing input and output of plugin is fine, but without checking some mid-results you will quickly find that finding and error is not as simple as we would like it to be.</p>
<p>Now, if you read <a href="http://docs.jquery.com/Plugins/Authoring">something about jQuery plugin development</a> you probably already have methods array and a nice dispatcher that lets you call $(selector).myPlugin(&#8216;methodName&#8217;, arguments);. It seems like a perfect way to expose plugin internals and usually it is. But in case of testing it really isn&#8217;t. Keep in mind that these methods are useful AFTER initialization. There is really no good way of testing what happens inside, without any overhead. The options I considered are:</p>
<h2>Debug mode</h2>
<p>You may put in your config object an debug callback. Then call it in any place you want, like that:</p>
<pre class="brush: jscript; title: ; notranslate">
methods = {
    _someInternalMethod: function() {
        // do something
        if(opts.debug) { opts.debug({
            //object with debug data
        }); }
    }
}
</pre>
<p>However, this makes your code look like crap and with big plugins every line of code counts. In gMap I use log option, but in a very limited way.</p>
<h2>Use $.data()</h2>
<p>This is something that I hesitated about for a long time. $.data() binds any desired data to your DOM element. I&#8217;m a performance freak, so it always gives me goosebumps. DOM interaction is very slow, can&#8217;t be compiled as far as I know and it&#8217;s always kinda weird. It&#8217;s against MVC, storing data in view when you want to use them in controller. However, jQuery plugins are usually designed to be stateless, or at least to hide theirs state. This is one of the fastest ways to expose your internal data and I use it sometimes. I&#8217;m not going to put any new example here, you can see use of $.data() in almost each previously shown. It requires some work to ensure that exposed data are always correct, especially when something internal changes, but here tests becomes handy and saves a lot of time. If you use $.data(), prepare a lot of them and check everywhere if it&#8217;s working. Also try to use <a href="http://jsperf.com/jquery-data-vs-jqueryselection-data/16">the fastest method</a> of data binding which is, at the moment, $.data(jQueryObject, key, value).</p>
<h2>Turn your plugin into a builder</h2>
<p><a href="http://en.wikipedia.org/wiki/Builder_pattern">Builder</a> is a very good design pattern. It works like a stack &#8211; you can add some config options with provided methods and call execute() or build() when needed. This is how I should have designed gMaps to begin with  and now with every version I introduce more and more functions for changing map setup. It&#8217;s very useful for both your users and testing.</p>
<p>Time for an overkill example:</p>
<pre class="brush: jscript; title: ; notranslate">
test(&quot;changeSettings - fit new center&quot;, function() {
    map = createNewMap();
    var markers = [
                {
                    latitude: 50.083,
                    longitude: 19.917
                }
            ];
    var markers2 = [
                {
                    latitude: 50.083,
                    longitude: 19.917
                },
                {
                    latitude: 50.20917,
                    longitude: 19.75435
                },
                {
                    latitude: 50.502343,
                    longitude: 19.91243
                }
            ];
    map.gMap({
        markers: markers,
        zoom: 9,
        latitude: &quot;fit&quot;,
        longitude: &quot;fit&quot;,
        onComplete: function() {
            map.gMap('removeAllMarkers');
            window.setTimeout(function() {
                map.gMap('addMarkers', markers2);
                window.setTimeout(function() {
                    map.gMap('changeSettings', {
                      latitude: 'fit',
                      longitude: 'fit'
                    });
                    window.setTimeout(function() {
                        var center = map.data('gmap').gmap.getCenter();
                        ok(Math.abs(center.lat() - (50.083 + 50.502343)/2) &lt; 0.001, 'center latitude correct');
                        ok(Math.abs(center.lng() - (19.917 + 19.75435)/2) &lt; 0.001, 'center longitude correct');
                        start();
                    },1000);
                },1000);
            },1000);
        }
    });
    stop();
});
</pre>
<p>Here all mentioned methods are combined. One array of markers is added, then removed, second one is added and new center calculated. And the best part is that at the every mentioned stage you can add test coverage. I don&#8217;t do it, as I have separated tests for these things, but it&#8217;s possible.</p>
<p>This is probably the best way of dealing with testing and plugins in general. If you or your user at any moment would like to alter configuration, it is the proper way to deal with it. And I&#8217;m so confident about that, because for a long time I encouraged people to get Google Map object and markers from $.data() and manipulate them manually. It&#8217;s not very effective, it&#8217;s slow and forces user to know a lot about programming in general. Your users are not always newbies, but if they are, there is no way they could learn advanced stuff fast enough. Encourage people to find out how your code works, but never force them to do so.</p>
<h2>Bonus: continuous integration</h2>
<p>Just a quick note here. These are two very good tools that you can integrate with your git, or any other, not as good, version control.</p>
<h3>JS test driver</h3>
<p><a href="http://www.smashinglabs.pl/wp-content/uploads/2011/11/Overview.png"><img class="aligncenter size-full wp-image-561" title="JS Test Driver in action" src="http://www.smashinglabs.pl/wp-content/uploads/2011/11/Overview.png" alt="" width="523" height="379" /></a>The image is quite self-explanatory. You push your changes to the repository, JS Test Driver reads source and config, on its server multiple browsers are started, tests are runned and result is sent back. Simple and genius, you don&#8217;t have to start every browser manually and wait for test results.</p>
<p><a href="http://code.google.com/p/js-test-driver/">http://code.google.com/p/js-test-driver/</a></p>
<h3>Testling</h3>
<p>Testling is built on the same concept, but is provided as an SaaS. You send test file in specified format to Testling via wget and you get your reports back. It&#8217;s a paid service, but provides a free account for limited CPU time (30 min, at the moment). If you don&#8217;t want to setup your JS Test Driver, which usually requires separate machine, try Testling.</p>
<p><a href="http://testling.com/">http://testling.com/</a></p>
<h2>Summary</h2>
<p>This is the end of the series, I hope you liked it. On <a href="https://github.com/fridek/smashinglabs-unit-testing-for-jQuery-plugins">my github</a> you can find code for the first two parts. For this one you have to <a href="https://github.com/fridek/gmap/tree/beta">download gMap</a> and tests are here.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/unit-testing-for-jquery-plugins-part-3/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>[PL] meet.js Krakow #3 &#8211; 08.10.2011</title>
		<link>http://www.smashinglabs.pl/pl-meet-js-krakow-3-08-10-2011</link>
		<comments>http://www.smashinglabs.pl/pl-meet-js-krakow-3-08-10-2011#comments</comments>
		<pubDate>Sun, 09 Oct 2011 11:14:14 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[meet.js]]></category>
		<category><![CDATA[polish]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[front-end]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=391</guid>
		<description><![CDATA[8 października w Krakowie odbyło kolejne spotkanie z cyklu meet.js, organizowane przeze mnie, Wojtka Dłubacza i Damiana Wielgosika. Chciałbym zacząć od podziękowania lokalowi który zgodził się nas przyjąć &#8211; Touch Inn. Wybraliśmy miejsce ze względu na fajne ekrany na stołach dzięki którym można zamawiać piwo w sposób odpowiedni dla geeka. Właściciel Touch Inn stanął na wysokości zadania<a href="http://www.smashinglabs.pl/pl-meet-js-krakow-3-08-10-2011">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>8 października w Krakowie odbyło kolejne spotkanie z cyklu meet.js, organizowane przeze mnie, <a title="Wojtek Dłubacz Twitter" href="http://twitter.com/#!/Sahadar">Wojtka Dłubacza</a> i <a title="Blog Damian Wielgosik" href="http://ferrante.pl/">Damiana Wielgosika</a>. <span id="more-391"></span>Chciałbym zacząć od podziękowania lokalowi który zgodził się nas przyjąć &#8211; <a href="http://www.touchinn.pl/">Touch Inn</a>. <a href="http://www.smashinglabs.pl/wp-content/uploads/2011/10/logo-touch-inn.jpg"><img class="aligncenter size-medium wp-image-532" title="logo touch inn" src="http://www.smashinglabs.pl/wp-content/uploads/2011/10/logo-touch-inn-300x61.jpg" alt="" width="300" height="61" /></a>Wybraliśmy miejsce ze względu na fajne ekrany na stołach dzięki którym można zamawiać piwo w sposób odpowiedni dla geeka. Właściciel Touch Inn stanął na wysokości zadania (czego nie mogliśmy ostatnio powiedzieć o Drukarni, meh). Nagłośnienie i obraz były idealne. Trochę doskwierał słaby zasięg wifi i IE7 na stołach, ale postaramy się żeby to się zmieniło następnym razem <img src='http://www.smashinglabs.pl/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  Naszą konferencję wsparło też Lunar Logic Polska, organizator <a href="http://frontrowconf.com/">Front Row Conference</a>, fundując nagrodę w konkursie &#8211; wejściówkę na konferencję. <a href="http://frontrowconf.com/"><img class="aligncenter size-medium wp-image-533" title="logo" src="http://www.smashinglabs.pl/wp-content/uploads/2011/10/logo-e1318104360609-296x300.png" alt="" width="296" height="300" /></a></p>
<h2>jQuery Mobile &#8211; szybko, tanio, prosto&#8230; ale czy na pewno?</h2>
<p>Adrian Gadzina i <a href="http://twitter.com/#!/proprocek">Krzysztof Ścira</a> opowiedzieli o swoich doświadczeniach z jQuery mobile. Prezentacja zwróciła uwagę na wiele problemów z którymi zmaga się projekt (obecnie w wersji RC1). Myślę, że na wyróżnienie (negatywne) zasługują ciągłe zmiany w API, ciężkie stylowanie i chwalenie się na wyrost kompatybilnością z wieloma platformami. Zobaczyliśmy kilka rozwiązań takich problemów, integracje z PhoneGapem i stylowanie elementów. Pod koniec prezentacji znajduje się kod QR z linkiem do przykładowej aplikacji.</p>
<p><a href="http://www.smashinglabs.pl/wp-content/uploads/2011/10/jqm.pdf">Prezentacja (PDF)</a></p>
<h2>Geolocation</h2>
<p><a href="http://twitter.com/#!/lydiawil">Lidia Wilczyńska</a> zaprezentowała krótko tematykę geolokacji. Dowiedzieliśmy się jakie metody działają a jakie nie w przypadku przeglądarek, jak wygląda obiekt pozycji, co można z nim zrobić i jakie metody używać do śledzenia zmian. Został też poruszony ważny temat prywatności w sieci.</p>
<p><a href="http://blog.ily.li/geolocationSlides/">Prezentacja (www)</a></p>
<h2>Responsive Web Design</h2>
<p><a href="http://twitter.com/#!/tglazar">Tobiasz Glazar</a> zaprezentował metody budowania dynamicznych systemów gridowych dla przeglądarek w zróżnicowanych środowiskach. Pokazał kilka problemów (i rozwiązań) skalowania obrazów i serwowania różnego contentu dla różnych ekranów.</p>
<p><a href="http://glazar.me/slides/meetjs/responsive/">Prezentacja (www)</a></p>
<h2>Node.js &#8211; server side javascript</h2>
<p>Maciej Jastrzębski zaprezentował podstawy node.js i jego testy przeprowadzone w Dreamlabie Onetu. Wydajność w porównaniu z Apache + PHP czy Tornado + PyPy była znacząco wyższa. Sam test był bardzo sprytny, zamiast hello world które łatwo cacheować, w teście użyto timestamp serwera aby content był odświeżany za każdym razem. Oprawa graficzna prezentacji jest świetna i dobrze wyjaśnia jak właściwie działa node.js i dlaczego może być o tyle szybszy w niektórych zadaniach.</p>
<p>Bardzo miłą niespodzianką był też mały press release ze strony Onetu &#8211; 1 stycznia 2012 Dreamlab uruchomi Onet.cloud, serwis PaaS, SaaS i IaaS. Prawdopodobnie część backendu będzie oparta właśnie na node.js.</p>
<p>Ta prezentacja wywołała <del>zaciekły flamewar</del> długą dyskusję, argumenty obu stron wyglądały mniej więcej tak: <a href="http://blog.brianbeck.com/post/node-js-cures-cancer">pro1</a>, <a href="http://joshuakehn.com/2011/10/3/Diagnosis-No-Cancer.html">pro2</a>, <a href="http://teddziuba.com/2011/10/node-js-is-cancer.html">con1</a>, <a href="http://teddziuba.com/2011/10/straight-talk-on-event-loops.html">con2</a>. Konkluzja &#8211; node.js jest jeszcze mało dojrzały, ma niewiele stabilnych i dobrych pakietów (pomimo gigantcznego repozytorim npm), ale w wyspecjalizowanych zadaniach jest bardzo szybki i wart użycia.</p>
<p><a href="http://www.smashinglabs.pl/wp-content/uploads/2011/10/meetjs-nodejs-serverside-javascript.ppsx">Prezentacja (pptx)</a> Polecam też <a href="http://it-onet.blogujacy.pl/2011/09/%E2%80%9Ezobaczmy-to-jeszcze-raz%E2%80%9D-%E2%80%93-javascript-i-node-js/">post o node.js</a> na blogu Dreamlabu.</p>
<h2>Asynchroniczna pułapka</h2>
<p>Meet.js został zaplanowany tak, aby poziom trudności kolejnych prezentacji był lekko rosnący. Gdyby jednak chcieć umiejscowić prezentację <a href="http://twitter.com/#!/reinmarpl">Piotrka Koszulińskiego</a> w odpowiednim miejscu, musiałaby być siedemnasta, może osiemnasta w kolejności. Ilość i poziom kodu na slajdach zwalała z nóg, ale dla wytrwałych nagroda była wielka. Piotrek pokazał problemy które spotykamy (głównie korzystając z node.js) przy funkcjach wywoływanych asynchronicznie. Funkcje które powinny być wywoływane równolegle lub sekwencyjnie tworzą zazwyczaj przerażająco zagnieżdżony kod, pełen callbacków i nadmiarowych linijek. Lekarstwem na to mają być biblioteki które ostatnio mnożą się na githubie. Piotrek pokazał bliżej dwie &#8211; <a href="https://github.com/caolan/async">async</a> i <a href="https://github.com/medikoo/deferred">deferred</a>, które systematyzują i upraszczają najczęściej spotykane struktury.</p>
<p>O ile async był prawdopodobnie dla wszystkich zrozumiały, o tyle deferred jest oparty na bardzo magicznych właściwościach JavaScriptu i dla niewprawnego oka wygląda strasznie. Po spokojnym przejrzeniu kodu widać elegancję takiego rozwiązania, więc polecam to wszystkim.</p>
<p><a href="http://reinmar.github.com/meetjs-async/">Prezentacja (www)</a></p>
<h2>Konkurs</h2>
<p>W czasie meet.js zorganizowaliśmy mały konkurs na najlepszy pomysł na grę w przeglądarce. Po dogrywce nagrody zdobyły dwa pomysły:</p>
<ul>
<li>miejsce I i wejściówka na Front Row Conference od Lunar Logic Polska &#8211; Angry Nyan Cat, <a href="http://temporal.pr0.pl/devblog/">Jacek Złydach</a></li>
<li>miejsce II i książka &#8220;<a href="http://www.amazon.com/Essential-Guide-HTML5-Using-JavaScript/dp/1430233834">The Essential Guide to HTML5: Using Games to learn HTML5 and JavaScript</a>&#8221; ode mnie - Sokoban QR, anonimowy uczestnik (proszę o maila jeśli ktoś zna <img src='http://www.smashinglabs.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  )</li>
</ul>
<div>Mam nadzieję, że zwycięzcy zabiorą się jak najszybciej za implementowanie swoich pomysłów i opowiedzą o nich naastępnym razem. Call for papers na kolejny meet.js do <a href="http://twitter.com/#!/Sahadar">Wojtka Dłubacza</a> :)</div>
<div><a href="http://lanyrd.com/2011/meetjs-krakow-3/">I jeszcze link do eventu na lanyrd.com.</a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/pl-meet-js-krakow-3-08-10-2011/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>High quality WebGL learning resources</title>
		<link>http://www.smashinglabs.pl/high-quality-webgl-learning-resources</link>
		<comments>http://www.smashinglabs.pl/high-quality-webgl-learning-resources#comments</comments>
		<pubDate>Thu, 06 Oct 2011 20:02:21 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[javascript]]></category>
		<category><![CDATA[links]]></category>
		<category><![CDATA[WebGL]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=520</guid>
		<description><![CDATA[At last! In my recent post I complained a lot about available tutorials. Now I&#8217;m happy to share with you two sites I&#8217;ve found very useful. Blog-O-Ben &#8211; tutorial On his blog Ben (I couldn&#8217;t find his full name) is posting a series of lessons about WebGL. It&#8217;s similar to learningwebgl.com, but it&#8217;s explained and<a href="http://www.smashinglabs.pl/high-quality-webgl-learning-resources">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>At last! In <a title="What do we need for HTML5 games to be awesome?" href="http://www.smashinglabs.pl/what-do-we-need-for-html5-games-to-be-awesome">my recent post</a> I complained a lot about available tutorials. Now I&#8217;m happy to share with you two sites I&#8217;ve found <span style="text-decoration: underline;">very</span> useful.</p>
<p><span id="more-520"></span></p>
<h2>Blog-O-Ben &#8211; tutorial</h2>
<p>On his blog Ben (I couldn&#8217;t find his full name) is posting a series of lessons about WebGL. It&#8217;s similar to learningwebgl.com, but it&#8217;s explained and structured very well. It involves some <del>basic</del> awesome math that anybody willing to work with 3D simply has to know. For the time being it covers six topics:</p>
<ul>
<li><a title="WebGL Basics 1 – Context in canvas" href="http://blogoben.wordpress.com/2011/03/01/webgl-basics-1-context-in-canvas/">Context in canvas</a></li>
<li><a title="WebGL Basics 2 – White 2D triangle" href="http://blogoben.wordpress.com/2011/03/20/webgl-basics-2-white-2d-triangle/">White 2D triangle</a></li>
<li><a title="WebGL Basics 3 – Rotating triangle" href="http://blogoben.wordpress.com/2011/04/11/webgl-basics-3-rotating-triangle/">Rotating triangle</a></li>
<li><a title="WebGL Basics 4 – Wireframe 3D object" href="http://blogoben.wordpress.com/2011/04/16/webgl-basics-4-wireframe-3d-object/">Wireframe 3D object</a></li>
<li><a title="WebGL Basics 5 – Full transformation matrix" href="http://blogoben.wordpress.com/2011/06/05/webgl-basics-5-full-transformation-matrix/">Full transformation matrix</a></li>
<li><a title="WebGL Basics 6 – Torus-shaped strip" href="http://blogoben.wordpress.com/2011/06/22/webgl-basics-6-torus-shaped-strip/">Torus-shaped strip</a> (types of draw call explained <a href="http://blogoben.googlecode.com/svn/trunk/webgl-basics/part-6-strip-torus.html">in the example</a>)</li>
</ul>
<p>It is exactly what I was looking for &#8211; very thorough and not avoiding difficult parts. I hope it will grow soon and cover more topics. For now it is about less complex things that those covered in learningwebgl.com, but it&#8217;s a great way to start.</p>
<h2>A3 &#8211; new rendering framework</h2>
<p>While I have almost nothing to say about A3 itself (but I&#8217;ll dig into it), I would like to point your attention at videos on framework page. They show how the engine was designed and they are really worth watching. There are only two for now &#8211; introduction and vectors &#8211; but I&#8217;m waiting for more! It&#8217;s like 101 course to 3D engine math with examples in JS and some important explanations. Also, a guy who records them is a little bit crazy, so it&#8217;s fun to watch.</p>
<p><a href="http://aerotwist.com/a3/">http://aerotwist.com/a3/</a></p>
<p>So, that&#8217;s it! Two websites, one for hardcore math nerds and the other one for fun math nerds. Check them out.</p>
<p>&nbsp;</p>
<p>UPDATE:</p>
<p>It&#8217;s not pure WebGL, but if you are lazy and not willing to ever write your own engine, go with <a href="https://github.com/mrdoob/three.js">three.js</a>, <a href="http://www.aerotwist.com/lab/getting-started-with-three-js/">basic tutorial</a> for it and then <a href="http://learningthreejs.com/">http://learningthreejs.com/</a> for further ideas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/high-quality-webgl-learning-resources/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Poland has joined the no-IE6 club</title>
		<link>http://www.smashinglabs.pl/poland-has-joined-the-no-ie6-club</link>
		<comments>http://www.smashinglabs.pl/poland-has-joined-the-no-ie6-club#comments</comments>
		<pubDate>Sun, 02 Oct 2011 17:01:33 +0000</pubDate>
		<dc:creator>Sebastian Poręba</dc:creator>
				<category><![CDATA[polish]]></category>

		<guid isPermaLink="false">http://www.smashinglabs.pl/?p=510</guid>
		<description><![CDATA[I&#8217;m happy to announce that, according to http://www.ie6countdown.com, Polish IE6 usage has dropped below 1% in September. Among other countries (Norway, Finland, Denmark, Sweden) which already have passed this limit, we are the first with over 10M internet users. But before we could open a bottle of champagne, take a look at our local, not-so-optimistic statistics. IE6 still<a href="http://www.smashinglabs.pl/poland-has-joined-the-no-ie6-club">&#160;&#160;[ Read More ]</a>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m happy to announce that, according to <a href="http://www.ie6countdown.com/">http://www.ie6countdown.com</a>, Polish IE6 usage has dropped below 1% in September.</p>
<p><span id="more-510"></span></p>
<p>Among <a href="http://www.ie6countdown.com/champions.aspx">other countries</a> (Norway, Finland, Denmark, Sweden) which already have passed this limit, we are the first with over 10M internet users.</p>
<div id="attachment_511" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.smashinglabs.pl/wp-content/uploads/2011/10/die-ie6-die-by-Mike-Rohde-434x366.png"><img class="size-medium wp-image-511" title="«Die IE6, DIE!» By Mike Rohde (rohdesign.com). Sous Licence CC." src="http://www.smashinglabs.pl/wp-content/uploads/2011/10/die-ie6-die-by-Mike-Rohde-434x366-300x252.png" alt="«Die IE6, DIE!» By Mike Rohde (rohdesign.com). Sous Licence CC." width="300" height="252" /></a><p class="wp-caption-text">«Die IE6, DIE!» By Mike Rohde (rohdesign.com). Sous Licence CC.</p></div>
<p>But before we could open a bottle of champagne, take a look at our <a href="http://ranking.pl/en/rankings/web-browsers.html">local, not-so-optimistic statistics</a>. IE6 still has around 1.5% and IE9 has only 3% of the market. This numbers are improving, as more and more people move from older versions to IE9 or to better browsers <img src='http://www.smashinglabs.pl/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  but still, only 3%? Microsoft, it&#8217;s really time to force (or at least strongly encourage) browser updates.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.smashinglabs.pl/poland-has-joined-the-no-ie6-club/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

