Category Archives: Code
MAR 21
Code Javascript

USING SENCHA TOUCH COMPONENTS AS BUTTONS

The documentaiton for the Sencha Touch framework can often be a bit sparse. Case in point: the typical way to make a button inside a container is:

var buttonContainer = Ext.create('Ext.Container', {
	width: '100%',
	height: '100%',
	items: [
		{
			xtype: 'button',
			width: '100',
			height: 40,
			text: 'OK',
			listeners: {
				tap: function() {
					// Do something
				}
			}
		}
	]
});

This is all well and good, if you want to make buttons that adhere strictly to the Sencha framework. But what if you want to make something that you have a little more visual control over, say a container, respond to mouse events?

The previous recommended behavior was to hook into the components ‘initialize’ method, which enabled you to attach listeners to that component. That works fine – as long as you don’t build your project. When the project is built, the references to initialize don’t get called anymore (I lost quite a few hairs trying to figure that one out). Instead, the correct method is:

var buttonContainer = Ext.create('Ext.Container', {
	width: '100%',
	height: '100%',
	items: [
		{
			text: 'Element 1',
		},
		{
			text: 'Element 2',
		},
		{
			text: 'Element 3',
		}
	],
	listeners: {
		tap: {
	        fn: function() {
				// Do Something			
	        },
	        element: 'element'  // The special sauce that gives the listener its reference
	    },
	}	
});
0
NOV 9
Code Games Javascript

There are a few ways you can handle authentication when making an HTML5 Facebook app. Facebook has relatively mature APIs in both PHP and Javascript for interacting with its backend Open Graph API. Whether you want to go PHP or Javascript depends on your comfort with the language and the resulting medium. For apps that will use Facebook as a merely a login system and live on a non-Facebook page, PHP seems to be relatively painless. ┬áBut for apps that will live solely on Facebook pages, the Javascript API is essential (if you’re curious why, check beneath the code).

The code (heavily commented) is as follows:

<html>
	<head>
		<title>JS Test</title>
		<script src="//connect.facebook.net/en_US/all.js"></script>
  		<script src="http://code.jquery.com/jquery-latest.js"></script>
	</head>
 
	<body>
		<div id="fb-root"></div>
		<script>
			window.fbAsyncInit = function() {
				FB.init({
					appId      : 'YOUR APPLICATION ID', // Insert your App ID here
					status     : true, // check login status
					cookie     : true, // enable cookies to allow the server to access the session
					oauth      : true, // enable OAuth 2.0
					xfbml      : true  // parse XFBML
				});
 
			    /*** Initialization code here ***/
 
				// Get the users login status
				FB.getLoginStatus(function(response) {
					if (response.authResponse) {
						// Logged in and connected user, someone you know
						console.log("User is logged in");
						loginToFacebook();  // Pass directly to login so we can get the users name and email (at this point we only have the facebook ID)
					} else {
						// No user session available, someone you dont know
						console.log("User is NOT logged in");				
						showLogin();
					}
				});
			};  // End Facebook async login
 
		  // Load the SDK Asynchronously
			(function(d){
				var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
				js = d.createElement('script'); js.id = id; js.async = true;
				js.src = "//connect.facebook.net/en_US/all.js";
				d.getElementsByTagName('head')[0].appendChild(js);
			}(document));
		</script>		
 
		<script>
			/*** USER TRIGGERED JS ***/
			var username = '';
			var userid = '';
			var userEmail = '';	
 
			function loginToFacebook() {
				console.log('Login to facebook');
				// Login
				FB.login(function(response) {
					if (response.authResponse) {
						console.log('Welcome!  Fetching your information.... ');
						FB.api('/me', function(response) {
							console.log('Good to see you, ' + response.name + ', ' + response.email + '.');
							username = response.name;
							userid = response.id;
							userEmail = response.email;
 
							showLobby(response.id, response.name, response.email);
						});
					} else {
						console.log('User cancelled login or did not fully authorize.');
						showErrorScreen();
					}
				}, {scope: 'email'});
			}
 
			function showLogin() {
				// Get DOM elements to show/hide
				var lobby = document.getElementById("lobby");  
				var login = document.getElementById("login");  
 
				lobby.style.display = 'none';  // Show the lobby
				login.style.display = 'block	';  // Show the lobby
			}
 
			function showLobby(facebookID, name, email) {
				console.log('showLobby -> ' + facebookID, name, email);
 
				// Get DOM elements to show/hide
				var lobby = document.getElementById("lobby");  
				var login = document.getElementById("login");  
				lobby.style.display = 'block';  // Show the lobby
				login.style.display = 'none';  // Show the lobby				
			}
			function showErrorScreen() {
				console.log('showErrorScreen');
			}
			</script>
 
		<div id="login" style="display:none;">
			<a href="#" onClick="loginToFacebook()">Login to the application</a>
		</div>
 
		<div id="lobby" style="display:none;">
			Game screen goes here
		</div>
	</body>
</html>
One Note:

You might be asking yourself – Why is there a login screen at all? Can’t you just trigger the login method if you don’t get back any information on the user? Unfortunately, you can’t (that violates security parameters within the site).

Testing

After you get everything rolling with your code, there are eight use cases you should be aware of when testing your application.

HTTP

  • User is logged in to Facebook
    • User has authorized the application
    • User hasn’t authorized the application
  • User is not logged in to Facebook
    • User has authorized the application
    • User hasn’t authorized the application

HTTPS

  • User is logged in to Facebook
    • User has authorized the application
    • User hasn’t authorized the application
  • User is not logged in to Facebook
    • User has authorized the application
    • User hasn’t authorized the application

Why the Javascript API is essential

Essential? Sounds so – absolute. Here’s why.

Assume you’ve got a Facebook app that you want surfaced solely on apps.facebook.com/myBitchinApp. That app has to be hosted on some personal domain somewhere – probably something like http://www.myRadSite.com/myBitchinApp/. The annoying thing about the PHP API is that when you do the authentication call (from either the Facebook or your personal domain), the redirect_uri parameter will *always* redirect the user back to the personal domain. If you try to set the redirect_uri parameter manually back to apps.facebook.com/myBitchinApp, you’ll find you get a Facebook error that you don’t have access to the domain. Boo hiss.

1
NOV 17
Code Flash

Dealing with PNG images in Flash can sometimes be a pain, especially if you want to scale their bitmapData. The problem is that Flash uses bilinear interpolation to shrink images down, and once you get below 50%, there can be some nasty artifacts. The workaround I discovered this week gets around a lot of these problems – progressive bilinear interpolation.

Many thanks to Maxime Cousinou who figured this out initially. The image on the left has been shrunk to 13% without progressive filtering – the one on the right has been stepped down in 50% increments.

Better Scaling

I’ll take the one on the right. ┬áCode as follows, and you can download a sample here.

var typicalScaling:Sprite = new Sprite();
addChild(typicalScaling);

var modifiedScaling:Sprite = new Sprite();
modifiedScaling.x = 235;
modifiedScaling.y = 5;
addChild(modifiedScaling);

loadTypicalImage();
loadModifiedImage();

function loadTypicalImage():void {
	var loader:Loader = new Loader();
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onTypicalLoaderComplete);
	loader.load(new URLRequest('rgbLogo.png'));
}

function onTypicalLoaderComplete(e:Event):void {
	var scalingMatrix:Matrix = new Matrix();
	scalingMatrix.scale(.15, .15);
	var loadedImage:Bitmap = Bitmap(e.target.content);  // Cast the loaded content as a bitmap
	var bitmapData:BitmapData = new BitmapData(loadedImage.width, loadedImage.height, true, 0);
	bitmapData.draw(loadedImage, scalingMatrix, null, null, null, true);
	var tempBitmap:Bitmap = new Bitmap(bitmapData);
	typicalScaling.addChild(tempBitmap);
}

function loadModifiedImage():void {
	var loader:Loader = new Loader();
	loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onModifiedLoaderComplete);
	loader.load(new URLRequest('rgbLogo.png'));
}

function onModifiedLoaderComplete(e:Event):void {
	var loadedImage:Bitmap = Bitmap(e.target.content);  // Cast the loaded content as a bitmap
	var bitmapData:BitmapData = new BitmapData(loadedImage.width, loadedImage.height, true, 0);
	bitmapData.draw(loadedImage, new Matrix(), null, null, null, true);
	var tempBitmap:Bitmap = new Bitmap(resampleBitmapData(bitmapData,.15));
	modifiedScaling.addChild(tempBitmap);
}

function resampleBitmapData (bmp:BitmapData, ratio:Number, transparent:Boolean = true):BitmapData {
	if (ratio >= 1) {
		return (resizeBitmapData(bmp, ratio, transparent));
	}
	else {
		var bmpData:BitmapData 	= bmp.clone();
		var appliedRatio:Number = 1;

		do {
			if (ratio < 0.5 * appliedRatio) {
				bmpData = resizeBitmapData(bmpData, 0.5, transparent);
				appliedRatio = 0.5 * appliedRatio;
			}
			else {
				bmpData = resizeBitmapData(bmpData, ratio / appliedRatio, transparent);
				appliedRatio = ratio;
			}
		} while (appliedRatio != ratio);
	return (bmpData);
	}
}

function resizeBitmapData (bmp:BitmapData, ratio:Number, transparent:Boolean = true):BitmapData {
	var bmpData:BitmapData = new BitmapData(Math.round(bmp.width * ratio), 
                                                Math.round(bmp.height * ratio), transparent, 0x00FFFFFF);
	var scaleMatrix:Matrix = new Matrix(bmpData.width / bmp.width, 0, 0, bmpData.height / bmp.height, 0, 0);
	var colorTransform:ColorTransform = new ColorTransform();
	bmpData.draw(bmp, scaleMatrix, colorTransform, null, null, true);

	return (bmpData);
}
0
OCT 27
Code

I work with a lot of clients who are really visually oriented and minimal. Especially in their shops, the more screen real-estate that’s taken up by their imagery, the better. To that end, I came up with a method of making interesting store elements that maximizes the amount of space each image gets, while not sacrificing information that customers need to make their decisions.

You can see the effect here:

The code is relatively straightforward – you start with HTML markup that creates a elements for the image and info boxes, wrapped by a containing div:

<div class="store_element">
  <a href="#" title="Echo Bloom Presents Jamboree"><i mg src="/oneoffs/media/images/echobloom_jamboree.jpg" /></a>
  <div class="element_info">
    <a href="#"><span class="element_title">Echo Bloom Presents Jamboree</span>
    <span class="element_price">$10.00</span></a>
  </div>
</div>

The element_title and element_price pieces then only need to be correctly aligned to function correctly:


.element_info {
  position: relative;
  top: -288px;
  color: #fff;
  display: none;
  font-weight: bold;
}

.element_info a {
  color:#FFF;
}

.element_title {
  background-color:#333;
  display:block;
  padding:5px;
  width:240px;
  height:auto;
}

.element_price {
  background-color:#333;
  display:block;
  float:right;
  position:relative;
  top:100px;
  padding:5px;
  width:70px;
  height:auto;
  text-align:center;
}

The result allows you to tile elements in a store without having to make room for a ‘Buy’ button or include additional space for text descriptions – perfect for minimal layouts.

You can download the code for this here.

0
OCT 26
Code Tools

Ever wonder how your blog, with an address like http://www.yerblog/2010/10/26/Yer-Post-Title actually got that content? There isn’t an actual directory there – how does it work?

mod_rewrite rewrites a URL at the server level to load content different from what the URL is telling you. For example – a page could display the URL http://www.bloomfoundry.com/bands/accadacca – BUT IN REALITY the page is really loading from http://www.bloomfoundry.com/bands.php?asskickingrockers=accadacca. Pretty clever.

There are some things you need to do at the server level to enable it for your site. If you’re running a LAMP stack, you need the mod_rewrite module installed on your Apache server. If you’re using a hosting company, check with them (it was on for my rented space by default).

The actual code goes into the .htaccess file that’s at the root of your directory. A simple example would be something like:

RewriteEngine on
RewriteRule ^red.html$ green.html

With this, any time you load the URL red.html, you’d be loading CONTENT from green.html. Nobody would be any the wiser. If you wanted to let your users know that something was changing, you can insert a flag after the command to let them know chicanery’s happening under the surface. That would look like:

RewriteEngine on
RewriteRule ^red.html$ green.html [R]

With this, any time you load the URL red.html, you get redirected to green.html at the server level. It’s darn cool stuff, and you can do some really complex, interesting things with it. Here are some resources:

0