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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | //----------------------------------------------------------------------------------- /* 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 { } |
(petit problème de la new sur Firefox : le code passe en dessous du menu de droite, surement un clear : left qui manque…)
14 avr 2009 @ 17:48
Réparé !
Merci pour le report !
14 avr 2009 @ 18:08
Thanks for this class !
just added (for autocompletion) :
/**
* Dispatched when the resize of the stage starts.
*/
[Event(name="stageResizeStart", type="com.electrofrog.events.StageResizeManagerEvent")]
/**
* Dispatched when the stage is being resized.
*/
[Event(name="stageResizeProgress", type="com.electrofrog.events.StageResizeManagerEvent")]
/**
* Dispatched when the resize of the stage is finished.
*/
[Event(name="stageResizeEnd", type="com.electrofrog.events.StageResizeManagerEvent")]
28 avr 2009 @ 18:39
That’s better with this thanks! I’ve updated the sources.
C’est mieux comme ça merci! J’ai mis à jour les sources.
29 avr 2009 @ 11:55
Sympathique cette classe, néanmoins en AS3 la valeur stage n’existe plus, on ne peut la récupérer que depuis la propriété stage d’un objet de la displaylist, donc tel quel j’obtiens une erreur impossible d’accéder à la propriété … nu.
Ou alors j’ai pas compris un truc.
Laurent
08 mai 2009 @ 14:39
Effectivement en AS3 n’importe quel objet de la Display List référence la propriété stage… justement la classe StageResizeManager utilise cette propriété par composition. Lorsqu’on invoque le constructeur de la classe par la méthode getInstance on écrit :
_srm = StageResizeManager.getinstance( stage, 200 );
où ’stage’ représente la valeur de cette propriété. On pourrait écrire aussi:
_srm = StageResizeManager.getinstance( this.stage, 200 );
ou
_srm = StageResizeManager.getinstance( monDisplayObject.stage, 200 );
08 mai 2009 @ 15:32
Après plusieurs demandes, j’ai ajouté les sources au format Flash CS3 / CS4
08 mai 2009 @ 16:00