Метод slideTo перемещает объект из одного места в другое. Теперь мы немного изменим метод slideTo для создания метода scaleTo, который будем применять с объектом Stage для создания фоновой панели изменяемого размера, которая будет изменяться с увеличением или уменьшением фильма и находиться по центру под названием.
Stage.addListener(bg);
bg.onResize = function() { this._xscale = Stage.width-50; this._yscale = Stage.height-50; };
Все работает корректно. Уголки скользят на свои места, и было бы неплохо, чтобы фон так же постепенно изменял размер. Мы реализуем это в нашем следующем шаге. Сохраните фильм в файле resize002.fla.
MovieClip.prototype.scaleTo = function (xsc, ysc, speed,callbackObj, callbackFunc) { var noo; if (this.scaleControl) { noo = this.scaleControl; } else { noo = this.createEmptyMovieClip ("scaleControl", this. depth++); } noo.txsc = xsc; noo.tysc = ysc; noo.speed = speed; noo.callBackObj = callBackObj; noo.calIBackFunc = callBackFunc; noo.onEnterFrame = function() { this._parent._xscale += (this.txsc-this._parent._xscale)/this, speed; this._parent._yscale += (this.tysc-this._parent._yscale)/this .speed; if (Math.abs(this.txsc-this._parent._xscale)<0.2 && КMath.abs(this.tysc-this._parent._yscale)<0.2) { this._parent._xscale = this.tx; this._parent._yscale = this.ty; //execute callback (not used yet) this.callBackObj [this.callBackFunc](this._parent); this.removeMovieClip(); } }; };
bg.onResize = function() { var xsc = Stage.width-50; var ysc = Stage.height-50; this.scaleTo(xsc, ysc, 5); };
Все работает прекрасно, но необходимость применять различные методы для изменения различных параметров раздражает. Для изменения интенсивности придется добавить еще один метод, и т.д. Изменять набор значений внутри фильма на набор конечных значений было бы лучше с помощью одного метода.
На самом деле это можно сделать, передав методу объект с набором всех значений, которые мы хотим изменить. После этого нужно организовать цикл для каждого значения и постепенно приближать соответствующее значение к значению в конечном объекте. Когда значения приблизятся друг к другу, значение фильма переключится на конечное значение, и затем это значение удалится из объекта targets. Для перемещения объекта к точке нужно передать объект примерно так:
var obj = {_x:50, _y:100}; this.tweenTo (obj, 5);
Начало метода будет таким же, как в случае с методом slideTo, т.е. будет создаваться управляющий фильм, если такового еще не существует, и затем внутри него будут устанавливаться значения.
MovieClip.prototype.tweenTo = function(targetsObj, speed, КcallbackObj, callbackFunc) { var noo; if (this.tweenControl) { noo = this.tweenControl; } else { noo = this.createEmptyMovieClip("tweenControl", this.depth++); } // store the object containing target properties and values noo.targetsObj = targetsObj; noo.speed = speed; noo.callBackObj = callBackObj; noo.callBackFunc = callBackFunc; noo.onEnterFrame = function() { var count; // as its an object we can't check length. } }
for (var prop in this.targetsObj) { this._parent[prop]+=(this.targetsObj [prop]this._parent[prop] )/this, speed; }
По мере работы цикла, prop будет обращаться к имени каждого параметра, и в следующей строке кода мы получим очередное значение этого параметра в фильме, приближающееся к значению в параметре объекта targets.
for (var prop in this.targetsObj) { this._parent[prop] += (this.targetsObj [prop] this ._parent[prop]) /this.speed; // if property has reached target value if (Math.abs(this.targetsObj[prop]- this._parent[prop])<0.4) { this._parent[prop] = this.targetsObj[prop]; delete this.targetsObj[prop]; } }
MovieClip.prototype.tweenTo = function (targetsObj, speed, callbackObj, calIbackFunc) { var noo; if (this.tweenControl) { noo = this.tweenControl; } else { noo = this.createEmptyMovieClip ("tweenControl", this.depth++); } noo.targetsObj = targetsObj; noo.speed = speed; noo.callBackObj = callBackObj; noo.callBackFunc = callBackFunc; noo.onEnterFrame = function() { var count; // as it's an object we can't check length. for (var prop in this. targetsObj) { this._parent[prop] += (this.targetsObj[prop] - Кthis._parent [prop]) /this.speed; if (Math.abs (this.targetsObj [prop] this._parent [prop])<0.4) { this._parent[prop] = this.targetsObj[prop]; delete this.targetsObj[prop]; } count++; } if (!count) { this.callBackObj[this.calIBackFunc](this._parent); this.removeMovieClip(); } }; };Пример 5.5.
br.onResize = function() { // define targets var obj = (_x:Stage.right-this._width, _y:Stage.bottom this ._height}; this.tweenTo(obj, 5); }; :а вот фоновый приемник, влияющий на значения _xscale и _yscale. bg.onResize = function() { var obj = (_xscale:Stage.width-50, _yscale:Stage.height-50}; this.tweenTo(obj, 5); };
Ниже приведен целиком код, в котором также были изменены функции onResize.
fscommand("allowscale", "false"); Stage.scaleMode="showAll"; Stage.originalWidth = Stage.Width; Stage.originalHeight = Stage.Height; Stage.scaleMode="noScale"; Stage.onResize = function() { this.left = this.getLeft(); this.top = this.getTop(); this.right = this.getRight(); this.bottom = this.getBottom(); }; Stage.getLeft = function() { return -1*(this.width-this.originalWidth)/2; }; Stage.getTop = function() { return -1* (this.height-this.originalHeight)/2; }; Stage.getRight = function() { return this.left+this.width; }; Stage.getBottom = function() { return this.top+this.height; }; Stage.addListener(Stage); Stage.addListener(tl); Stage.addListener(tr); Stage.addListener(bl); Stage.addListener(br); Stage.addListener(bg); MovieClip.prototype.tweenTo = function(targetsObj, speed, callbackObj, callbackFunc) { var noo; if (this.tweenControl) { noo = this.tweenControl; } else { noo = this.createEmptyMovieClip("tweenControl",this.depth++); } noo.targetsObj = targetsObj; noo.speed = speed; noo.callBackObj = callBackObj; noo.callBackFunc = callBackFunc; noo.onEnterFrame = function() { var count; // as its an object we can't check length, for (var prop in this.targetsObj) { this._parent[prop] += (this.targetsObj[prop]- this._parent [prop] ) / Кthis. speed; if (Math.abs(this.targetsObj [prop]- this._parent[prop])<0.4) { this._parent [prop] = this.targetsObj[prop]; delete this.targetsObj [prop]; } count++; } if (! count) { this.callBackObj [this.callBackFunc](this._parent); this.removeMovieClip(); } }; }; tl.onResize = function() { var obj = (_x:Stage.left, _y:Stage.top}; this.tweenTo(obj, 5); }; tr.onResize = function() { var obj = (_x:Stage.right-this._width, _y:Stage.top}; this.tweenTo(obj, 5); }; bl.onResize = function() { var obj = (_x:Stage.left, _y:Stage.bottom-this._height}; this.tweenTo(ob j, 5); }; br.onResize = function() { var obj = (_x:Stage.right-this._width, _y:Stage.bottom thi s._height}; this.tweenTo(obj, 5); }; bg.onResize = function() { var obj = (_xscale:Stage.width-50, _yscale:Stage.height-50}; thi s.tweenTo(obj, 5); };Пример 5.6.
Можно сделать еще больше - например, поставить интенсивность фона в зависимость от размера рабочего места.
bg.onResize = function() { var obj = {_alpha:100* (Stage.Width/Stage.originalWidth), К_xscale:Stage.width-50, _yscale:Stage.height-50}; this.tweenTo(obj, 5); };
Эффект будет лучше заметен, если изменять цвет квадрата в фильме с серого на красный или синий. Если вы сделаете рабочее место совсем небольшим, фон практически полностью исчезнет (resize004.fla).
Нужно иметь в виду, что вместо создания tweenTo в виде метода объекта MovieClip можно было бы создать отдельный класс tween, унаследовав его из класса MovieClip. Это удобно, если большое количество фильмов требует доступ к этим методам. Реализовать это можно так.
function tweenable() { } tweenable.prototype = new Movieclip(); Object.registerClass("tweenableMc", tweenable); tweenable.tweenTo = function() { var noo; if (this.tweenControl) { noo = this.tweenControl; } else { noo = this.createEmptyMovieClip("tweenControl", this.depth++); } noo.targetsObj = targetsObj; noo.speed = speed; noo.callBackObj = callBackObj; noo.callBackFunc = callBackFunc; noo.onEnter Frame = function() { var count; // as it's an object we can't check length, for (var prop in this.targetsObj) { this._parent [prop] += (this.targetsObj [prop] Кthis._parent [prop] ) /this. speed; if (Math.abs (this.targetsObj [prop] this._parent [prop] ) <0.4) { this._parent[prop] = this.targetsObj [prop]; delete this.targetsObj [prop]; } count++; } if (!count) { this.callBackObj [this.callBackFunc](this._parent); this.removeMovieClip(); } }; };Пример 5.7.
Можно использовать Object.registerClass для связывания любого отдельного символа фильма с данным классом. Тогда вы могли бы добавить дополнительные методы к этому классу для добавления параметров к tween.
tweenable.prototype.addToTween = function(obj) { //loop through and add properties to targetsObj for (var prop in obj) { this.tweenControl.targetsObj [prop] = obj [prop]; } };
Также можно присвоить каждому параметру свою скорость, свои обратные связи для использования по достижении цели, или передавать аргумент с именем параметра и достигнутым значением. Все это зависит от того, как вы хотите использовать эти параметры. Можно было бы вернуться к подходу, с помощью которого мы установили точку наблюдения для события rollOver с компонентом всплывающей подсказки, и придумать в данном случае нечто аналогичное, чтобы обычные события onEnterFrame выполнялись в одно и то же время, что и функция tweenTo, и чтобы не нужно было добавлять управляющий фильм.