Archive for the ‘Interactive’ Category

Coding as an organic, creative, and cathartic process

Worth posting it.

Quote from Processing: creative coding and computational art by Ira Greenberg:

“When I tell people I write code as my main artistic medium, they smile politely and quickly
change the subject, or they tell me about their job-seeking cousin who makes videos using
iMovie.
For nonprogrammers, code is a mysterious and intimidating construct that gets
grouped into the category of things too complicated, geeky, or time-consuming to be
worth learning.
At the other extreme, for some professional programmers, code is seen
only as a tool to solve a technical problem—certainly not a creative medium.
There is another path—a path perhaps harder to maneuver, but ultimately more rewarding
than either the path of avoidance or detachment—a holistic “middle” way.
This is the path the book promotes; it presents the practice of coding as an art form/art practice,
rather than simply a means to an end. Although there are times when a project is scoped
out, and we are simply trying to implement it, most of the time as artists, we are trying to
find our way in the process of creating a project.
This approach of finding and searching is one of the things that makes the artist’s journey distinctive
and allows new unexpected solutions to be found. It is possible to do this in coding as well, and the
Processing language facilitates and encourages such a “creative coding” approach.”

No Comments


HDVideoPlayer class

I worked on a project where I built a video player. So far, nothing out of normality.
The issue was that we decided to set up the video dimensions on the Flash side rather than in the CMS with checkboxes or something similar.

Video dimensions vary in width and height, but also in proportion, or aspect ratio.

Wiki video standards chart

The client had all sorts of videos, 640 x 480, 400 x 300, 1280 x 720, etc.
The solution is to detect the file dimensions in an onMetaData event handler and set your visual elements accordingly.
For wide screen mode I decided to draw the black stripes on top and bottom.
I use the NetStream and NetConnection objects to handle the video file.

Preview:
HD video player

Here is the source code for the video player class.

HDVideoPlayer.as:

package src{

	/*Import*/

	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
        import flash.text.TextFormat;
	import flash.media.SoundTransform;
	import flash.media.Video;
	import flash.net.NetConnection;
	import flash.net.NetStream;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;

	import caurina.transitions.*;
	import caurina.transitions.properties.ColorShortcuts;

	/*Class*/
	public class HDVideoPlayer extends MovieClip {

		/*Properties*/
		private var mVideo:Video;
		private var ncVideo:NetConnection = new NetConnection();
		private var nsVideo:NetStream;
		private var netClient:Object = new Object();
		private var mySound:SoundTransform;
		private var videoDuration:Number;
		private var actualTime:Number = 0;
		private var actualTimeDragger:Number;
		private var actualLength:Number;
		private var volPercentage:Number;
		private var pctLoaded:Number;
		private var pctPlayed:Number;
		private var dragTime:Number;
		private var videoURL:String  = new String();
		private var MODE:String;

		private var mBG:Sprite = new Sprite();
		private var mBlackStripes:Sprite = new Sprite();
		private var mBGBar:Sprite = new Sprite();
		private var mProgressBar:Sprite = new Sprite();
		private var mLoadBar:Sprite = new Sprite();
		private var mDragger:Sprite = new Sprite();
		private var mControl:MovieClip = new MovieClip();
		private var mPlay:PlayPause = new PlayPause();
		private var mStop:Stop = new Stop();
		private var mVolume:Volume = new Volume();
		private var bFull:Full = new Full();
		private var bBack:Back = new Back();

		private var tAlert:TextField;
		private var format:TextFormat = new TextFormat();
		private var volEquation:Number;
		private var videoWidth:Number;
		private var videoHeight:Number;
		private var ratio:Number;
		private var diffDragger:Number = 0;
		private var overColor:uint;

		/*Constructor*/
		public function HDVideoPlayer(fileData:Object):void{
			trace("//---> HDVideoPlayer");
			videoURL = fileData.file;
			overColor = 0xFFFFFF;
			ColorShortcuts.init();
			addEventListener(Event.ADDED_TO_STAGE, init);
		};

		private function init(e:Event):void{
			removeEventListener(Event.ADDED_TO_STAGE, init);
 			addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
			buildVideo();
		};

		private function removedFromStage(e:Event):void{
			trace("// ---- HDVideoPlayer removed from stage");
			mySound.volume = 0;
			nsVideo.soundTransform = mySound;
			nsVideo.close();
			ncVideo.close();
			mVideo.clear();
			mVideo.alpha = 0;
			removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
		};

		public function buildVideo ():void{

			MODE = "SD";

			mBG.graphics.beginFill(0x231F20, 1);
			mBG.graphics.drawRect(0, 0, 400, 364);
			mBG.graphics.endFill();
			mBG.alpha = 0;
			addChild(mBG);

			mBlackStripes.graphics.beginFill(0x000000, 1);
			mBlackStripes.graphics.drawRect(0, 0, 400, 300);
			mBlackStripes.graphics.endFill();
			addChild(mBlackStripes);

			mPlay.x = 25;
			mPlay.y = 14;
			mControl.addChild(mPlay);

			mStop.x = 64;
			mStop.y = 14;
			mControl.addChild(mStop);

			bFull.x = 175;
			bFull.y = 10;
			bFull.visible = false;
			mControl.addChild(bFull);

			bBack.x = -12;
			bBack.y = -12;
			bBack.visible = false;
			addChild(bBack);

			mVolume.x = 302;
			mVolume.y = 18;
			mControl.addChild(mVolume);

			mBGBar.graphics.beginFill(0x3F3F3F, 1);
			mBGBar.graphics.drawRect(0, 0, 400, 3);
			mBGBar.graphics.endFill();
			mBGBar.x = 0;
			mBGBar.y = 54;
			mControl.addChild(mBGBar);

			mLoadBar.graphics.beginFill(0xFFFFFF, 1);
			mLoadBar.graphics.drawRect(0, 0, 400, 3);
			mLoadBar.graphics.endFill();
			mLoadBar.x = 0;
			mLoadBar.y = 54;
			mLoadBar.width = 0;
			mControl.addChild(mLoadBar);

			mProgressBar.graphics.beginFill(0xF5F5F5, 1);
			mProgressBar.graphics.drawRect(0, 0, 400, 3);
			mProgressBar.graphics.endFill();
			mProgressBar.x = 0;
			mProgressBar.y = 54;
			mProgressBar.alpha = 0;
			mControl.addChild(mProgressBar);

			mDragger.graphics.beginFill(0xFFFFFF, 1);
			mDragger.graphics.drawRect(0, 0, 14, 7);
			mDragger.graphics.endFill();
			mDragger.x = 0;
			mDragger.y = 47;
			mControl.addChild(mDragger);

			diffDragger = mBGBar.width - mDragger.width;

			tAlert = new TextField();
                        tAlert.autoSize = TextFieldAutoSize.CENTER;
			tAlert.x = 120;
			tAlert.width = 160;
			tAlert.height = 14;
			tAlert.textColor = 0xFFFFFF;

                        format.font = "Arial";
			format.bold = true;
                        format.color = 0xFFFFFF;
                        format.size = 8;
                        tAlert.defaultTextFormat = format;
			mControl.addChild(tAlert);

			mControl.y = 308;
			mControl.alpha = 0;
			addChild(mControl);

			Tweener.addTween(mDragger,{_color:overColor, time:0});

			Tweener.addTween(mControl, {alpha:1, time:1, transition:"linear",
				onComplete:function(){
					connectVideo();
				}
			});

		};

		public function connectVideo ():void{
			//Video connection
			ncVideo.connect(null);
			nsVideo = new NetStream(ncVideo);
			nsVideo.client = this;
			nsVideo.bufferTime = 5;

			mVideo = new Video();
			mVideo.x = 0;
			mVideo.y = 0;
			addChild(mVideo);

			this.swapChildren(mVideo, bBack);

			mVideo.attachNetStream(nsVideo);
			nsVideo.play(videoURL);
			mVideo.smoothing = true;

			mPlay.gotoAndStop(1);
			//Sound
			mySound = nsVideo.soundTransform;
			mySound.volume = 1;
			nsVideo.soundTransform = mySound;
			//Bars
			mLoadBar.width = 0;
			mProgressBar.width = 0;
			//Listeners
			nsVideo.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);

			bFull.addEventListener(MouseEvent.MOUSE_DOWN, buildVideoHD);
			bFull.addEventListener(MouseEvent.ROLL_OVER, eventOver);
			bFull.addEventListener(MouseEvent.ROLL_OUT, eventOut);

			bBack.addEventListener(MouseEvent.MOUSE_DOWN, backVideo);
			bBack.addEventListener(MouseEvent.ROLL_OVER, eventOver);
			bBack.addEventListener(MouseEvent.ROLL_OUT, eventOut);

			mPlay.addEventListener(MouseEvent.MOUSE_DOWN, pauseVideo);
			mPlay.addEventListener(MouseEvent.ROLL_OVER, eventOver);
			mPlay.addEventListener(MouseEvent.ROLL_OUT, eventOut);

			mStop.addEventListener(MouseEvent.MOUSE_DOWN, stopVideo);
			mStop.addEventListener(MouseEvent.ROLL_OVER, eventOver);
			mStop.addEventListener(MouseEvent.ROLL_OUT, eventOut);

			mDragger.addEventListener(MouseEvent.MOUSE_DOWN, dragSeek);

			mVolume.mVolSlider.addEventListener(MouseEvent.MOUSE_DOWN, volumeScrubberClicked);
			stage.addEventListener(MouseEvent.MOUSE_UP, volumeScrubberUnClicked);
			mVolume.mVolSlider.addEventListener(MouseEvent.ROLL_OVER, volumeScrubberRolledOver);

			mLoadBar.addEventListener(Event.ENTER_FRAME, loadBar);

			mPlay.buttonMode = true;
			mStop.buttonMode = true;
			bFull.buttonMode = true;
			bBack.buttonMode = true;
			mDragger.buttonMode = true;
			mVolume.mVolSlider.buttonMode = true;

			mPlay.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
			mStop.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
			bFull.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
			bBack.dispatchEvent(new MouseEvent(MouseEvent.ROLL_OUT));
		};

		public function eventOver (e:MouseEvent):void{
			Tweener.addTween(e.currentTarget, {alpha:1, time:0.2, transition:"linear"});
		};

		public function eventOut (e:MouseEvent):void{
			Tweener.addTween(e.currentTarget, {alpha:.5, time:0.2, transition:"linear"});
		};

		public function netStatusHandler(evt:NetStatusEvent):void{

			if(evt.info.code == "NetStream.FileStructureInvalid"){
				tAlert.text = "File structure invalid. ";
			}else if(evt.info.code == "NetStream.NoSupportedTrackFound"){
				tAlert.text = "File is not supported. ";
			}else if (evt.info.code ==  "NetStream.Play.StreamNotFound") {
				tAlert.text = "Error: Stream not found. ";
			}else if (evt.info.code ==  "NetStream.Play.Start") {
				tAlert.text = "Buffering video... ";
				trace("evt.info.code --->>> "+evt.info.code+"\n")
			}else if (evt.info.code ==  "NetStream.Buffer.Empty") {
				tAlert.text = "Buffering video... ";
				trace("evt.info.code --->>> "+evt.info.code+"\n")
			}else if (evt.info.code == "NetStream.Buffer.Full") {
				mPlay.gotoAndStop(2);
				trace("evt.info.code --->>> "+evt.info.code+"\n")
				tAlert.text = " ";
			}else if (evt.info.code ==  "NetStream.Play.Stop"){
				mPlay.gotoAndStop(1);
				trace("evt.info.code --->>> "+evt.info.code+"\n")
			}

		};

		public function onMetaData(obj:Object):void{
			for(var propName:String in obj){
				//trace("**Metadata video: "+propName + " = " + obj[propName])
				if (propName == "width") {
					videoWidth = obj[propName]
				}
				if (propName == "height") {
					videoHeight = obj[propName]
				}
			};

			ratio = videoHeight/videoWidth;
			ratio = Number(ratio.toFixed(4));
			//trace("videoWidth original ---> "+videoWidth)
			//trace("videoHeight original ---> "+videoHeight)
			//trace("ratio ---> "+ratio)
			addEventListener(Event.ENTER_FRAME, dragSeekBar);
			videoDuration = obj.duration;
			setVideo();
		};

		private function setVideo():void{

			if (MODE == "SD") {
				mVideo.width = 400;
				if (ratio < 0.6) {
					bFull.visible = true;
					mVideo.y = 36;

				}else{
					mVideo.y = 0;
					bFull.visible = false;
				}

			}else if (MODE == "HD960"){
				mVideo.width = 960;
			}else if (MODE == "HD640"){
				mVideo.width = 640;
			}
			mVideo.height = Math.round(mVideo.width*ratio);
			trace("mVideo.height adjusted ---> "+mVideo.height)
		};

		public function buildVideoHD(obj:Object):void{

			if (stage.stageHeight < 810) {

				MODE = "HD640";

				mBG.width = 640;
				mBG.height = 424;
				mBlackStripes.width = 640;
				mBlackStripes.height = 360;
				mBGBar.width = 640;
				mLoadBar.width = 640;
				mProgressBar.width = 640;

				mControl.y = 368;
				mVolume.x = 530;
				bFull.x = 300;
				bFull.visible = false;
				bBack.x = -13;
				bBack.visible = true;
				tAlert.x = 320;

				mVideo.y = 0;
				setVideo();

				diffDragger = mBGBar.width - mDragger.width;
			}else{

				MODE = "HD960";

				mBG.width = 960;
				mBG.height = 604;
				mBlackStripes.width = 960;
				mBlackStripes.height = 540;
				mBGBar.width = 960;
				mLoadBar.width = 960;
				mProgressBar.width = 960;

				mControl.y = 548;
				mVolume.x = 850;
				bFull.x = 460;
				bFull.visible = false;
				bBack.x = -13;
				bBack.visible = true;
				tAlert.x = 480;

				mVideo.y = 0;
				setVideo();

				diffDragger = mBGBar.width - mDragger.width;
			}

		};

		public function backVideo(obj:Object):void{

			MODE = "SD";

			mBG.width = 400;
			mBG.height = 364;
			mBlackStripes.width = 400;
			mBlackStripes.height = 300;
			mBGBar.width = 400;
			mLoadBar.width = 400;
			mProgressBar.width = 400;

			mControl.y = 308;
			mVolume.x = 302;
			bFull.x = 175;

			bBack.visible = false;
			tAlert.x = 120;

			setVideo();

			diffDragger = mBGBar.width - mDragger.width;
		};

		public function pauseVideo(evt:MouseEvent):void{

			if (mPlay.currentFrame == 2) {
				mPlay.gotoAndStop(1);
				nsVideo.pause();
			}else{
				mPlay.gotoAndStop(2);
				setVideo();
				nsVideo.resume();
			}
		};

		public function stopVideo(evt:MouseEvent):void{
			nsVideo.pause();
			nsVideo.seek(0);
			mPlay.gotoAndStop(1);
		};

		public function loadBar(evt:Event):void{
			//trace("buffer ---> "+nsVideo.bufferLength)

			pctLoaded = Math.floor(nsVideo.bytesLoaded / nsVideo.bytesTotal * 100);
			Tweener.addTween(mLoadBar, {width: (mBGBar.width * pctLoaded) / 100, time:1, transition:"linear"});
			if (pctLoaded >= 100){
				evt.currentTarget.removeEventListener(Event.ENTER_FRAME, loadBar);
			}
		};

		public function dragSeekBar(evt:Event):void{
			actualTime = nsVideo.time;
			Tweener.addTween(mDragger, {x: Math.round(actualTime / videoDuration * diffDragger), time:.1, transition:"linear"});
			actualTime = nsVideo.time;
			if (Math.round(actualTime) == Math.round(videoDuration)){
				Tweener.addTween(this, {time:1, transition:"linear",
					onComplete:function(){
						tAlert.text = "";
						nsVideo.pause();
						nsVideo.seek(0);
						mPlay.gotoAndStop(1);
					}
				});
			}
		};

		public function dragSeek(evt:Event):void{
			//actualTimeDragger = int(((evt.currentTarget.x) / mBGBar.width) * videoDuration);
			nsVideo.pause();
			removeEventListener(Event.ENTER_FRAME, dragSeekBar);
			Tweener.removeAllTweens();
			stage.addEventListener(MouseEvent.MOUSE_UP, dragSeekOut);
			evt.currentTarget.startDrag(false, new Rectangle(0,47,diffDragger,0));
		};

		public function dragSeekOut(evt:MouseEvent):void{
			dragTime = Math.round(mDragger.x / diffDragger * videoDuration);
			actualTime = dragTime;
			mDragger.x = (actualTime / videoDuration * diffDragger);
			nsVideo.seek(dragTime);
			nsVideo.resume();
			mPlay.gotoAndStop(2);
			mDragger.stopDrag();
			stage.removeEventListener(MouseEvent.MOUSE_UP, dragSeekOut);
			addEventListener(Event.ENTER_FRAME, dragSeekBar);
		};

		public function volumeScrubberClicked(evt:Event):void {
			mVolume.mVolSlider.startDrag(false, new Rectangle(8, 0, 66, 0));
			mVolume.mVolSlider.addEventListener(Event.ENTER_FRAME, volumeScrubberSlide);
		};

		public function volumeScrubberRolledOver(evt:Event):void	{
			evt.currentTarget.buttonMode = true;
		};

		public function volumeScrubberUnClicked(evt:Event):void	{
			mVolume.mVolSliderbuttonMode = false;
			mVolume.mVolSlider.stopDrag();
			mVolume.mVolSlider.removeEventListener(Event.ENTER_FRAME, volumeScrubberSlide);
		};

		public function volumeScrubberSlide(evt:Event):void{
			volEquation = (100*(evt.currentTarget.x - 8))/66;
			volPercentage = volEquation / 100;
			mySound.volume = volPercentage;
			nsVideo.soundTransform = mySound;
		};

		public function formatTime(t:int):String {
			// returns the minutes and seconds with leading zeros
			// for example: 70 returns 01:10
			var s:int = Math.round(t);
			var m:int = 0;
			if (s > 0) {
				while (s > 59) {
					m++;
					s -= 60;
				}
				return String((m < 10 ? "0" : "") + m + ":" + (s < 10 ? "0" : "") + s);
			}else {
				return "00:00";
			}
		};

	};// end player class
};// end package

You can download the entire source code here:

HDVideo_source

The library contains all the visual elements and in the Main.as file you can change which video sample to play.
There are three high-def videos to play with.
I uploaded them separately because they are quite big.
So, download it from here and place it in the video folder from the HDVideo_source.zip file.

Video files

No Comments


Arduino + Flash + Wii

More and more I want to have a chance to work on a project using Arduino!

Check this example out:
Arduino + Flash + Wii Nunchuck + Servos + Webcam

2 Comments


CaT 2009: Open Source Everything

Ben Fry, co-founder of Processing and director of Seed Phyllotaxis Lab and Carlos Ulloa, founder and creator of Papervision3D and HelloEnjoy talk about their software as well as their views on the future of open source and collaboration.

CaT 2009: Open source everything

No Comments


DUI – Drawing under the influence

In this little experiment I tried to change usual mouse interaction to something similar to a staggery or frantic effect.
It all depends on the type of effect chosen. Options given are related to known drug effects.
In fact, I wish there was a different kind of way to interact with our precious machines.
I’ve seen stuff around and it may be bound to happen soon.

See it live:

demo

Download source and doc:

source

No Comments


[ Portfolio projects remaining list ]


This list contains previous projects I worked on and were not included in my portfolio featured list.
Each project contains a link, a thumbnail and a larger image of one page.
Enjoy it!



O’Pub
O’Pub Augmented Reality

O’Pub

O'Pub
O'Pub5



DeepCover

DeepCover is an image game. The challenge here was to serialize/parse bytearrays to a bitmapdata object and save the picture locally.

O'Pub
O'Pub5



SociedadeDDP

SociedadeDDP is a multidisciplineray communication agency.
It aims non-traditional advertising through resource optimization and efficient communication.
Visual identity for each section of the site.

SociedadeDDP
SociedadeDDP4



Ao Vivo

Light, camera, action!
Release of a 15 min. movie about a girl’s delirium to become famous.
Object of movie production debates and summits.
World-wide nominee for film festivals.

Ao Vivo
Ao Vivo5



Feelmes

A growing film production company.
Website displays their reel and the logo.
Feel me.

Feelmes
Feelmes3



Relax Medic

Relax Medic is a dealer of products designed for relaxation purposes.
Quality of life matters the most.
Dynamic integration with the product database and all effects for each section made me wanna work using one of their chairs!

Relax
Relax4



Mater

Mater is a reproductive medicine center with facilities in different countries.
They are specialized in human offspring fertility and all treatment options.
Two leveled navigation system to exposure all content, from staff to treatments and articles.

Mater
Mater1



Claus Lehmann

Photographer portfolio.
Showcase for his selected pieces along with roll over effects and bitmapdata manipulation.

Claus
Claus3



The Globe and Mail banner

RSS feed banner for the auto section.

The Globe and Mail
The Globe and Mail1



Autohound banner

AutoHound.ca features used cars and trucks for sale in Canada.
Interactive banner for MSN Auto portal.

Autohound
Autohound1



SoftFluid

High-tech infra-strucure company.
Networking services including design, installation & maintenance for professional environments.
Fancy robotic effects implemented to display the necessary information for any client of theirs.

softfluid
softfluid1



Soberan

Agricultural and rural product manufactered by Bayer.
Bayer’s intranet showcase for this product, the project involved animations, charts and xml navigation to ensure the success and popularity of the project.

Soberan
Soberan1



Medco

Number one pharmacy benefit management company in the US.
Worked with the IBM B2C team implementing new requirements and maintanance.
From the jsp client side to the Broadvision framework and C++ components.

Medco
Medco1



Sotheby’s eGallery

Sotheby’s International Realty Canada is a premier full-service luxury real estate portfolio management brokerage with an experienced team of real estate sales and marketing professionals that provide marketing and sales services.
Worked with the server side team to integrate data for a slideshow displayed in a plasma TV in all SIR offices around the world.

eGallery
eGallery1



Sotheby’s

Sotheby’s International Realty is a premier full-service luxury real estate portfolio management brokerage with an experienced team of real estate sales and marketing professionals that provide marketing and sales services.
One year project for IBM.
Web designed new pages and the map application.

Sotheby's
Sotheby's1

Tags: , , ,

No Comments


Singing Tree

Cerrado (central regionof Brazil) is the perfect place for such installation!

No Comments


Ferrofluid Art

Ferrofluid is a liquid which becomes strongly polarised in the presence of a magnetic field.
Sachiko Kodama is a japanese fellow known for his art assembling towers with such fluid.
Ypu can find out more on his website: http://www.kodama.hc.uec.ac.jp/spiral/

No Comments


Adobe Flash CS5 demo

Flash on The Beach demo presentation for Flash CS5.
They showed something I was expecting a long ago: a better workflow environment.
That means Flash Builder integrates with the Flash IDE and vice-versa.
Can’t wait to put my hands on it.

No Comments


Flash Camp Brasil

2 Comments



SetPageWidth