Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Как лучше сделать Хинты с картинками (http://www.flasher.ru/forum/showthread.php?t=146624)

Dukobpa3 13.11.2010 11:55

Как лучше сделать Хинты с картинками
 
Здравствуйте.

Есть список товаров, с картинками.

В списке есть иконка, при наведении на которую клиент хочеть видеть всплывающую подсказку с картинкой товара.

Я делаю следующим образом:

Код AS3:

/*
в цикле перебираются строки списка. Это двумерный вектор, первый индекс - номер строки, второй - номер элемента строки. Отображаются только элементы 0-2, под номером три собственно иконка по наведении на которую должен віскочить хинт.*/

//**************************
menuItems[r][3] = new dishphotoicon(); //собственно иконка
menuItems[r][3].stop();
menuItems[r][3].x = 350;
menuItems[r][3].y = 5;
menuItems[r][3].addEventListener(MouseEvent.MOUSE_OVER, showHint);
menuItems[r][3].addEventListener(MouseEvent.MOUSE_OUT, hideHint);
menuItems[r][3].name = String(SERVER + IMG_path + IMG_name)
//**************************
 
private function showHint(e:MouseEvent):void {
  var _request:URLRequest = new URLRequest(e.target.name);
  var loader:Loader = new Loader();
  loader.load(_request);
 
  loader.contentLoaderInfo.addEventListener(Event.COMPLETE, showHint1);
  e.target.gotoAndStop(2);
  //тут собственно создал загрузчик и слушатель завершения.
}
 
private function showHint1(e:Event): void {
  var loader:Loader = e.target.loader as Loader;
  loader.x = 10;
  loader.y = 10;
 
  hint = new Panel(loader.width + 20, loader.height + 20); /* hint - это глобальная переменная которая хранит текущий открытый хинт. А панель это мой класс, который просто делает подложку. Это расширенный мувиклип, в котором с указанными размерами рисуется roundrect*/
  hint.x = mouseX + 20;
  hint.y = mouseY;
 
  hint.addChild(loader);
 
  this.addChild(hint);
}
 
private function hideHint(e:MouseEvent):void { //ну тут всё прозрачно...
  e.target.gotoAndStop(1);
  if (hint) this.removeChild(hint);
  hint = null;
}

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

посоветуйте как это в порядок привести? В идеале надо чтоб отображались адекватно, там где надо, и удалялись вовремя.

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

mikhailk 13.11.2010 12:14

Я бы сделал так:

1. Хинт показывать сразу (не дожидаясь окончания загрузки), вместо картинки - квадратик с крутящимся прогресс-баром
2. Картинки перевести в низкое качество и довести до 3-5кб.
3. Хинтер переработать так, чтобы он всегда показывал ту картинку, которая сейчас нужна (те, которые начали загружаться, но теперь не нужны - останутся в кеше)

А вообще-то, если товар показывается партиями, то превьюшки для хинтера грузить при открытии партии товара. Например, 10х5кб - это совершенно несерьезный размер.

Dukobpa3 13.11.2010 12:22

Была идея грузить картинки сразу, но иконки фотоаппарата показывать только когда они загрузились.

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

Насчет варианта:
3. Хинтер переработать так, чтобы он всегда показывал ту картинку, которая сейчас нужна (те, которые начали загружаться, но теперь не нужны - останутся в кеше)

//****************
а каким макаром проследить нужна она или уже нет? Типа убрался курсор с иконки - значит отставить показывать? Там где у меня стоит удаление, там надо походу докрутить еще и проверку на отбой показывания.

Или лучше на прогрессИвент что-то вешать?

mikhailk 13.11.2010 12:27

У Вас хинт всегда в единственном экземпляре существует. Заведите в классе статическую переменную (как вариант), в которую пишите текущий активный лоадер. При снятии мыша с позиции товара, обнуляйте его. Потом, когда картинка догрузилась, проверяйте, активный ли это лоадер. Если активный - показывайте, если нет - прибивайте. В кеше браузера картинка все равно останется.

cleptoman 13.11.2010 12:54

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

Dukobpa3 13.11.2010 12:57

Проблема решена:)

Просто я хинт добавлял только после того как загрузилась картинка, а надо было добавлять его сразу (как ваше предложение с прелоадером). Пустой хинт отображается сразу же, а следовательно в дальнейших проверках он уже не null, а следовательно я могу его удалить если убрал мышу с картинки. Потом при получении картинки смотрю есть хинт или нет, если есть, то показываю картинку, если нет, то забиваю на картинку.

Код AS3:

private function showHint(e:MouseEvent):void {
  var _request:URLRequest = new URLRequest(e.target.name);
  var loader:Loader = new Loader();
  loader.load(_request);
 
  loader.contentLoaderInfo.addEventListener(Event.COMPLETE, showHint1);
  e.target.gotoAndStop(2);
 
//собственно вот типа прелоадер добавил.
  hint = new Panel(20, 20);
  hint.x = mouseX + 20;
  hint.y = mouseY;
  this.addChild(hint);
}
 
private function showHint1(e:Event): void {
  var loader:Loader = e.target.loader as Loader;
  loader.x = 10;
  loader.y = 10;
 
  f (hint){//а здесь порверяю есть ли хинт, и если есть то отображаю картинку.
        this.removeChild(hint);
        hint = new Panel(loader.width + 20, loader.height + 20);
        hint.x = mouseX + 20;
        hint.y = mouseY;
        hint.addChild(loader);
        this.addChild(hint);
  }
}

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

Добавлено через 2 минуты
Цитата:

Сообщение от cleptoman (Сообщение 949515)
не нужна тут статическая.
делаете лоадер свойством класса. при скрытии хинта убивайте насмерть лоадер, прекращайте загрузки.

Действительно протупил ...

Подложка в свойства вынесена, а лоадер создается как временный, хотя надо бы наоборот.....

Спасибо:)

cleptoman 13.11.2010 14:00

вы можете сделать Dictionary , где ключ будет ваша картинка, а значение - загруженый для него хинт (если он был загружен).
таким образом делаем проверку - если есть уже хинт, то лоадер не дергаем, а берем хинт из хэша

Dukobpa3 13.11.2010 17:52

Цитата:

Сообщение от cleptoman (Сообщение 949530)
вы можете сделать Dictionary

Ну вообще в приведенном куске кода этого нима, повырезал, но вот этот двумерный массив объектов фактичеки хранит всю мою таблицу данных. В том числе и картинки.

То дальше уже буду крутить сравнения с наличием в моей таблице и если что - не делать лоадер. Меня пока интересовал сам механизм отображения картинки. (картинки в хинте не единственное место в базе с картинками, а вот так вот в режиме риалтайм отображается только тут... Во всех остальных случаях как раз так и есть как вы говорите, пытаемся отобразить из архива, если нету то качаем, засовываем в архив, отображаем)


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

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