Съвет как да спрем драгването в AS3

B13_Savage

Registered
Днес в работа научих нещо сравнително полезно, ха да го споделя.
Ако сте писали на ActionScript2 сигурно помните хубавата функцийка stopDrag(); дето спира да драги всичко живо по сцента. В AS3 обаче, това стана метод на Sprite/MovieClip. Така, хубаво можете да почнете да си влачите нещо при MOUSE_DOWN, и да спрете да си го влачите при MOUSE_UP. Обаче, както често се случва, MOUSE_UP Еvent-a се извика не за вашия клип, а за този, който е под курсора в момента (ако някой си влачи мишката фриволно, това е честа ситуация). Така получаваме разни скролове, снимки и джунджурии които се влачат по курсора и когато не трябва, всичко е бъгаво грозно и сакато.
Решение е да се опишат всички възможни Object.stopDrag() за всички възможни получатели на MOUSE_UP. Това обаче е твърде трудоемко и често става много времеотнемащо. След като ни взеха глобалния stopDrag(), сегашния спира само за по едно обектче.
Това, което трябва да се сетия човек е да прочете спецификацията, в която пише, че макар и Obj.stopDrag() да спира драгенето за един обект, startDrag() го спира за всички (по-лесно е да се намери логика в Prolog, от колкото в това)
Ето и едно супер просто решение на проблема с не-спиращите да се влачат по курсора обекти : aбонираме клипа, държащ всичко на сцената (всички знаем, че цялото съдържание във Флаш нещо трябва да си има holder клип, нали ) за MouseEvent.MOUSE_UP. Заради пропагандирането на събитията, където и да е възникнал този Event, той все ще достигне до holder-a.
Трябва да си направим и един fake movie clip / sprite в този holder. Това, което е нужно е, когато прихванем такъв Event (a.k.a MouseEvent.MOUSE_UP) от и да кажем например :
Код:
//import bla-bla
pageHolder.addEventListener(MouseEvent.MOUSE_UP,StopAllDrag);
function StopAlLDrag(e:MouseEvent):void{
pageHolder.startDrag(pageHolder.fakeMovieClip_mc,new Rectangle(1,1,1,1));
pageHolder.fakeMovieClip.stopDrag();
}
Това супер естествено и очаквано начиние - да спираме драгването на каквото и да било със startDrag() спестява тонове код и главоболия.
Сполай и goodLuck с ActionScript-a.
*къдеот пише Event, може да се чете MouseEvent, понеже MouseEvent-a е Event, нали .. и дали е MovieClip или Sprite все тая too.
 
ако имаш нужда от такива хакове стил AS1, значи логиката ти куца.
а този "pageHolder" за който говориш се казва stage и практиката е event listener-a за MOUSE_UP да се добавя при започване на драгването (демек при MOUSE_DOWN) и да се изчиства след приключване на драгването.
колкото до този fakeMovieClip_mc по добре го махнеш да добавиш.
Код:
var dragged:Sprite;
да и присвояваш стойност за текущия драгван клип и при stage MOUSE_UP
Код:
dragged.stopDrag();


или като цяло

Код:
var dragged:Sprite;

someSprite.addEventListener(MouseEvent.MOUSE_DOWN, doDrag);

function doDrag(e:MouseEvent):void{
dragged = Sprite(e.currentTarget);
dragged.startDrag();
stage.addEventListener(MouseEvent.MOUSE_UP, doDrop);
}

function doDrop(e:MouseEvent):void {
dragged.stopDrag();
dragged = null;
stage.removeEventListener(MouseEvent.MOUSE_UP, doDrop);
}
 
Е, имаш известно право.
Но така пишеш няколко реда код повече, всеки път когато драгваш. Тоест, келепира не е голям, пък и в крайна сметка правиш нещо по същата логика.

Иначе че holder си трябва, трябва си ;]
 
ако говорим за генерални случай мисля че имам повече от известно право.
това което си предложил би имало приложение в случай при които искаш да регистрираш drop върху конкретен обект.
от контекста на написаното от теб останах с впечатление че описваш обаче един по-скоро генерален сценарии при който аз лично не бих намесил актьори като pageHolder, fakeMovieClip и new Rectangle.
поставям на първо място четимоста на кода, не обема му.
 
Определено четимоста на кода е нещо много важно и според мен :)
Предпочитам обаче също, да напиша едно нещо на едно място, вместо на много.
(А без играчите pageHolder и new Rectangle света е едно много по-мрачно място :) )

Иначе имаме нещо глобално, което се грижи за неприятните неща. Глобалните неща, колкото и с лоша репутация да са, продължават да съществуват, защото понякога е добре да се ползват .. когато е разумно.
Например глобална функция NavigateTo(вътрешни линкове, подКатегории, продукти, външни линкове, бла-бла), когато правиш някакъв сайт; StopDrag (тоест, non-intrusive имплементация), когато не ти се обясня на всяко нещо да спира да се драгва и други разни такива примери. Ако работиш в голям екип, сигурно не е добра идея. Иначе си е екстра, в никой случай не прави нещо нечетимо.

И все пак е важна поуката .. хващайте Ъп-а за стопДраг далеч, където винаги сте сигурни че ще дойде, за да нямаме разревани. Подходи сигурно има и други, но за всеки могат да се изтъкнат и бенефите и недостатъци.

Но безспорно е хубаво, да имаме във форума различни гледни точки над някакви проблеми :?: :?:
 

Back
Горе