Monitoring your brand online with mention - mention.net

I recorded the following quick screencast to show you how to Monitor your brand or certain keywords using mention.net 

 


Flash Actionscript3 Parallax effect

Parallax effect is widely used in games but its also used in websites to give that awesome feel to it... its not just like you would just use it because its cool but you'll have to define the purpose behind using it ( it might be just useless ).

below is a demo of one way of doing it, i might do another one that wont require greensock or any tweening engine to get the same effect, & by the way im using TweenNano which is a very light version of TweenMax.

Edit:

 

 
Demo | Download

 

import com.greensock.TweenNano;
import com.greensock.easing.*;

//ease type
var easeType = Expo.easeOut;
//xmouse will hold x position of the mouse in relation to the center of the stage.
//assuming that the stage center's value is 0;
var xmouse:Number = 0;
// percentage of the xmouse position
var xPct:Number = 0;
// speed or durationl
var speed:Number = 2;

// add event listener based on mouse movement
stage.addEventListener(MouseEvent.MOUSE_MOVE, render);

function render(e:MouseEvent):void
{
	//if xmouse pos is greater than the center of the stage
	if( e.stageX > stage.stageWidth/2) {

		xmouse= -(e.stageX -stage.stageWidth) - stage.stageWidth/2; //-512

	}
	else
	{
		xmouse = ((stage.stageWidth/2) - e.stageX); //512

	}

	xPct = Math.round ((xmouse/stage.stageWidth) * 200);

	//where will the sky moveclip move to...
	var skyXto:Number = ((xPct/100) * (sky_mc.width - stage.stageWidth)/2) + stage.stageWidth/2;

	TweenNano.to(sky_mc,speed, {x:skyXto, ease:easeType});

	var fieldXto:Number = ((xPct/100) * (field_mc.width - stage.stageWidth)/2) + stage.stageWidth/2;

	TweenNano.to(field_mc,speed, {x:fieldXto, ease:easeType});

	var grassXto:Number = ((xPct/100) * (grass_mc.width - stage.stageWidth)/2) + stage.stageWidth/2;

	TweenNano.to(grass_mc,speed, {x:grassXto, ease:easeType});

}

Twitter & Flash AS3 fun experiment

 
 
Demo | Download

 

note: this wont work for protected accounts, it'll require authentication.

neat yeah? :-) buggy though, you may download the source code and improve it anyway you could!

in a nutshell, Im using PHP to receive data from flash & send it over to twitter via an API call and then send back the received XML to flash,

twitter.as

package {
	import flash.display.*;
	import flash.events.*;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.Security;
    import flash.net.URLVariables;
	import flash.net.*;

	public class Twitter extends MovieClip {
		private var cont:MovieClip;
		public var speed:Number=-6;
		private var menu:Array = new Array();
		//Security.allowDomain("twitter.com");

		public function Twitter():void {
			//create a new container ( a movieclip )
			cont = new MovieClip();
			// set its x and y
			cont.x=stage.stageWidth*0.5;
			cont.y=(stage.stageHeight*0.5);
			// add it to the stage
			addChild(cont);
			//attach an event listener
			addEventListener(Event.ENTER_FRAME, render);
			//attach an event listener to the "go" button
			go.addEventListener(MouseEvent.CLICK,loadTweets)
		}

		private function loadTweets(E:Event):void{
			loading_mc.alpha = 1;
			//PHP path or full path
			var url:String = "proxy.php";
			//Grab the twitter handle
			var tweetHandle:String = handle.text;
			//declare variables
			var myVars:URLVariables = new URLVariables();
			//assign variables
			myVars.user = tweetHandle;
			//create a new request
			var Request:URLRequest = new URLRequest();
			//assign request url
			Request.url = url;
			//define the methiod ( GET or POST )
			Request.method = URLRequestMethod.POST;
			//attach the variables to the request
			Request.data = myVars;
			//create a kiader for the request
			var tweetXmlLoader:URLLoader = new URLLoader();
			//define the data format
			tweetXmlLoader.dataFormat = URLLoaderDataFormat.TEXT;
			// attach an event listener
			tweetXmlLoader.addEventListener(Event.COMPLETE, generateTweets);
			//time for action!
			tweetXmlLoader.load(Request);
			//remove unwanted library items and ditach unused events listeners
			go.enabled = false;
			go.removeEventListener(MouseEvent.CLICK, loadTweets);
			removeChild(go);
			removeChild(handle);

		}

		public function generateTweets(e:Event):void {
			//remove "loading tweets" movieclip from stage
			removeChild(loading_mc);
			//define an XMLList and assign the new received data to it
			 var tweetXML:XMLList = new XMLList(e.target.data );
				// loop em BABY!
				 for (var i:uint=0; i<10; i++) {
				//grab a tweetbox from the library ( runtime loading ) see export for more info.
				 var t:MovieClip = new tweetBox();
				 //assign the status ( tweet ) to the text within the tweetBox
				 t.txtBox.text = tweetXML.status[i].text
				 //just to check
				 trace (tweetXML.status[i].text);
                 // assign a z prop ( focal length ) how close/far is each box
				 t.z=3000-(i*400);
				 // add it to the container we created earlier
				 cont.addChild(t);
				//push the movieclip to use it on the Event.ENTER_FRAME function ( render )
				 menu.push(t);
			 }

		}

		function render(e:Event):void {
			// loop through menu
			for(var j:int=menu.length-1;j>=0;j--) {
				//increase the z prop!
				menu[j].z+=speed;

				// if item in menu Z prop is greater less than 600 then take it back to 3400
				if (menu[j].z<-600){
					menu[j].z=3400;
				}
			}
		}
	}
}

Now for the PHP part ... you may also consider using the php function "readfile" instead if cURL, I just felt like testing it!

<?php

$url = $_POST['user'];

$curl_handle=curl_init();
curl_setopt($curl_handle,CURLOPT_URL,'https://api.twitter.com/1/statuses/user_timeline.xml?screen_name='.$url);
curl_setopt($curl_handle,CURLOPT_CONNECTTIMEOUT,2);
curl_setopt($curl_handle,CURLOPT_RETURNTRANSFER,1);
$buffer = curl_exec($curl_handle);
curl_close($curl_handle);

if (empty($buffer))
{
    print "Sorry, Moe is a sicko!.<p>";
}
else
{
    print $buffer;
}
?>

 


Google maps application with actionscript 3 for android ( AIR )

What are we building:

-

Download the source code here Download

What is required?

  1. Install google maps api for flash ( Emanuele Feronato tutorial )
  2. Flash IDE ( Ability to compile & export apk for android ) Im currently using flash CS5
  3. AS3 knowledge ( duh )

once you install google maps api for flash, navigate to the components and drag out a GoogleMapsLibrary component to the library.

Under the document class enter Main ( the external AS3 file ) which we'll be having the code in.

Save the Fla file and in the same directory create an AS file and save it as Main.as, Copy & Paste the following code in Main.as :

package  {

	//Flash imports
	import flash.display.MovieClip;
	import flash.sensors.Geolocation;
	import flash.events.GeolocationEvent;
	import flash.geom.Point;
	import flash.events.Event;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.text.TextField;
	import flash.text.TextFormat;
	//Google maps imports
	import com.google.maps.LatLng;
	import com.google.maps.Map;
	import com.google.maps.MapEvent;
	import com.google.maps.MapType;
	import com.google.maps.controls.ZoomControl;
	import com.google.maps.controls.MapTypeControl;
	import com.google.maps.overlays.Marker;
	import com.google.maps.overlays.MarkerOptions;
	import com.google.maps.MapMouseEvent;
	import com.google.maps.InfoWindowOptions;

	public class Main extends MovieClip {
		//declare map
		public var map:Map;
		//declare geilocation
		private var myLoc:Geolocation;
		//declare marker
		private var marker:Marker;
		private var myText:TextField;
		public var format:TextFormat;

		public function Main() {
			// constructor code

			super();
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;

			addEventListener(Event.ADDED_TO_STAGE, init);

		}//main ends

		private function init(e:Event):void
		{
			removeEventListener(Event.ADDED_TO_STAGE, init);

			map = new Map();
			map.key = "ABQIAAAAYE0bGtlAc2aNHkbZAX8d5xTtk0dF-T8JMCdCfbxeilM7kTvGfhSLRtD2VK3FR9ecXk7jWpMWxZuZvw";
			map.sensor = "false";
			map.url = "http://www.zainals.com";
			map.setSize(new Point (stage.stageWidth, stage.stageHeight));
			addChildAt( map, 0 ) ;
			map.addEventListener(MapEvent.MAP_READY, onMapReady);

			txtField();

		}//init ends 

		private function onMapReady(e:MapEvent):void
		{
				map.addControl (new ZoomControl()  );
				map.addControl (new MapTypeControl() );
				map.setCenter( new LatLng( 26.116602, 50.482178), 14, MapType.SATELLITE_MAP_TYPE);

				if(Geolocation.isSupported) {

					myLoc = new Geolocation();
					myLoc.addEventListener(GeolocationEvent.UPDATE, onGeoUpdate);
					myLoc.setRequestedUpdateInterval(100);

				}

		}//onMapReady Ends

		private function onGeoUpdate(e:GeolocationEvent):void
		{
				map.setCenter( new LatLng( e.latitude, e.longitude), 18, MapType.SATELLITE_MAP_TYPE);
				setMarker( new LatLng(e.latitude, e.longitude));

		}//onGeoUpdate ends

		private function txtField():void
		{
			format = new TextFormat();
			format.size = 20;
			format.align = "center"
			format.font = "Verdana"
			format.color = 0xffffff;

			myText = new TextField();
			myText.width = stage.stageWidth
			myText.height = 40;
			myText.background = true;
			myText.backgroundColor = 0x000000;
			myText.y= 0;
			myText.text = "initializing GMAPS";
			addChild(myText);
			myText.setTextFormat(format);
		}//txtField

		private function setMarker(p:LatLng):void
		{
			if (marker){

				marker.setLatLng(p);

			}else {

			marker = new Marker(p);
			map.addOverlay(marker);
			marker.addEventListener(MapMouseEvent.CLICK, showInfo);

			}//if else ends

			myText.htmlText = p.toString();
			myText.setTextFormat(format);

		}//setMarker Ends

		private function showInfo(e:MapMouseEvent):void
		{

		var markerContent:String = marker.getLatLng().toString();
		marker.openInfoWindow( new InfoWindowOptions({contentHTML: markerContent}));

		}//showinfo ends

	}//class ends

}//package ends

dont forget to set application permissions:AIR for Android settings > Permissions & tick:

  • Internet
  • Access fine location

QuickSand tutorial - Create a filterable portfolio

Its been a while since I wrote my last tutorial in 2007 " play youtube videos in flash tutorial "and now im back with a different topic jQuery *tsk tsk* now lets get started!

What we are trying toachieveis a filterable portfolio based on its categories ( all, web & print ) using quicksand and jQuery...

Demo | Download

Download required files first:

  1. jQuery 1.3+
  2. QuickSand Plugin
  3. jQuery easing ( yes Robert Penners )
  4. Rotation and Scaling Plugin

The HTML:

i omitted the head section with the includes, you can find it in the source code downloadable above!

[cc lang="html" tab_size="2" lines="60"]

[/cc]

A closer look at the filter menu:

[cc lang="html" tab_size="2" lines="2"]

  • web
  • [/cc]

    Notice that i added a title attribute for each, in our case here the title attribute is "web", which will be pulled by jQuery later in a conditional statement...

    A closer look to the list items of the portfolio:

    [cc lang="html" tab_size="2" lines="2"]

  • [/cc]

    notes the [data-id="id-1"] which is used for sorting and the [data-type="web"] used for filtering

    The CSS:

    Nothing fancy below just few lines of basic CSS styling

    [cc lang="css" tab_size="2" lines="10"]
    #content {width:960px; border: 1px solid #ddd; margin-left: auto ; margin-right: auto ; overflow:hidden; height:auto;}
    #content ul { float:left;}
    #content li { float:left; padding:3px; list-style:none; overflow:hidden;}
    .box { width: 950px;}
    [/cc]

    And finally The jQuery "sortable.js":

    [cc lang="jquery" tab_size="2" lines="60"]
    $(document).ready(function() {
    // Custom sorting plugin // --- No Need to edit this ---\\
    (function($) {
    $.fn.sorted = function(customOptions) {
    var options = {
    reversed: false,
    by: function(a) { return a.text(); }
    };
    $.extend(options, customOptions);
    $data = $(this);
    arr = $data.get();
    arr.sort(function(a, b) {
    var valA = options.by($(a));
    var valB = options.by($(b));
    if (options.reversed) {
    return (valA < valB) ? 1 : (valA > valB) ? -1 : 0;
    } else {
    return (valA < valB) ? -1 : (valA > valB) ? 1 : 0;
    }
    });
    return $(arr);
    };
    })(jQuery);

    //---------------------------------------- EDIT BELOW ------------------------------\\

    // Filter Handler
    var $filter = $('#menu a');

    // define portfolio "#div" with the portfolio list ( li ) elements in
    var $portfolio = $('#content #items');

    // clone the "#div"
    var $data = $portfolio.clone();

    // attempt to call Quicksand on every click event handler
    $filter.click(function(e) {

    //check if the title attr is set to "all"
    if ($($(this)).attr("title") == 'all') {

    //if all then show all list ( li )
    var $filteredData = $data.find('li');

    } else {

    //get the title attribute dynamically using $(this)
    var $filteredData = $data.find('li[data-type=' + $($(this)).attr("title") + ']');

    }
    // finally, call quicksand and dump the $fileredData in
    $portfolio.quicksand($filteredData, {
    duration: 800,
    easing: 'easeInOutQuad'
    });

    });
    });
    [/cc]

    A closer look at the jQuery code :

    the code below defines $filter, thats where the filter requests will come from based on clicks, now remember that each link element has a unique title attribute.

    [cc lang="jquery" tab_size="2" lines="5"]
    var $filter = $('#menu a');
    [/cc]

    This one defines the path to the portfolio list and adds it to $portfolio

    [cc lang="jquery" tab_size="2" lines="5"]
    var $portfolio = $('#content #items');
    [/cc]

    Clone the portfolio list

    [cc lang="jquery" tab_size="2" lines="5"]
    var $data = $portfolio.clone();
    [/cc]

    Add/bind a click event to the function where it first checks if the button/link which was clicked has the "all" attribute, if its true then it will locate all list elements and adds it to $filteredData, if it was false then it will grab the title attribute dynamically, it will then find lists with the similar title attributes and adds it to the $filteredData .

    [cc lang="jquery" tab_size="2" lines="6"]
    $filter.click(function(e) {
    if ($($(this)).attr("title") == 'all') {
    var $filteredData = $data.find('li');
    } else {
    var $filteredData = $data.find('li[data-type=' + $($(this)).attr("title") + ']');
    }
    [/cc]

    time for some magic *tada* call the quicksand and pass it the $filteredData along with Duration & easing type.

    [cc lang="jquery" tab_size="2" lines="5"]
    $portfolio.quicksand($filteredData, {
    duration: 800,
    easing: 'easeInOutQuad'
    });
    [/cc]

    Happy filtering :-)


    custom fields problem fix - wordpress

    Okay, i have been pulling my hairs since yesterday ( whatever left of it at least ) trying to solve this issue!

    Scenario:

    You login to the admin panel in wordpress to publish a new post or page with custom fields, you enter the custom field key and value then click "add custom field" button but nothing happens, the truth is it actually inserts the key and the value, the problem is there is no Ajax/Jquery visual feedback .

    By examining the console window using firebug, you'll get the following when clicking the button:

    XML or text declaration not at start of entity
    [Break on this error] ... position='1'>< ![CDATA[

    Solution:

    Believe it or don't, if you have been working on the file function.php make sure you remove extra line breaks top to bottom!
    And yeah im serious! Extra line breaks were the reason why custom fields were misbehaving!