Форум Flasher.ru
Ближайшие курсы в Школе RealTime
Список интенсивных курсов: [см.]  
  
Специальные предложения: [см.]  
  
 
Блоги Правила Справка Пользователи Календарь Сообщения за день
 

Вернуться   Форум Flasher.ru > Flash > ActionScript 3.0

Версия для печати  Отправить по электронной почте    « Предыдущая тема | Следующая тема »  
Опции темы Опции просмотра
 
Создать новую тему Ответ
Старый 04.02.2011, 23:40
NikosHope вне форума Посмотреть профиль Отправить личное сообщение для NikosHope Найти все сообщения от NikosHope
  № 1  
Ответить с цитированием
NikosHope

Регистрация: Nov 2010
Сообщений: 12
По умолчанию Эффект шторок (ActionScript 3, Flash CS5)

Здравствуйте.

При реализации так называемого "эффекта шторок" возникла проблема.

Сперва о сути задачи:
По всей ширине сцены находится некоторое фиксированное количество прямоугольников равной ширины. При наведении на любой из них, запускается анимация, равномерно увеличивающая ширину активного прямоугольника. В то же время, остальные сокращаются в ширине, меняя свои ширину и координаты относительно состояния активного. При выведении курсора со сцены, происходит восстановление изначального состояния всех элементов.

Основной момент, при реализации которого возникли трудности: при перемещении с активного прямоугольника на соседний, происходит плавное сокращение ширины первого и, соответственно, увеличение второго. Остальные прямоугольники при этом остаются недвижимыми.

Подскажите варианты решения вопроса.

Код ниже:
Код AS3:
package {
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import fl.transitions.easing.Strong;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
 
	public class main extends MovieClip {
 
		public var i;
		public var k = 2;
		public var sW;
		public var sH;
		public var maxBarWidth;
		public var normBarWidth;
		public var lastOverBarIndex = -1;
		public var currentOverBarIndex = -1;
		public var bars = new Array();
 
		public function main(){
 
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.frameRate = 30;
 
			for (i = 0; i < 10; i++) bars[i] = new bar_mc;
 
			for (i = 0; i < bars.length; i++) {
				addChild(bars[i]);
				overControl(i);
			}
 
			stage.addEventListener(Event.RESIZE, stageResize);
			stage.addEventListener(MouseEvent.MOUSE_OUT, stageOut);
 
			stageResize(null);
 
		}
 
		public function stageOut(e:MouseEvent) {
 
			var outTween = new Tween(bars[currentOverBarIndex], "width", Strong.easeInOut, bars[currentOverBarIndex].width, normBarWidth, 20);
			outTween.addEventListener(TweenEvent.MOTION_CHANGE,transformer);
 
		}
 
		public function overControl(a) {
 
			bars[a].addEventListener(MouseEvent.MOUSE_OVER,function() {
				lastOverBarIndex = currentOverBarIndex;
				currentOverBarIndex = a;
				var barTween = new Tween(bars[a], "width", Strong.easeInOut, bars[a].width, maxBarWidth, 20);
				barTween.addEventListener(TweenEvent.MOTION_CHANGE,transformer);
				bars[a].width = maxBarWidth;
				transformer(null);
			});
 
		}
 
		public function transformer(e:Event) {
 
			//if (lastOverBarIndex == -1) { // отслеживаем анимацию из базового состояния
				var bufW = (sW - bars[currentOverBarIndex].width) / (bars.length - 1);
				var bufX = 0;
				for (var j = 0; j < bars.length; j++) {
					if (j != currentOverBarIndex) {
						bars[j].width = bufW;
						bars[j].x = bufX;
						bufX += bufW;
					}
					else if (j == currentOverBarIndex) {
						bars[j].x = bufX;
						bufX += bars[j].width;
					}
				}
			//}
			/*if (lastOverBarIndex != -1) { // отслеживем анимацию при наведении курсора на соседнее поле (один из элементов уже развернут)
				if (currentOverBarIndex > lastOverBarIndex) {
					//bars[lastOverBarIndex].width = sW - normBarWidth*(bars.length - 2) - bars[currentOverBarIndex].width;
					bars[currentOverBarIndex].x = bars[lastOverBarIndex].x + bars[lastOverBarIndex].width;
				}
				else {
					bars[lastOverBarIndex].x = bars[currentOverBarIndex].x + bars[currentOverBarIndex].width;
					//bars[lastOverBarIndex].width = sW - normBarWidth*(bars.length - 2) - bars[currentOverBarIndex].width;
				}
			}*/
		}
 
		public function stageResize(e:Event):void {
 
			sW = stage.stageWidth;
			sH = stage.stageHeight;
			normBarWidth = sW/bars.length;
			maxBarWidth = normBarWidth*k;
 
			var bufX = 0;
			for (var i = 0; i < bars.length; i++) {
				bars[i].width = normBarWidth;
				bars[i].height = sH;
				bars[i].x = bufX
				bars[i].y = 0;
				bufX += normBarWidth;
			}
 
		}
 
	}
 
}
Вложения
Тип файла: zip project.zip (11.5 Кб, 55 просмотров)


Последний раз редактировалось NikosHope; 04.02.2011 в 23:44.
Старый 10.02.2011, 03:19
NikosHope вне форума Посмотреть профиль Отправить личное сообщение для NikosHope Найти все сообщения от NikosHope
  № 2  
Ответить с цитированием
NikosHope

Регистрация: Nov 2010
Сообщений: 12
Исходники скачали 9 человек, - неужели никто не продвинулся? Подскажите, может у кого идеи есть, хотя бы в теории.

Старый 10.02.2011, 11:31
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 3  
Ответить с цитированием
in4core
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
ну в теории если не вчитываясь в ваш код, можно пихать ссылки на объекты в массив, при наведении на активный он делает одну анимацию, и перебором через цикл вы запускаете другую анимацию для всех остальных. Отталкиваясь от итератора цикла, вы можете управлять например анимацией каждого отдельного, увеличивая или уменьшая пропорционально. Так же стоит сохранять активный элемент, и при отпускании производить с ним ОТДЛЬНУЮ манипуляцию, переводя ссылку на новый.

Старый 10.02.2011, 12:45
NikosHope вне форума Посмотреть профиль Отправить личное сообщение для NikosHope Найти все сообщения от NikosHope
  № 4  
Ответить с цитированием
NikosHope

Регистрация: Nov 2010
Сообщений: 12
in4core, что вы подразумеваете под ссылками?
Боюсь, если реализовывать анимацию для каждого элемента в отдельности, то, в случае их большого количества, - начнутся тормоза.

Старый 10.02.2011, 13:12
in4core вне форума Посмотреть профиль Отправить личное сообщение для in4core Найти все сообщения от in4core
  № 5  
Ответить с цитированием
in4core
 
Аватар для in4core

Регистрация: Mar 2009
Сообщений: 4,219
Записей в блоге: 14
Под ссылками подразумеваются ссылки на объекты)
Код AS3:
var a:Shape = new Shape();
var b:Shape = new Shape();
var c:Shape = new Shape();
var d:Shape = new Shape();
 
arr = [a,b,c,d]
Тормозов поидее быть не должно, тут ситуация немного другая. Главное архитектуру правильно разписать, чтобы вовремя отписывать события, удалять ссылки, очищаться ( как в бане ) с GC))

Старый 11.02.2011, 16:43
NikosHope вне форума Посмотреть профиль Отправить личное сообщение для NikosHope Найти все сообщения от NikosHope
  № 6  
Ответить с цитированием
NikosHope

Регистрация: Nov 2010
Сообщений: 12
Наваял вот такой код.
Но где-то есть ошибка в логике...

Код AS3:
package {
 
	import flash.display.MovieClip;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import fl.transitions.easing.Strong;
	import fl.transitions.Tween;
	import fl.transitions.TweenEvent;
 
	public class main extends MovieClip {
 
		public var i;
		public var j;
		public var k = 1.5;
		public var sW;
		public var sH;
		public var bufW;
		public var bufX;
		public var maxBarWidth;
		public var normBarWidth;
		public var minBarWidth;
		public var lastOverBarIndex = -1;
		public var currentOverBarIndex = -1;
		public var bars = new Array();
 
		public function main(){
 
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			stage.frameRate = 30;
 
			for (i = 0; i < 5; i++) bars[i] = new bar_mc;
 
			for (i = 0; i < bars.length; i++) {
				addChild(bars[i]);
				overControl(i);
			}
 
			stage.addEventListener(Event.RESIZE, stageResize);
			stage.addEventListener(Event.MOUSE_LEAVE, stageOut);
 
			stageResize(null);
 
		}
 
		public function stageOut(e:Event) {
 
			lastOverBarIndex = currentOverBarIndex;
			currentOverBarIndex = -1;			
			var outTween = new Tween(bars[lastOverBarIndex], "width", Strong.easeInOut, bars[lastOverBarIndex].width, normBarWidth, 20);
			outTween.addEventListener(TweenEvent.MOTION_CHANGE,transformer);
 
		} // stageOut
 
		public function overControl(a) {
 
			bars[a].addEventListener(MouseEvent.MOUSE_OVER,function() {
				lastOverBarIndex = currentOverBarIndex;
				currentOverBarIndex = a;
				var barTween = new Tween(bars[a], "width", Strong.easeInOut, bars[a].width, maxBarWidth, 20);
				barTween.addEventListener(TweenEvent.MOTION_CHANGE,transformer);
				bars[a].width = maxBarWidth;
				transformer(null);
			});
 
		} // overControl
 
		public function transformer(e:Event) {
 
			if (currentOverBarIndex == -1) { // отслеживаем анимацию при выведении курсора со сцены
				bufW = (sW - bars[lastOverBarIndex].width) / (bars.length - 1);
				bufX = 0;
				for (j = 0; j < bars.length; j++) {
					if (j != lastOverBarIndex) {
						bars[j].width = bufW;
						bars[j].x = bufX;
						bufX += bufW;
					}
					else if (j == lastOverBarIndex) {
						bars[j].x = bufX;
						bufX += bars[j].width;
					}
				}
			}
			if (lastOverBarIndex == -1) { // отслеживаем анимацию из базового состояния
				bufW = (sW - bars[currentOverBarIndex].width) / (bars.length - 1);
				bufX = 0;
				for (j = 0; j < bars.length; j++) {
					if (j != currentOverBarIndex) {
						bars[j].width = bufW;
						bars[j].x = bufX;
						bufX += bufW;
					}
					else if (j == currentOverBarIndex) {
						bars[j].x = bufX;
						bufX += bars[j].width;
					}
				}
			}
			if (lastOverBarIndex != -1 && currentOverBarIndex != -1) { // отслеживем анимацию при наведении курсора на соседнее поле (один из элементов уже развернут)
				bufW = (sW - bars[currentOverBarIndex].width - bars[lastOverBarIndex].width) / (bars.length - 2);
				bufX = 0;
				var l_sum = 0;
				var r_sum = 0;
				for (j = 0; j < bars.length; j++) {
					if (j == lastOverBarIndex) {
						if (currentOverBarIndex > lastOverBarIndex) {
							bars[lastOverBarIndex].width = minBarWidth + maxBarWidth - bars[currentOverBarIndex].width;
							bars[currentOverBarIndex].x = bars[lastOverBarIndex].x + bars[lastOverBarIndex].width;
						}
						if (currentOverBarIndex < lastOverBarIndex) {
							bars[lastOverBarIndex].x = bars[currentOverBarIndex].x + bars[currentOverBarIndex].width;
							bars[lastOverBarIndex].width = minBarWidth + maxBarWidth - bars[currentOverBarIndex].width;
						}
					}
				}
			}
 
		} // transformer
 
		public function stageResize(e:Event):void {
 
			sW = stage.stageWidth;
			sH = stage.stageHeight;
			normBarWidth = sW/bars.length;
			maxBarWidth = normBarWidth*k;
			minBarWidth = (sW-maxBarWidth)/(bars.length-1);
 
			var bufX = 0;
			for (var i = 0; i < bars.length; i++) {
				bars[i].width = normBarWidth;
				bars[i].height = sH;
				bars[i].x = bufX
				bars[i].y = 0;
				bufX += normBarWidth;
			}
 
		} // stageResize
 
	} // main
 
} // package


Последний раз редактировалось NikosHope; 14.02.2011 в 21:58.
Создать новую тему Ответ Часовой пояс GMT +4, время: 17:25.
Быстрый переход
  « Предыдущая тема | Следующая тема »  

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


 


Часовой пояс GMT +4, время: 17:25.


Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.