Просмотр полной версии : Сохранение размера MovieClip внутри масштабируемого MovieClip
vanguish
27.08.2009, 15:00
Допустим у нас есть обьект 1_mc внутри другого обьекта 2_mc!
Когда мы начинаем менять масштаб 2_mc._xscale , то меняется размер и mc_1!
Возникает вопрос, как сохранить размер или масштаб 1_mc, при менющемся масштабе mc_2?
У нас есть Stage.scaleMode = "noScale" - возможно применение этого метода для MovieClip? Или может есть какой-то подобный оператор?
Для чего это нужно вы спросите.... пример реализации такого эффекта на http://mapia.ua . Если выбрать категории заведений, то при изменении размеров карты , иконки заведения остаются одного и того же размера... хотя по видимому координатная сетка меняется.
Пропорцию типа:
2_mc._xscale = 200;
1_mc._xscale = 50;
я и сам могу написать... но с ней проблема, таких обьектов внутри 2_mc._xscale очень много... и каждый зумировать заберёт много ресурсов.
Помогите, подскажите! Спасибо!
iflamberg
27.08.2009, 15:29
а зачем не-масштабируемый пихать внутрь мастшабируемого? На слой поверху его надо. Вот и вся математика =)
noScale-подобного метода для MovieClip нет.
vanguish
27.08.2009, 15:52
Ну не зря ж я поднял этот вопрос!
Именно такая связка, клип внутри клипа!
Есть мувик - он же координатная сетка карты, карту мы можем приблежать и отдалять... но при это обекты или метки которые на ней лежат не должны менять свой размер и находиться в своей координате при любом зуме!
Посмотри на пример карты!
Вот ещё один пример http://www.anychart.com/products/anychart/gallery/sample_195.html
Видишь, ка бы мы не меняли масштаб карты, метки отмеченных городов сохраняют свой размер.
Если рисовать их программно. то там есть свойство не сохранять размер векторной графике, а если у нас метки MovieClip?
а зачем не-масштабируемый пихать внутрь мастшабируемого?
Тоже об этом подумал. Нужда во множестве нетривиальных решений отпадает на этапе правильного планирования ролика.
По теме - ИМХО, только через обратно-пропорциональное масшатбирование.
Добавлено через 7 минут
Вот ещё один пример http://www.anychart.com/products/anychart/gallery/sample_195.html
Либо там метки городов не находятся внутри карты, а лежат в отдельном слое и их координаты пересчитываются по X и Y пропорционально изменению масштаба...
Либо находятся внутри, но их масштаб меняется обратно пропорционально изменению масштаба карты.
Сталкивался с такой задачей...
vanguish
27.08.2009, 16:33
Либо находятся внутри, но их масштаб меняется обратно пропорционально изменению масштаба карты.
Сталкивался с такой задачей...
И как сказалось на производительности?
Я предполагаю использовать много таких меток, 50-100 шт.
Сейчас попробую пересчитывать масштаб, обратно пропорционально...
Выводами поделюсь )
iflamberg
27.08.2009, 16:40
А вы что, все 100 планируете на экране отображать? Включая те, что за пределами видимого экрана? Э, батенька, далеко вы так не поедете...
vanguish
27.08.2009, 16:46
Нет естественно.... Как вы могли такое подумать подумать...
Это столько обьектов будет в видимой области!
Например если раскрыть карту на весь экран.
Добавлено через 10 минут
ООоо!! У меня возникла идея!!
Можно ж в каждыю метку засунуть onEnterFrame и при изменения масштаба карты менять обратно пропорционально масштаб данной метки.... НО... 50 onEnterFrame точно затормозят систему (((
Возможно ли написать слушатель события по изменению масштаба карты addListener к каждой отметки?
Типа 1_mc.addListener(resize);
Только к чему привязать листенер?
Зачем листенер? Меняете масштаб карты - меняются пропорции меток.
Добавлено через 5 минут
Мой вам совет - уберите метки из карты.
Сделайте с ними отдельный слой, мувик. И просто передвигайете их пропорционально изменению масштаба. Намучаетесь иначе с перемасштабированием стольких объектов.
vanguish
27.08.2009, 18:42
Значит так.... сделал.... по схеме отбратон пропорционального масштабирования:for (var i = 0; i<100; i++) {
engine_mc.v_map_mc.attachMovie('id','id'+i,engine_mc.v_map_mc.getNextHighestDepth(),{_x:100*i, _y:100*i, _xscale:100*current_zoom, _yscale:100*current_zoom});
engine_mc.v_map_mc['id'+i].onEnterFrame = function() {
this._yscale = this._xscale=100*current_zoom;
};
}
engine_mc - это слой который масштабируется
current_zoom - текущий масштаб
Как видите разместил 100 обьектов.... производительность не упала... ни при двигании карты , ни при её зумировании!!!
Всем спасибо ))) Наверно так и оставлю. Можно конечно попробовать изменять координаты меток... и сравнить что меньше жрёт ресурс.. но думаю разницы особой не будет!
Если есть какие-то ещё варианты прошу поделиться ))
Ужас. onEnterFrame в каждом мувике. Одного-то почему мало было?
Вам нужно всего-то было при изменении мастштаба пересчитать координаты меток.
Не захотели вытаскивать метки, видимо. Зря.
А вообще, ИМХО, разница будет. Одно дело - двигать мувик с векторной картинкой, а другое - изменять его масштаб, тем более
vanguish
12.09.2009, 01:06
Почему выбрал именно масштабирование, объясню....
Карта приближается и отдаляется плавно... соответственно если менять координаты отметок в не масштабируемом контейнере, то они как бы будут догонять свои координаты....отставать , причем визуально видимо...
Если же эти отметки лежат в масштабируемом контейнере , где их координаты постоянны... то придется менять их масштаб обратно пропорционально масштабу карты.
Поэтому в каждом есть событие onEnterFrame ...для изменения масштаба....
Может не рационально... тогда подскажите как разгрузить систему от onEnterFrame .
Зачем вам вообще нужен это onEnterFrame?
Организуйте без него. Ведь есть же событие, при котором вы масштаб карты меняете? При этом же событии и пересчет меток делайте.
Добавлено через 56 секунд
то они как бы будут догонять свои координаты....отставать , причем визуально видимо...
Вы это проверили или как...?
Может не рационально... тогда подскажите как разгрузить систему от onEnterFrame .
Вот посмотрите пример.
Там нет onEnterFrame.
Масштаб меняется с кнопок и с колесика мыши.
По желанию плавного увеличения/уменьшения масштаба с кнопок можно переделать изменение масштаба не пошагово, а через интервальную функцию и событие кнопки onPress.
Ну вот еще вариант не РАЦИОНАЛЬНЫЙ придумал)))
if(resize) { attachMovie(new_mc_for_scale)};
Вообщем у вас какое то событие Resize ( или функция) при которой меняется масштаб - если он вдруг меняется, то удаляется 1 клип, на место него ставится 2й.
Все это происходит после зума, кстати проверь вложенный клип после зума будет ресайзится вообще или нет - если нет то че парится то! Аттачи все время тот же клип а потом удаляй и снова аттачи при ресайзе.
Оригинально, но...
А если у него плавно зум идет, например, с колесика, меняется масштаб раз 3-10 в секунду. На карте, допустим, 20-100 меток.
Значит в секунду от 60 до 1000 циклов удаления-аттача... Может, конечно, нагрузка и не такая сильная будет и соизмерима с перемасштабированием.
Но я все-таки остаюсь за вариант простого пересчета-передвижки координат меток во внешнем мувике.
Но я все-таки остаюсь за вариант простого пересчета-передвижки координат меток во внешнем мувике.*** да это и так понятно мой друг. Но ТС то че делает придумывает велосипед! Вот мы ему и помогаем велосипед сделать! разными способами)))
Кстати, по поводу аттача. Не годится, т.к. после аттача в мувик карты эта метка точно также изменит свой размер сообразно масштабу родительского. И к тому же координаты для аттача все равно надо пересчитывать. Но первая причина делает вообще дальнейшие действия бессмысленными.
На момент скролл, я бы вообще снял битмап и матрицей менял его размеры, чем гонять ресурсоемкий вектор. После остановки скрола строил бы новую карту из вектора.
На момент скролл, я бы вообще снял битмап и матрицей менял его размеры, чем гонять ресурсоемкий вектор. После остановки скрола строил бы новую карту из вектора.
Так? :
1. Делаем один шаг масштабирования (например, колесико делает одну дельту)
2. Читаем битмапу карты.
3. Пересчитываем размеры битамапы с помощью матрицы с учетом дельты.
4. Отрисовываем из новой битмапы вектор в мувик обратно.
Такие циклы, также 3-10 раз в секунду будут ли менее ресурсоемкими?
Не так. Вектор показываем только после n секунд после прекращения зума. Точное значение получаем в результате тестов. При чем, если позволяет технология, отрисовку вектора начинаем от центра зумирования (курсора).
vanguish
14.09.2009, 16:14
Ого )) Спасибо всем , что откликнулись и поддержали тему!
Буду последовательным и комментировать посты по порядку.
Зачем вам вообще нужен это onEnterFrame?
Организуйте без него. Ведь есть же событие, при котором вы масштаб карты меняете? При этом же событии и пересчет меток делайте.
Добавлено через 56 секунд
Вы это проверили или как...?
Да , проверял, пример к сожалению удалил... чтоб показать, но было видимое отставание меток от заданных позиций при масштабировании... особенно при их количестве больше 50-ти.... использовал правда, опять же таки onEnterFrame для каждой отметки для пересчета её координат, понимаю.. что это глупо, но нужно было быстрое решение...
Скачал, пример... перерасчет координат , при каждой дельте зумма, думал над этим, наверное попробую сделать... отпишу ка вышло...
По поводу, как организовал масштабирование....
function zoom_map_function() {
var moving_scale = (100/current_zoom-engine_mc._xscale)/delta_scale;
var centre_point:Object = {x:Stage.width/2, y:Stage.height/2};
engine_mc.globalToLocal(centre_point);
var init_x = (!mash_mc.hitTest(_xmouse, _ymouse)) ? engine_mc._xmouse : centre_point.x;
var init_y = (!mash_mc.hitTest(_xmouse, _ymouse)) ? engine_mc._ymouse : centre_point.y;
var moving_x = (moving_scale<0) ? init_x/current_zoom/delta_scale : -init_x/2/current_zoom/delta_scale;
var moving_y = (moving_scale<0) ? init_y/current_zoom/delta_scale : -init_y/2/current_zoom/delta_scale;
def_start_x = -Math.ceil((engine_mc._x+moving_x*delta_scale)/200+1);
def_start_y = -Math.ceil((engine_mc._y+moving_y*delta_scale)/200+1);
var t = 0;
go_zoom_interval = setInterval(go_zoom_function, 30);
function go_zoom_function() {
if (t++<delta_scale) {
engine_mc._xscale += moving_scale;
engine_mc._yscale += moving_scale;
engine_mc._x += moving_x;
engine_mc._y += moving_y;
} else {
engine_mc.rast_map_mc['map_'+current_zoom+'_mc'].removeMovieClip();
engine_mc.rast_map_mc.createEmptyMovieClip('map_'+current_zoom+'_mc',engine_mc.rast_map_mc.getNextHighestDepth());
engine_mc.rast_map_mc['map_'+current_zoom+'_mc']._xscale = 100*current_zoom;
engine_mc.rast_map_mc['map_'+current_zoom+'_mc']._yscale = 100*current_zoom;
creat_def_setka_function(def_start_x,def_start_y);
clearInterval(go_zoom_interval);
scroll_flag = true;
}
};
}
Это сам код функции срабатывающей при скролле или нажатии на кнопку масштабирования...
масштабирую setIntervalom - вобще пришёл все таки к выводу что setInеerval намного лучше onEnterFrame... Можно регулировать затраты ресурсов системы, частотой срабатывания функции... Ведь движок влеша не формула один... а у некоторых пользователей ещё стоять до потомные мамонты, или маломощные ноутбуки.... Выход один в таком случае, замедлять анимацию.... в onEnterFrame её никак не уменьшиш, только частотой самого swf - что не всешда удобно...
Но ТС то че делает придумывает велосипед! Вот мы ему и помогаем велосипед сделать! разными способами)))
По теории вселенной, все уже на свете уже придумано, просто мы до этого ещё не додумались!!! Так что изобретаю велосипед заново, а как по другому... я понимаю что гугл карты давно уже все это прошли и придумали,... но кто мне даст исходник гуггл карты ..Ыч..
На момент скролл, я бы вообще снял битмап и матрицей менял его размеры, чем гонять ресурсоемкий вектор
Битмап - очень сильная штука для анимации во флеше... Но у меня карты в расте.
принцип как на гуггл... если кто видел флешевый движок гугла.
Или той же мапии...
Вот , точно!! Собсно реализую подобный проект http://mapia.ua
Сейчас более или менее сделал подобное, покажу как закончу ))
Работает на vBulletin ® версия 3.7.3. Copyright ©2000-2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Copyright © 1999-2008 Flasher.ru. All rights reserved.