Notas
do autor, em 8 de novembro de 2002:
Uma nota a respeito do código nesta amostra. Na versão original
deste artigo, utilizei um identificador onEnterFrame para verificar
um carregamento completo. A condição usada para a verificação
da conclusão foi, basicamente, bytes carregados = total de bytes
(bytesloaded = totalbytes). Subseqüentemente, notei que setInterval
talvez fosse preferível para fazer a verificação
e que, também, o Flash não retorna sempre as propriedades
_width e _height no mesmo quadro como bytes carregados
= total de bytes (nem sempre permite que elas sejam determinadas lá).
Assim, o loop carregado para fazer a verificação deve ser
substituído por um que use setInterval, e que procure por
_width > 0, antes de prosseguir. O método loadjpg
inclui agora também um parâmetro opcional para o nome do
movieclip detentor, de forma a poder ser acessado para mostrar o progresso
do carregamento ou qualquer outra coisa que seja necessária ao
chamador (caller). O fla foi modificado adequadamente e tem o código
exibido abaixo.
Para carregar um jpg em um filme Flash
Para carregar um jpg externo em um filme Flash MX, você precisa
de três coisas somente: um jpg não-progressivo, um movieclip em branco para carregar o jpg e um comando em seu filme para
fazer carregar. Como em todas as coisas externas no Flash, se você
necessitar fazer alguma coisa com o jpg (posicioná-lo, girá-lo,
modificar seu tamanho, por exemplo), precisará esperar até
que seja carregado antes de fazê-lo, especialmente se o arquivo
for grande.
Para cobrir aquele critério "espere até
que esteja carregado", temos definido um método loadjpg no
protótipo MovieClip (de modo que possa utilizar o mesmo
método para qualquer movieclip). Então, no filme, uma vez
que eu determine qual movieclip usarei para conter o jpg (um novo, criado
no momento em que roda com createEmptyMovieClipe, ou um em branco,
criado no IDE e localizado no palco no momento em que roda, ou ainda um
em branco, anexado da biblioteca enquanto roda), posso usar o método
loadjpg para fazer isto:
--
criar
um (visível somente internamente) movieclip contentor (holder)*
dentro dele para conter o jpg,
-- carregar o jpg,
-- verificar o carregamento completo, e
-- chamar uma função específica (e apagar o loop
verificador) quando feito.
*A
razão para criar um movieclip contentor dentro do clip vazio é
sutil mas importante. Se eu não criar um clip contentor, e então
tentar anexar um identificador de evento (event handler) a um clip vazio,
a ação de carregar um conteúdo (um jpg) dentro do clip vazio poderia causar o cancelamento do identificador. Mas se eu anexar
o identificador ao clip vazio e carregar conteúdo em um clip dentro
daquele clip vazio, o identificador fica intacto (identificadores de evento
são usados nesta amostra para executar ações durante
o carregamento, como mostrar progresso, e/ou o completar do carregamento).
O código para fazer isto está em seguida, que vai no quadro
1, ou em um arquivo externo .as contendo uma coleção
de códigos re-utilizáveis como este:
MovieClip.prototype.loadjpg
= function(picName, holderName) {
// holderName can be passed in case needed for progress
indicator
// if not passed, use 'holder' as default
var h = holderName == undefined ? "holder"
: holderName;
this.createEmptyMovieClip(h, 1);
this._visible = false;
this[h].loadMovie(picName);
var id = setInterval(function (mc) { if (mc[h].getBytesLoaded()>1
&& mc[h].getBytesLoaded()>mc[h].getBytesTotal()-10 &&
mc[h]._width>0) {mc._alpha = 99;clearInterval(id);mc._visible =
true;mc.onComplete();} else {mc.onLoading();}}, 80, this);
};
Naquele
pedaço de código, atribuí um nome ao movieclip contentor
se o usuário não passou um. Então criei um clip contentor
em branco, configurei o clip principal como invisível (assim ele
não vai aparecer enquanto sua largura estiver sendo detectada),
e usei setInterval para verificar o carregamento completo. Verifiquei
pelo getBytesLoaded() > 1 para assegurar que o carregamento
começou, getBytesLoaded() > getBytesTotal()-10 para assegurar-me
que ele foi quase completamente carregado (porque algumas pessoas tem
reportado que, em algumas ocasiões, o bytesLoaded nunca
obtém o total de bytes (bytesTotal), e verificar que a propriedade
_width pode ser detectada (e então configurada), o que pode
acontecer um quadro, ou quase isso, depois que o carregamento é
completado. Eu poderia provavelmente me arranjar somente com o uso da
condição _width, mas coloquei a parte getBytes
dentro por segurança, no caso de existirem situações
onde _width puder ser de alguma maneira > 0, antes de
completar o carregamento.
Quando o carregamento está completo, configuro
o alfa para 99 para evitar problemas de mudança no bitmap, desligar
o intervalo de verificação, tornar o clip visível,
e chamar a função onComplete que o usuário
pode ter definido previamente. Note que dentro da função
setInterval, "this" não se refere ao movieclip atual
(ele parece estar indefinido), assim passei o movieclip atual para a função
setInterval como um parâmetro, após 80 (o número de
milisegundos que se passa entre os intervalos).
Por exemplo, se quero carregar o jpg e posicioná-lo em 50, 50 no
palco, posso fazer isso incluindo o código acima, junto com este
código:
(Note
que o jpg é referido como "this" dentro da função
positionIt. Porque esta função é designada para o
método myjpg's onComplete, qualquer referência ao "this"
dentro dele irá referir-se ao myjpg.)
Mostre
o progresso enquanto carregar
Se eu quero fazer a mesma coisa, mas mostrar o progresso do carregamento
em um campo de texto dtfLoadingMsg, posso fazer isto passando o
nome do contentor para o método loadjpg. Note que no código
acima, atribuí a função diretamente para a propriedade
myjpg's onComplete, ao invés de defini-la primeiro e então
atribuí-la. Ambos os modos estão ok para se fazer, mas certifique-se
de definir a função antes de fazer o loadjpg (carregar
o jpg) em ambos os casos.
Para fazer um jpg girar depois de carregado, por exemplo, se quero que
ele gire 5 graus no sentido dos ponteiros do relógio cada quadro,
posso fazer isto com este código (o método loadjpg no topo
deste artigo adicional):
//
rotate around upper left corner
function rotateIt() {
this.onEnterFrame = function() {
this._rotation += 5;
};
}
this.createEmptyMovieClipe("myjpg", 1);
myjpg.onComplete = rotateIt;
myjpg.loadjpg("jumpman.jpg", "hhh");
Note
(se você experimentá-lo) que o código acima faz com
que a figura gire em volta do canto superior esquerdo. Talvez você
gostasse, ao invés, de ter ela girando em volta de seu próprio
centro. Humm, como fazer isto, quando o ponto de registro de um movieclip
criado com um script é sempre 0,0? Bem, uma vez que a coisa que
estamos girando é um movieclip (myjpg) que retém
outro movieclip (holder) que contém a figura atual, podemos
compensar o contentor dentro do myjpg e assim podemos simular um ponto
central de registro na figura. Já estamos passando o nome do movieclip
contentor e, assim, usaremos isso para re-alinhar o jpg uma vez carregado:
//
rotate around center
function rotateIt() {
// position correctly once
this.holder._x = 0 - this.holder._width/2;
this.holder._y = 0 - this.holder._height/2;
// rotate on each frame
this.onEnterFrame = function() {
this._rotation += 5;
}
}
this.createEmptyMovieClipe("myjpg", 1);
myjpg.onComplete = rotateIt;
myjpg.loadjpg("jumpman.jpg", "holder");
Configurar
uma máscara com script
Em nossa amostra acima, não precisamos do nosso jpg se movendo
ou girando, portanto somente usaremos o método loadjpg para carregar
e posicionar a figura. Mas nos desejamos mascarar parte da figura que
não é o homem saltando e portanto criamos um movieclip
máscara que podemos aplicar usando código. Neste caso, usei
um caminho para recortar para fazer uma gif preta e branca que eu importei
para dentro do Flash, tracei um bitmap sobre ela, e então converti
a forma em um movieclip, dando-lhe o nome de instância de maskman.
Uma máscara pode ser criada com qualquer ferramenta de desenho,
pintura, ou ferramenta de apagar do Flash - mas se você quiser aplicá-la
com um script, nada obstante, ela deve ser convertida em um movieclip
e nomeada com um nome de instância. O código para aplicar
a máscara é simples:
jumpman.setMask(maskman);
Onde
jumpman é o nome do movieclip a ser mascarado, e maskman é
o movieclip contendo a máscara (no qual qualquer área preenchida
define a porção do movieclip mascarado que vai mostrar).
Em vez disso, uma máscara pode também ser criada com um
código no IDE, e então aplicada do exato mesmo modo. Por
exemplo, se quisermos, por alguma razão, aplicar uma máscara
triangular ao jpg, podemos definir uma função que chamamos
onComplete para ser:
function
maskIt() {
this.createEmptyMovieClipe("tri",2);
with (this.tri) {
beginFill(0,100);
moveTo(100,2);
lineTo(150,150);
lineTo(30,35);
lineTo(100,2);
endFill();
}
this.setMask(this.tri);
}
Mostrar
um segundo plano atrás do jpg
O último passo em nossa amostra é mostrar uma imagem de
fundo atrás do jpg mascarado. Neste caso, usamos duas imagens diferentes
para o fundo, uma jpg de gaivotas que importamos e convertemos em um movieclip
com o nome de instância seagulls, e um gráfico vetorial,
também um movieclip, com o nome de instância candle.
No início do filme, a visibilidade de ambas é configurada
para falso (0), e elas são mais tarde mostradas pela simples configuração
da visibilidade (individualmente) para 1. Na amostra, as imagens de fundo
foram criadas no IDE, mas elas poderiam ser, em vez disso, serem facilmente
lidas a partir de um jpg externo, utilizando-se o mesmo método
loadjpg que nós usamos para a imagem principal. Você
poderia criar um movieclip vazio no momento em que roda para conter a
imagem a ser mostrada e então carregar o jpg dentro dele (loadjpg).
Olhar o código em cada uma das seqüências de quadro
no fla poderá tornar claro como e quando as imagens estão
sendo carregadas, mascaradas e/ou tornadas visíveis/invisíveis.
Devido à reformulação implementada no site, pode ser que você encontre alguns links quebrados. Por favor, ajude-nos a corrigir eventuais problemas nos informando links quebrados