Dernièrement lors de la réalisation d’un projet, j’ai eu besoin d’utiliser l’évènement RESIZE de la classe Stage, mais je n’étais pas entièrement satisfait de son fonctionnement. En effet, il est diffusé de manière répétée (et incontrôlable…) lorsque l’utilisateur redimensionne la scène, et cela était parfaitement incompatible avec ce que je voulais faire, à savoir une boucle sur plusieurs dizaines de Sprites avec repositionnement de chacun d’entre eux + mouvement. J’ai donc crée cette petite classe StageResizeManager qui diffuse un évènement au début du resize (RESIZE_START), puis ensuite l’évènement classique est diffusé de manière répétitive lors du redimensionnement (notez qu’il ne s’appelle plus RESIZE mais RESIZE_PROGRESS ) et enfin un dernier évènement (RESIZE_END) est diffusé à la fin du redimensionnement, c’est à dire n millisecondes après la fin de détection de mouvement de souris continu lors d’un resize. C’est lui qu’il est intéressant d’écouter.
La classe est un singleton, et la méthode qui permet de l’instancier prend deux paramètres. Le premier, pStage est obligatoire et c’est la référence à la scène, le second est facultatif, sa valeur par défaut est de 250ms, et représente le délai après lequel l’évènement RESIZE_END est diffusé.
Le fichier d’exemple qui contient la classe est un projet Flex 3 qui ne fait rien d’autre que de tracer PIM, PAM et POUM en fonction des évènements diffusés. Cette classe n’utilise aucune particularité du framework Flex, elle est donc entièrement compatible avec tout projet en AS3.
################# edit du 8/05/2009
Après plusieurs demandes, j’ai ajouté les sources au format Flash CS3/CS4



//-----------------------------------------------------------------------------------
/*
Copyleft (¢) 2009 Vincent Maitray - www.electrofrog.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Mention to the author would be appreciated !
*/
//-----------------------------------------------------------------------------------
package com.electrofrog.utils
{
import com.electrofrog.events.StageResizeManagerEvent;
import flash.display.Stage;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.TimerEvent;
import flash.ui.Mouse;
import flash.utils.Timer;
/**
* Handle the resize process of the stage more accuratly than the simple Event.resize event.
*
* @param pStage The stage instance to be listen to.
* @param pResizeEndDelay The delay in ms after which the ResizeManagerEvent.STAGE_RESIZE_END event is dispatched.
*
* @author Vincent Maitray
* @date April 03, 2009.
*/
public class StageResizeManager extends EventDispatcher
{
private static var _instance:StageResizeManager;
private var _stage:Stage;
private var _t1:Timer;
private var _resizeEndDelay:int;
/**
* Method for instanciating this class as a Singleton
*/
public static function getinstance( pStage:Stage, pResizeEndDelay:int = 250 ):StageResizeManager
{
if ( !_instance )
_instance = new StageResizeManager( new SingletonEnforcer(), pStage, pResizeEndDelay );
return _instance;
}
/**
* hidden constructor.
* @private
*/
public function StageResizeManager( se:SingletonEnforcer, pStage:Stage, pResizeEndDelay:int )
{
if ( !se )
throw( new Error( "operator 'new' is not not allowed with singleton classes. Use ResizeManager.getInstance() instead !" ) );
_stage = pStage;
_resizeEndDelay = pResizeEndDelay;
_stage.addEventListener( Event.RESIZE, onStageResize );
_t1 = new Timer( 50, 0 );
_t1.addEventListener( TimerEvent.TIMER, onTimer );
}
/**
* Fired when the user resizes the stage
*
* @param e Event
*/
private function onStageResize( e:Event ):void
{
if( !_t1.running )
{
dispatchEvent( new StageResizeManagerEvent( StageResizeManagerEvent.STAGE_RESIZE_START, false, false ) );
_t1.start();
}
else
{
dispatchEvent( new StageResizeManagerEvent( StageResizeManagerEvent.STAGE_RESIZE_PROGRESS, false, false ) );
_t1.reset();
_t1.start();
}
}
/**
* Fired each pResizeEndDelay ms ( eg 250 ) when the timer is running.
*
* @param e Event
*/
private function onTimer( e:TimerEvent ):void
{
var t:Timer = e.currentTarget as Timer
var count:int = t.currentCount * t.delay;
if( count > _resizeEndDelay )
{
_t1.reset();
dispatchEvent( new StageResizeManagerEvent( StageResizeManagerEvent.STAGE_RESIZE_END, false, false ) );
}
}
}
}
/**
* Dummy class, part of the Singleton subsystem
*/
class SingletonEnforcer
{
}
related / voir aussi
3 Comments
Permalink
chouette !
Merci
Permalink
HUmmm. le fait d’utiliser un timer ne « ralentit » pas le process ? ( vu que tu as un Timer + event Resize qui tournent en meme temps )
j’ai eu un projet avec la meme problematique, et j’avais choisis de diffuser l’evenement tout les 5 tick:
onResize -> i++
et des que i = 5 –> on appelle les differentes fonctions de resize.
Permalink
@daweed très bonne idée le coup de l’incrément… je vais tester ça.