La classe StageResizeManager

Source : electrofrog.com

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

telecharger_code_source_flex

telecharger_code_source_flash

?View Code ACTIONSCRIPT3
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
{
}
  • Share/Save/Bookmark
Bookmark and Share

7 réponses Souscrire aux commentaires


  1. Bugreport

    (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


  2. maru

    Réparé !
    Merci pour le report !

    14 avr 2009 @ 18:08


  3. Rémi.T

    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


  4. Vincent Maitray

    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


  5. Ldesmarets

    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


  6. Vincent Maitray

    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


  7. Vincent Maitray

    Après plusieurs demandes, j’ai ajouté les sources au format Flash CS3 / CS4

    08 mai 2009 @ 16:00

Répondre