EaselJS parte 1

Nesse tutorial vamos criar uma interatividade básica com JavaScript sobre a tag canvas do HTML5 usando o framework EaselJS. Para quem não conhece esse framework, ele é inspirando no ActionScript3 a linguagem de programação mais atual do plugin FlashPlayer.

O EaselJS faz parte de um conjunto de frameworks escrito em JavaScript do pacote CreateJS, faz parte também dessa família os frameworks TweenJS, PreloadJS e SoundJS. Os principais patrocinadores dessas ferramentas são: Adobe, Microsoft, AOL e GSkinner. Ano passado (2012) a GSkinner reescreveu uma série de games criado pela ATARI no passado, usando CreateJS, você pode conferir aqui.

Então chega de blablabla e vamos ao que interessa.

Primeiro, aconselho que vocês naveguem no site da CreateJS, vejam os trabalhos já publicados, teste os vários exemplos que tem disponíveis, aproveite também e espie a documentação, pois ela vai atender suas necessidades. Logo em seguida, baixe todo o pacote da CreateJS ou se preferir, apenas o EaselJS.

Após baixar o(s) pacote(s), crie um simples arquivo html, como abaixo, e salve com um nome de sua preferência.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head>
		<title> TEST with JavaScript </title>
	</head>

	<body onload="Main();">
		<h3> CLICK TO DRAW </h3>
    	<canvas id="canvas" width="550" height="550">
        </canvas>

        <!-- imports js -->
        <script src="js/easeljs-0.6.0.min.js"></script>
        <script src="js/Main.js"></script>
	</body>
</html>

Nessa estrutura básica de html, temos um elemento canvas onde acontecerão nossas interações, arquivos javascripts onde na linha 11 e a referência para o framework EaselJs baixado, a linha 12 está configurada para o arquivo “Main.js” que criaremos logo em seguida.

Observe que a tag body tem a propriedade “onload” que recebe como parâmetro uma função JavaScript.

Crie um arquivo Javascript como abaixo, salve-o com o nome “Main.js”. Se salvar com um nome diferente, não se esqueça de alterar esse nome no html.


var canvas;
var stage;
var containerBalls;
var containerLines;
var shapeLines;
var graphicsLines;

 function Main()
{
	// canvas
	canvas = document.getElementById('canvas');
	stage = new createjs.Stage( canvas );
 	// enabled interaction
	stage.mouseEventsEnabled = true;

 	// container
	containerBall = new createjs.Container();
	containerLines = new createjs.Container();

 	//lines
	shapeLines = new createjs.Shape();
 	graphicsLines = new createjs.Graphics();

 	//background black
	var g = new createjs.Graphics();
	g.beginFill( "#000000");
	g.drawRect(0,0, canvas.width, canvas.height);
 	var s = new createjs.Shape(g);
	s.x = 0;
	s.y = 0;

	stage.addChild(s);

 	//add elements
	containerLines.addChild(shapeLines);
	stage.addChild(containerLines);
	stage.addChild(containerBall);

 	stage.addEventListener( 'click', onClickStage );
}

function onClickStage( e )
{
	var ball = createBall(8);
	ball.x = stage.mouseX;
	ball.y = stage.mouseY;
	containerBall.addChild(ball);

	stage.update();
	debug( "stage-click => x "+ ball.x + " y => " + ball.y );
}

function createBall( raio )
{
	var g = new createjs.Graphics();
	g.beginFill('red');
	g.drawCircle(0, 0, raio);
	var s = new createjs.Shape(g);

	return s;
}

function debug( s )
{
	console.log( s );
}

Segue abaixo fluxo do algoritmo.

Figura 1.

Figura 1.

Observe: sempre que adicionarmos uma bola ao palco é necessário fazer uma atualização do mesmo. Caso você se esqueça de fazer essa atualização, não conseguirá visualizar as alterações ocorridas.

Até o momento, nosso experimento está adicionando uma bola vermelha ao clicar no palco. Que deve estar parecido com esse abaixo.

Figura 2.

Figura 2.

Até o momento estamos conseguindo visualizar apenas as bolas, mas calma, vamos implementar agora o desenho das linhas. Basta alterar a função “onClickStage”, como abaixo, e todas as bolas estarão conectadas umas com as outras.


function onClickStage( e )
{
	var ball = createBall(8);
	ball.x = stage.mouseX;
	ball.y = stage.mouseY;
	containerBall.addChild(ball);

	debug( "stage-click => x "+ ball.x + " y => " + ball.y );

	var len = containerBall.getNumChildren()-1;
	for (var i = 0; i < len; i++)
	{
		//debug("filhos: ", i);
		var l = containerBall.getNumChildren();
		for (var j = i+1; j < l ; j++)
		{
			//captura bola i
			var dObj1 = containerBall.getChildAt(i);
			//captura bola j
			var dObj2 = containerBall.getChildAt(j);
			//inicia define cor da linha em hexa
			graphicsLines.beginStroke("#ffffff");
			//início da linha, como se movesse a caneta para cima da bola i
			graphicsLines.moveTo(dObj1.x, dObj1.y);
			//como se riscasse um traço da bola i em direção a bola j
			graphicsLines.lineTo(dObj2.x, dObj2.y);
			//finaliza linha
			graphicsLines.endStroke();

			//debug("container I: ", dObj1, " container J: ", dObj2);
		}

	}

	//apenas atualiza a propriedade graphics.
	//containerLines.removeChild(shapeLines);
	//shapeLines = new createjs.Shape(graphicsLines);
	shapeLines.graphics = graphicsLines;
	// containerLines.addChild(shapeLines);

	stage.update();
}

O segredo está nessa estrutura de repetição. Então vou detalhar todo o processo.

Cada bola deve estar conectada uma com a outra e cada bola estará adicionada no container “containerBall“. Com o método “getNumChildren() eu consigo saber quantos filhos tem dentro do container. Agora faremos uma simulação de três bolas para ficar mais fácil o entendimento.

Vamos supor que tenho 3 bolas dentro do container, essas bolas devem estar conectadas entre si. A bola 1 deve estar conectada com a bola 2 e 3. A bola 2 tem que se conectar apenas com a bola 3, já que temos uma conexão da bola 1 com a bola 2. Então, não é nessário repetir a conexão da bola 2 com a 1, concorda? Já a bola 3 não precisa ter nenhuma conexão, pois as bolas 1 e 2 já fazem conexão com ela.

Veja o um exemplo com 4 bolas.

Figura 3

Figura 3

O código está bem comentado e simples, mas caso você tenha alguma dúvida, não deixe de perguntar.

Você pode baixar o código fonte aqui.

Você pode visualizar o resultado final aqui.

Obrigado.

Como criar uma sequência de imagens com o Adobe Flash para seu App.

A plataforma Flash é bastante conhecida no mercado Web, por produzir um conteúdo mais interativo que o convencional Html & Css. Mas, isso tem mudado bastante.

Hum, tudo bem, mas que importância isso tem pra mim que sou um programador que utiliza o Titanium Studio?

Com o Flash você pode criar uma sequência animada de imagens (SpriteSheet) e importá-las para seu projeto feito no Titanium, deixando o seu projeto com um diferencial bem atrativo.

Se você não tem experiência com o Flash, não se preocupe. Pois, o que vou demostrar, não exige nenhum conhecimento e detalharei todos os passos, basta seguir com atenção.

Se você não tem o Flash instalado, você poderá baixar uma versão trial direto do site da Adobe. Se você tem o Flash instalado e for superior ou igual a versão “CS 3″ acredito que também não terá nenhum problema eu usarei a versão “CS 6″.

Primeiro baixe a imagem abaixo, pois criaremos uma animação de um coração pulsando.

Fígura 1.

Figura 1.

Abra o Flash e crie um novo documento com 278px de largura por 215px de altura, frame rate com 24 fps.  A versão do ActionScript não faz nenhuma diferença.

Figura 2.

Figura 2.

Agora importe a “Figura 1” para o palco com as teclas command + r no Mac ou ctrl + r no Windows, a “Figura 1″ deve ter aparecido no palco. A imagem está bem maior que o palco, pois nem estamos visualizando-o. Clique na imagem importada pressione command + k ou ctrl + k aparecerá a janela “Transform” em “Scale Width” e “Scale Hight” deixe em 31%.

Fígura 3.

Figura 3.

O palco é esse retângulo branco que você está visualizando, senão aperte command + 2 ou ctrl + 2 para visualiza-lo.

Clique na imagem, pois vamos centralizá-la no centro do palco. Pressione command + K ou ctrl + k, aparecerá uma janela “Align” então selecione a segunda e a quinta opção de “Align” e se a opção “Align to Stage” não estiver marcada marque-a.

Fígura 3

Fígura 3

A imagem está centralizada no palco, vamos converte-la em um símbolo. Clique direito sobre ela, escolha a opção “Convert to Symbol” nomeie para “coracao” em “Type” deixe como “Movie Clip” em “Registration” marque o pontinho branco  no centro caso ele esteja desmarcado.

Fígura 4.

Fígura 4.

Nosso símbolo está pronto para ser animado. Poderíamos criar uma animação de forma manual, mas vamos utilizar uma animação já definida pelo Flash. Vá em Window da barra de tarefa e escolha “Motion Presents” dentro da pasta “Default Presents” escolha “pulse” e clique no botão “apply“.

Fígura 5.

Fígura 5.

Observe que foi adicionado alguns quadros na timeline e você pode clicar em um deles e pressionar “Enter” para reproduzir a animação de “pulse” escolhida.

Se por algum motivo a imagem escolhida não estiver em uma resolução satisfatória, vá na “Library”. Se essa janela não estiver visível, vá em Window e clique em “Library“. Na “Library” você vai visualizar a imagem importada e o símbolo criado. Clique direito sobre a imagem e depois em “Properties…“, marque a opção “Allow smoothing” e em “Compression” escolha “Photo (JPEG)” em “Quality” deixa marcado a opção “Use imported JPEG data“.
Dessa forma, a imagem não vai ter nenhum tipo de compressão e ainda vai suavizar os pixels quando estiverem em movimento.

Fígura 6.

Fígura 6.

Agora vamos exportar essa animação em uma sequência de imagens para utilizarmos no Titanium. Na barra de ferramentas click File -> Export -> Export Movie escolha “PNG” como formato e nomeie como “coracao” e click em “save” aparecerá a janela “Export PNG” deixe-a como abaixo e click em “Export

Figura 7.

Figura 7.

Observe que foi gerado 24 imagens “coracao0001.png”, “coracao0002.png”… Pois a animação tem duração de 1 segundo a 24 fps. Se você precisar de mais frames por segundo basta aumentar o fps no Flash.

Ok, agora que temos a sequência de imagens vamos criar nosso projeto no Titanium. Estarei disponibilizando todos os arquivos, então se você não tem o Flash instalado e também não o instalou pode iniciar a partir daqui.

No Titanium crie um novo projeto do tipo “Default Project” ou outro de sua preferência. Eu estou usando a versão 3.0.2 do SDK e vou exportar apenas para iPhone e Android.

Abra o arquivo “app.js” apague todo código e o deixe como abaixo.

//create window
var window = Ti.UI.createWindow();

//create view
var view = Ti.UI.createView({
	backgroundColor:'#ffffff',
	layout:'vertical'
});

//label
var label = Ti.UI.createLabel({
	color:'#000000',
	text:'Sequência de imagens',
	height:'auto',
	width:'auto',
	top:'10dp'
});

//add label in view
view.add( label );

//add view in window
window.add( view );

// open app
window.open();

Esses passos são bem básicos, então acho que você não vai ter nenhuma dificuldade. Isso é o que temos até o momento.
Figura 8.Vamos adicionar a sequência de imagens criada no app. Para isso, vamos criar um objeto do tipo ImageView. Mas, antes de tudo, criei uma pasta “images” dentro da ”Resources” e adicione as imagens.

Precisamos de uma array para setarmos o caminho de todas as imagens, que nesse caso são 24, com os seguintes nomes: ‘coracao0001.png’, ‘coracao0002.png’…
Não seria nem um pouco elegante criar uma array e setar todos esses valores na mão. Utilizaremos então, uma estrutura de repetição que todos já devem conhercer, o famoso “for”.

// images
var images = [];
for( var i = 1; i < 25; i++ )
{
	var path = '/images/coracao0' + (i < 10 ? '00' : '0') + i + '.png';
	images.push( path );
}

var image = Ti.UI.createImageView({
	images:images,
	width:'278dp',
	height:'215dp',
	top:'15dp',
	repeatCount:0, // 0 repetição infinita
	duration:(1/24) // configurando frame-rate
});

// add image in view
view.add( image );

Observe que fiz uma condição para verificar quantos zeros são necessários antes de concatenar o valor do “i” a “string“. Se for menor que 10, utilizo 2 zeros, senão apenas um. Se você executar o app nesse estágio, não vai visualizar nada diferente da última execução. Precimos adicionar um evento para saber quando todas as imagens foram carregadas e iniciar a animação com o método “resume“.

image.addEventListener('load', function(e){
	image.resume();
});

Execute novamente e o coração estará pulsando no seu app. Esse resultado deve ser praticamente o mesmo para o emulador Android.

Figura 8.

Figura 8.

Segue abaixo todo o código do app.

//create window
var window = Ti.UI.createWindow();

//create view
var view = Ti.UI.createView({
	backgroundColor:'#ffffff',
	layout:'vertical'
});

//label
var label = Ti.UI.createLabel({
	color:'#000000',
	text:'Sequência de imagens',
	height:'auto',
	width:'auto',
	top:'10dp'
});

var images = [];
for( var i = 1; i < 25; i++ )
{
	var path = '/images/coracao0' + (i < 10 ? '00' : '0') + i + '.png';
	images.push( path );
}

var image = Ti.UI.createImageView({
	images:images,
	width:'278dp',
	height:'215dp',
	top:'15dp',
	repeatCount:0, // 0 repetição infinita
	duration:(1/24) // configurando frame-rate
});

image.addEventListener('load', function(e){
	image.resume();
});

var changeStatus = Ti.UI.createButton({
	title:'clange-status',
	top:'15dp',
	color:'#ff0000'
});

changeStatus.addEventListener('click', function(e){
	image.animating ? image.pause() : image.resume();
});

//add label in view
view.add( label );

// add image in view
view.add( image );

//add button
view.add( changeStatus );

//add view in window
window.add( view );

// open app
window.open();

Vlw galera, até a próxima.

Baixe aqui os arquivos