Thursday, August 21, 2008

Movie Clip Fit

Um problema básico hoje em dia para fazer resize em flash é posicionar os movieclips corretamente, existe este projeto que facilita a vida para fazer resize do flash dentro do browser:

http://swffit.millermedeiros.com/

Baseado neste projeto fiz este objeto que ajuda a ajusta as posições dos movieclips dentro do flash de acordo com o resize:


var fit = {
baseStageWidth: Stage.width,
baseStageHeight: Stage.height,
oldStageWidth: Stage.width,
oldStageHeight: Stage.height,
xLeft: 0,
xRight: 1,
yTop: 0,
yBottom: 1,
xMovies: new Array(),
xs: new Array(),
xAligns: new Array(),
x: function (mv:MovieClip, align:Number, x:Number) {
if (align == null) {
align = this.xLeft;
}
this.xMovies.push(mv);
if (x == null) {
if (align == this.xLeft) {
x = mv._x;
} else if (align == this.xRight) {
x = mv._x + mv._width;
}
}
this.xs.push(x);
this.xAligns.push(align);
},
yMovies: new Array(),
ys: new Array(),
yAligns: new Array(),
y: function (mv:MovieClip, align:Number, y:Number) {
if (align == null) {
align = this.yTop;
}
this.yMovies.push(mv);
if (y == null) {
if (align == this.yTop) {
y = mv._y;
} else if (align == this.yBottom) {
y = mv._y + mv._height;
}
}
this.ys.push(y);
this.yAligns.push(align);
},
widthMovies: new Array(),
widths: new Array(),
width: function (mv:MovieClip) {
this.widthMovies.push(mv);
this.widths.push(mv._width);
},
heightMovies: new Array(),
heights: new Array(),
height: function (mv:MovieClip) {
this.heightMovies.push(mv);
this.heights.push(mv._height);
},
proportionalMovies: new Array(),
proportionalWidths: new Array(),
proportionalHeights: new Array(),
proportional: function (mv:MovieClip) {
this.proportionalMovies.push(mv);
this.proportionalWidths.push(mv._width);
this.proportionalHeights.push(mv._height);
},
fix: function () {
for (var k:Number = 0; k < this.widthMovies.length; k++) {
this.widths[k] = (Stage.width * this.widths[k]) / this.oldStageWidth;
this.xMovies[k]._width = this.widths[k];
}
for (var k:Number = 0; k < this.heightMovies.length; k++) {
this.heights[k] = (Stage.height * this.heights[k]) / this.oldStageHeight;
this.heightMovies[k]._height = this.heights[k];
}
for (var k:Number = 0; k < this.proportionalMovies.length; k++) {
var ratioW = Stage.width / this.proportionalWidths[k];
var ratioH = Stage.height / this.proportionalHeights[k];
if (ratioW < ratioH ) {
this.proportionalWidths[k] = this.proportionalWidths[k] * ratioW;
this.proportionalHeights[k] = this.proportionalHeights[k] * ratioW;
} else {
this.proportionalWidths[k] = this.proportionalWidths[k] * ratioH;
this.proportionalHeights[k] = this.proportionalHeights[k] * ratioH;
}
this.proportionalMovies[k]._width = this.proportionalWidths[k];
this.proportionalMovies[k]._height = this.proportionalHeights[k];
}
for (var k:Number = 0; k < this.xMovies.length; k++) {
this.xs[k] = (Stage.width * this.xs[k]) / this.oldStageWidth;
if (Stage.align.indexOf("L") > -1) {
this.xMovies[k]._x = this.xs[k];
} else {
this.xMovies[k]._x = ((this.baseStageWidth - Stage.width) / 2) + this.xs[k];
}
if (this.xAligns[k] == this.xRight) {
this.xMovies[k]._x -= this.xMovies[k]._width;
}
}
for (var k:Number = 0; k < this.yMovies.length; k++) {
this.ys[k] = (Stage.height * this.ys[k]) / this.oldStageHeight;
if (Stage.align.indexOf("T") > -1) {
this.yMovies[k]._y = this.ys[k];
} else {
this.yMovies[k]._y = ((this.baseStageHeight - Stage.height) / 2) + this.ys[k];
}
if (this.yAligns[k] == this.yBottom) {
this.yMovies[k]._y -= this.yMovies[k]._height;
}
}
this.oldStageWidth = Stage.width;
this.oldStageHeight = Stage.height;
}
};


Se quiser que um movieclip fique sempre na posição x e y de acordo com o resize, basta passar a referência do movieclip para as funções x e y:


fit.x(MovieClip);
fit.y(MovieClip);


Ou então se precisar que um movieclip tenha o tamanho dinâmico de acordo com o resize, basta passar a referência do movieclip para as funções width e height:


fit.width(MovieClip);
fit.height(MovieClip);


Para fazer resize em porporção, ideal para imagens, use:


fit.proportional(MovieClip);


E para fazer alinhamentos, por exemplo alinhar um movieclip colado ao lado direito:


fit.x(MovieClip, fit.xRight);


E para alinhar colado a base:


fit.y(MovieClip, fit.yBottom);


Os alinhamentos suportados para o x são fit.xLeft(padrão) e fit.xRight, e para y são fit.yTop(padrão) e fit.yBottom.

O alinhamento esta preparado apenas para a configuração padrão de alinhamento do Flash e para o "TL" (alinhamento Top/Left):


Stage.scaleMode = "noScale";
Stage.align = "TL";


Outros parâmetros de alinhamento não foram testados.

No exemplo do swffit tem a função calcSize que é chamada quando cada resize é feito, é preciso adicionar a função fix, para cada vez que for feito o resize ajustar as posições:


function calcSize() {
fit.fix();
...
}


Veja o video que demonstra como utilizar: