10
фев
  ZOOM’бала, она же заготовка для масштабируемой Flash карты 3 балла
 

Вопрос:


Привет. Спасибо за ресурс. Впервые нормально оформлен, отлично описан, доходчиво рассказан, что для чего и почему. Что очень радует. И ещё раз спасибо. Хотел бы предложить наверное ещё одну тему из всеобщего обсуждения, “а как это сделать?” ;) А именно, флеш карта… С прокруткой, зумом описанием обьектов и других примочек.

Что скажешь?

Ответ:


А что я могу сказать? =) Конечно полностью делать за вас масштабируемую Flash карту я не буду, но заготовочку, как пищу для размышлений, подкину. Кстати, хочется сказать, что это чуть-ли не единственное письмо, которое я опубликовал без исправлений/сокращений, приятно и понятно всё написано, вы уж не обессуйте, что я полторы недели вас заставлял ждать, уж совсем не было времени.

Масштабируемая флешка


Собственно ничего сложного нет… Что такое “масштабируемая”? Это когда флешку / объект внутри флеш, можно уменьшать/увеличивать без потери качества и другого гемороя. Как известно, в этом плане Flash с растром не очень дружат. При увеличении, что естественно, растр ухудшается в качестве, на нём появляются квадратики и прочее. Так же при поворотах и “сжатии”, растр любит “ломаться”, что тоже, согласитесь, не очень красиво. Что остаётся? А остаётся нам использовать вектор, благо Илюстратором и Корелом сейчас мало кого удивишь, да и Flash, сама по себе программа для векторной графики/анимации, так что пробуем =)

Ах да, что-то я так увлёкся рассказом теоретической части «что-использовать-и-зачем» и совсем забыл упомянуть о функциях и свойствах, которые мы будем юзать для создания нужного эффекта в нашей флешке. Тут, тоже, ничего нового я вам не открою, использовать мы будем _xscale и _yscalse свойства Movie Clip объектов. Именно эти два свойства отвечают за масштабирование в процентах по оси X (ширина) и оси Y (высота). Единственное, что я вам посоветую, так это центрировать нужный вам объект не по левому верхнему углу, а по центру, чтобы центральная точка рисунка или клипа, совпадала с началом координат его родительского объекта.

Непосредственно код


В приведённом мною примере я создал на рабочем поле объект logo_mc, который, собственно, и масштабируется, а так же ползунок pan_mc, в котором помещается изображение “шкалы” делений, и непосредственно сам красный ползунок, имя ему тоже pan_mc. Для пущей красоты, вы можете, как и я, наложить маску на масштабируемый объект, нарисовать рамочку, но это всё не так важно, основной функционал можно осуществить и без этого. В общем ориентируйтесь на то, что вам надо, и смотрите код:

/*
Сегодня по просьбе телезрителей, хоть и с запозданием, н овсё же, мы разбираем урок по ЗУМУ (приближению/
/масштабированию) объектов
*/
//Делаем, чтобы флешка не масштабировалась
Stage.scaleMode = “noScale”;
_root._quality = “BEST”;
//
//Функция МАСШТАБИРОВАНИЯ
//
function zoom_func() {
        trace(“zoom_func”);
        //
        //Проверяем положение позунка
        //
        //Сразу надо отметить, что функция Math.round - округляет не целые числа, до ближайшего целого числа.
        //Т.е. число 0.5 вернёт нам 1, а число 0.3 - ноль
        //Функция Math.abs - возвращает нам модуль числа, т.е. всё время будет возвращать положительные значения
        //Так, запись Math.abs(-5) и Math.abs(5) вернёт абсолютно одинаковые значения, т.е. 5
        //
        //Кто не знает, свойства _xscale и _yscale отвечают за масштабирование обхекта по X и Y соответственно,
        //стандартное значение этих свойств у объекта без искажений по ширине или высоте будет 100,
        //если ширина/высота увеличиваются, то значения _xscale и _yscale будут больше 100,
        //если ширина/высота уменьшаются, то и значения свойств будут меньше 100.
        if (_root.pan_mc.pan_mc._y<-1) {
                //Если он выше координаты 0 по Y
                _root.logo_mc._xscale = _root.logo_mc._yscale=100+1900/50*Math.round(Math.abs(_root.pan_mc.pan_mc._y));
        } else if (_root.pan_mc.pan_mc._y>1) {
                //Если он ниже координаты 0 по Y
                _root.logo_mc._xscale = _root.logo_mc._yscale=100-95/50*Math.round(Math.abs(_root.pan_mc.pan_mc._y));
        } else {
                //Если ползунок находится в районе нулевой координаты
                _root.logo_mc._xscale = _root.logo_mc._yscale=100;
        }
        //Присваиваем текстовому полю текущее значение масштаба объекта logo_mc
        _root.zoom_txt.text = _root.logo_mc._xscale+“%”;
        //Запускаем функцию, которая будет смещать объект logo_mc в зависимости от положения курсора
        //и размеров объекта (см. ниже)
        _root.onMouseMove();
}
//
//ПОЛЗУНОК РЕГУЛИРОВАНИЯ МАСШТАБА ОБЪЕКТА
//
//Создаём событие “НАЖАТЬ”
pan_mc.pan_mc.onPress = function() {
        //Когда на ползунок нажали, для бОльшей наглядности, меняем цвет ползунка, на более блеклый
        this.gotoAndStop(2);
        //Начинаем перетаксивать ползунок
        this.startDrag(false, this._x, -50, this._x, 50);
        //При движении мышью запускаем функцию МАСШТАБИРОВАНИЯ, которая была описана выше
        this.onMouseMove = _root.zoom_func;
};
//Создаём событие “ОТПУСТИТЬ”
pan_mc.pan_mc.onRelease = pan_mc.pan_mc.onReleaseOutside=function () {
        //Возвращаем начальный цвет ползунку
        this.gotoAndStop(1);
        //Останавливаем перетаскивание
        this.stopDrag();
        //Удаляем событие, которое срабатывало каждый раз при движении мышки
        delete this.onMouseMove;
};
//
//Создаём событие на движение мышки, в зависимости от положения курсора мы будемсдвигать клип logo_mc
//либо левее, либо правее центра экрана
//
onMouseMove = function () {
        //Проверяем, если мышка находится в пределах рамки, размером 650 на 400 пикселей, то активируем
        //перемещение объекта logo_mc
        if (_xmouse>0 and _xmouse<650 and _ymouse>0 and _ymouse<400) {
                //Расчитываем коэфициент “СДВИГА”, грубо говоря, он нам будет показывать на сколько левее или правее
                //от центра флешки находится курсор мышки в процентном соотношении.
                //Этот коэфициент будет изменяться от -1 до 1, где -1 - это курсор находится в самой крайней левой
                //по оси X, ещё чуть чуть и курсор выйдет за край рамки слева. 0 - это курсор находится на середине
                //флешки. 1 - курсор находится в крайней правой точке.
                varKoefX = (_xmouse/325)-1;
                trace(“varKoef “+varKoefX);
                //Расчитываем разницу, между шириной объекта и шириной рамки (рабочей области). Полученное значение
                //делится на 2, потому что есть правй и левый край. Не знаю, как объяснить лучже даже, в общем
                //примите это как есть =)
                varDif = (650-logo_mc._width)/2;
                trace(“varDif “+varDif);
                //Проверяем, меньше или больше ширина клипа ширины рабочей области.
                //В зависимости от условий проверки применяем свой алгоритм расчёта смещения клипа от центра.
                //
                //325 - это ширина рабочей области, делённая по-полам, т.е., грубо говоря, СЕРЕДИНА.
                if (logo_mc._width<650) {
                        logo_mc._x = 325-(varDif*varKoefX);
                } else {
                        logo_mc._x = 325+(varDif*varKoefX);
                }
                //ПРОВОДИМ АНАЛОГИЧНЫЕ ДЕЙСТВИЯ С ВЫСОТОЙ ОБЪЕКТА И СМЕЩЕНИЕМ ЕГО ПО ОСИ Y
                varKoefY = (_ymouse/200)-1;
                trace(“varKoefY “+varKoefY);
                varDifY = (400-logo_mc._height)/2;
                trace(“varDifY “+varDifY);
                if (logo_mc._height<400) {
                        logo_mc._y = 200-(varDifY*varKoefY);
                } else {
                        logo_mc._y = 200+(varDifY*varKoefY);
                }
        }
};
//
//Создаём событие на ВРАЩЕНИЕ КУРСОРА
//
//В качестве слушателя события подключаем _root
Mouse.addListener(this);
//Создаём само событие вращения колёсика (подробнее о нём можете почитать здесь:
//	http://www.flashist.ru/2007/12/08/vrashhenie-kolyosika-myshki-i-peremotka/
this.onMouseWheel = function(varDelta:Number) {
        trace(“onMouseWheel”);
        //Смещаем положение ползунка
        _root.pan_mc.pan_mc._y -= varDelta;
        //Проверяем, если ползунок поднимается выше отметки -50 по Y, то ставим его на положение -50
        if (_root.pan_mc.pan_mc._y<-50) {
                _root.pan_mc.pan_mc._y = -50;
        } else if (_root.pan_mc.pan_mc._y>50) {
                //Если опускается ниже 50, то ставим на 50
                _root.pan_mc.pan_mc._y = 50;
        }
        //Запускаем функцию МАСШТАБИРОВАНИЯ
        _root.zoom_func();
};

Вот, собственно, и всё, масштабируемый объект создан, как он работает вы можете посмотреть в примере, ну и скачать fla исходник, в котором обильно содержатся комментарии к коду. Good Luck — удачи, по-нашему =)

Сама флешка (swf) | Исходник (fla)

Комментарии (28)   Автор: admin
Комментарии
mikesvb
01.03.09 | 14:54
11 баллов

Огромное спасибо. Будет от чего оттолкнутья.

admin
01.03.09 | 15:07
0 баллов

Огромное пожалуйста, рад, что вам пригодился этот урок =)

dok_sj2
04.03.09 | 20:55
0 баллов

А такую карту сделать реально????
Подкиньте маленький исходничек для размышлений.
Очень Вас прошу.

admin
04.03.09 | 21:23
0 баллов

В конце новости есть ссылка на исходник, качайте его.

dok_sj2
04.03.09 | 21:42
0 баллов

Я качал.
Спасибо -но вот меня интересует такой вопрос как реализовать такой поиск по улицам ,как показивать всю улицу и как добавлять метки?
Буду очень признателен

admin
04.03.09 | 23:38
0 баллов

Тут в один комментарий тяжело будет уместить весь ответ. В целом, изучайте (если ещё не знаете) работу с массивами. Я бы, скорее всего, создал массив, с объектами, у которых были бы свойства _x, _y, _name (и возможно какие-то другие), потом, когда нужно было бы организовать поиск перебирал бы массив и сравнивал значения свойства _name с необходимым значением, если бы значение совпадало, то передвигал бы карту к координатам _x и _y, примерно вот такой вот принцип.

dok_sj2
05.03.09 | 00:07
0 баллов

Спасибо буду пробовать

mikesvb
09.03.09 | 14:43
0 баллов

Как бы сделать передвижение по карте с помощью нажатой левой клавиши мышки и как бы рука в кулак становится?, а то зависимость от простого движения мыши мне кажется неудобной.

admin
09.03.09 | 19:57
0 баллов

1. Чтобы двигать объекты при зажатой кнопке мышки можно использовать startDrag()/stopDrag() функции, а можно реализовывать свои методы при событиях onPress/onRelease/onReleaseOutside.

2. Менять изображение курсора можно, если скрыть курсор через Mouse.hide(), и подключить на поле клип с изображением курсора, которое вам будет нужно. Потом это изображение курсора нужно будет двигать при событии onMouseMove в координаты _xmouse, _ymouse,

mikesvb
10.03.09 | 16:48
0 баллов

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

-----
и ещё столкнулся с проблемой. Если увеличить карту в самом краю, а потом её уменьшить, то она кудато за край экрана уходит. И потом надо искать её за краем флэшки. Что сделать, чтобы она в центр экрана уходила (уменьшалась)?

admin
10.03.09 | 18:57
0 баллов

1) Сделайте прозрачный фон или фон цвета фона флешки в клипе с картой.
2) Каждый раз при изменении размеров проверяйте положение карты, если она «уходит» куда-то, то возвращайте её на крайнюю возможную позицию.

mikesvb
13.03.09 | 14:53
0 баллов

по первому пункту сделал.
по второму трабл.
Как мне возвращать карту плавно? ЧТобы при уменьшении масштаба она к центру сдвигалась? может посоветуете логику...

И ещё.
А зачем там нужна маска? Что она даёт полезного?

admin
14.03.09 | 01:45
0 баллов

Маска, в моём примере, нужна для того, чтобы если флешка открывалась бы не в HTML, а напрямую, то чтобы был виден только участок карты.

Чтобы карта сдвигалась к центру, при изменении масштаба, каждый раз когда изменяется масштаб сдвигайте её к центру. Что именно у вас не получается, я не знаю, постарайтесь описать точнее проблему.

mikesvb
14.03.09 | 16:20
0 баллов

Понтяненько с маской. Получается мне надо условие поставить: Если уменьшается масштаб то плюсовать или минусовать по координатам х и у. Как мне узнать что уменьшается масштаб ??? Есть ли такое средство?

admin
15.03.09 | 00:09
0 баллов

У вас есть событие, которые вызывается для изменения масштаба, внутри него и производите все необходимые действия.

TiamaT
25.03.09 | 14:49
0 баллов

Добрый день! Такой вопросик: если мне надо разместить на карте объекты, которые не меняют свой масштаб при изменении масштаба карты, их надо размещать на отдельном слое или впихнуть в мувик карты? И как мне менять их координаты? Перебирая многомерный массив? Дергаться не начнет если будет до 20-30 объектов? А лучше, просто направьте на путь истинный... Заранее спасибо

admin
25.03.09 | 16:49
0 баллов

Вообще самый простой способ сделать так, чтобы объекты не менялись в размерах — перебирать массив с ними и изменять их пропорции обратно тому, как изменяются пропорции самой карты, то есть, если карта увеличивается, то уменьшаем пропорции объектов, если карта уменьшается, то увеличиваем.

На счёт тормозов — сказать тяжело, всё будет зависеть от того, сколько у вас будет объектов в массиве, что это будут за объекты, что будет использоваться в качестве карты (растр или вектор), и т.п.

TiamaT
30.03.09 | 16:04
-13 баллов

Подскажите пжалста, как организовать появление окошка комментариев при наведении курсора на объект.
Примного благодарен.

admin
30.03.09 | 21:01
0 баллов

Событие onRollOver (в AS2) или MOUSE_OVER (в AS3). Как делается остальное — можно догадаться, если посмотреть исходники на сайте (например, урок по созданию окон, как в Windows).

На будущее, если есть вопросы, то пишите их в раздел вопросов, не стоит их постить в комментарии к другим статьям.

mikesvb
28.03.09 | 04:36
0 баллов

всё вроде нормально получается с заготовкой, можно сказать карта готова. Но есть небольшой трабл если убираю Stage.scaleMode = “noScale”; то масштабируется абсолютно всё. Что прописать, чтобы не увеличивалась шкала масштаба? И ещё Есть ли средства стандартные чтобы при нажати накарту, её движении появлялась сомкнутая ладонь курсора

admin
29.03.09 | 16:04
0 баллов

1) Если вы убираете "noScale", то всё и будет масштабироваться. Если вам нужно, чтобы масштабировались какие-то определённые объекты, то ставьте "noSCale" и при событии onResize масштабируйте те объекты, которые вам нужны.

2) Таких средств, на сколько я знаю, нет.

Антон
22.07.09 | 06:28
0 баллов

несколько неудобно, что карта постоянно бегает за мышкой (при наличии менюшек и управляющих кнопок, карта постоянно съезжает в сторону при наведении на них).
Поставил движение карты по событию onPress. Чтобы элементы на карте оставались активными, событие onPress привязал к мувику, который лежит между картой и активными элементами.
Работает не плохо. Но появилась новая проблема, над которой бьюсь уже третий день.
При увеличенной карте, если начинаю вращать колесиком мыши карту сильно "швыряет" в стороны. Если хочу приблизить какой-то участок в углу отображаемой области, меня "выкидывает" в самый угол карты :(

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

Nismo
11.09.09 | 18:31
0 баллов

Все замечательно, но объясните пожалуйста, в этих строках:

_root.logo_mc._xscale = _root.logo_mc._yscale=100+1900/50*Math.round(Math.abs(_root.pan_mc.pan_mc._y));
	} else if (_root.pan_mc.pan_mc._y>1) {
		//Если он ниже координаты 0 по Y
		_root.logo_mc._xscale = _root.logo_mc._yscale=100-95/50*Math.round(Math.abs(_root.pan_mc.pan_mc._y));

откуда взялся коэффициент 1900/50* и 95/50. Что 100 - это 100%, натуральная величина, это понятно.

dok_sj2
04.10.09 | 20:33
0 баллов

Скажите а можно флеш ролик или флеш приложение поместить в вашу карти и отменить увеличение \уменьшение прогрес баром а зделать скролом. пож покажите наоочно если можно.

inclean
28.10.09 | 16:36
0 баллов

спасибо за урок!
есть несколько вопросов:

1. как сделать "zoom" еще и клавишами "+" и "-"? если это возможно
2. как сделать перемещение вправо, влево, вниз, вверх кнопками и клавишами, при увеличении изображения и выхода его за рамки?
3. как сделать, чтобы при возвращении исходного размера, карта возвращалась в центр?

ere
06.11.09 | 17:12
0 баллов

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

	function onLoad(){
		Mouse.addListener(this);	
	}
	 function onMouseWheel (delta:Number, scrollTarget:String) {
		this._x = this._x-5*this._xmouse*delta/100;
		this._y = this._y-5*this._ymouse*delta/100;		
		
		this._xscale = this._xscale+5*delta;
		this._yscale = this._yscale+5*delta;		
	}

Единственный нюанс, что при загрузке такой флешки прелоадером код перестаёт работать.Может кто подскажет решение.

agasya
22.12.09 | 09:07
0 баллов

Здравствуйте! Меня интересует вот какой вопрос. Как сделать так, чтобы при движение мышкой, карта под зумом двигалась медленнее... А то при большом зуме объекты на карте просто пролетают. Можно ли сделать так, чтобы к примеру движении мышки в правый верхний угол карта как бы „подтягивалась“ к курсору.
Заранее спасибо!

agasya
22.12.09 | 14:29
0 баллов

to inclean
Я могу ответить тока на второй твой вопрос
Нужно добавить вот этот скрипт

var speed:Number = 4;
logo_mc.onEnterFrame = function() {
if (Key.isDown(Key.RIGHT)) {
this._x = this._x+speed;
} else if (Key.isDown(Key.LEFT)) {
this._x = this._x-speed;
}
if (Key.isDown(Key.UP)) {
this._y = this._y-speed;
} else if (Key.isDown(Key.DOWN)) {
this._y = this._y+speed;
}
};

 
 
 
 

Последние комментарии

Полезные ссылки

Реклама сайтов

Раскрутка сайта в интернете. раскрутка сайта - наилучшие результаты.
подержанные корейские автобусы продажа автобусов продажа автобуса
У вас проблема: создание сайтов для Интернет-магазина. Мы ее решим!
Купальники известный марки Amarea