PDA

Просмотр полной версии : выход курсора за пределы флешки


AlexSol
06.02.2007, 22:01
делаю флешку для сайта. Есть объекты которорые 'прилипают' к курсору если навести мышку на некую область, когда курсор выходит их области объекты возвращаются на свои места. Поскольку области могут иметь общую границу с самой флешкой, то возникает проблема возврашения объектов на свои места, когда курсор уходит за пределы флешки...
пробовал определить наличие мыша в области ролика так:
_root.onEnterFrame = function() {
if (_root._xmouse<0 || _root._xmouse>Stage.width || _root._ymouse<0 || _root._ymouse>Stage.height) {
tt.text = '!!!';
} else {
tt.text = Stage.width+':'+_root._xmouse+'\n'+Stage.height+':'+_root._ymouse;
}
};
срабатывает только в момент загрузки, а потом выдает последние координаты мышки в ролике.
Подскажите как можно отследить, что курсор ушел c флешки?

etc
06.02.2007, 22:06
В AS3 есть специальное событие для этого. Варианты реализации (не идеальные) под младшие версии есть на форуме.

AlexSol
06.02.2007, 22:50
про as3 знаю, но нужна 8. тоже складывается ощущение, что видел на форуме, вот только подобрать слова для поиска что-то не получается...

lowka
06.02.2007, 23:11
(Обновлено)
Может такой вариант подойдет:

import mx.utils.Delegate;

class AdvancedStage extends Stage {
private static var background:MovieClip;
private static var _initialized:Boolean;
private static var _atStage:Boolean;

private static var broadcastMessage:Function;
public static var addListener:Function;
public static var removeListener:Function;

/**
* Инициализация.
*/
public static function init():Void {
if(!AdvancedStage._initialized && AdvancedStage.background.getDepth()){
return;
}
AsBroadcaster.initialize(AdvancedStage);
AdvancedStage._initialized = true;
AdvancedStage.createBackground();

Stage.addListener(AdvancedStage);

AdvancedStage.onResize();
}

/**
* Создаем прозрачный фон.
*/
private static function createBackground():Void {
AdvancedStage.background = _root.createEmptyMovieClip("__stageBackground", -16900);
AdvancedStage.background.useHandCursor = false;

with(AdvancedStage.background){
beginFill(0xff0000, 0);
lineTo(10, 0);
lineTo(10, 10);
lineTo(0, 10);
lineTo(0, 0);
}

AdvancedStage._atStage = false;
AdvancedStage.background.onRollOver = Delegate.create(AdvancedStage, AdvancedStage.onRollOver);
AdvancedStage.background.onRollOut = AdvancedStage.background.onReleaseOutside = Delegate.create(AdvancedStage, AdvancedStage.onRollOut);
}

/**
* Генерация события onStageOver.
*/
private static function onRollOver():Void {
if(AdvancedStage.background._xmouse > 0 && AdvancedStage.background._ymouse > 0 &&
AdvancedStage.background._xmouse < AdvancedStage.background._width &&
AdvancedStage.background._ymouse < AdvancedStage.background._height && !AdvancedStage._atStage){

AdvancedStage._atStage = true;
AdvancedStage.broadcastMessage("onStageOver");
}
}

/**
* Генерация события onStageOut.
*/
private static function onRollOut():Void {
if(AdvancedStage._atStage){
AdvancedStage._atStage = false;
AdvancedStage.broadcastMessage("onStageOut");
}
updateAfterEvent();
}

/**
* Изменение размера фона в соответствие с размерами сцены.
* Генерация события onStageResize.
*/
private static function onResize():Void {
AdvancedStage.background._width = Stage.width;
AdvancedStage.background._height = Stage.height;

AdvancedStage.broadcastMessage("onStageResize");
}
}

Недостаток: Если курсор покинул сцену, а кнопка мыши зажата, то событие onStageOut сработает только после того, как кнопка будет отпущена.

AlexSol
07.02.2007, 14:48
спасибо! частично работает.
недостатки такие:
1) в момент загрузки не срабатывает ни одно из событий - начинает работать только при наведение на флешку /это я поправил/
2)есть несколько клипов, для которых прописано onPress - при наведение на них фызывается "onStageOut".
помогите пожалуйста обойти второй момент.

lowka
07.02.2007, 20:50
Работает только с align=TL. А для всех возможных кнопок на сцене нужно делать проверку в обработчике :( (см. пример кода).

import AdvancedStage;

var button:MovieClip;

//Проверка положения курсора.
function cursorAtTarget(target:MovieClip):Boolean {
if(target._xmouse>=0 && target._ymouse>=0 &&
traget._xmouse <= target._width &&
target._ymouse <= target._height ){
return true;
}else{
return false;
}
}

function onStageOut() {
//эту проверку нужно осуществлять для всех объектов
//у которых есть обработчик хотя бы одного
//из перечисленных ниже событий:
//onRelease, onReleaseOutside,
//onPress, onRollOver, onRollOut.
//если курсор над объектом, то игнорируем событие.
if(cursorAtTraget(button)){
return;
}
trace("onStageOut");
}

function onStageOver() {
trace("onStageOver");
}

//инициалиация (в onEnterFrame для IE).
function onEnterFrame():Void {
//корректно работает только для topleft :(
AdvancedStage.align="TL";

AdvancedStage.init();
AdvancedStage.addListener(this);

delete this.onEnterFrame;
}

AlexSol
08.02.2007, 17:26
спасибо за помошь!
часть проблем ушла, но часть осталась - если курсор на объекте, а объект пересекается с границами ролика, то событие onStageOut не срабатывает.